From 9e78d14a9f641c0476f733f6fc559ba5cac6f52b Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 10 Dec 2013 15:26:48 +0000 Subject: [PATCH 0001/9167] Use %pd in eCryptFS Use the new %pd printk() specifier in eCryptFS to replace passing of dentry name or dentry name and name length * 2 with just passing the dentry. Signed-off-by: David Howells cc: ecryptfs@vger.kernel.org Signed-off-by: Tyler Hicks --- fs/ecryptfs/file.c | 4 ++-- fs/ecryptfs/inode.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index b1eaa7a1f82c..c705360e2b16 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c @@ -230,8 +230,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file) if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " "the lower file for the dentry with name " - "[%s]; rc = [%d]\n", __func__, - ecryptfs_dentry->d_name.name, rc); + "[%pd]; rc = [%d]\n", __func__, + ecryptfs_dentry, rc); goto out_free; } if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index c36c44824471..87ad33e091e9 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -250,8 +250,8 @@ int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " "the lower file for the dentry with name " - "[%s]; rc = [%d]\n", __func__, - ecryptfs_dentry->d_name.name, rc); + "[%pd]; rc = [%d]\n", __func__, + ecryptfs_dentry, rc); goto out; } rc = ecryptfs_write_metadata(ecryptfs_dentry, ecryptfs_inode); @@ -313,8 +313,8 @@ static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode) if (rc) { printk(KERN_ERR "%s: Error attempting to initialize " "the lower file for the dentry with name " - "[%s]; rc = [%d]\n", __func__, - dentry->d_name.name, rc); + "[%pd]; rc = [%d]\n", __func__, + dentry, rc); return rc; } @@ -418,8 +418,8 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, if (IS_ERR(lower_dentry)) { rc = PTR_ERR(lower_dentry); ecryptfs_printk(KERN_DEBUG, "%s: lookup_one_len() returned " - "[%d] on lower_dentry = [%s]\n", __func__, rc, - ecryptfs_dentry->d_name.name); + "[%d] on lower_dentry = [%pd]\n", __func__, rc, + ecryptfs_dentry); goto out; } if (lower_dentry->d_inode) -- GitLab From 1fde2548460c1ded9fe71220b506473f0b7de768 Mon Sep 17 00:00:00 2001 From: Yijing Wang Date: Thu, 5 Dec 2013 19:31:18 +0800 Subject: [PATCH 0002/9167] ioat/dca: Use dev_is_pci() to check whether it is pci device Use PCI standard marco dev_is_pci() instead of directly compare pci_bus_type to check whether it is pci device. Signed-off-by: Yijing Wang Signed-off-by: Dan Williams --- drivers/dma/ioat/dca.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/dma/ioat/dca.c b/drivers/dma/ioat/dca.c index 9e84d5bc9307..79009632830d 100644 --- a/drivers/dma/ioat/dca.c +++ b/drivers/dma/ioat/dca.c @@ -147,7 +147,7 @@ static int ioat_dca_add_requester(struct dca_provider *dca, struct device *dev) u16 id; /* This implementation only supports PCI-Express */ - if (dev->bus != &pci_bus_type) + if (!dev_is_pci(dev)) return -ENODEV; pdev = to_pci_dev(dev); id = dcaid_from_pcidev(pdev); @@ -179,7 +179,7 @@ static int ioat_dca_remove_requester(struct dca_provider *dca, int i; /* This implementation only supports PCI-Express */ - if (dev->bus != &pci_bus_type) + if (!dev_is_pci(dev)) return -ENODEV; pdev = to_pci_dev(dev); @@ -320,7 +320,7 @@ static int ioat2_dca_add_requester(struct dca_provider *dca, struct device *dev) u16 global_req_table; /* This implementation only supports PCI-Express */ - if (dev->bus != &pci_bus_type) + if (!dev_is_pci(dev)) return -ENODEV; pdev = to_pci_dev(dev); id = dcaid_from_pcidev(pdev); @@ -354,7 +354,7 @@ static int ioat2_dca_remove_requester(struct dca_provider *dca, u16 global_req_table; /* This implementation only supports PCI-Express */ - if (dev->bus != &pci_bus_type) + if (!dev_is_pci(dev)) return -ENODEV; pdev = to_pci_dev(dev); @@ -496,7 +496,7 @@ static int ioat3_dca_add_requester(struct dca_provider *dca, struct device *dev) u16 global_req_table; /* This implementation only supports PCI-Express */ - if (dev->bus != &pci_bus_type) + if (!dev_is_pci(dev)) return -ENODEV; pdev = to_pci_dev(dev); id = dcaid_from_pcidev(pdev); @@ -530,7 +530,7 @@ static int ioat3_dca_remove_requester(struct dca_provider *dca, u16 global_req_table; /* This implementation only supports PCI-Express */ - if (dev->bus != &pci_bus_type) + if (!dev_is_pci(dev)) return -ENODEV; pdev = to_pci_dev(dev); -- GitLab From b8c01d259a08d75c5049b2bd5f579648262c30a4 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Tue, 10 Dec 2013 09:32:37 -0300 Subject: [PATCH 0003/9167] dma: mv_xor: Add DMA API error checks This commit adds proper error checking for various DMA API calls, as reported by DMA_API_DEBUG=y. Signed-off-by: Ezequiel Garcia Signed-off-by: Dan Williams --- drivers/dma/mv_xor.c | 56 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 766b68ed505c..e70f271c99fa 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -784,7 +784,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan) static int mv_xor_memcpy_self_test(struct mv_xor_chan *mv_chan) { - int i; + int i, ret; void *src, *dest; dma_addr_t src_dma, dest_dma; struct dma_chan *dma_chan; @@ -821,19 +821,44 @@ static int mv_xor_memcpy_self_test(struct mv_xor_chan *mv_chan) src_dma = dma_map_page(dma_chan->device->dev, virt_to_page(src), 0, PAGE_SIZE, DMA_TO_DEVICE); - unmap->to_cnt = 1; unmap->addr[0] = src_dma; + ret = dma_mapping_error(dma_chan->device->dev, src_dma); + if (ret) { + err = -ENOMEM; + goto free_resources; + } + unmap->to_cnt = 1; + dest_dma = dma_map_page(dma_chan->device->dev, virt_to_page(dest), 0, PAGE_SIZE, DMA_FROM_DEVICE); - unmap->from_cnt = 1; unmap->addr[1] = dest_dma; + ret = dma_mapping_error(dma_chan->device->dev, dest_dma); + if (ret) { + err = -ENOMEM; + goto free_resources; + } + unmap->from_cnt = 1; unmap->len = PAGE_SIZE; tx = mv_xor_prep_dma_memcpy(dma_chan, dest_dma, src_dma, PAGE_SIZE, 0); + if (!tx) { + dev_err(dma_chan->device->dev, + "Self-test cannot prepare operation, disabling\n"); + err = -ENODEV; + goto free_resources; + } + cookie = mv_xor_tx_submit(tx); + if (dma_submit_error(cookie)) { + dev_err(dma_chan->device->dev, + "Self-test submit error, disabling\n"); + err = -ENODEV; + goto free_resources; + } + mv_xor_issue_pending(dma_chan); async_tx_ack(tx); msleep(1); @@ -868,7 +893,7 @@ static int mv_xor_memcpy_self_test(struct mv_xor_chan *mv_chan) static int mv_xor_xor_self_test(struct mv_xor_chan *mv_chan) { - int i, src_idx; + int i, src_idx, ret; struct page *dest; struct page *xor_srcs[MV_XOR_NUM_SRC_TEST]; dma_addr_t dma_srcs[MV_XOR_NUM_SRC_TEST]; @@ -931,19 +956,42 @@ mv_xor_xor_self_test(struct mv_xor_chan *mv_chan) unmap->addr[i] = dma_map_page(dma_chan->device->dev, xor_srcs[i], 0, PAGE_SIZE, DMA_TO_DEVICE); dma_srcs[i] = unmap->addr[i]; + ret = dma_mapping_error(dma_chan->device->dev, unmap->addr[i]); + if (ret) { + err = -ENOMEM; + goto free_resources; + } unmap->to_cnt++; } unmap->addr[src_count] = dma_map_page(dma_chan->device->dev, dest, 0, PAGE_SIZE, DMA_FROM_DEVICE); dest_dma = unmap->addr[src_count]; + ret = dma_mapping_error(dma_chan->device->dev, unmap->addr[src_count]); + if (ret) { + err = -ENOMEM; + goto free_resources; + } unmap->from_cnt = 1; unmap->len = PAGE_SIZE; tx = mv_xor_prep_dma_xor(dma_chan, dest_dma, dma_srcs, src_count, PAGE_SIZE, 0); + if (!tx) { + dev_err(dma_chan->device->dev, + "Self-test cannot prepare operation, disabling\n"); + err = -ENODEV; + goto free_resources; + } cookie = mv_xor_tx_submit(tx); + if (dma_submit_error(cookie)) { + dev_err(dma_chan->device->dev, + "Self-test submit error, disabling\n"); + err = -ENODEV; + goto free_resources; + } + mv_xor_issue_pending(dma_chan); async_tx_ack(tx); msleep(8); -- GitLab From 8d1d32767ca0df1b5cd75cdc1be3915bc6887ed1 Mon Sep 17 00:00:00 2001 From: Rashika Date: Mon, 16 Dec 2013 15:40:40 +0530 Subject: [PATCH 0004/9167] drivers: dma: Mark functions as static in dma_v3.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mark the functions ioat3_prep_xor_val(), ioat3_prep_pq_val() and ioat3_prep_pqxor_val() as static in dma_v3.c because they are not used outside this file. This eliminates the following warnings in dma_v3.c: drivers/dma/ioat/dma_v3.c:741:1: warning: no previous prototype for ‘ioat3_prep_xor_val’ [-Wmissing-prototypes] drivers/dma/ioat/dma_v3.c:1092:1: warning: no previous prototype for ‘ioat3_prep_pq_val’ [-Wmissing-prototypes] drivers/dma/ioat/dma_v3.c:1134:1: warning: no previous prototype for ‘ioat3_prep_pqxor_val’ [-Wmissing-prototypes] Signed-off-by: Rashika Kheria Reviewed-by: Josh Triplett Acked-by: Vinod Koul Signed-off-by: Dan Williams --- drivers/dma/ioat/dma_v3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index b9b38a1cf92f..85971d6e9646 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c @@ -740,7 +740,7 @@ ioat3_prep_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, return __ioat3_prep_xor_lock(chan, NULL, dest, src, src_cnt, len, flags); } -struct dma_async_tx_descriptor * +static struct dma_async_tx_descriptor * ioat3_prep_xor_val(struct dma_chan *chan, dma_addr_t *src, unsigned int src_cnt, size_t len, enum sum_check_flags *result, unsigned long flags) @@ -1091,7 +1091,7 @@ ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, } } -struct dma_async_tx_descriptor * +static struct dma_async_tx_descriptor * ioat3_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, unsigned int src_cnt, const unsigned char *scf, size_t len, enum sum_check_flags *pqres, unsigned long flags) @@ -1133,7 +1133,7 @@ ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src, flags); } -struct dma_async_tx_descriptor * +static struct dma_async_tx_descriptor * ioat3_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src, unsigned int src_cnt, size_t len, enum sum_check_flags *result, unsigned long flags) -- GitLab From 2358b820d42a33f1d1052b438489c90a4cc8f3fc Mon Sep 17 00:00:00 2001 From: Rashika Date: Mon, 16 Dec 2013 15:44:39 +0530 Subject: [PATCH 0005/9167] drivers: dma: Include appropriate header file in dca.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Includes an appropriate header file dma_v2.h in ioat/dca.c because functions ioat2_dca_init() and ioat3_dca_init() have their function declarations in dma_v2.h. This eliminates the following warning in ioat/dca.c: drivers/dma/ioat/dca.c:410:22: warning: no previous prototype for ‘ioat2_dca_init’ [-Wmissing-prototypes] drivers/dma/ioat/dca.c:624:22: warning: no previous prototype for ‘ioat3_dca_init’ [-Wmissing-prototypes] Signed-off-by: Rashika Kheria Reviewed-by: Josh Triplett Acked-by: Vinod Koul Signed-off-by: Dan Williams --- drivers/dma/ioat/dca.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/ioat/dca.c b/drivers/dma/ioat/dca.c index 79009632830d..3b55bb8d969a 100644 --- a/drivers/dma/ioat/dca.c +++ b/drivers/dma/ioat/dca.c @@ -35,6 +35,7 @@ #include "dma.h" #include "registers.h" +#include "dma_v2.h" /* * Bit 7 of a tag map entry is the "valid" bit, if it is set then bits 0:6 -- GitLab From 368da992b93eaf8861f1ef2d27bbe22c01140733 Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Thu, 6 Mar 2014 21:11:21 +0100 Subject: [PATCH 0006/9167] ioat: Use pci_enable_msix_exact() instead of pci_enable_msix() As result of deprecation of MSI-X/MSI enablement functions pci_enable_msix() and pci_enable_msi_block() all drivers using these two interfaces need to be updated to use the new pci_enable_msi_range() or pci_enable_msi_exact() and pci_enable_msix_range() or pci_enable_msix_exact() interfaces. Function pci_enable_msix() returns a tri-state value while pci_enable_msi_exact() is a canonical zero/-errno variant. The former is being phased out in favor of the latter. In case of 'ioat' there (should be) no difference. Cc: Vinod Koul Signed-off-by: Alexander Gordeev Signed-off-by: Dan Williams --- drivers/dma/ioat/dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index 4e3549a16132..b76c1485933b 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -947,7 +947,7 @@ int ioat_dma_setup_interrupts(struct ioatdma_device *device) for (i = 0; i < msixcnt; i++) device->msix_entries[i].entry = i; - err = pci_enable_msix(pdev, device->msix_entries, msixcnt); + err = pci_enable_msix_exact(pdev, device->msix_entries, msixcnt); if (err) goto msi; -- GitLab From 890766d278548afdc059cd977687c4f1297d72a0 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 7 Mar 2014 16:46:45 -0300 Subject: [PATCH 0007/9167] dma: mv_xor: Remove unneeded mv_xor_clean_completed_slots() call In mv_xor_status(), we are currently calling mv_xor_clean_completed_slots() when the transaction is complete (the cookie status is DMA_COMPLETE). However, a completed status means that mv_xor_slot_cleanup() was called, which cleans the completed slots. In other words, there's nothing to cleanup for a completed transaction in mv_xor_status(). Remove the unneeded call to mv_xor_clean_completed_slots(). Reported-by: Dan Williams Signed-off-by: Ezequiel Garcia Signed-off-by: Dan Williams --- drivers/dma/mv_xor.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index e70f271c99fa..e2c8ec91155e 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -702,10 +702,8 @@ static enum dma_status mv_xor_status(struct dma_chan *chan, enum dma_status ret; ret = dma_cookie_status(chan, cookie, txstate); - if (ret == DMA_COMPLETE) { - mv_xor_clean_completed_slots(mv_chan); + if (ret == DMA_COMPLETE) return ret; - } mv_xor_slot_cleanup(mv_chan); return dma_cookie_status(chan, cookie, txstate); -- GitLab From e43147acba6f64ba32664dd0e590657cc49b6940 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 7 Mar 2014 16:46:46 -0300 Subject: [PATCH 0008/9167] dma: mv_xor: Remove all callers of mv_xor_slot_cleanup() In order to simplify the code, remove all the calls to the locked mv_xor_slot_cleanup() and instead use the unlocked version only, It's less error prone to have just one function, and require the caller to ensure proper locking. Signed-off-by: Ezequiel Garcia Signed-off-by: Dan Williams --- drivers/dma/mv_xor.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index e2c8ec91155e..fad016a6dd84 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -379,7 +379,10 @@ mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) static void mv_xor_tasklet(unsigned long data) { struct mv_xor_chan *chan = (struct mv_xor_chan *) data; - mv_xor_slot_cleanup(chan); + + spin_lock_bh(&chan->lock); + __mv_xor_slot_cleanup(chan); + spin_unlock_bh(&chan->lock); } static struct mv_xor_desc_slot * @@ -658,9 +661,10 @@ static void mv_xor_free_chan_resources(struct dma_chan *chan) struct mv_xor_desc_slot *iter, *_iter; int in_use_descs = 0; - mv_xor_slot_cleanup(mv_chan); - spin_lock_bh(&mv_chan->lock); + + __mv_xor_slot_cleanup(mv_chan); + list_for_each_entry_safe(iter, _iter, &mv_chan->chain, chain_node) { in_use_descs++; @@ -704,7 +708,10 @@ static enum dma_status mv_xor_status(struct dma_chan *chan, ret = dma_cookie_status(chan, cookie, txstate); if (ret == DMA_COMPLETE) return ret; - mv_xor_slot_cleanup(mv_chan); + + spin_lock_bh(&mv_chan->lock); + __mv_xor_slot_cleanup(mv_chan); + spin_unlock_bh(&mv_chan->lock); return dma_cookie_status(chan, cookie, txstate); } -- GitLab From fbeec99ad5c03060ba71c470ac373e24e23a80e0 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Fri, 7 Mar 2014 16:46:47 -0300 Subject: [PATCH 0009/9167] dma: mv_xor: Rename __mv_xor_slot_cleanup() to mv_xor_slot_cleanup() Now that mv_xor_slot_cleanup() has no remaining callers, we remove it and rename __mv_xor_slot_cleanup() to mv_xor_slot_cleanup(). We take this opportunity to add a comment that makes it clear that the channel spinlock should be held before calling mv_xor_slot_cleanup(). Signed-off-by: Thomas Petazzoni Signed-off-by: Ezequiel Garcia Signed-off-by: Dan Williams --- drivers/dma/mv_xor.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index fad016a6dd84..8eca90d8cd4c 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -312,7 +312,8 @@ mv_xor_clean_slot(struct mv_xor_desc_slot *desc, return 0; } -static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) +/* This function must be called with the mv_xor_chan spinlock held */ +static void mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) { struct mv_xor_desc_slot *iter, *_iter; dma_cookie_t cookie = 0; @@ -368,20 +369,12 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) mv_chan->dmachan.completed_cookie = cookie; } -static void -mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) -{ - spin_lock_bh(&mv_chan->lock); - __mv_xor_slot_cleanup(mv_chan); - spin_unlock_bh(&mv_chan->lock); -} - static void mv_xor_tasklet(unsigned long data) { struct mv_xor_chan *chan = (struct mv_xor_chan *) data; spin_lock_bh(&chan->lock); - __mv_xor_slot_cleanup(chan); + mv_xor_slot_cleanup(chan); spin_unlock_bh(&chan->lock); } @@ -663,7 +656,7 @@ static void mv_xor_free_chan_resources(struct dma_chan *chan) spin_lock_bh(&mv_chan->lock); - __mv_xor_slot_cleanup(mv_chan); + mv_xor_slot_cleanup(mv_chan); list_for_each_entry_safe(iter, _iter, &mv_chan->chain, chain_node) { @@ -710,7 +703,7 @@ static enum dma_status mv_xor_status(struct dma_chan *chan, return ret; spin_lock_bh(&mv_chan->lock); - __mv_xor_slot_cleanup(mv_chan); + mv_xor_slot_cleanup(mv_chan); spin_unlock_bh(&mv_chan->lock); return dma_cookie_status(chan, cookie, txstate); -- GitLab From c4cf3ba4f34819170fee43532f729e2fc6aa9a76 Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Fri, 27 Jun 2014 01:11:59 +0530 Subject: [PATCH 0010/9167] ecryptfs: Drop cast This patch does away with cast on void * and the if as it is unnecessary. The following Coccinelle semantic patch was used for making the change: @r@ expression x; void* e; type T; identifier f; @@ ( *((T *)e) | ((T *)x)[...] | ((T *)x)->f | - (T *) e ) Signed-off-by: Himangi Saraogi Signed-off-by: Tyler Hicks --- fs/ecryptfs/inode.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 87ad33e091e9..a27121d35b23 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -53,9 +53,7 @@ static void unlock_dir(struct dentry *dir) static int ecryptfs_inode_test(struct inode *inode, void *lower_inode) { - if (ecryptfs_inode_to_lower(inode) == (struct inode *)lower_inode) - return 1; - return 0; + return ecryptfs_inode_to_lower(inode) == lower_inode; } static int ecryptfs_inode_set(struct inode *inode, void *opaque) -- GitLab From 3db593e8af0a7361037a2abbe8910d4e44041d89 Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Mon, 16 Jun 2014 20:06:12 +0200 Subject: [PATCH 0011/9167] fs/ecryptfs/messaging.c: remove null test before kfree Fix checkpatch warning: WARNING: kfree(NULL) is safe this check is probably not required Signed-off-by: Fabian Frederick Cc: ecryptfs@vger.kernel.org Signed-off-by: Tyler Hicks --- fs/ecryptfs/messaging.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index e57380e5f6bd..286f10b0363b 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c @@ -434,8 +434,7 @@ void ecryptfs_release_messaging(void) mutex_lock(&ecryptfs_msg_ctx_lists_mux); for (i = 0; i < ecryptfs_message_buf_len; i++) { mutex_lock(&ecryptfs_msg_ctx_arr[i].mux); - if (ecryptfs_msg_ctx_arr[i].msg) - kfree(ecryptfs_msg_ctx_arr[i].msg); + kfree(ecryptfs_msg_ctx_arr[i].msg); mutex_unlock(&ecryptfs_msg_ctx_arr[i].mux); } kfree(ecryptfs_msg_ctx_arr); -- GitLab From 27199b15e4f027e24969f6644ce4ff414c7e6cba Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 18 Jun 2014 21:15:59 -0400 Subject: [PATCH 0012/9167] ecryptfs: Remove unnecessary include of syscall.h in keystore.c There's no reason to include syscalls.h in keystore.c. Remove it. Signed-off-by: Steven Rostedt Signed-off-by: Tyler Hicks --- fs/ecryptfs/keystore.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 4725a07f003c..831c5f8529be 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -26,7 +26,6 @@ */ #include -#include #include #include #include -- GitLab From 04ec5f5c0022ee941615e304bc75853fe1bc94ba Mon Sep 17 00:00:00 2001 From: Fabian Frederick Date: Tue, 8 Jul 2014 18:30:07 +0200 Subject: [PATCH 0013/9167] ecryptfs: remove unnecessary break after goto Signed-off-by: Fabian Frederick Cc: ecryptfs@vger.kernel.org Signed-off-by: Tyler Hicks --- fs/ecryptfs/keystore.c | 1 - 1 file changed, 1 deletion(-) diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index 831c5f8529be..635e8e16a5b7 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -1845,7 +1845,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, "(Tag 11 not allowed by itself)\n"); rc = -EIO; goto out_wipe_list; - break; default: ecryptfs_printk(KERN_DEBUG, "No packet at offset [%zd] " "of the file header; hex value of " -- GitLab From 017b5522d5e31a0b2c2f54f566aa8887838bccc7 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 8 Jul 2014 18:21:11 +0200 Subject: [PATCH 0014/9167] ARM: at91: Add new binding for sama5d3-ddramc The IP for the SDRAM controller found on sama5d3 SoCs is different from the g45 one. Introduce a new compatible string to reflect that. Signed-off-by: Alexandre Belloni Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre --- Documentation/devicetree/bindings/arm/atmel-at91.txt | 1 + arch/arm/mach-at91/setup.c | 1 + 2 files changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt index 16f60b41c147..33bcf8b57798 100644 --- a/Documentation/devicetree/bindings/arm/atmel-at91.txt +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt @@ -61,6 +61,7 @@ RAMC SDRAM/DDR Controller required properties: - compatible: Should be "atmel,at91rm9200-sdramc", "atmel,at91sam9260-sdramc", "atmel,at91sam9g45-ddramc", + "atmel,sama5d3-ddramc", - reg: Should contain registers location and length For at91sam9263 and at91sam9g45 you must specify 2 entries. diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index f7a07a58ebb6..faff1eae3e65 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -384,6 +384,7 @@ static struct of_device_id ramc_ids[] = { { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby }, { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby }, { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby }, + { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby }, { /*sentinel*/ } }; -- GitLab From e81b6abebc87ec40a434ada4ca8d1f2aa16cea9d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 8 Jul 2014 18:21:12 +0200 Subject: [PATCH 0015/9167] memory: add a driver for atmel ram controllers Atmel SoCs have one or multiple RAM controllers that need one or multiple clocks to run. This driver handle those clocks. Signed-off-by: Alexandre Belloni Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre --- drivers/memory/Kconfig | 10 ++++ drivers/memory/Makefile | 1 + drivers/memory/atmel-sdramc.c | 98 +++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 drivers/memory/atmel-sdramc.c diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index c59e9c96e86d..257061c3c816 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -7,6 +7,16 @@ menuconfig MEMORY if MEMORY +config ATMEL_SDRAMC + bool "Atmel (Multi-port DDR-)SDRAM Controller" + default y + depends on ARCH_AT91 && OF + help + This driver is for Atmel SDRAM Controller or Atmel Multi-port + DDR-SDRAM Controller available on Atmel AT91SAM9 and SAMA5 SoCs. + Starting with the at91sam9g45, this controller supports SDR, DDR and + LP-DDR memories. + config TI_AEMIF tristate "Texas Instruments AEMIF driver" depends on (ARCH_DAVINCI || ARCH_KEYSTONE) && OF diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index 71160a2b7313..b8637261e1a1 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -5,6 +5,7 @@ ifeq ($(CONFIG_DDR),y) obj-$(CONFIG_OF) += of_memory.o endif +obj-$(CONFIG_ATMEL_SDRAMC) += atmel-sdramc.o obj-$(CONFIG_TI_AEMIF) += ti-aemif.o obj-$(CONFIG_TI_EMIF) += emif.o obj-$(CONFIG_FSL_IFC) += fsl_ifc.o diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c new file mode 100644 index 000000000000..fed04e8efe75 --- /dev/null +++ b/drivers/memory/atmel-sdramc.c @@ -0,0 +1,98 @@ +/* + * Atmel (Multi-port DDR-)SDRAM Controller driver + * + * Copyright (C) 2014 Atmel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include +#include +#include +#include +#include +#include + +struct at91_ramc_caps { + bool has_ddrck; + bool has_mpddr_clk; +}; + +static const struct at91_ramc_caps at91rm9200_caps = { }; + +static const struct at91_ramc_caps at91sam9g45_caps = { + .has_ddrck = 1, + .has_mpddr_clk = 0, +}; + +static const struct at91_ramc_caps sama5d3_caps = { + .has_ddrck = 1, + .has_mpddr_clk = 1, +}; + +static const struct of_device_id atmel_ramc_of_match[] = { + { .compatible = "atmel,at91rm9200-sdramc", .data = &at91rm9200_caps, }, + { .compatible = "atmel,at91sam9260-sdramc", .data = &at91rm9200_caps, }, + { .compatible = "atmel,at91sam9g45-ddramc", .data = &at91sam9g45_caps, }, + { .compatible = "atmel,sama5d3-ddramc", .data = &sama5d3_caps, }, + {}, +}; +MODULE_DEVICE_TABLE(of, atmel_ramc_of_match); + +static int atmel_ramc_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct at91_ramc_caps *caps; + struct clk *clk; + + match = of_match_device(atmel_ramc_of_match, &pdev->dev); + caps = match->data; + + if (caps->has_ddrck) { + clk = devm_clk_get(&pdev->dev, "ddrck"); + if (IS_ERR(clk)) + return PTR_ERR(clk); + clk_prepare_enable(clk); + } + + if (caps->has_mpddr_clk) { + clk = devm_clk_get(&pdev->dev, "mpddr"); + if (IS_ERR(clk)) { + pr_err("AT91 RAMC: couldn't get mpddr clock\n"); + return PTR_ERR(clk); + } + clk_prepare_enable(clk); + } + + return 0; +} + +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, + }, +}; + +static int __init atmel_ramc_init(void) +{ + return platform_driver_register(&atmel_ramc_driver); +} +module_init(atmel_ramc_init); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Alexandre Belloni "); +MODULE_DESCRIPTION("Atmel (Multi-port DDR-)SDRAM Controller"); -- GitLab From 63e60368956ea076278dd3d70dc80b366e0ec6f3 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 8 Jul 2014 18:21:13 +0200 Subject: [PATCH 0016/9167] ARM: at91: select ATMEL_SDRAMC when using OF When using device tree, select the Atmel RAM controller driver to handle its clocks. Signed-off-by: Alexandre Belloni Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre --- arch/arm/mach-at91/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 45b55e0f0db6..7a69ffd93b6b 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -49,6 +49,8 @@ config SOC_AT91SAM9 select GENERIC_CLOCKEVENTS select MULTI_IRQ_HANDLER select SPARSE_IRQ + select MEMORY if USE_OF + select ATMEL_SDRAMC if USE_OF config SOC_SAMA5 bool @@ -58,6 +60,8 @@ config SOC_SAMA5 select MULTI_IRQ_HANDLER select SPARSE_IRQ select USE_OF + select MEMORY + select ATMEL_SDRAMC menu "Atmel AT91 System-on-Chip" -- GitLab From b736bcb3d8fe6182d12feb0412106802d80b4527 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 8 Jul 2014 18:21:16 +0200 Subject: [PATCH 0017/9167] clk: at91: remove the useless CLK_IGNORE_UNUSED flag The CLK_IGNORE_UNUSED flag was added on all the system clocks because of the ddrck. Now that it is handled by the ram controller driver, we can drop it. Signed-off-by: Alexandre Belloni Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre --- drivers/clk/at91/clk-system.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c index 8c96307d7363..a76d03fd577b 100644 --- a/drivers/clk/at91/clk-system.c +++ b/drivers/clk/at91/clk-system.c @@ -119,13 +119,7 @@ at91_clk_register_system(struct at91_pmc *pmc, const char *name, init.ops = &system_ops; init.parent_names = &parent_name; init.num_parents = 1; - /* - * CLK_IGNORE_UNUSED is used to avoid ddrck switch off. - * TODO : we should implement a driver supporting at91 ddr controller - * (see drivers/memory) which would request and enable the ddrck clock. - * When this is done we will be able to remove CLK_IGNORE_UNUSED flag. - */ - init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED; + init.flags = CLK_SET_RATE_PARENT; sys->id = id; sys->hw.init = &init; -- GitLab From 6ca4f46005dd7934308588d8e4d73637bbaef7ad Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Tue, 1 Jul 2014 16:58:40 +0200 Subject: [PATCH 0018/9167] power: reset: Add if statement instead of multiple depends on All the config option so far are depending on the POWER_RESET symbol Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Alexandre Belloni --- drivers/power/reset/Kconfig | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index bdcf5173e377..19d546c5edfa 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -6,15 +6,17 @@ menuconfig POWER_RESET Say Y here to enable board reset and power off +if POWER_RESET + config POWER_RESET_AS3722 bool "ams AS3722 power-off driver" - depends on MFD_AS3722 && POWER_RESET + depends on MFD_AS3722 help This driver supports turning off board via a ams AS3722 power-off. config POWER_RESET_AXXIA bool "LSI Axxia reset driver" - depends on POWER_RESET && ARCH_AXXIA + depends on ARCH_AXXIA help This driver supports restart for Axxia SoC. @@ -22,7 +24,7 @@ config POWER_RESET_AXXIA config POWER_RESET_GPIO bool "GPIO power-off driver" - depends on OF_GPIO && POWER_RESET + depends on OF_GPIO help This driver supports turning off your board via a GPIO line. If your board needs a GPIO high/low to power down, say Y and @@ -30,13 +32,13 @@ config POWER_RESET_GPIO config POWER_RESET_MSM bool "Qualcomm MSM power-off driver" - depends on POWER_RESET && ARCH_QCOM + depends on ARCH_QCOM help Power off and restart support for Qualcomm boards. config POWER_RESET_QNAP bool "QNAP power-off driver" - depends on OF_GPIO && POWER_RESET && PLAT_ORION + depends on OF_GPIO && PLAT_ORION help This driver supports turning off QNAP NAS devices by sending commands to the microcontroller which controls the main power. @@ -54,14 +56,13 @@ config POWER_RESET_RESTART config POWER_RESET_SUN6I bool "Allwinner A31 SoC reset driver" depends on ARCH_SUNXI - depends on POWER_RESET help Reboot support for the Allwinner A31 SoCs. config POWER_RESET_VEXPRESS bool "ARM Versatile Express power-off and reset driver" depends on ARM || ARM64 - depends on POWER_RESET && VEXPRESS_CONFIG + depends on VEXPRESS_CONFIG help Power off and reset support for the ARM Ltd. Versatile Express boards. @@ -69,7 +70,6 @@ config POWER_RESET_VEXPRESS config POWER_RESET_XGENE bool "APM SoC X-Gene reset driver" depends on ARM64 - depends on POWER_RESET help Reboot support for the APM SoC X-Gene Eval boards. @@ -80,3 +80,4 @@ config POWER_RESET_KEYSTONE help Reboot support for the KEYSTONE SoCs. +endif -- GitLab From ecfe64d8c55f8f210a609cd2eabfcc03f03672a9 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 2 Jul 2014 17:46:58 +0200 Subject: [PATCH 0019/9167] power: reset: Add AT91 reset driver Implement the reset behaviour of the various AT91 SoCS in drivers/power/reset. It used to be (and still is) located in arch/arm/mach-at91, and in order to preserve bisectability is not removed yet, but every board should be converted to use this driver instead. Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Alexandre Belloni --- drivers/power/reset/Kconfig | 8 + drivers/power/reset/Makefile | 1 + drivers/power/reset/at91-reset.c | 252 +++++++++++++++++++++++++++++++ 3 files changed, 261 insertions(+) create mode 100644 drivers/power/reset/at91-reset.c diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 19d546c5edfa..360bac75a3da 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -14,6 +14,14 @@ config POWER_RESET_AS3722 help This driver supports turning off board via a ams AS3722 power-off. +config POWER_RESET_AT91_RESET + bool "Atmel AT91 reset driver" + depends on MACH_AT91 + default SOC_AT91SAM9 || SOC_SAMA5 + help + This driver supports restart for Atmel AT91SAM9 and SAMA5 + SoCs + config POWER_RESET_AXXIA bool "LSI Axxia reset driver" depends on ARCH_AXXIA diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index dde2e8bbac53..1599214b91d9 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o +obj-$(CONFIG_POWER_RESET_AT91_RESET) += at91-reset.o obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o diff --git a/drivers/power/reset/at91-reset.c b/drivers/power/reset/at91-reset.c new file mode 100644 index 000000000000..3611806c9cfd --- /dev/null +++ b/drivers/power/reset/at91-reset.c @@ -0,0 +1,252 @@ +/* + * Atmel AT91 SAM9 SoCs reset code + * + * Copyright (C) 2007 Atmel Corporation. + * Copyright (C) BitBox Ltd 2010 + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD + * Copyright (C) 2014 Free Electrons + * + * 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 AT91_RSTC_CR 0x00 /* Reset Controller Control Register */ +#define AT91_RSTC_PROCRST BIT(0) /* Processor Reset */ +#define AT91_RSTC_PERRST BIT(2) /* Peripheral Reset */ +#define AT91_RSTC_EXTRST BIT(3) /* External Reset */ +#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */ + +#define AT91_RSTC_SR 0x04 /* Reset Controller Status Register */ +#define AT91_RSTC_URSTS BIT(0) /* User Reset Status */ +#define AT91_RSTC_RSTTYP GENMASK(10, 8) /* Reset Type */ +#define AT91_RSTC_NRSTL BIT(16) /* NRST Pin Level */ +#define AT91_RSTC_SRCMP BIT(17) /* Software Reset Command in Progress */ + +#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */ +#define AT91_RSTC_URSTEN BIT(0) /* User Reset Enable */ +#define AT91_RSTC_URSTIEN BIT(4) /* User Reset Interrupt Enable */ +#define AT91_RSTC_ERSTL GENMASK(11, 8) /* External Reset Length */ + +enum reset_type { + RESET_TYPE_GENERAL = 0, + RESET_TYPE_WAKEUP = 1, + RESET_TYPE_WATCHDOG = 2, + RESET_TYPE_SOFTWARE = 3, + RESET_TYPE_USER = 4, +}; + +static void __iomem *at91_ramc_base[2], *at91_rstc_base; + +/* +* unless the SDRAM is cleanly shutdown before we hit the +* reset register it can be left driving the data bus and +* killing the chance of a subsequent boot from NAND +*/ +static void at91sam9260_restart(enum reboot_mode mode, const char *cmd) +{ + asm volatile( + /* Align to cache lines */ + ".balign 32\n\t" + + /* Disable SDRAM accesses */ + "str %2, [%0, #" __stringify(AT91_SDRAMC_TR) "]\n\t" + + /* Power down SDRAM */ + "str %3, [%0, #" __stringify(AT91_SDRAMC_LPR) "]\n\t" + + /* Reset CPU */ + "str %4, [%1, #" __stringify(AT91_RSTC_CR) "]\n\t" + + "b .\n\t" + : + : "r" (at91_ramc_base[0]), + "r" (at91_rstc_base), + "r" (1), + "r" (AT91_SDRAMC_LPCB_POWER_DOWN), + "r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST)); +} + +static void at91sam9g45_restart(enum reboot_mode mode, const char *cmd) +{ + asm volatile( + /* + * Test wether we have a second RAM controller to care + * about. + * + * First, test that we can dereference the virtual address. + */ + "cmp %1, #0\n\t" + "beq 1f\n\t" + + /* Then, test that the RAM controller is enabled */ + "ldr r0, [%1]\n\t" + "cmp r0, #0\n\t" + + /* Align to cache lines */ + ".balign 32\n\t" + + /* Disable SDRAM0 accesses */ + "1: str %3, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" + /* Power down SDRAM0 */ + " str %4, [%0, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" + /* Disable SDRAM1 accesses */ + " strne %3, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" + /* Power down SDRAM1 */ + " strne %4, [%1, #" __stringify(AT91_DDRSDRC_RTR) "]\n\t" + /* Reset CPU */ + " str %5, [%2, #" __stringify(AT91_RSTC_CR) "]\n\t" + + " b .\n\t" + : + : "r" (at91_ramc_base[0]), + "r" (at91_ramc_base[1]), + "r" (at91_rstc_base), + "r" (1), + "r" (AT91_DDRSDRC_LPCB_POWER_DOWN), + "r" (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST) + : "r0"); +} + +static void __init at91_reset_status(struct platform_device *pdev) +{ + u32 reg = readl(at91_rstc_base + AT91_RSTC_SR); + char *reason; + + switch ((reg & AT91_RSTC_RSTTYP) >> 8) { + case RESET_TYPE_GENERAL: + reason = "general reset"; + break; + case RESET_TYPE_WAKEUP: + reason = "wakeup"; + break; + case RESET_TYPE_WATCHDOG: + reason = "watchdog reset"; + break; + case RESET_TYPE_SOFTWARE: + reason = "software reset"; + break; + case RESET_TYPE_USER: + reason = "user reset"; + break; + default: + reason = "unknown reset"; + break; + } + + pr_info("AT91: Starting after %s\n", reason); +} + +static struct of_device_id at91_ramc_of_match[] = { + { .compatible = "atmel,at91sam9260-sdramc", }, + { .compatible = "atmel,at91sam9g45-ddramc", }, + { .compatible = "atmel,sama5d3-ddramc", }, + { /* sentinel */ } +}; + +static struct of_device_id at91_reset_of_match[] = { + { .compatible = "atmel,at91sam9260-rstc", .data = at91sam9260_restart }, + { .compatible = "atmel,at91sam9g45-rstc", .data = at91sam9g45_restart }, + { /* sentinel */ } +}; + +static int at91_reset_of_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + struct device_node *np; + int idx = 0; + + at91_rstc_base = of_iomap(pdev->dev.of_node, 0); + if (!at91_rstc_base) { + dev_err(&pdev->dev, "Could not map reset controller address\n"); + return -ENODEV; + } + + for_each_matching_node(np, at91_ramc_of_match) { + at91_ramc_base[idx] = of_iomap(np, 0); + if (!at91_ramc_base[idx]) { + dev_err(&pdev->dev, "Could not map ram controller address\n"); + return -ENODEV; + } + idx++; + } + + match = of_match_node(at91_reset_of_match, pdev->dev.of_node); + arm_pm_restart = match->data; + + return 0; +} + +static int at91_reset_platform_probe(struct platform_device *pdev) +{ + const struct platform_device_id *match; + struct resource *res; + int idx = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + at91_rstc_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(at91_rstc_base)) { + dev_err(&pdev->dev, "Could not map reset controller address\n"); + return PTR_ERR(at91_rstc_base); + } + + for (idx = 0; idx < 2; idx++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, idx + 1 ); + at91_ramc_base[idx] = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (IS_ERR(at91_ramc_base[idx])) { + dev_err(&pdev->dev, "Could not map ram controller address\n"); + return PTR_ERR(at91_ramc_base[idx]); + } + } + + match = platform_get_device_id(pdev); + arm_pm_restart = (void (*)(enum reboot_mode, const char*)) + match->driver_data; + + return 0; +} + +static int at91_reset_probe(struct platform_device *pdev) +{ + int ret; + + if (pdev->dev.of_node) + ret = at91_reset_of_probe(pdev); + else + ret = at91_reset_platform_probe(pdev); + + if (ret) + return ret; + + at91_reset_status(pdev); + + return 0; +} + +static struct platform_device_id at91_reset_plat_match[] = { + { "at91-sam9260-reset", (unsigned long)at91sam9260_restart }, + { "at91-sam9g45-reset", (unsigned long)at91sam9g45_restart }, + { /* sentinel */ } +}; + +static struct platform_driver at91_reset_driver = { + .probe = at91_reset_probe, + .driver = { + .name = "at91-reset", + .of_match_table = at91_reset_of_match, + }, + .id_table = at91_reset_plat_match, +}; +module_platform_driver(at91_reset_driver); -- GitLab From ae499f0fadaf28bf3138676fa2d3f6cf7d57556a Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Jul 2014 14:07:18 +0200 Subject: [PATCH 0020/9167] power: reset: Add AT91 poweroff driver Add a driver to handle the shutdown of the Atmel SoCs. This code used to be (and still is) in arch/arm/mach-at91. We didn't remove it yet so that we can convert all the boards to using this driver, before removing it entirely in a separate patch. Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Alexandre Belloni --- drivers/power/reset/Kconfig | 8 ++ drivers/power/reset/Makefile | 1 + drivers/power/reset/at91-poweroff.c | 156 ++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 drivers/power/reset/at91-poweroff.c diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index 360bac75a3da..1f9d0c53fc14 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -14,6 +14,14 @@ config POWER_RESET_AS3722 help This driver supports turning off board via a ams AS3722 power-off. +config POWER_RESET_AT91_POWEROFF + bool "Atmel AT91 poweroff driver" + depends on MACH_AT91 + default SOC_AT91SAM9 || SOC_SAMA5 + help + This driver supports poweroff for Atmel AT91SAM9 and SAMA5 + SoCs + config POWER_RESET_AT91_RESET bool "Atmel AT91 reset driver" depends on MACH_AT91 diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index 1599214b91d9..8bf941bac3da 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o +obj-$(CONFIG_POWER_RESET_AT91_POWEROFF) += at91-poweroff.o obj-$(CONFIG_POWER_RESET_AT91_RESET) += at91-reset.o obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o diff --git a/drivers/power/reset/at91-poweroff.c b/drivers/power/reset/at91-poweroff.c new file mode 100644 index 000000000000..40bf42d146f1 --- /dev/null +++ b/drivers/power/reset/at91-poweroff.c @@ -0,0 +1,156 @@ +/* + * Atmel AT91 SAM9 SoCs reset code + * + * Copyright (C) 2007 Atmel Corporation. + * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD + * Copyright (C) 2014 Free Electrons + * + * 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 + +#define AT91_SHDW_CR 0x00 /* Shut Down Control Register */ +#define AT91_SHDW_SHDW BIT(0) /* Shut Down command */ +#define AT91_SHDW_KEY (0xa5 << 24) /* KEY Password */ + +#define AT91_SHDW_MR 0x04 /* Shut Down Mode Register */ +#define AT91_SHDW_WKMODE0 GENMASK(2, 0) /* Wake-up 0 Mode Selection */ +#define AT91_SHDW_CPTWK0_MAX 0xf /* Maximum Counter On Wake Up 0 */ +#define AT91_SHDW_CPTWK0 (AT91_SHDW_CPTWK0_MAX << 4) /* Counter On Wake Up 0 */ +#define AT91_SHDW_CPTWK0_(x) ((x) << 4) +#define AT91_SHDW_RTTWKEN BIT(16) /* Real Time Timer Wake-up Enable */ +#define AT91_SHDW_RTCWKEN BIT(17) /* Real Time Clock Wake-up Enable */ + +#define AT91_SHDW_SR 0x08 /* Shut Down Status Register */ +#define AT91_SHDW_WAKEUP0 BIT(0) /* Wake-up 0 Status */ +#define AT91_SHDW_RTTWK BIT(16) /* Real-time Timer Wake-up */ +#define AT91_SHDW_RTCWK BIT(17) /* Real-time Clock Wake-up [SAM9RL] */ + +enum wakeup_type { + AT91_SHDW_WKMODE0_NONE = 0, + AT91_SHDW_WKMODE0_HIGH = 1, + AT91_SHDW_WKMODE0_LOW = 2, + AT91_SHDW_WKMODE0_ANYLEVEL = 3, +}; + +static const char *shdwc_wakeup_modes[] = { + [AT91_SHDW_WKMODE0_NONE] = "none", + [AT91_SHDW_WKMODE0_HIGH] = "high", + [AT91_SHDW_WKMODE0_LOW] = "low", + [AT91_SHDW_WKMODE0_ANYLEVEL] = "any", +}; + +static void __iomem *at91_shdwc_base; + +static void __init at91_wakeup_status(void) +{ + u32 reg = readl(at91_shdwc_base); + char *reason = "unknown"; + + /* Simple power-on, just bail out */ + if (!reg) + return; + + if (reg & AT91_SHDW_RTTWK) + reason = "RTT"; + else if (reg & AT91_SHDW_RTCWK) + reason = "RTC"; + + pr_info("AT91: Wake-Up source: %s\n", reason); +} + +static void at91_poweroff(void) +{ + writel(AT91_SHDW_KEY | AT91_SHDW_SHDW, at91_shdwc_base + AT91_SHDW_CR); +} + +const enum wakeup_type at91_poweroff_get_wakeup_mode(struct device_node *np) +{ + const char *pm; + int err, i; + + err = of_property_read_string(np, "atmel,wakeup-mode", &pm); + if (err < 0) + return AT91_SHDW_WKMODE0_ANYLEVEL; + + for (i = 0; i < ARRAY_SIZE(shdwc_wakeup_modes); i++) + if (!strcasecmp(pm, shdwc_wakeup_modes[i])) + return i; + + return -ENODEV; +} + +static void at91_poweroff_dt_set_wakeup_mode(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + enum wakeup_type wakeup_mode; + u32 mode = 0, tmp; + + wakeup_mode = at91_poweroff_get_wakeup_mode(np); + if (wakeup_mode < 0) { + dev_warn(&pdev->dev, "shdwc unknown wakeup mode\n"); + return; + } + + if (!of_property_read_u32(np, "atmel,wakeup-counter", &tmp)) { + if (tmp > AT91_SHDW_CPTWK0_MAX) { + dev_warn(&pdev->dev, + "shdwc wakeup counter 0x%x > 0x%x reduce it to 0x%x\n", + tmp, AT91_SHDW_CPTWK0_MAX, AT91_SHDW_CPTWK0_MAX); + tmp = AT91_SHDW_CPTWK0_MAX; + } + mode |= AT91_SHDW_CPTWK0_(tmp); + } + + if (of_property_read_bool(np, "atmel,wakeup-rtc-timer")) + mode |= AT91_SHDW_RTCWKEN; + + if (of_property_read_bool(np, "atmel,wakeup-rtt-timer")) + mode |= AT91_SHDW_RTTWKEN; + + writel(wakeup_mode | mode, at91_shdwc_base + AT91_SHDW_MR); +} + +static int at91_poweroff_probe(struct platform_device *pdev) +{ + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + at91_shdwc_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(at91_shdwc_base)) { + dev_err(&pdev->dev, "Could not map reset controller address\n"); + return PTR_ERR(at91_shdwc_base); + } + + at91_wakeup_status(); + + if (pdev->dev.of_node) + at91_poweroff_dt_set_wakeup_mode(pdev); + + pm_power_off = at91_poweroff; + + return 0; +} + +static struct of_device_id at91_poweroff_of_match[] = { + { .compatible = "atmel,at91sam9260-shdwc", }, + { .compatible = "atmel,at91sam9rl-shdwc", }, + { .compatible = "atmel,at91sam9x5-shdwc", }, + { /*sentinel*/ } +}; + +static struct platform_driver at91_poweroff_driver = { + .probe = at91_poweroff_probe, + .driver = { + .name = "at91-poweroff", + .of_match_table = at91_poweroff_of_match, + }, +}; +module_platform_driver(at91_poweroff_driver); -- GitLab From 063de897c411af65cb113cb5fb9a0022f913460e Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 8 Jul 2014 18:21:14 +0200 Subject: [PATCH 0021/9167] ARM: at91/dt: sama5d3: define mpddr clock and ramc clocks Define the available clock for mprddr and take both mpddr_clk and ddrck in the ram controller driver. Signed-off-by: Alexandre Belloni Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre --- arch/arm/boot/dts/sama5d3.dtsi | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index e0b15a6e8897..04c35ce1e33e 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -402,8 +402,10 @@ }; ramc0: ramc@ffffea00 { - compatible = "atmel,at91sam9g45-ddramc"; + compatible = "atmel,sama5d3-ddramc"; reg = <0xffffea00 0x200>; + clocks = <&ddrck>, <&mpddr_clk>; + clock-names = "ddrck", "mpddr"; }; dbgu: serial@ffffee00 { @@ -1170,6 +1172,11 @@ #clock-cells = <0>; reg = <48>; }; + + mpddr_clk: mpddr_clk { + #clock-cells = <0>; + reg = <49>; + }; }; }; -- GitLab From 7e948346000cfc300f39f1c14335b2ef364257ef Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 8 Jul 2014 18:21:15 +0200 Subject: [PATCH 0022/9167] ARM: at91/dt: at91sam9: use ddrck in ramc Make the ram controller driver take the ddrck clock for at91sam9n12 and at91sam9x5. Signed-off-by: Alexandre Belloni Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre --- arch/arm/boot/dts/at91sam9n12.dtsi | 2 ++ arch/arm/boot/dts/at91sam9x5.dtsi | 2 ++ 2 files changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index d1b82e6635d5..1534e4997ee3 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -85,6 +85,8 @@ ramc0: ramc@ffffe800 { compatible = "atmel,at91sam9g45-ddramc"; reg = <0xffffe800 0x200>; + clocks = <&ddrck>; + clock-names = "ddrck"; }; pmc: pmc@fffffc00 { diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 1a57298636a5..72e1483a651c 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -93,6 +93,8 @@ ramc0: ramc@ffffe800 { compatible = "atmel,at91sam9g45-ddramc"; reg = <0xffffe800 0x200>; + clocks = <&ddrck>; + clock-names = "ddrck"; }; pmc: pmc@fffffc00 { -- GitLab From 1e165a7dc2f07054736a6a16bdc2fa024f3aa2d4 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Jul 2014 12:01:29 +0200 Subject: [PATCH 0023/9167] ARM: at91/dt: Declare a second ram controller when relevant The G45 and 9263 SoCs has two identical ram controller, that are defined as a single node, with two reg cells. The proper way to support such a case is to have two separate DT nodes. Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Alexandre Belloni --- arch/arm/boot/dts/at91sam9263.dtsi | 10 +++++++--- arch/arm/boot/dts/at91sam9g45.dtsi | 8 ++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index fece8665fb63..e8ecb03772ce 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -71,10 +71,14 @@ reg = <0xfffffc00 0x100>; }; - ramc: ramc@ffffe200 { + ramc0: ramc@ffffe200 { compatible = "atmel,at91sam9260-sdramc"; - reg = <0xffffe200 0x200 - 0xffffe800 0x200>; + reg = <0xffffe200 0x200>; + }; + + ramc1: ramc@ffffe800 { + compatible = "atmel,at91sam9260-sdramc"; + reg = <0xffffe800 0x200>; }; pit: timer@fffffd30 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index ace6bf197b70..6f648b85b725 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -75,8 +75,12 @@ ramc0: ramc@ffffe400 { compatible = "atmel,at91sam9g45-ddramc"; - reg = <0xffffe400 0x200 - 0xffffe600 0x200>; + reg = <0xffffe400 0x200>; + }; + + ramc1: ramc@ffffe600 { + compatible = "atmel,at91sam9g45-ddramc"; + reg = <0xffffe600 0x200>; }; pmc: pmc@fffffc00 { -- GitLab From 16aa7f1f173f3ca105296cf2709cb039c99ffe4a Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 3 Jul 2014 14:08:47 +0200 Subject: [PATCH 0024/9167] ARM: at91/dt: sama5d3: Add shutdown controller The SAMA5D3 has a shutdown controller identical to the sam9x5 SoC family. Declare it in the DT. Signed-off-by: Maxime Ripard Acked-by: Nicolas Ferre Acked-by: Alexandre Belloni --- arch/arm/boot/dts/sama5d3.dtsi | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/boot/dts/sama5d3.dtsi b/arch/arm/boot/dts/sama5d3.dtsi index 04c35ce1e33e..97952ef7f240 100644 --- a/arch/arm/boot/dts/sama5d3.dtsi +++ b/arch/arm/boot/dts/sama5d3.dtsi @@ -1185,6 +1185,11 @@ reg = <0xfffffe00 0x10>; }; + shutdown-controller@fffffe10 { + compatible = "atmel,at91sam9x5-shdwc"; + reg = <0xfffffe10 0x10>; + }; + pit: timer@fffffe30 { compatible = "atmel,at91sam9260-pit"; reg = <0xfffffe30 0xf>; -- GitLab From 2618a18246a6164c212c47ee6b0031ad85909cc9 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 22 Jul 2014 21:30:14 +0200 Subject: [PATCH 0025/9167] ARM: dts: omap3-gta04: Add nand support Add the needed sections to enable nand support on gta04 board. Add nand partitions information. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dts | 54 +++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index 021311f7964b..7d7ddd7065c1 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -309,3 +309,57 @@ }; }; }; + +&gpmc { + ranges = <0 0 0x30000000 0x04>; /* CS0: NAND */ + + nand@0,0 { + reg = <0 0 0>; /* CS0, offset 0 */ + nand-bus-width = <16>; + ti,nand-ecc-opt = "bch8"; + + gpmc,sync-clk-ps = <0>; + gpmc,cs-on-ns = <0>; + gpmc,cs-rd-off-ns = <44>; + gpmc,cs-wr-off-ns = <44>; + gpmc,adv-on-ns = <6>; + gpmc,adv-rd-off-ns = <34>; + gpmc,adv-wr-off-ns = <44>; + gpmc,we-off-ns = <40>; + gpmc,oe-off-ns = <54>; + gpmc,access-ns = <64>; + gpmc,rd-cycle-ns = <82>; + gpmc,wr-cycle-ns = <82>; + gpmc,wr-access-ns = <40>; + gpmc,wr-data-mux-bus-ns = <0>; + gpmc,device-width = <2>; + + #address-cells = <1>; + #size-cells = <1>; + + x-loader@0 { + label = "X-Loader"; + reg = <0 0x80000>; + }; + + bootloaders@80000 { + label = "U-Boot"; + reg = <0x80000 0x1e0000>; + }; + + bootloaders_env@260000 { + label = "U-Boot Env"; + reg = <0x260000 0x20000>; + }; + + kernel@280000 { + label = "Kernel"; + reg = <0x280000 0x400000>; + }; + + filesystem@680000 { + label = "File System"; + reg = <0x680000 0xf980000>; + }; + }; +}; -- GitLab From 9edc57af01a22f227c30ae1261cf232ab8673cbf Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 22 Jul 2014 21:59:08 +0200 Subject: [PATCH 0026/9167] ARM: dts: omap3-gta04: Fix magnetometer model gta04 is using hmc5883l not hmc5843 so fix wrong compatible entry. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index 7d7ddd7065c1..406749573e35 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -220,7 +220,7 @@ /* compass aka magnetometer */ hmc5843@1e { - compatible = "honeywell,hmc5843"; + compatible = "honeywell,hmc5883l"; reg = <0x1e>; }; -- GitLab From e51c6beaefe3e2fc7490064b7a4a5f70cd861cde Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 22 Jul 2014 21:30:16 +0200 Subject: [PATCH 0027/9167] ARM: dts: omap3-gta04: Add wifi reset node Define gpio node in tca6507 which will be used as wifi reset pin. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index 406749573e35..0c44827da259 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -196,6 +196,9 @@ #size-cells = <0>; reg = <0x45>; + gpio-controller; + #gpio-cells = <2>; + gta04_led0: red_aux@0 { label = "gta04:red:aux"; reg = <0x0>; @@ -216,6 +219,11 @@ label = "gta04:green:power"; reg = <0x4>; }; + + wifi_reset: wifi_reset@6 { + reg = <0x6>; + compatible = "gpio"; + }; }; /* compass aka magnetometer */ -- GitLab From 6c402f8d678ebc438c66fea8507f8c820843c26d Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 22 Jul 2014 21:30:17 +0200 Subject: [PATCH 0028/9167] ARM: dts: omap3-gta04: Move spi gpio pins to pmx_core2 Because of commit: 3d495383648a7cda3ea51a1e2fa5d288581479aa spi_gpio_pins node isn't valid anymore. Move to pmx_core2 node. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index 0c44827da259..31ddd396d5de 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -141,12 +141,15 @@ 0x0da (PIN_OUTPUT | MUX_MODE0) /* dss_data23.dss_data23 */ >; }; +}; +&omap3_pmx_core2 { spi_gpio_pins: spi_gpio_pinmux { - pinctrl-single,pins = <0x5a8 (PIN_OUTPUT | MUX_MODE4) /* clk */ - 0x5b6 (PIN_OUTPUT | MUX_MODE4) /* cs */ - 0x5b8 (PIN_OUTPUT | MUX_MODE4) /* tx */ - 0x5b4 (PIN_INPUT | MUX_MODE4) /* rx */ + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE4) /* clk */ + OMAP3630_CORE2_IOPAD(0x25e6, PIN_OUTPUT | MUX_MODE4) /* cs */ + OMAP3630_CORE2_IOPAD(0x25e8, PIN_OUTPUT | MUX_MODE4) /* tx */ + OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT | MUX_MODE4) /* rx */ >; }; }; -- GitLab From 1520a13bf03b3be8a87df665db878d0600560108 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 22 Jul 2014 21:30:18 +0200 Subject: [PATCH 0029/9167] ARM: dts: omap3-gta04: Add USB host support Define USB Host port mode and the PHY device. Also provide pin multiplexer information for USB host pins. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dts | 45 +++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index 31ddd396d5de..83bb1e010380 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -74,9 +74,30 @@ }; }; }; + + hsusb2_phy: hsusb2_phy { + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio6 14 GPIO_ACTIVE_LOW>; + }; }; &omap3_pmx_core { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusb2_pins + >; + + hsusb2_pins: pinmux_hsusb2_pins { + pinctrl-single,pins = < + OMAP3_CORE1_IOPAD(0x21d4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi1_cs3.hsusb2_data2 */ + OMAP3_CORE1_IOPAD(0x21d6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_clk.hsusb2_data7 */ + OMAP3_CORE1_IOPAD(0x21d8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_simo.hsusb2_data4 */ + OMAP3_CORE1_IOPAD(0x21da, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_somi.hsusb2_data5 */ + OMAP3_CORE1_IOPAD(0x21dc, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs0.hsusb2_data6 */ + OMAP3_CORE1_IOPAD(0x21de, PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcspi2_cs1.hsusb2_data3 */ + >; + }; + uart1_pins: pinmux_uart1_pins { pinctrl-single,pins = < 0x152 (PIN_INPUT | MUX_MODE0) /* uart1_rx.uart1_rx */ @@ -144,6 +165,22 @@ }; &omap3_pmx_core2 { + pinctrl-names = "default"; + pinctrl-0 = < + &hsusb2_2_pins + >; + + hsusb2_2_pins: pinmux_hsusb2_2_pins { + pinctrl-single,pins = < + OMAP3630_CORE2_IOPAD(0x25f0, PIN_OUTPUT | MUX_MODE3) /* etk_d10.hsusb2_clk */ + OMAP3630_CORE2_IOPAD(0x25f2, PIN_OUTPUT | MUX_MODE3) /* etk_d11.hsusb2_stp */ + OMAP3630_CORE2_IOPAD(0x25f4, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d12.hsusb2_dir */ + OMAP3630_CORE2_IOPAD(0x25f6, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d13.hsusb2_nxt */ + OMAP3630_CORE2_IOPAD(0x25f8, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d14.hsusb2_data0 */ + OMAP3630_CORE2_IOPAD(0x25fa, PIN_INPUT_PULLDOWN | MUX_MODE3) /* etk_d15.hsusb2_data1 */ + >; + }; + spi_gpio_pins: spi_gpio_pinmux { pinctrl-single,pins = < OMAP3630_CORE2_IOPAD(0x25d8, PIN_OUTPUT | MUX_MODE4) /* clk */ @@ -259,6 +296,14 @@ power = <50>; }; +&usbhshost { + port2-mode = "ehci-phy"; +}; + +&usbhsehci { + phys = <0 &hsusb2_phy>; +}; + &mmc1 { pinctrl-names = "default"; pinctrl-0 = <&mmc1_pins>; -- GitLab From 91b8457e6853540966960a50573d0e0d20f355ea Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 22 Jul 2014 21:30:19 +0200 Subject: [PATCH 0030/9167] ARM: dts: omap3-gta04: Add display alias Define alias for lcd display present on gta04 board. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index 83bb1e010380..ab58607d51fe 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -26,6 +26,10 @@ reg = <0x80000000 0x20000000>; /* 512 MB */ }; + aliases { + display0 = &lcd; + }; + gpio-keys { compatible = "gpio-keys"; -- GitLab From 4318bad2a02dcc678afab376713b1132ca333951 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 22 Jul 2014 21:30:20 +0200 Subject: [PATCH 0031/9167] ARM: dts: omap3-gta04: Add twl4030 regulators parameters Define voltages and properties for various twl4030 regulators used on gta04 board. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/omap3-gta04.dts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dts index ab58607d51fe..fd34f913ace3 100644 --- a/arch/arm/boot/dts/omap3-gta04.dts +++ b/arch/arm/boot/dts/omap3-gta04.dts @@ -346,11 +346,37 @@ bb_uamp = <150>; }; +/* spare */ +&vaux1 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <3000000>; +}; + +/* sensors */ +&vaux2 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-always-on; +}; + +/* camera */ +&vaux3 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; +}; + +/* WLAN/BT */ &vaux4 { regulator-min-microvolt = <2800000>; regulator-max-microvolt = <3150000>; }; +/* GPS LNA */ +&vsim { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3150000>; +}; + /* Needed to power the DPI pins */ &vpll2 { regulator-always-on; -- GitLab From 1d2ce978d160fa960f12d06bf84e45f47c141272 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 23 Jul 2014 17:10:44 -0300 Subject: [PATCH 0032/9167] x86, microcode, amd: Fix missing static declaration Make locally used variable static. Signed-off-by: Henrique de Moraes Holschuh Link: http://lkml.kernel.org/r/1406146251-8540-1-git-send-email-hmh@hmh.eng.br Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/microcode/amd_early.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/microcode/amd_early.c b/arch/x86/kernel/cpu/microcode/amd_early.c index 617a9e284245..7aa1acc79789 100644 --- a/arch/x86/kernel/cpu/microcode/amd_early.c +++ b/arch/x86/kernel/cpu/microcode/amd_early.c @@ -27,7 +27,7 @@ static u32 ucode_new_rev; u8 amd_ucode_patch[PATCH_MAX_SIZE]; static u16 this_equiv_id; -struct cpio_data ucode_cpio; +static struct cpio_data ucode_cpio; /* * Microcode patch container file is prepended to the initrd in cpio format. -- GitLab From 05a5f76d033f413396bc48ce2f8651b5659bcd31 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 23 Jul 2014 17:10:45 -0300 Subject: [PATCH 0033/9167] x86, microcode, intel: Add missing static declarations gcc reports that a few declarations are missing. Fix two obvious ones. Signed-off-by: Henrique de Moraes Holschuh Link: http://lkml.kernel.org/r/1406146251-8540-1-git-send-email-hmh@hmh.eng.br Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/microcode/intel_early.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c index 18f739129e72..b105c11c6f59 100644 --- a/arch/x86/kernel/cpu/microcode/intel_early.c +++ b/arch/x86/kernel/cpu/microcode/intel_early.c @@ -28,8 +28,8 @@ #include #include -unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT]; -struct mc_saved_data { +static unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT]; +static struct mc_saved_data { unsigned int mc_saved_count; struct microcode_intel **mc_saved; } mc_saved_data; -- GitLab From f99b45c3c2aa6960b8d21bb200d144be48a0a783 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 23 Jul 2014 17:10:46 -0300 Subject: [PATCH 0034/9167] x86, microcode, intel: Fix typos Fix some typos. One of them was in a struct name, fortunately harmless because it happened on a "sizeof(struct foo*)" construction. Signed-off-by: Henrique de Moraes Holschuh Link: http://lkml.kernel.org/r/1406146251-8540-1-git-send-email-hmh@hmh.eng.br Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/microcode/intel_early.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c index b105c11c6f59..b88343f7a3b3 100644 --- a/arch/x86/kernel/cpu/microcode/intel_early.c +++ b/arch/x86/kernel/cpu/microcode/intel_early.c @@ -415,7 +415,7 @@ static void __ref show_saved_mc(void) struct ucode_cpu_info uci; if (mc_saved_data.mc_saved_count == 0) { - pr_debug("no micorcode data saved.\n"); + pr_debug("no microcode data saved.\n"); return; } pr_debug("Total microcode saved: %d\n", mc_saved_data.mc_saved_count); @@ -506,7 +506,7 @@ int save_mc_for_early(u8 *mc) if (mc_saved && mc_saved_count) memcpy(mc_saved_tmp, mc_saved, - mc_saved_count * sizeof(struct mirocode_intel *)); + mc_saved_count * sizeof(struct microcode_intel *)); /* * Save the microcode patch mc in mc_save_tmp structure if it's a newer * version. @@ -526,7 +526,7 @@ int save_mc_for_early(u8 *mc) show_saved_mc(); /* - * Free old saved microcod data. + * Free old saved microcode data. */ if (mc_saved) { for (i = 0; i < mc_saved_count_init; i++) -- GitLab From 532ed3740c1ed1583ea3fa6de9410edf0d508563 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Thu, 24 Jul 2014 15:23:21 -0300 Subject: [PATCH 0035/9167] x86, microcode, intel: Rename apply_microcode and declare it static Rename apply_microcode() in microcode/intel.c to apply_microcode_intel(), and declare it as static. This is a cosmetic fix to silence a warning issued by sparse. Signed-off-by: Henrique de Moraes Holschuh Link: http://lkml.kernel.org/r/1406146251-8540-1-git-send-email-hmh@hmh.eng.br Signed-off-by: Borislav Petkov --- arch/x86/kernel/cpu/microcode/intel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/cpu/microcode/intel.c b/arch/x86/kernel/cpu/microcode/intel.c index a276fa75d9b5..c6826d1e8082 100644 --- a/arch/x86/kernel/cpu/microcode/intel.c +++ b/arch/x86/kernel/cpu/microcode/intel.c @@ -127,7 +127,7 @@ static int get_matching_mc(struct microcode_intel *mc_intel, int cpu) return get_matching_microcode(csig, cpf, mc_intel, crev); } -int apply_microcode(int cpu) +static int apply_microcode_intel(int cpu) { struct microcode_intel *mc_intel; struct ucode_cpu_info *uci; @@ -314,7 +314,7 @@ static struct microcode_ops microcode_intel_ops = { .request_microcode_user = request_microcode_user, .request_microcode_fw = request_microcode_fw, .collect_cpu_info = collect_cpu_info, - .apply_microcode = apply_microcode, + .apply_microcode = apply_microcode_intel, .microcode_fini_cpu = microcode_fini_cpu, }; -- GitLab From 03d795589d4e5adf83af0623ac5bac93ae2ce2a9 Mon Sep 17 00:00:00 2001 From: Reyad Attiyat Date: Fri, 25 Jul 2014 22:14:00 +0100 Subject: [PATCH 0036/9167] iio: hid-sensor-magn-3d: Fix build warning Fix build warning, sizeof() called on dynamically sized pointer, by removing the call and the dependent function parameter. It is not needed or used in this driver, when pushing values to an iio buffer. Changes from v1 - Fix mistake in varible name Signed-off-by: Reyad Attiyat Signed-off-by: Jonathan Cameron --- drivers/iio/magnetometer/hid-sensor-magn-3d.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c b/drivers/iio/magnetometer/hid-sensor-magn-3d.c index 3ec777a8f64e..1e717c71c244 100644 --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c @@ -246,8 +246,7 @@ static const struct iio_info magn_3d_info = { }; /* Function to push data to buffer */ -static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data, - int len) +static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data) { dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n"); iio_push_to_buffers(indio_dev, data); @@ -263,9 +262,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev, dev_dbg(&indio_dev->dev, "magn_3d_proc_event\n"); if (atomic_read(&magn_state->common_attributes.data_ready)) - hid_sensor_push_data(indio_dev, - magn_state->iio_vals, - sizeof(magn_state->iio_vals)); + hid_sensor_push_data(indio_dev, magn_state->iio_vals); return 0; } -- GitLab From 472988972737cdc2ee83c05931822792a2bf2f76 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Fri, 25 Jul 2014 22:43:00 +0100 Subject: [PATCH 0037/9167] iio: add support of the max5821 Signed-off-by: Philippe Reynes Signed-off-by: Jonathan Cameron --- .../devicetree/bindings/iio/dac/max5821.txt | 14 + drivers/iio/dac/Kconfig | 8 + drivers/iio/dac/Makefile | 1 + drivers/iio/dac/max5821.c | 405 ++++++++++++++++++ 4 files changed, 428 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/dac/max5821.txt create mode 100644 drivers/iio/dac/max5821.c diff --git a/Documentation/devicetree/bindings/iio/dac/max5821.txt b/Documentation/devicetree/bindings/iio/dac/max5821.txt new file mode 100644 index 000000000000..54276ce8c971 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/max5821.txt @@ -0,0 +1,14 @@ +Maxim max5821 DAC device driver + +Required properties: + - compatible: Must be "maxim,max5821" + - reg: Should contain the DAC I2C address + - vref-supply: Phandle to the vref power supply + +Example: + + max5821@38 { + compatible = "maxim,max5821"; + reg = <0x38>; + vref-supply = <®_max5821>; + }; diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index f278eff42a4c..2236ea22f98a 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -152,6 +152,14 @@ config MAX517 This driver can also be built as a module. If so, the module will be called max517. +config MAX5821 + tristate "Maxim MAX5821 DAC driver" + depends on I2C + depends on OF + help + Say yes here to build support for Maxim MAX5821 + 10 bits DAC. + config MCP4725 tristate "MCP4725 DAC driver" depends on I2C diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index 10107640bb46..52be7e1acf16 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -17,5 +17,6 @@ obj-$(CONFIG_AD5791) += ad5791.o obj-$(CONFIG_AD5686) += ad5686.o obj-$(CONFIG_AD7303) += ad7303.o obj-$(CONFIG_MAX517) += max517.o +obj-$(CONFIG_MAX5821) += max5821.o obj-$(CONFIG_MCP4725) += mcp4725.o obj-$(CONFIG_MCP4922) += mcp4922.o diff --git a/drivers/iio/dac/max5821.c b/drivers/iio/dac/max5821.c new file mode 100644 index 000000000000..6e914495b346 --- /dev/null +++ b/drivers/iio/dac/max5821.c @@ -0,0 +1,405 @@ + /* + * iio/dac/max5821.c + * Copyright (C) 2014 Philippe Reynes + * + * 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 + +#define MAX5821_MAX_DAC_CHANNELS 2 + +/* command bytes */ +#define MAX5821_LOAD_DAC_A_IN_REG_B 0x00 +#define MAX5821_LOAD_DAC_B_IN_REG_A 0x10 +#define MAX5821_EXTENDED_COMMAND_MODE 0xf0 +#define MAX5821_READ_DAC_A_COMMAND 0xf1 +#define MAX5821_READ_DAC_B_COMMAND 0xf2 + +#define MAX5821_EXTENDED_POWER_UP 0x00 +#define MAX5821_EXTENDED_POWER_DOWN_MODE0 0x01 +#define MAX5821_EXTENDED_POWER_DOWN_MODE1 0x02 +#define MAX5821_EXTENDED_POWER_DOWN_MODE2 0x03 +#define MAX5821_EXTENDED_DAC_A 0x04 +#define MAX5821_EXTENDED_DAC_B 0x08 + +enum max5821_device_ids { + ID_MAX5821, +}; + +struct max5821_data { + struct i2c_client *client; + struct regulator *vref_reg; + unsigned short vref_mv; + bool powerdown[MAX5821_MAX_DAC_CHANNELS]; + u8 powerdown_mode[MAX5821_MAX_DAC_CHANNELS]; + struct mutex lock; +}; + +static const char * const max5821_powerdown_modes[] = { + "three_state", + "1kohm_to_gnd", + "100kohm_to_gnd", +}; + +enum { + MAX5821_THREE_STATE, + MAX5821_1KOHM_TO_GND, + MAX5821_100KOHM_TO_GND +}; + +static int max5821_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct max5821_data *st = iio_priv(indio_dev); + + return st->powerdown_mode[chan->channel]; +} + +static int max5821_set_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + unsigned int mode) +{ + struct max5821_data *st = iio_priv(indio_dev); + + st->powerdown_mode[chan->channel] = mode; + + return 0; +} + +static const struct iio_enum max5821_powerdown_mode_enum = { + .items = max5821_powerdown_modes, + .num_items = ARRAY_SIZE(max5821_powerdown_modes), + .get = max5821_get_powerdown_mode, + .set = max5821_set_powerdown_mode, +}; + +static ssize_t max5821_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct max5821_data *st = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", st->powerdown[chan->channel]); +} + +static int max5821_sync_powerdown_mode(struct max5821_data *data, + const struct iio_chan_spec *chan) +{ + u8 outbuf[2]; + + outbuf[0] = MAX5821_EXTENDED_COMMAND_MODE; + + if (chan->channel == 0) + outbuf[1] = MAX5821_EXTENDED_DAC_A; + else + outbuf[1] = MAX5821_EXTENDED_DAC_B; + + if (data->powerdown[chan->channel]) + outbuf[1] |= data->powerdown_mode[chan->channel] + 1; + else + outbuf[1] |= MAX5821_EXTENDED_POWER_UP; + + return i2c_master_send(data->client, outbuf, 2); +} + +static ssize_t max5821_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct max5821_data *data = iio_priv(indio_dev); + bool powerdown; + int ret; + + ret = strtobool(buf, &powerdown); + if (ret) + return ret; + + data->powerdown[chan->channel] = powerdown; + + ret = max5821_sync_powerdown_mode(data, chan); + if (ret < 0) + return ret; + + return len; +} + +static const struct iio_chan_spec_ext_info max5821_ext_info[] = { + { + .name = "powerdown", + .read = max5821_read_dac_powerdown, + .write = max5821_write_dac_powerdown, + .shared = IIO_SEPARATE, + }, + IIO_ENUM("powerdown_mode", IIO_SEPARATE, &max5821_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", &max5821_powerdown_mode_enum), + { }, +}; + +#define MAX5821_CHANNEL(chan) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .output = 1, \ + .channel = (chan), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE), \ + .ext_info = max5821_ext_info, \ +} + +static const struct iio_chan_spec max5821_channels[] = { + MAX5821_CHANNEL(0), + MAX5821_CHANNEL(1) +}; + +static const u8 max5821_read_dac_command[] = { + MAX5821_READ_DAC_A_COMMAND, + MAX5821_READ_DAC_B_COMMAND +}; + +static const u8 max5821_load_dac_command[] = { + MAX5821_LOAD_DAC_A_IN_REG_B, + MAX5821_LOAD_DAC_B_IN_REG_A +}; + +static int max5821_get_value(struct iio_dev *indio_dev, + int *val, int channel) +{ + struct max5821_data *data = iio_priv(indio_dev); + struct i2c_client *client = data->client; + u8 outbuf[1]; + u8 inbuf[2]; + int ret; + + if ((channel != 0) && (channel != 1)) + return -EINVAL; + + outbuf[0] = max5821_read_dac_command[channel]; + + mutex_lock(&data->lock); + + ret = i2c_master_send(client, outbuf, 1); + if (ret < 0) { + mutex_unlock(&data->lock); + return ret; + } else if (ret != 1) { + mutex_unlock(&data->lock); + return -EIO; + } + + ret = i2c_master_recv(client, inbuf, 2); + if (ret < 0) { + mutex_unlock(&data->lock); + return ret; + } else if (ret != 2) { + mutex_unlock(&data->lock); + return -EIO; + } + + mutex_unlock(&data->lock); + + *val = ((inbuf[0] & 0x0f) << 6) | (inbuf[1] >> 2); + + return IIO_VAL_INT; +} + +static int max5821_set_value(struct iio_dev *indio_dev, + int val, int channel) +{ + struct max5821_data *data = iio_priv(indio_dev); + struct i2c_client *client = data->client; + u8 outbuf[2]; + int ret; + + if ((val < 0) || (val > 1023)) + return -EINVAL; + + if ((channel != 0) && (channel != 1)) + return -EINVAL; + + outbuf[0] = max5821_load_dac_command[channel]; + outbuf[0] |= val >> 6; + outbuf[1] = (val & 0x3f) << 2; + + ret = i2c_master_send(client, outbuf, 2); + if (ret < 0) + return ret; + else if (ret != 2) + return -EIO; + else + return 0; +} + +static int max5821_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct max5821_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + return max5821_get_value(indio_dev, val, chan->channel); + case IIO_CHAN_INFO_SCALE: + *val = data->vref_mv; + *val2 = 10; + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static int max5821_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + if (val2 != 0) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + return max5821_set_value(indio_dev, val, chan->channel); + default: + return -EINVAL; + } +} + +#ifdef CONFIG_PM_SLEEP +static int max5821_suspend(struct device *dev) +{ + u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE, + MAX5821_EXTENDED_DAC_A | + MAX5821_EXTENDED_DAC_B | + MAX5821_EXTENDED_POWER_DOWN_MODE2 }; + + return i2c_master_send(to_i2c_client(dev), outbuf, 2); +} + +static int max5821_resume(struct device *dev) +{ + u8 outbuf[2] = { MAX5821_EXTENDED_COMMAND_MODE, + MAX5821_EXTENDED_DAC_A | + MAX5821_EXTENDED_DAC_B | + MAX5821_EXTENDED_POWER_UP }; + + return i2c_master_send(to_i2c_client(dev), outbuf, 2); +} + +static SIMPLE_DEV_PM_OPS(max5821_pm_ops, max5821_suspend, max5821_resume); +#define MAX5821_PM_OPS (&max5821_pm_ops) +#else +#define MAX5821_PM_OPS NULL +#endif /* CONFIG_PM_SLEEP */ + +static const struct iio_info max5821_info = { + .read_raw = max5821_read_raw, + .write_raw = max5821_write_raw, + .driver_module = THIS_MODULE, +}; + +static int max5821_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct max5821_data *data; + struct iio_dev *indio_dev; + u32 tmp; + int ret; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + mutex_init(&data->lock); + + /* max5821 start in powerdown mode 100Kohm to ground */ + for (tmp = 0; tmp < MAX5821_MAX_DAC_CHANNELS; tmp++) { + data->powerdown[tmp] = true; + data->powerdown_mode[tmp] = MAX5821_100KOHM_TO_GND; + } + + data->vref_reg = devm_regulator_get(&client->dev, "vref"); + if (IS_ERR(data->vref_reg)) { + ret = PTR_ERR(data->vref_reg); + dev_err(&client->dev, + "Failed to get vref regulator: %d\n", ret); + goto error_free_reg; + } + + ret = regulator_enable(data->vref_reg); + if (ret) { + dev_err(&client->dev, + "Failed to enable vref regulator: %d\n", ret); + goto error_free_reg; + } + + ret = regulator_get_voltage(data->vref_reg); + if (ret < 0) { + dev_err(&client->dev, + "Failed to get voltage on regulator: %d\n", ret); + goto error_disable_reg; + } + + data->vref_mv = ret / 1000; + + indio_dev->name = id->name; + indio_dev->dev.parent = &client->dev; + indio_dev->num_channels = ARRAY_SIZE(max5821_channels); + indio_dev->channels = max5821_channels; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &max5821_info; + + return iio_device_register(indio_dev); + +error_disable_reg: + regulator_disable(data->vref_reg); + +error_free_reg: + + return ret; +} + +static int max5821_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct max5821_data *data = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + regulator_disable(data->vref_reg); + + return 0; +} + +static const struct i2c_device_id max5821_id[] = { + { "max5821", ID_MAX5821 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, max5821_id); + +static const struct of_device_id max5821_of_match[] = { + { .compatible = "maxim,max5821" }, + { } +}; + +static struct i2c_driver max5821_driver = { + .driver = { + .name = "max5821", + .pm = MAX5821_PM_OPS, + .owner = THIS_MODULE, + }, + .probe = max5821_probe, + .remove = max5821_remove, + .id_table = max5821_id, +}; +module_i2c_driver(max5821_driver); + +MODULE_AUTHOR("Philippe Reynes "); +MODULE_DESCRIPTION("MAX5821 DAC"); +MODULE_LICENSE("GPL v2"); -- GitLab From 7ddebf54292052898dd0cf3925d113e3527608a7 Mon Sep 17 00:00:00 2001 From: Teodora Baluta Date: Fri, 25 Jul 2014 09:50:00 +0100 Subject: [PATCH 0038/9167] staging: iio: ad5933: fix sparse warnings Fix the following sparse warnings: CHECK drivers/staging/iio/impedance-analyzer/ad5933.c drivers/staging/iio/impedance-analyzer/ad5933.c:241:17: warning: incorrect type in assignment (different base types) drivers/staging/iio/impedance-analyzer/ad5933.c:241:17: expected unsigned int [unsigned] [usertype] d32 drivers/staging/iio/impedance-analyzer/ad5933.c:241:17: got restricted __be32 [usertype] drivers/staging/iio/impedance-analyzer/ad5933.c:263:13: warning: incorrect type in assignment (different base types) drivers/staging/iio/impedance-analyzer/ad5933.c:263:13: expected unsigned short [unsigned] dat drivers/staging/iio/impedance-analyzer/ad5933.c:263:13: got restricted __be16 [usertype] drivers/staging/iio/impedance-analyzer/ad5933.c:271:13: warning: incorrect type in assignment (different base types) drivers/staging/iio/impedance-analyzer/ad5933.c:271:13: expected unsigned short [unsigned] [addressable] dat drivers/staging/iio/impedance-analyzer/ad5933.c:271:13: got restricted __be16 [usertype] drivers/staging/iio/impedance-analyzer/ad5933.c:310:19: warning: cast to restricted __be32 drivers/staging/iio/impedance-analyzer/ad5933.c:310:19: warning: cast to restricted __be32 drivers/staging/iio/impedance-analyzer/ad5933.c:310:19: warning: cast to restricted __be32 drivers/staging/iio/impedance-analyzer/ad5933.c:310:19: warning: cast to restricted __be32 drivers/staging/iio/impedance-analyzer/ad5933.c:310:19: warning: cast to restricted __be32 drivers/staging/iio/impedance-analyzer/ad5933.c:310:19: warning: cast to restricted __be32 drivers/staging/iio/impedance-analyzer/ad5933.c:446:21: warning: incorrect type in assignment (different base types) drivers/staging/iio/impedance-analyzer/ad5933.c:446:21: expected unsigned short [unsigned] dat drivers/staging/iio/impedance-analyzer/ad5933.c:446:21: got restricted __be16 [usertype] drivers/staging/iio/impedance-analyzer/ad5933.c:454:21: warning: incorrect type in assignment (different base types) drivers/staging/iio/impedance-analyzer/ad5933.c:454:21: expected unsigned short [unsigned] [addressable] dat drivers/staging/iio/impedance-analyzer/ad5933.c:454:21: got restricted __be16 [usertype] drivers/staging/iio/impedance-analyzer/ad5933.c:548:23: warning: cast to restricted __be16 drivers/staging/iio/impedance-analyzer/ad5933.c:548:23: warning: cast to restricted __be16 drivers/staging/iio/impedance-analyzer/ad5933.c:548:23: warning: cast to restricted __be16 drivers/staging/iio/impedance-analyzer/ad5933.c:548:23: warning: cast to restricted __be16 Signed-off-by: Teodora Baluta Signed-off-by: Jonathan Cameron --- drivers/staging/iio/impedance-analyzer/ad5933.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c index 2b96665da8a2..2cef4b95ba63 100644 --- a/drivers/staging/iio/impedance-analyzer/ad5933.c +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -220,7 +220,7 @@ static int ad5933_set_freq(struct ad5933_state *st, { unsigned long long freqreg; union { - u32 d32; + __be32 d32; u8 d8[4]; } dat; @@ -244,7 +244,7 @@ static int ad5933_set_freq(struct ad5933_state *st, static int ad5933_setup(struct ad5933_state *st) { - unsigned short dat; + __be16 dat; int ret; ret = ad5933_reset(st); @@ -297,7 +297,7 @@ static ssize_t ad5933_show_frequency(struct device *dev, int ret; unsigned long long freqreg; union { - u32 d32; + __be32 d32; u8 d8[4]; } dat; @@ -402,7 +402,7 @@ static ssize_t ad5933_store(struct device *dev, struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); u16 val; int i, ret = 0; - unsigned short dat; + __be16 dat; if (this_attr->address != AD5933_IN_PGA_GAIN) { ret = kstrtou16(buf, 10, &val); @@ -521,7 +521,7 @@ static int ad5933_read_raw(struct iio_dev *indio_dev, long m) { struct ad5933_state *st = iio_priv(indio_dev); - unsigned short dat; + __be16 dat; int ret = -EINVAL; mutex_lock(&indio_dev->mlock); -- GitLab From 61072dbc8a017039059ec0e94548e4ba31602893 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 17 Jul 2014 16:59:00 +0100 Subject: [PATCH 0039/9167] iio: buffer: Use roundup() instead of open-coding it Makes the code slightly shorter and a bit easier to understand. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 2952ee038477..7462f1233974 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -979,9 +979,7 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, else length = ch->scan_type.storagebits / 8; /* Make sure we are aligned */ - in_loc += length; - if (in_loc % length) - in_loc += length - in_loc % length; + in_loc = roundup(in_loc, length) + length; } p = kmalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) { @@ -994,10 +992,8 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, ch->scan_type.repeat; else length = ch->scan_type.storagebits / 8; - if (out_loc % length) - out_loc += length - out_loc % length; - if (in_loc % length) - in_loc += length - in_loc % length; + out_loc = roundup(out_loc, length); + in_loc = roundup(in_loc, length); p->from = in_loc; p->to = out_loc; p->length = length; @@ -1019,10 +1015,8 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, ch->scan_type.repeat; else length = ch->scan_type.storagebits / 8; - if (out_loc % length) - out_loc += length - out_loc % length; - if (in_loc % length) - in_loc += length - in_loc % length; + out_loc = roundup(out_loc, length); + in_loc = roundup(in_loc, length); p->from = in_loc; p->to = out_loc; p->length = length; -- GitLab From ebc14ddcc9454c02439b67f6536628289faaa26e Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Wed, 23 Jul 2014 17:10:49 -0300 Subject: [PATCH 0040/9167] x86, microcode, intel: Fix total_size computation According to the Intel SDM vol 3A (order code 253668-051US, June 2014), on section 9.11.1, page 9-28: "For microcode updates with a data size field equal to 00000000H, the size of the microcode update is 2048 bytes. The first 48 bytes contain the microcode update header. The remaining 2000 bytes contain encrypted data." "For microcode updates with a data size not equal to 00000000H, the total size field specifies the size of the microcode update." Up to 2002/2003, Intel used an "old format" for the microcode update containers that was always 2048 bytes in size. That old format did not have Data Size and Total Size fields, the quadwords at those positions in the microcode container header were "reserved". The microcode header of the "old format" microcode container has a hrdver of 0x01. You can hunt down an old copy of the Intel SDM to validate this through its order number (#243192). I found one from 1999 through a Google search. Sometime in 2002/2003 (AFAICT, for the Prescott processors), Intel documented a new format for the microcode containers and contributed in 2003 some code to the Linux kernel microcode driver implementing support for the new format. This new format has Data Size and Total Size fields, as well as the optional extended signature table. However, it reuses the same hrdver as the old format (0x01), and it can only be told apart from the old format by a non-zero Data Size field. In fact, the only reason we can even trust a Data Size of zero to mean that the microcode container is in the old format, is because Intel reatroatively promised that the old format would always have a zero there when they wrote the documentation for the _new_ format. This is a very old bug, dating back to 2003. It has been dormant ever since, as Intel seems to set all reserved fields to zero on the microcode updates they distribute: I could not find a public microcode update that would trigger this bug. Signed-off-by: Henrique de Moraes Holschuh Link: http://lkml.kernel.org/r/1406146251-8540-1-git-send-email-hmh@hmh.eng.br Signed-off-by: Borislav Petkov --- arch/x86/include/asm/microcode_intel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/microcode_intel.h b/arch/x86/include/asm/microcode_intel.h index 9067166409bf..bbe296e0bce1 100644 --- a/arch/x86/include/asm/microcode_intel.h +++ b/arch/x86/include/asm/microcode_intel.h @@ -43,7 +43,7 @@ struct extended_sigtable { #define DWSIZE (sizeof(u32)) #define get_totalsize(mc) \ - (((struct microcode_intel *)mc)->hdr.totalsize ? \ + (((struct microcode_intel *)mc)->hdr.datasize ? \ ((struct microcode_intel *)mc)->hdr.totalsize : \ DEFAULT_UCODE_TOTALSIZE) -- GitLab From 611b3682bbefd8213b9f46e5883c15f132b20f7c Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Fri, 25 Jul 2014 11:56:40 +0300 Subject: [PATCH 0041/9167] ath10k: improve 'hard' simulate fw crash Different firmware may support different numbers of vdevs. Use value that is always out of range for all firmware. Signed-off-by: Ben Greear Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/debug.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index 3030158c478e..c9e35c87edfb 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -531,7 +531,10 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file, ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0); } else if (!strcmp(buf, "hard")) { ath10k_info("simulating hard firmware crash\n"); - ret = ath10k_wmi_vdev_set_param(ar, TARGET_NUM_VDEVS + 1, + /* 0x7fff is vdev id, and it is always out of range for all + * firmware variants in order to force a firmware crash. + */ + ret = ath10k_wmi_vdev_set_param(ar, 0x7fff, ar->wmi.vdev_param->rts_threshold, 0); } else { ret = -EINVAL; -- GitLab From 24c88f7807fb7c723690474d0a5d3441468185d9 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 25 Jul 2014 13:32:17 +0200 Subject: [PATCH 0042/9167] ath10k: add support for 10.2 firmware The 10.2 firmware is a successor of 10.1 firmware (formerly identified as 10.x). Both share a lot but have some slight ABI differences that need to be taken care of. The 10.2 firmware introduces some new features but those can be added in subsequent patches. This patch makes ath10k boot and work with 10.2 with comparable functionality to 10.1. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 14 + drivers/net/wireless/ath/ath10k/core.h | 5 + drivers/net/wireless/ath/ath10k/hw.h | 3 +- drivers/net/wireless/ath/ath10k/pci.c | 2 +- drivers/net/wireless/ath/ath10k/wmi.c | 451 +++++++++++++++++++++++-- drivers/net/wireless/ath/ath10k/wmi.h | 233 ++++++++++++- 6 files changed, 678 insertions(+), 30 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 93adb8c58969..bef797d5f4d3 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -499,6 +499,13 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name) goto err; } + if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) && + !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { + ath10k_err("feature bits corrupted: 10.2 feature requires 10.x feature to be set as well"); + ret = -EINVAL; + goto err; + } + /* now fetch the board file */ if (ar->hw_params.fw.board == NULL) { ath10k_err("board data file not defined"); @@ -531,6 +538,13 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) { int ret; + ar->fw_api = 3; + ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); + + ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API3_FILE); + if (ret == 0) + goto success; + ar->fw_api = 2; ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 83a5fa91531d..ded3af2266d0 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -330,6 +330,11 @@ enum ath10k_fw_features { /* Firmware does not support P2P */ ATH10K_FW_FEATURE_NO_P2P = 3, + /* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature bit + * is required to be set as well. + */ + ATH10K_FW_FEATURE_WMI_10_2 = 4, + /* keep last */ ATH10K_FW_FEATURE_COUNT, }; diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 007e855f4ba9..ffd04890407e 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -28,12 +28,13 @@ #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_2_FILE "firmware-2.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 #define ATH10K_FW_API2_FILE "firmware-2.bin" +#define ATH10K_FW_API3_FILE "firmware-3.bin" /* includes also the null byte */ #define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K" diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 0ffff205478d..2d340cc522e3 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2809,5 +2809,5 @@ 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_2_FILE); +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_BOARD_DATA_FILE); diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index c2c87c916b5a..b09661db9447 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -487,6 +487,127 @@ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = { .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, }; +/* firmware 10.2 specific mappings */ +static struct wmi_cmd_map wmi_10_2_cmd_map = { + .init_cmdid = WMI_10_2_INIT_CMDID, + .start_scan_cmdid = WMI_10_2_START_SCAN_CMDID, + .stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID, + .scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID, + .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, + .pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, + .pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID, + .pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID, + .pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, + .pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, + .pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, + .pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, + .pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, + .pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, + .pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, + .pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, + .pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, + .vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID, + .vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID, + .vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID, + .vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID, + .vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID, + .vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID, + .vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID, + .vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID, + .vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID, + .peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID, + .peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID, + .peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID, + .peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID, + .peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID, + .peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, + .peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, + .peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID, + .bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID, + .pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID, + .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, + .bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID, + .prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID, + .mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID, + .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, + .addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID, + .addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID, + .addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID, + .delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID, + .addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID, + .send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID, + .sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID, + .sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID, + .sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID, + .pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID, + .pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID, + .roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE, + .roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, + .roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD, + .roam_scan_rssi_change_threshold = + WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, + .roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE, + .ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, + .ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, + .ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD, + .p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO, + .p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, + .p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE, + .p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, + .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, + .ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID, + .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, + .peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, + .wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, + .wlan_profile_set_hist_intvl_cmdid = + WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, + .wlan_profile_get_profile_data_cmdid = + WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, + .wlan_profile_enable_profile_id_cmdid = + WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, + .wlan_profile_list_profile_id_cmdid = + WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, + .pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID, + .pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID, + .add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID, + .rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID, + .wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, + .wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, + .wow_enable_disable_wake_event_cmdid = + WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, + .wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID, + .wow_hostwakeup_from_sleep_cmdid = + WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, + .rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID, + .rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID, + .vdev_spectral_scan_configure_cmdid = + WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, + .vdev_spectral_scan_enable_cmdid = + WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, + .request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID, + .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, + .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, + .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, + .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, + .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, + .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, + .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, + .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, + .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, + .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, + .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, + .echo_cmdid = WMI_10_2_ECHO_CMDID, + .pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID, + .dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID, + .pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID, + .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, + .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, + .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, + .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID, + .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID, +}; + int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) { int ret; @@ -2325,20 +2446,144 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) dev_kfree_skb(skb); } +static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb) +{ + struct wmi_cmd_hdr *cmd_hdr; + enum wmi_10_2_event_id id; + + cmd_hdr = (struct wmi_cmd_hdr *)skb->data; + id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); + + if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) + return; + + trace_ath10k_wmi_event(id, skb->data, skb->len); + + switch (id) { + case WMI_10_2_MGMT_RX_EVENTID: + ath10k_wmi_event_mgmt_rx(ar, skb); + /* mgmt_rx() owns the skb now! */ + return; + case WMI_10_2_SCAN_EVENTID: + ath10k_wmi_event_scan(ar, skb); + break; + case WMI_10_2_CHAN_INFO_EVENTID: + ath10k_wmi_event_chan_info(ar, skb); + break; + case WMI_10_2_ECHO_EVENTID: + ath10k_wmi_event_echo(ar, skb); + break; + case WMI_10_2_DEBUG_MESG_EVENTID: + ath10k_wmi_event_debug_mesg(ar, skb); + break; + case WMI_10_2_UPDATE_STATS_EVENTID: + ath10k_wmi_event_update_stats(ar, skb); + break; + case WMI_10_2_VDEV_START_RESP_EVENTID: + ath10k_wmi_event_vdev_start_resp(ar, skb); + break; + case WMI_10_2_VDEV_STOPPED_EVENTID: + ath10k_wmi_event_vdev_stopped(ar, skb); + break; + case WMI_10_2_PEER_STA_KICKOUT_EVENTID: + ath10k_wmi_event_peer_sta_kickout(ar, skb); + break; + case WMI_10_2_HOST_SWBA_EVENTID: + ath10k_wmi_event_host_swba(ar, skb); + break; + case WMI_10_2_TBTTOFFSET_UPDATE_EVENTID: + ath10k_wmi_event_tbttoffset_update(ar, skb); + break; + case WMI_10_2_PHYERR_EVENTID: + ath10k_wmi_event_phyerr(ar, skb); + break; + case WMI_10_2_ROAM_EVENTID: + ath10k_wmi_event_roam(ar, skb); + break; + case WMI_10_2_PROFILE_MATCH: + ath10k_wmi_event_profile_match(ar, skb); + break; + case WMI_10_2_DEBUG_PRINT_EVENTID: + ath10k_wmi_event_debug_print(ar, skb); + break; + case WMI_10_2_PDEV_QVIT_EVENTID: + ath10k_wmi_event_pdev_qvit(ar, skb); + break; + case WMI_10_2_WLAN_PROFILE_DATA_EVENTID: + ath10k_wmi_event_wlan_profile_data(ar, skb); + break; + case WMI_10_2_RTT_MEASUREMENT_REPORT_EVENTID: + ath10k_wmi_event_rtt_measurement_report(ar, skb); + break; + case WMI_10_2_TSF_MEASUREMENT_REPORT_EVENTID: + ath10k_wmi_event_tsf_measurement_report(ar, skb); + break; + case WMI_10_2_RTT_ERROR_REPORT_EVENTID: + ath10k_wmi_event_rtt_error_report(ar, skb); + break; + case WMI_10_2_WOW_WAKEUP_HOST_EVENTID: + ath10k_wmi_event_wow_wakeup_host(ar, skb); + break; + case WMI_10_2_DCS_INTERFERENCE_EVENTID: + ath10k_wmi_event_dcs_interference(ar, skb); + break; + case WMI_10_2_PDEV_TPC_CONFIG_EVENTID: + ath10k_wmi_event_pdev_tpc_config(ar, skb); + break; + case WMI_10_2_INST_RSSI_STATS_EVENTID: + ath10k_wmi_event_inst_rssi_stats(ar, skb); + break; + case WMI_10_2_VDEV_STANDBY_REQ_EVENTID: + ath10k_wmi_event_vdev_standby_req(ar, skb); + break; + case WMI_10_2_VDEV_RESUME_REQ_EVENTID: + 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); + break; + case WMI_10_2_READY_EVENTID: + ath10k_wmi_ready_event_rx(ar, skb); + break; + case WMI_10_2_RTT_KEEPALIVE_EVENTID: + case WMI_10_2_GPIO_INPUT_EVENTID: + case WMI_10_2_PEER_RATECODE_LIST_EVENTID: + case WMI_10_2_GENERIC_BUFFER_EVENTID: + case WMI_10_2_MCAST_BUF_RELEASE_EVENTID: + case WMI_10_2_MCAST_LIST_AGEOUT_EVENTID: + case WMI_10_2_WDS_PEER_EVENTID: + ath10k_dbg(ATH10K_DBG_WMI, + "received event id %d not implemented\n", id); + break; + default: + ath10k_warn("Unknown eventid: %d\n", id); + break; + } + + dev_kfree_skb(skb); +} static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) { - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - ath10k_wmi_10x_process_rx(ar, skb); - else + 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_10_2_process_rx(ar, skb); + else + ath10k_wmi_10x_process_rx(ar, skb); + } else { ath10k_wmi_main_process_rx(ar, skb); + } } /* WMI Initialization functions */ int ath10k_wmi_attach(struct ath10k *ar) { if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { - ar->wmi.cmd = &wmi_10x_cmd_map; + 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 { @@ -2738,14 +2983,109 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); } +static int ath10k_wmi_10_2_cmd_init(struct ath10k *ar) +{ + struct wmi_init_cmd_10_2 *cmd; + 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); + config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS); + config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS); + config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT); + config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK); + config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK); + config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); + config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); + config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); + config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI); + config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE); + + config.scan_max_pending_reqs = + __cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS); + + config.bmiss_offload_max_vdev = + __cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV); + + config.roam_offload_max_vdev = + __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV); + + config.roam_offload_max_ap_profiles = + __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES); + + config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS); + config.num_mcast_table_elems = + __cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS); + + config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE); + config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE); + config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES); + config.dma_burst_size = __cpu_to_le32(TARGET_10X_DMA_BURST_SIZE); + config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM); + + val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; + config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val); + + config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG); + + config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC); + config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES); + + len = sizeof(*cmd) + + (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); + + buf = ath10k_wmi_alloc_skb(len); + if (!buf) + return -ENOMEM; + + 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(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(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_dbg(ATH10K_DBG_WMI, "wmi init 10.2\n"); + return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); +} + int ath10k_wmi_cmd_init(struct ath10k *ar) { int ret; - if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) - ret = ath10k_wmi_10x_cmd_init(ar); - else + if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { + if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) + ret = ath10k_wmi_10_2_cmd_init(ar); + else + ret = ath10k_wmi_10x_cmd_init(ar); + } else { ret = ath10k_wmi_main_cmd_init(ar); + } return ret; } @@ -2865,8 +3205,8 @@ int ath10k_wmi_start_scan(struct ath10k *ar, channels->num_chan = __cpu_to_le32(arg->n_channels); for (i = 0; i < arg->n_channels; i++) - channels->channel_list[i] = - __cpu_to_le32(arg->channels[i]); + channels->channel_list[i].freq = + __cpu_to_le16(arg->channels[i]); off += sizeof(*channels); off += sizeof(__le32) * arg->n_channels; @@ -3447,24 +3787,12 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar, return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); } -int ath10k_wmi_peer_assoc(struct ath10k *ar, - const struct wmi_peer_assoc_complete_arg *arg) +static void +ath10k_wmi_peer_assoc_fill(struct ath10k *ar, void *buf, + const struct wmi_peer_assoc_complete_arg *arg) { - struct wmi_peer_assoc_complete_cmd *cmd; - struct sk_buff *skb; + struct wmi_common_peer_assoc_complete_cmd *cmd = buf; - if (arg->peer_mpdu_density > 16) - return -EINVAL; - if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) - return -EINVAL; - if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) - return -EINVAL; - - skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_peer_assoc_complete_cmd *)skb->data; cmd->vdev_id = __cpu_to_le32(arg->vdev_id); cmd->peer_new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1); cmd->peer_associd = __cpu_to_le32(arg->peer_aid); @@ -3499,6 +3827,78 @@ int ath10k_wmi_peer_assoc(struct ath10k *ar, __cpu_to_le32(arg->peer_vht_rates.tx_max_rate); cmd->peer_vht_rates.tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); +} + +static void +ath10k_wmi_peer_assoc_fill_main(struct ath10k *ar, void *buf, + const struct wmi_peer_assoc_complete_arg *arg) +{ + struct wmi_main_peer_assoc_complete_cmd *cmd = buf; + + ath10k_wmi_peer_assoc_fill(ar, buf, arg); + memset(cmd->peer_ht_info, 0, sizeof(cmd->peer_ht_info)); +} + +static void +ath10k_wmi_peer_assoc_fill_10_1(struct ath10k *ar, void *buf, + const struct wmi_peer_assoc_complete_arg *arg) +{ + ath10k_wmi_peer_assoc_fill(ar, buf, arg); +} + +static void +ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void *buf, + const struct wmi_peer_assoc_complete_arg *arg) +{ + struct wmi_10_2_peer_assoc_complete_cmd *cmd = buf; + int max_mcs, max_nss; + u32 info0; + + /* TODO: Is using max values okay with firmware? */ + max_mcs = 0xf; + max_nss = 0xf; + + info0 = SM(max_mcs, WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX) | + SM(max_nss, WMI_PEER_ASSOC_INFO0_MAX_NSS); + + ath10k_wmi_peer_assoc_fill(ar, buf, arg); + cmd->info0 = __cpu_to_le32(info0); +} + +int ath10k_wmi_peer_assoc(struct ath10k *ar, + const struct wmi_peer_assoc_complete_arg *arg) +{ + struct sk_buff *skb; + int len; + + if (arg->peer_mpdu_density > 16) + return -EINVAL; + if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) + return -EINVAL; + if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) + return -EINVAL; + + if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { + if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features)) + len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd); + else + len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd); + } else { + len = sizeof(struct wmi_main_peer_assoc_complete_cmd); + } + + skb = ath10k_wmi_alloc_skb(len); + if (!skb) + return -ENOMEM; + + 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_main(ar, skb->data, arg); + } ath10k_dbg(ATH10K_DBG_WMI, "wmi peer assoc vdev %d addr %pM (%s)\n", @@ -3532,6 +3932,7 @@ int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif) cmd->msdu_id = 0; cmd->frame_control = __cpu_to_le32(fc); cmd->flags = 0; + cmd->antenna_mask = __cpu_to_le32(WMI_BCN_TX_REF_DEF_ANTENNA); if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero) cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index e93df2c10413..c9ac11cbc5d2 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -803,6 +803,159 @@ enum wmi_10x_event_id { WMI_10X_PDEV_UTF_EVENTID = WMI_10X_END_EVENTID-1, }; +enum wmi_10_2_cmd_id { + WMI_10_2_START_CMDID = 0x9000, + WMI_10_2_END_CMDID = 0x9FFF, + WMI_10_2_INIT_CMDID, + WMI_10_2_START_SCAN_CMDID = WMI_10_2_START_CMDID, + WMI_10_2_STOP_SCAN_CMDID, + WMI_10_2_SCAN_CHAN_LIST_CMDID, + WMI_10_2_ECHO_CMDID, + WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, + WMI_10_2_PDEV_SET_CHANNEL_CMDID, + WMI_10_2_PDEV_SET_PARAM_CMDID, + WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, + WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, + WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, + WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, + WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, + WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, + WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, + WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, + WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, + WMI_10_2_VDEV_CREATE_CMDID, + WMI_10_2_VDEV_DELETE_CMDID, + WMI_10_2_VDEV_START_REQUEST_CMDID, + WMI_10_2_VDEV_RESTART_REQUEST_CMDID, + WMI_10_2_VDEV_UP_CMDID, + WMI_10_2_VDEV_STOP_CMDID, + WMI_10_2_VDEV_DOWN_CMDID, + WMI_10_2_VDEV_STANDBY_RESPONSE_CMDID, + WMI_10_2_VDEV_RESUME_RESPONSE_CMDID, + WMI_10_2_VDEV_SET_PARAM_CMDID, + WMI_10_2_VDEV_INSTALL_KEY_CMDID, + WMI_10_2_VDEV_SET_DSCP_TID_MAP_CMDID, + WMI_10_2_PEER_CREATE_CMDID, + WMI_10_2_PEER_DELETE_CMDID, + WMI_10_2_PEER_FLUSH_TIDS_CMDID, + WMI_10_2_PEER_SET_PARAM_CMDID, + WMI_10_2_PEER_ASSOC_CMDID, + WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, + WMI_10_2_PEER_UPDATE_WDS_ENTRY_CMDID, + WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, + WMI_10_2_PEER_MCAST_GROUP_CMDID, + WMI_10_2_BCN_TX_CMDID, + WMI_10_2_BCN_PRB_TMPL_CMDID, + WMI_10_2_BCN_FILTER_RX_CMDID, + WMI_10_2_PRB_REQ_FILTER_RX_CMDID, + WMI_10_2_MGMT_TX_CMDID, + WMI_10_2_ADDBA_CLEAR_RESP_CMDID, + WMI_10_2_ADDBA_SEND_CMDID, + WMI_10_2_ADDBA_STATUS_CMDID, + WMI_10_2_DELBA_SEND_CMDID, + WMI_10_2_ADDBA_SET_RESP_CMDID, + WMI_10_2_SEND_SINGLEAMSDU_CMDID, + WMI_10_2_STA_POWERSAVE_MODE_CMDID, + WMI_10_2_STA_POWERSAVE_PARAM_CMDID, + WMI_10_2_STA_MIMO_PS_MODE_CMDID, + WMI_10_2_DBGLOG_CFG_CMDID, + WMI_10_2_PDEV_DFS_ENABLE_CMDID, + WMI_10_2_PDEV_DFS_DISABLE_CMDID, + WMI_10_2_PDEV_QVIT_CMDID, + WMI_10_2_ROAM_SCAN_MODE, + WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, + WMI_10_2_ROAM_SCAN_PERIOD, + WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, + WMI_10_2_ROAM_AP_PROFILE, + WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, + WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, + WMI_10_2_OFL_SCAN_PERIOD, + WMI_10_2_P2P_DEV_SET_DEVICE_INFO, + WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, + WMI_10_2_P2P_GO_SET_BEACON_IE, + WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, + WMI_10_2_AP_PS_PEER_PARAM_CMDID, + WMI_10_2_AP_PS_PEER_UAPSD_COEX_CMDID, + WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, + WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, + WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, + WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, + WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, + WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, + WMI_10_2_PDEV_SUSPEND_CMDID, + WMI_10_2_PDEV_RESUME_CMDID, + WMI_10_2_ADD_BCN_FILTER_CMDID, + WMI_10_2_RMV_BCN_FILTER_CMDID, + WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, + WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, + WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, + WMI_10_2_WOW_ENABLE_CMDID, + WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, + WMI_10_2_RTT_MEASREQ_CMDID, + WMI_10_2_RTT_TSF_CMDID, + WMI_10_2_RTT_KEEPALIVE_CMDID, + WMI_10_2_PDEV_SEND_BCN_CMDID, + WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, + WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, + WMI_10_2_REQUEST_STATS_CMDID, + WMI_10_2_GPIO_CONFIG_CMDID, + WMI_10_2_GPIO_OUTPUT_CMDID, + WMI_10_2_VDEV_RATEMASK_CMDID, + WMI_10_2_PDEV_SMART_ANT_ENABLE_CMDID, + WMI_10_2_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID, + WMI_10_2_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID, + WMI_10_2_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID, + WMI_10_2_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID, + WMI_10_2_FORCE_FW_HANG_CMDID, + WMI_10_2_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID, + WMI_10_2_PDEV_SET_CTL_TABLE_CMDID, + WMI_10_2_PDEV_SET_MIMOGAIN_TABLE_CMDID, + WMI_10_2_PDEV_RATEPWR_TABLE_CMDID, + WMI_10_2_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID, + WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1, +}; + +enum wmi_10_2_event_id { + WMI_10_2_SERVICE_READY_EVENTID = 0x8000, + WMI_10_2_READY_EVENTID, + WMI_10_2_DEBUG_MESG_EVENTID, + WMI_10_2_START_EVENTID = 0x9000, + WMI_10_2_END_EVENTID = 0x9FFF, + WMI_10_2_SCAN_EVENTID = WMI_10_2_START_EVENTID, + WMI_10_2_ECHO_EVENTID, + WMI_10_2_UPDATE_STATS_EVENTID, + WMI_10_2_INST_RSSI_STATS_EVENTID, + WMI_10_2_VDEV_START_RESP_EVENTID, + WMI_10_2_VDEV_STANDBY_REQ_EVENTID, + WMI_10_2_VDEV_RESUME_REQ_EVENTID, + WMI_10_2_VDEV_STOPPED_EVENTID, + WMI_10_2_PEER_STA_KICKOUT_EVENTID, + WMI_10_2_HOST_SWBA_EVENTID, + WMI_10_2_TBTTOFFSET_UPDATE_EVENTID, + WMI_10_2_MGMT_RX_EVENTID, + WMI_10_2_CHAN_INFO_EVENTID, + WMI_10_2_PHYERR_EVENTID, + WMI_10_2_ROAM_EVENTID, + WMI_10_2_PROFILE_MATCH, + WMI_10_2_DEBUG_PRINT_EVENTID, + WMI_10_2_PDEV_QVIT_EVENTID, + WMI_10_2_WLAN_PROFILE_DATA_EVENTID, + WMI_10_2_RTT_MEASUREMENT_REPORT_EVENTID, + WMI_10_2_TSF_MEASUREMENT_REPORT_EVENTID, + WMI_10_2_RTT_ERROR_REPORT_EVENTID, + WMI_10_2_RTT_KEEPALIVE_EVENTID, + WMI_10_2_WOW_WAKEUP_HOST_EVENTID, + WMI_10_2_DCS_INTERFERENCE_EVENTID, + WMI_10_2_PDEV_TPC_CONFIG_EVENTID, + WMI_10_2_GPIO_INPUT_EVENTID, + WMI_10_2_PEER_RATECODE_LIST_EVENTID, + WMI_10_2_GENERIC_BUFFER_EVENTID, + WMI_10_2_MCAST_BUF_RELEASE_EVENTID, + WMI_10_2_MCAST_LIST_AGEOUT_EVENTID, + WMI_10_2_WDS_PEER_EVENTID, + WMI_10_2_PDEV_UTF_EVENTID = WMI_10_2_END_EVENTID - 1, +}; + enum wmi_phy_mode { MODE_11A = 0, /* 11a Mode */ MODE_11G = 1, /* 11b/g Mode */ @@ -1551,6 +1704,16 @@ struct wmi_resource_config_10x { __le32 max_frag_entries; } __packed; +struct wmi_resource_config_10_2 { + struct wmi_resource_config_10x common; + __le32 max_peer_ext_stats; + __le32 smart_ant_cap; /* 0-disable, 1-enable */ + __le32 bk_min_free; + __le32 be_min_free; + __le32 vi_min_free; + __le32 vo_min_free; + __le32 rx_batchmode; /* 0-disable, 1-enable */ +} __packed; #define NUM_UNITS_IS_NUM_VDEVS 0x1 #define NUM_UNITS_IS_NUM_PEERS 0x2 @@ -1588,11 +1751,28 @@ struct wmi_init_cmd_10x { struct host_memory_chunk host_mem_chunks[1]; } __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]; +} __packed; + +struct wmi_chan_list_entry { + __le16 freq; + u8 phy_mode; /* valid for 10.2 only */ + u8 reserved; +} __packed; + /* TLV for channel list */ struct wmi_chan_list { __le32 tag; /* WMI_CHAN_LIST_TAG */ __le32 num_chan; - __le32 channel_list[0]; + struct wmi_chan_list_entry channel_list[0]; } __packed; struct wmi_bssid_list { @@ -1821,7 +2001,7 @@ struct wmi_start_scan_arg { u32 n_bssids; u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN]; - u32 channels[64]; + u16 channels[64]; struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID]; struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID]; }; @@ -2515,6 +2695,19 @@ enum wmi_10x_pdev_param { WMI_10X_PDEV_PARAM_BURST_DUR, /* Set Bursting Enable*/ WMI_10X_PDEV_PARAM_BURST_ENABLE, + + /* following are available as of firmware 10.2 */ + WMI_10X_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, + WMI_10X_PDEV_PARAM_IGMPMLD_OVERRIDE, + WMI_10X_PDEV_PARAM_IGMPMLD_TID, + WMI_10X_PDEV_PARAM_ANTENNA_GAIN, + WMI_10X_PDEV_PARAM_RX_DECAP_MODE, + WMI_10X_PDEV_PARAM_RX_FILTER, + WMI_10X_PDEV_PARAM_SET_MCAST_TO_UCAST_TID, + WMI_10X_PDEV_PARAM_PROXY_STA_MODE, + WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_MODE, + WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, + WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, }; struct wmi_pdev_set_param_cmd { @@ -3387,6 +3580,14 @@ enum wmi_10x_vdev_param { WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, + + /* following are available as of firmware 10.2 */ + WMI_10X_VDEV_PARAM_TX_ENCAP_TYPE, + WMI_10X_VDEV_PARAM_CABQ_MAXDUR, + WMI_10X_VDEV_PARAM_MFPTEST_SET, + WMI_10X_VDEV_PARAM_RTS_FIXED_RATE, + WMI_10X_VDEV_PARAM_VHT_SGIMASK, + WMI_10X_VDEV_PARAM_VHT80_RATEMASK, }; /* slot time long */ @@ -3470,6 +3671,11 @@ enum wmi_bcn_tx_ref_flags { WMI_BCN_TX_REF_FLAG_DELIVER_CAB = 0x2, }; +/* TODO: It is unclear why "no antenna" works while any other seemingly valid + * chainmask yields no beacons on the air at all. + */ +#define WMI_BCN_TX_REF_DEF_ANTENNA 0 + struct wmi_bcn_tx_ref_cmd { __le32 vdev_id; __le32 data_len; @@ -3481,6 +3687,8 @@ struct wmi_bcn_tx_ref_cmd { __le32 frame_control; /* to control CABQ traffic: WMI_BCN_TX_REF_FLAG_ */ __le32 flags; + /* introduced in 10.2 */ + __le32 antenna_mask; } __packed; /* Beacon filter */ @@ -4053,7 +4261,7 @@ struct wmi_peer_set_q_empty_callback_cmd { /* Maximum listen interval supported by hw in units of beacon interval */ #define ATH10K_MAX_HW_LISTEN_INTERVAL 5 -struct wmi_peer_assoc_complete_cmd { +struct wmi_common_peer_assoc_complete_cmd { struct wmi_mac_addr peer_macaddr; __le32 vdev_id; __le32 peer_new_assoc; /* 1=assoc, 0=reassoc */ @@ -4071,11 +4279,30 @@ struct wmi_peer_assoc_complete_cmd { __le32 peer_vht_caps; __le32 peer_phymode; struct wmi_vht_rate_set peer_vht_rates; +}; + +struct wmi_main_peer_assoc_complete_cmd { + struct wmi_common_peer_assoc_complete_cmd cmd; + /* HT Operation Element of the peer. Five bytes packed in 2 * INT32 array and filled from lsb to msb. */ __le32 peer_ht_info[2]; } __packed; +struct wmi_10_1_peer_assoc_complete_cmd { + struct wmi_common_peer_assoc_complete_cmd cmd; +} __packed; + +#define WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX_LSB 0 +#define WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX_MASK 0x0f +#define WMI_PEER_ASSOC_INFO0_MAX_NSS_LSB 4 +#define WMI_PEER_ASSOC_INFO0_MAX_NSS_MASK 0xf0 + +struct wmi_10_2_peer_assoc_complete_cmd { + struct wmi_common_peer_assoc_complete_cmd cmd; + __le32 info0; /* WMI_PEER_ASSOC_INFO0_ */ +} __packed; + struct wmi_peer_assoc_complete_arg { u8 addr[ETH_ALEN]; u32 vdev_id; -- GitLab From 72bdeb86552f8d992aa854af4e320401d8dd5cb5 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 28 Jul 2014 23:59:42 +0300 Subject: [PATCH 0043/9167] ath10k: fix aggregated 4addr Rx A-MSDU 4addr frames weren't reconstructed properly and in some cases this resulted in a warning: br0: received packet on wlan0.sta1 with own address as source address Since this was only related to A-MSDU it would trigger when more intense traffic was generated. Reported-by: Vu Hai NGUYEN Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index 80cdac15588a..e31d93e3e98b 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -866,7 +866,7 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, enum rx_msdu_decap_format fmt; enum htt_rx_mpdu_encrypt_type enctype; struct ieee80211_hdr *hdr; - u8 hdr_buf[64], addr[ETH_ALEN], *qos; + u8 hdr_buf[64], da[ETH_ALEN], sa[ETH_ALEN], *qos; unsigned int hdr_len; rxd = (void *)skb->data - sizeof(*rxd); @@ -904,10 +904,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, skb_trim(skb, skb->len - FCS_LEN); break; case RX_MSDU_DECAP_NATIVE_WIFI: - /* pull decapped header and copy DA */ + /* pull decapped header and copy SA & DA */ hdr = (struct ieee80211_hdr *)skb->data; hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); - memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN); + memcpy(da, ieee80211_get_DA(hdr), ETH_ALEN); + memcpy(sa, ieee80211_get_SA(hdr), ETH_ALEN); skb_pull(skb, hdr_len); /* push original 802.11 header */ @@ -921,8 +922,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, qos = ieee80211_get_qos_ctl(hdr); qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; - /* original 802.11 header has a different DA */ - memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN); + /* original 802.11 header has a different DA and in + * case of 4addr it may also have different SA + */ + memcpy(ieee80211_get_DA(hdr), da, ETH_ALEN); + memcpy(ieee80211_get_SA(hdr), sa, ETH_ALEN); break; case RX_MSDU_DECAP_ETHERNET2_DIX: /* strip ethernet header and insert decapped 802.11 -- GitLab From 76f5329a3dfe2f95dcc5664db603a2f1b0c9b825 Mon Sep 17 00:00:00 2001 From: Janusz Dziedzic Date: Mon, 28 Jul 2014 23:59:43 +0300 Subject: [PATCH 0044/9167] ath10k: extend debug code for RX path Print sequence number, AMSDU_MORE flag and AC when additional debug enabled in RX path. This is usefull for debugging purpose. Signed-off-by: Janusz Dziedzic Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/htt_rx.c | 41 ++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index e31d93e3e98b..763d6a228a13 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -819,19 +819,55 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar, return true; } +static const char * const tid_to_ac[] = { + "BE", + "BK", + "BK", + "BE", + "VI", + "VI", + "VO", + "VO", +}; + +static char *ath10k_get_tid(struct ieee80211_hdr *hdr, char *out, size_t size) +{ + u8 *qc; + int tid; + + if (!ieee80211_is_data_qos(hdr->frame_control)) + return ""; + + qc = ieee80211_get_qos_ctl(hdr); + tid = *qc & IEEE80211_QOS_CTL_TID_MASK; + if (tid < 8) + snprintf(out, size, "tid %d (%s)", tid, tid_to_ac[tid]); + else + snprintf(out, size, "tid %d", tid); + + return out; +} + static void ath10k_process_rx(struct ath10k *ar, struct ieee80211_rx_status *rx_status, struct sk_buff *skb) { struct ieee80211_rx_status *status; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + char tid[32]; status = IEEE80211_SKB_RXCB(skb); *status = *rx_status; ath10k_dbg(ATH10K_DBG_DATA, - "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %imic-err %i\n", + "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", skb, skb->len, + ieee80211_get_SA(hdr), + ath10k_get_tid(hdr, tid, sizeof(tid)), + is_multicast_ether_addr(ieee80211_get_DA(hdr)) ? + "mcast" : "ucast", + (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4, status->flag == 0 ? "legacy" : "", status->flag & RX_FLAG_HT ? "ht" : "", status->flag & RX_FLAG_VHT ? "vht" : "", @@ -843,7 +879,8 @@ static void ath10k_process_rx(struct ath10k *ar, status->freq, status->band, status->flag, !!(status->flag & RX_FLAG_FAILED_FCS_CRC), - !!(status->flag & RX_FLAG_MMIC_ERROR)); + !!(status->flag & RX_FLAG_MMIC_ERROR), + !!(status->flag & RX_FLAG_AMSDU_MORE)); ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ", skb->data, skb->len); -- GitLab From d17eb9b2a97131c75c7ea83ba981ebbe26135207 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Mon, 28 Jul 2014 21:53:31 +0200 Subject: [PATCH 0045/9167] ARM: dts: omap3-gta04: Rename gta04.dts to gta04.dtsi and add a4 model This patch is preparation of adding more boards which have common moved to omap3-gta04.dtsi. Other boards have only small additions to omap3-gta04a4. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/Makefile | 2 +- .../boot/dts/{omap3-gta04.dts => omap3-gta04.dtsi} | 0 arch/arm/boot/dts/omap3-gta04a4.dts | 13 +++++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) rename arch/arm/boot/dts/{omap3-gta04.dts => omap3-gta04.dtsi} (100%) create mode 100644 arch/arm/boot/dts/omap3-gta04a4.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b19f0c89f452..b812b6ced316 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -262,7 +262,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += am3517-craneboard.dtb \ omap3-devkit8000.dtb \ omap3-evm.dtb \ omap3-evm-37xx.dtb \ - omap3-gta04.dtb \ + omap3-gta04a4.dtb \ omap3-igep0020.dtb \ omap3-igep0030.dtb \ omap3-ldp.dtb \ diff --git a/arch/arm/boot/dts/omap3-gta04.dts b/arch/arm/boot/dts/omap3-gta04.dtsi similarity index 100% rename from arch/arm/boot/dts/omap3-gta04.dts rename to arch/arm/boot/dts/omap3-gta04.dtsi diff --git a/arch/arm/boot/dts/omap3-gta04a4.dts b/arch/arm/boot/dts/omap3-gta04a4.dts new file mode 100644 index 000000000000..c918bb1f0529 --- /dev/null +++ b/arch/arm/boot/dts/omap3-gta04a4.dts @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2014 Marek Belisko + * + * 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 "omap3-gta04.dtsi" + +/ { + model = "Goldelico GTA04A4"; +}; -- GitLab From 4cf64060a6ee4c2ab609fb915d924bdc98805875 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Mon, 28 Jul 2014 21:53:32 +0200 Subject: [PATCH 0046/9167] ARM: dts: Add gta04a3 model Add gta04a3 model with additional acceleromer. Signed-off-by: Marek Belisko Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/omap3-gta04a3.dts | 48 +++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 arch/arm/boot/dts/omap3-gta04a3.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b812b6ced316..455845ef5e7e 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -262,6 +262,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += am3517-craneboard.dtb \ omap3-devkit8000.dtb \ omap3-evm.dtb \ omap3-evm-37xx.dtb \ + omap3-gta04a3.dtb \ omap3-gta04a4.dtb \ omap3-igep0020.dtb \ omap3-igep0030.dtb \ diff --git a/arch/arm/boot/dts/omap3-gta04a3.dts b/arch/arm/boot/dts/omap3-gta04a3.dts new file mode 100644 index 000000000000..3099a892cf50 --- /dev/null +++ b/arch/arm/boot/dts/omap3-gta04a3.dts @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 H. Nikolaus Schaller + * + * 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 "omap3-gta04.dtsi" + +/ { + model = "Goldelico GTA04A3"; +}; + +&i2c2 { + + /* alternate accelerometer that might be installed on some GTA04A3 boards */ + lis302@1d { + compatible = "st,lis331dlh", "st,lis3lv02d"; + reg = <0x1d>; + interrupt-parent = <&gpio3>; + interrupts = <18 (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)>; + Vdd-supply = <&vaux2>; + Vdd_IO-supply = <&vaux2>; + + st,click-single-x; + st,click-single-y; + st,click-single-z; + st,click-thresh-x = <8>; + st,click-thresh-y = <8>; + st,click-thresh-z = <10>; + st,click-click-time-limit = <9>; + st,click-latency = <50>; + st,irq1-click; + st,wakeup-x-lo; + st,wakeup-x-hi; + st,wakeup-y-lo; + st,wakeup-y-hi; + st,wakeup-z-lo; + st,wakeup-z-hi; + st,min-limit-x = <32>; + st,min-limit-y = <3>; + st,min-limit-z = <3>; + st,max-limit-x = <3>; + st,max-limit-y = <32>; + st,max-limit-z = <32>; + }; +}; -- GitLab From c9940680b599300c3fb46e799986b736d394432d Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Mon, 28 Jul 2014 21:53:33 +0200 Subject: [PATCH 0047/9167] ARM: dts: Add gta04a5 model Add model a5 which have additional jack detection. Signed-off-by: Marek Belisko [tony@atomide.com: fixed a typo for make dtbs to work] Signed-off-by: Tony Lindgren --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/omap3-gta04a5.dts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 arch/arm/boot/dts/omap3-gta04a5.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 455845ef5e7e..3323028cc9a6 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -264,6 +264,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += am3517-craneboard.dtb \ omap3-evm-37xx.dtb \ omap3-gta04a3.dtb \ omap3-gta04a4.dtb \ + omap3-gta04a5.dtb \ omap3-igep0020.dtb \ omap3-igep0030.dtb \ omap3-ldp.dtb \ diff --git a/arch/arm/boot/dts/omap3-gta04a5.dts b/arch/arm/boot/dts/omap3-gta04a5.dts new file mode 100644 index 000000000000..52b386f6865b --- /dev/null +++ b/arch/arm/boot/dts/omap3-gta04a5.dts @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2014 H. Nikolaus Schaller + * + * 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 "omap3-gta04.dtsi" + +/ { + model = "Goldelico GTA04A5"; + + sound { + ti,jack-det-gpio = <&twl_gpio 2 0>; /* GTA04A5 only */ + }; +}; -- GitLab From 7d885749b6de2c9a1168d566e2380207b9177108 Mon Sep 17 00:00:00 2001 From: Mark Salter Date: Fri, 25 Jul 2014 18:02:46 -0400 Subject: [PATCH 0048/9167] perf tools: Fix arm64 build error I'm seeing the following build error on arm64: In file included from util/event.c:3:0: util/event.h:95:17: error: 'PERF_REGS_MAX' undeclared here (not in a function) u64 cache_regs[PERF_REGS_MAX]; ^ This patch adds a PERF_REGS_MAX definition for arm64. Signed-off-by: Mark Salter Acked-by: Jean Pihet Cc: Ingo Molnar Cc: Jean Pihet Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406325766-8085-1-git-send-email-msalter@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/arm64/include/perf_regs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h index e9441b9e2a30..1d3f39c3aa56 100644 --- a/tools/perf/arch/arm64/include/perf_regs.h +++ b/tools/perf/arch/arm64/include/perf_regs.h @@ -6,6 +6,8 @@ #include #define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1) +#define PERF_REGS_MAX PERF_REG_ARM64_MAX + #define PERF_REG_IP PERF_REG_ARM64_PC #define PERF_REG_SP PERF_REG_ARM64_SP -- GitLab From 5f1c4225f6bcb20cc004b271dc72b96d0da29e9e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 28 Jul 2014 12:39:50 -0300 Subject: [PATCH 0049/9167] perf evlist: Don't run workload if not told to The perf_evlist__prepare_workload() method works by forking and then waiting on a fd that must be written to to allow the workload to be exec()ed. But if the tool calling it fails to, say, set up the events with which it wants to sample the workload for, it will not call perf_evlist__start_workload(), but even in this case the workload ended up running: [acme@zoo linux]$ trace /bin/echo workload ends up running, it should not... Couldn't mmap the events: Operation not permitted workload ends up running, it should not... [acme@zoo linux]$ So check if at least one byte was written before letting exec() be called. Now the expected behaviour: [acme@zoo linux]$ trace /bin/echo workload ends up running, it should not... Couldn't mmap the events: Operation not permitted [acme@zoo linux]$ Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-oh1ixo8m74rf295a05gfjw8b@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 814e954c1318..3b366c085021 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1061,6 +1061,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar } if (!evlist->workload.pid) { + int ret; + if (pipe_output) dup2(2, 1); @@ -1078,8 +1080,22 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar /* * Wait until the parent tells us to go. */ - if (read(go_pipe[0], &bf, 1) == -1) - perror("unable to read pipe"); + ret = read(go_pipe[0], &bf, 1); + /* + * The parent will ask for the execvp() to be performed by + * writing exactly one byte, in workload.cork_fd, usually via + * perf_evlist__start_workload(). + * + * For cancelling the workload without actuallin running it, + * the parent will just close workload.cork_fd, without writing + * anything, i.e. read will return zero and we just exit() + * here. + */ + if (ret != 1) { + if (ret == -1) + perror("unable to read pipe"); + exit(ret); + } execvp(argv[0], (char **)argv); -- GitLab From 972f393bc8870e236edbd2ea0150a8da85b709e2 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 29 Jul 2014 10:21:58 -0300 Subject: [PATCH 0050/9167] perf symbols: Make sure --symfs usage includes the path separator Minchan reported that perf failed to load vmlinux if --symfs argument doesn't end with '/' character. Fix it by making sure that the '/' path separator is used when composing pathnames with a --symfs provided directory name. Reported-by: Minchan Kim Cc: David Ahern Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-8n4s6b6zvsez5ktanw006125@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 9 +++------ tools/perf/util/dso.c | 28 +++++++++++++--------------- tools/perf/util/symbol.c | 3 +-- tools/perf/util/symbol.h | 9 +++++++++ tools/perf/util/util.h | 16 ++++++++++++++++ 5 files changed, 42 insertions(+), 23 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 809b4c50beae..7745fec01a6b 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -899,10 +899,8 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) struct kcore_extract kce; bool delete_extract = false; - if (filename) { - snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", - symbol_conf.symfs, filename); - } + if (filename) + symbol__join_symfs(symfs_filename, filename); if (filename == NULL) { if (dso->has_build_id) { @@ -922,8 +920,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) * DSO is the same as when 'perf record' ran. */ filename = (char *)dso->long_name; - snprintf(symfs_filename, sizeof(symfs_filename), "%s%s", - symbol_conf.symfs, filename); + symbol__join_symfs(symfs_filename, filename); free_filename = false; } diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 90d02c661dd4..bdafd306fb52 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -37,6 +37,7 @@ int dso__read_binary_type_filename(const struct dso *dso, { char build_id_hex[BUILD_ID_SIZE * 2 + 1]; int ret = 0; + size_t len; switch (type) { case DSO_BINARY_TYPE__DEBUGLINK: { @@ -60,26 +61,25 @@ int dso__read_binary_type_filename(const struct dso *dso, break; case DSO_BINARY_TYPE__FEDORA_DEBUGINFO: - snprintf(filename, size, "%s/usr/lib/debug%s.debug", - symbol_conf.symfs, dso->long_name); + len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); + snprintf(filename + len, size - len, "%s.debug", dso->long_name); break; case DSO_BINARY_TYPE__UBUNTU_DEBUGINFO: - snprintf(filename, size, "%s/usr/lib/debug%s", - symbol_conf.symfs, dso->long_name); + len = __symbol__join_symfs(filename, size, "/usr/lib/debug"); + snprintf(filename + len, size - len, "%s", dso->long_name); break; case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO: { const char *last_slash; - size_t len; size_t dir_size; last_slash = dso->long_name + dso->long_name_len; while (last_slash != dso->long_name && *last_slash != '/') last_slash--; - len = scnprintf(filename, size, "%s", symbol_conf.symfs); + len = __symbol__join_symfs(filename, size, ""); dir_size = last_slash - dso->long_name + 2; if (dir_size > (size - len)) { ret = -1; @@ -100,26 +100,24 @@ int dso__read_binary_type_filename(const struct dso *dso, build_id__sprintf(dso->build_id, sizeof(dso->build_id), build_id_hex); - snprintf(filename, size, - "%s/usr/lib/debug/.build-id/%.2s/%s.debug", - symbol_conf.symfs, build_id_hex, build_id_hex + 2); + len = __symbol__join_symfs(filename, size, "/usr/lib/debug/.build-id/"); + snprintf(filename + len, size - len, "%.2s/%s.debug", + build_id_hex, build_id_hex + 2); break; case DSO_BINARY_TYPE__VMLINUX: case DSO_BINARY_TYPE__GUEST_VMLINUX: case DSO_BINARY_TYPE__SYSTEM_PATH_DSO: - snprintf(filename, size, "%s%s", - symbol_conf.symfs, dso->long_name); + __symbol__join_symfs(filename, size, dso->long_name); break; case DSO_BINARY_TYPE__GUEST_KMODULE: - snprintf(filename, size, "%s%s%s", symbol_conf.symfs, - root_dir, dso->long_name); + path__join3(filename, size, symbol_conf.symfs, + root_dir, dso->long_name); break; case DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE: - snprintf(filename, size, "%s%s", symbol_conf.symfs, - dso->long_name); + __symbol__join_symfs(filename, size, dso->long_name); break; case DSO_BINARY_TYPE__KCORE: diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index eb06746b06b2..f134ec138934 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1468,8 +1468,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map, if (vmlinux[0] == '/') snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s", vmlinux); else - snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s", - symbol_conf.symfs, vmlinux); + symbol__join_symfs(symfs_vmlinux, vmlinux); if (dso->kernel == DSO_TYPE_GUEST_KERNEL) symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX; diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index e7295e93cff9..196b29104276 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -13,6 +13,7 @@ #include #include "build-id.h" #include "event.h" +#include "util.h" #ifdef HAVE_LIBELF_SUPPORT #include @@ -143,6 +144,14 @@ struct symbol_conf { }; extern struct symbol_conf symbol_conf; + +static inline int __symbol__join_symfs(char *bf, size_t size, const char *path) +{ + return path__join(bf, size, symbol_conf.symfs, path); +} + +#define symbol__join_symfs(bf, path) __symbol__join_symfs(bf, sizeof(bf), path) + extern int vmlinux_path__nr_entries; extern char **vmlinux_path; diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 66864364ccb4..38af77550c75 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -68,6 +68,7 @@ #include #include #include +#include #include #include #include @@ -317,6 +318,21 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags); #define SRCLINE_UNKNOWN ((char *) "??:0") +static inline int path__join(char *bf, size_t size, + const char *path1, const char *path2) +{ + return scnprintf(bf, size, "%s%s%s", path1, path1[0] ? "/" : "", path2); +} + +static inline int path__join3(char *bf, size_t size, + const char *path1, const char *path2, + const char *path3) +{ + return scnprintf(bf, size, "%s%s%s%s%s", + path1, path1[0] ? "/" : "", + path2, path2[0] ? "/" : "", path3); +} + struct dso; char *get_srcline(struct dso *dso, unsigned long addr); -- GitLab From cbe88bcc8ec2f7d6739ea67d7c91517139f0a491 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 17 Jul 2014 16:59:00 +0100 Subject: [PATCH 0051/9167] iio: buffer: Coalesce adjacent demux table entries When copying multiple multiple samples that are adjacent in both the source as well as the destination buffer, instead of creating a new demux table entry for each sample just increase the length of the previous entry by the size of the new sample. This makes the demuxing process slightly more efficient. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/industrialio-buffer.c | 47 ++++++++++++++++++------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 7462f1233974..84a952931f9f 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -942,13 +942,34 @@ int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data) } EXPORT_SYMBOL_GPL(iio_push_to_buffers); +static int iio_buffer_add_demux(struct iio_buffer *buffer, + struct iio_demux_table **p, unsigned int in_loc, unsigned int out_loc, + unsigned int length) +{ + + if (*p && (*p)->from + (*p)->length == in_loc && + (*p)->to + (*p)->length == out_loc) { + (*p)->length += length; + } else { + *p = kmalloc(sizeof(*p), GFP_KERNEL); + if (*p == NULL) + return -ENOMEM; + (*p)->from = in_loc; + (*p)->to = out_loc; + (*p)->length = length; + list_add_tail(&(*p)->l, &buffer->demux_list); + } + + return 0; +} + static int iio_buffer_update_demux(struct iio_dev *indio_dev, struct iio_buffer *buffer) { const struct iio_chan_spec *ch; int ret, in_ind = -1, out_ind, length; unsigned in_loc = 0, out_loc = 0; - struct iio_demux_table *p; + struct iio_demux_table *p = NULL; /* Clear out any old demux */ iio_buffer_demux_free(buffer); @@ -981,11 +1002,6 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, /* Make sure we are aligned */ in_loc = roundup(in_loc, length) + length; } - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } ch = iio_find_channel_from_si(indio_dev, in_ind); if (ch->scan_type.repeat > 1) length = ch->scan_type.storagebits / 8 * @@ -994,20 +1010,14 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, length = ch->scan_type.storagebits / 8; out_loc = roundup(out_loc, length); in_loc = roundup(in_loc, length); - p->from = in_loc; - p->to = out_loc; - p->length = length; - list_add_tail(&p->l, &buffer->demux_list); + ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length); + if (ret) + goto error_clear_mux_table; out_loc += length; in_loc += length; } /* Relies on scan_timestamp being last */ if (buffer->scan_timestamp) { - p = kmalloc(sizeof(*p), GFP_KERNEL); - if (p == NULL) { - ret = -ENOMEM; - goto error_clear_mux_table; - } ch = iio_find_channel_from_si(indio_dev, indio_dev->scan_index_timestamp); if (ch->scan_type.repeat > 1) @@ -1017,10 +1027,9 @@ static int iio_buffer_update_demux(struct iio_dev *indio_dev, length = ch->scan_type.storagebits / 8; out_loc = roundup(out_loc, length); in_loc = roundup(in_loc, length); - p->from = in_loc; - p->to = out_loc; - p->length = length; - list_add_tail(&p->l, &buffer->demux_list); + ret = iio_buffer_add_demux(buffer, &p, in_loc, out_loc, length); + if (ret) + goto error_clear_mux_table; out_loc += length; in_loc += length; } -- GitLab From dc55e3074ca150d5820fd4be5d4afd6cb5e876ad Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 29 Jul 2014 12:53:36 +0300 Subject: [PATCH 0052/9167] ath10k: improve channel switching In some cases during heavy tx vdev stop-start would timeout on vdev synchronization causing traffic to stall for a few seconds. Instead of stop-starting use a dedicated vdev restart command and down vdevs explicitly before doing so. This gets rid of the synchronization warnings/timeouts and makes channel switching smoother during traffic. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 31 +++++++++++++++++++++------ 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 9d61bb157189..b76efe25f54b 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -796,7 +796,7 @@ static void ath10k_recalc_radar_detection(struct ath10k *ar) } } -static int ath10k_vdev_start(struct ath10k_vif *arvif) +static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart) { struct ath10k *ar = arvif->ar; struct cfg80211_chan_def *chandef = &ar->chandef; @@ -838,7 +838,11 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) arg.vdev_id, arg.channel.freq, ath10k_wmi_phymode_str(arg.channel.mode)); - ret = ath10k_wmi_vdev_start(ar, &arg); + if (restart) + ret = ath10k_wmi_vdev_restart(ar, &arg); + else + ret = ath10k_wmi_vdev_start(ar, &arg); + if (ret) { ath10k_warn("failed to start WMI vdev %i: %d\n", arg.vdev_id, ret); @@ -858,6 +862,16 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) return ret; } +static int ath10k_vdev_start(struct ath10k_vif *arvif) +{ + return ath10k_vdev_start_restart(arvif, false); +} + +static int ath10k_vdev_restart(struct ath10k_vif *arvif) +{ + return ath10k_vdev_start_restart(arvif, true); +} + static int ath10k_vdev_stop(struct ath10k_vif *arvif) { struct ath10k *ar = arvif->ar; @@ -2582,18 +2596,21 @@ static void ath10k_config_chan(struct ath10k *ar) if (!arvif->is_started) continue; + if (!arvif->is_up) + continue; + if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) continue; - ret = ath10k_vdev_stop(arvif); + ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); if (ret) { - ath10k_warn("failed to stop vdev %d: %d\n", + ath10k_warn("failed to down vdev %d: %d\n", arvif->vdev_id, ret); continue; } } - /* all vdevs are now stopped - now attempt to restart them */ + /* all vdevs are downed now - attempt to restart and re-up them */ list_for_each_entry(arvif, &ar->arvifs, list) { if (!arvif->is_started) @@ -2602,9 +2619,9 @@ static void ath10k_config_chan(struct ath10k *ar) if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) continue; - ret = ath10k_vdev_start(arvif); + ret = ath10k_vdev_restart(arvif); if (ret) { - ath10k_warn("failed to start vdev %d: %d\n", + ath10k_warn("failed to restart vdev %d: %d\n", arvif->vdev_id, ret); continue; } -- GitLab From b048a24cc8f29dce1bad564aaeb8680020d3701c Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Thu, 31 Jul 2014 13:13:51 +0200 Subject: [PATCH 0053/9167] perf kvm stat: Properly show submicrosecond times For lots of exits the min time (and sometimes max) is 0 or 1. Lets increase the accurancy similar to what the average field alread does. Signed-off-by: Christian Borntraeger Acked-by: David Ahern Cc: David Ahern Cc: Jiri Olsa Cc: Paolo Bonzini Cc: kvm@vger.kernel.org Link: http://lkml.kernel.org/r/1406805231-10675-2-git-send-email-borntraeger@de.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 43367eb00510..fe92dfdeab46 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -592,8 +592,8 @@ static void print_result(struct perf_kvm_stat *kvm) pr_info("%9s ", "Samples%"); pr_info("%9s ", "Time%"); - pr_info("%10s ", "Min Time"); - pr_info("%10s ", "Max Time"); + pr_info("%11s ", "Min Time"); + pr_info("%11s ", "Max Time"); pr_info("%16s ", "Avg time"); pr_info("\n\n"); @@ -610,8 +610,8 @@ static void print_result(struct perf_kvm_stat *kvm) pr_info("%10llu ", (unsigned long long)ecount); pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100); pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100); - pr_info("%8" PRIu64 "us ", min / 1000); - pr_info("%8" PRIu64 "us ", max / 1000); + pr_info("%9.2fus ", (double)min / 1e3); + pr_info("%9.2fus ", (double)max / 1e3); pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount/1e3, kvm_event_rel_stddev(vcpu, event)); pr_info("\n"); -- GitLab From 883fc268f55db3d59cb7871cc0b81062b754477e Mon Sep 17 00:00:00 2001 From: Teodora Baluta Date: Mon, 28 Jul 2014 12:18:00 +0100 Subject: [PATCH 0054/9167] staging: iio: hmc5843_core: fix sparse warnings Fix the following sparse warnings: CHECK drivers/staging/iio/magnetometer/hmc5843_core.c drivers/staging/iio/magnetometer/hmc5843_core.c:138:70: warning: incorrect type in argument 3 (different signedness) drivers/staging/iio/magnetometer/hmc5843_core.c:138:70: expected unsigned int *val drivers/staging/iio/magnetometer/hmc5843_core.c:138:70: got int * drivers/staging/iio/magnetometer/hmc5843_core.c:215:64: warning: incorrect type in argument 3 (different signedness) drivers/staging/iio/magnetometer/hmc5843_core.c:215:64: expected unsigned int *val drivers/staging/iio/magnetometer/hmc5843_core.c:215:64: got int * drivers/staging/iio/magnetometer/hmc5843_core.c:354:72: warning: incorrect type in argument 3 (different signedness) drivers/staging/iio/magnetometer/hmc5843_core.c:354:72: expected unsigned int *val drivers/staging/iio/magnetometer/hmc5843_core.c:354:72: got int * drivers/staging/iio/magnetometer/hmc5843_core.c:362:72: warning: incorrect type in argument 3 (different signedness) drivers/staging/iio/magnetometer/hmc5843_core.c:362:72: expected unsigned int *val drivers/staging/iio/magnetometer/hmc5843_core.c:362:72: got int * Signed-off-by: Teodora Baluta Signed-off-by: Jonathan Cameron --- drivers/staging/iio/magnetometer/hmc5843_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/magnetometer/hmc5843_core.c b/drivers/staging/iio/magnetometer/hmc5843_core.c index 914ae1acd31d..fd171d8b38fb 100644 --- a/drivers/staging/iio/magnetometer/hmc5843_core.c +++ b/drivers/staging/iio/magnetometer/hmc5843_core.c @@ -131,7 +131,7 @@ static s32 hmc5843_set_mode(struct hmc5843_data *data, u8 operating_mode) static int hmc5843_wait_measurement(struct hmc5843_data *data) { int tries = 150; - int val; + unsigned int val; int ret; while (tries-- > 0) { @@ -209,7 +209,7 @@ static ssize_t hmc5843_show_measurement_configuration(struct device *dev, char *buf) { struct hmc5843_data *data = iio_priv(dev_to_iio_dev(dev)); - int val; + unsigned int val; int ret; ret = regmap_read(data->regmap, HMC5843_CONFIG_REG_A, &val); @@ -344,7 +344,7 @@ static int hmc5843_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct hmc5843_data *data = iio_priv(indio_dev); - int rval; + unsigned int rval; int ret; switch (mask) { -- GitLab From 18210923ab663c799d1c218e4fc998a8f0f87765 Mon Sep 17 00:00:00 2001 From: Teodora Baluta Date: Mon, 28 Jul 2014 12:18:00 +0100 Subject: [PATCH 0055/9167] staging: iio: isl29018: fix sparse warning regarding incorrect type (different signedness) Fix the following sparse warning: drivers/staging/iio/light/isl29018.c:508:50: warning: incorrect type in argument 3 (different signedness) drivers/staging/iio/light/isl29018.c:508:50: expected unsigned int *conf_adc_bit drivers/staging/iio/light/isl29018.c:508:50: got int * Signed-off-by: Teodora Baluta Signed-off-by: Jonathan Cameron --- drivers/staging/iio/light/isl29018.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 3660a43b5f08..86cc8f9fef06 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -454,7 +454,7 @@ static const struct attribute_group isl29108_group = { static int isl29018_chip_init(struct isl29018_chip *chip) { int status; - int new_adc_bit; + unsigned int new_adc_bit; unsigned int new_range; /* Code added per Intersil Application Note 1534: -- GitLab From 7557138a943bf460e56972b8b9f45d535a473a3c Mon Sep 17 00:00:00 2001 From: Teodora Baluta Date: Mon, 28 Jul 2014 12:18:00 +0100 Subject: [PATCH 0056/9167] staging: iio: adis16240: fix sparse warnings regarding incorrect argument type Silence the following sparse warnings by changing cast from u16 to __be16: CHECK drivers/staging/iio/accel/adis16240_core.c drivers/staging/iio/accel/adis16240_core.c:128:51: warning: incorrect type in argument 3 (different signedness) drivers/staging/iio/accel/adis16240_core.c:128:51: expected unsigned short [usertype] *val drivers/staging/iio/accel/adis16240_core.c:128:51: got signed short * drivers/staging/iio/accel/adis16240_core.c:142:51: warning: incorrect type in argument 3 (different signedness) drivers/staging/iio/accel/adis16240_core.c:142:51: expected unsigned short [usertype] *val drivers/staging/iio/accel/adis16240_core.c:142:51: got signed short * Signed-off-by: Teodora Baluta Signed-off-by: Jonathan Cameron --- drivers/staging/iio/resolver/ad2s1210.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 7fbaba41c872..1360099fdaea 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -491,7 +491,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev, switch (chan->type) { case IIO_ANGL: - pos = be16_to_cpup((u16 *)st->rx); + pos = be16_to_cpup((__be16 *) st->rx); if (st->hysteresis) pos >>= 16 - st->resolution; *val = pos; @@ -499,7 +499,7 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev, break; case IIO_ANGL_VEL: negative = st->rx[0] & 0x80; - vel = be16_to_cpup((s16 *)st->rx); + vel = be16_to_cpup((__be16 *) st->rx); vel >>= 16 - st->resolution; if (vel & 0x8000) { negative = (0xffff >> st->resolution) << st->resolution; -- GitLab From 95752b759e2e1d9c590252a92e080eeb611fdbcd Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Sat, 2 Aug 2014 09:12:53 +0300 Subject: [PATCH 0057/9167] ath: Move spectral debugfs structs to shared header The ath9k and ath10k will share the definitions of the debugfs spectral structures and enums. Having them in the same place helps to avoid conflicts. Signed-off-by: Sven Eckelmann Signed-off-by: Simon Wunderlich Signed-off-by: Mathias Kretschmer Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath9k/spectral.h | 71 +---------------- drivers/net/wireless/ath/spectral_common.h | 88 ++++++++++++++++++++++ 2 files changed, 90 insertions(+), 69 deletions(-) create mode 100644 drivers/net/wireless/ath/spectral_common.h diff --git a/drivers/net/wireless/ath/ath9k/spectral.h b/drivers/net/wireless/ath/ath9k/spectral.h index ead63412ee1a..7b410c6858b0 100644 --- a/drivers/net/wireless/ath/ath9k/spectral.h +++ b/drivers/net/wireless/ath/ath9k/spectral.h @@ -17,6 +17,8 @@ #ifndef SPECTRAL_H #define SPECTRAL_H +#include "../spectral_common.h" + /* enum spectral_mode: * * @SPECTRAL_DISABLED: spectral mode is disabled @@ -54,8 +56,6 @@ struct ath_ht20_mag_info { u8 max_exp; } __packed; -#define SPECTRAL_HT20_NUM_BINS 56 - /* WARNING: don't actually use this struct! MAC may vary the amount of * data by -1/+2. This struct is for reference only. */ @@ -83,8 +83,6 @@ struct ath_ht20_40_mag_info { u8 max_exp; } __packed; -#define SPECTRAL_HT20_40_NUM_BINS 128 - /* WARNING: don't actually use this struct! MAC may vary the amount of * data. This struct is for reference only. */ @@ -125,71 +123,6 @@ static inline u8 spectral_bitmap_weight(u8 *bins) return bins[0] & 0x3f; } -/* FFT sample format given to userspace via debugfs. - * - * Please keep the type/length at the front position and change - * other fields after adding another sample type - * - * TODO: this might need rework when switching to nl80211-based - * interface. - */ -enum ath_fft_sample_type { - ATH_FFT_SAMPLE_HT20 = 1, - ATH_FFT_SAMPLE_HT20_40, -}; - -struct fft_sample_tlv { - u8 type; /* see ath_fft_sample */ - __be16 length; - /* type dependent data follows */ -} __packed; - -struct fft_sample_ht20 { - struct fft_sample_tlv tlv; - - u8 max_exp; - - __be16 freq; - s8 rssi; - s8 noise; - - __be16 max_magnitude; - u8 max_index; - u8 bitmap_weight; - - __be64 tsf; - - u8 data[SPECTRAL_HT20_NUM_BINS]; -} __packed; - -struct fft_sample_ht20_40 { - struct fft_sample_tlv tlv; - - u8 channel_type; - __be16 freq; - - s8 lower_rssi; - s8 upper_rssi; - - __be64 tsf; - - s8 lower_noise; - s8 upper_noise; - - __be16 lower_max_magnitude; - __be16 upper_max_magnitude; - - u8 lower_max_index; - u8 upper_max_index; - - u8 lower_bitmap_weight; - u8 upper_bitmap_weight; - - u8 max_exp; - - u8 data[SPECTRAL_HT20_40_NUM_BINS]; -} __packed; - void ath9k_spectral_init_debug(struct ath_softc *sc); void ath9k_spectral_deinit_debug(struct ath_softc *sc); diff --git a/drivers/net/wireless/ath/spectral_common.h b/drivers/net/wireless/ath/spectral_common.h new file mode 100644 index 000000000000..b9ab722747bd --- /dev/null +++ b/drivers/net/wireless/ath/spectral_common.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2013 Qualcomm Atheros, Inc. + * + * 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 SPECTRAL_COMMON_H +#define SPECTRAL_COMMON_H + +#define SPECTRAL_HT20_NUM_BINS 56 +#define SPECTRAL_HT20_40_NUM_BINS 128 + +/* FFT sample format given to userspace via debugfs. + * + * Please keep the type/length at the front position and change + * other fields after adding another sample type + * + * TODO: this might need rework when switching to nl80211-based + * interface. + */ +enum ath_fft_sample_type { + ATH_FFT_SAMPLE_HT20 = 1, + ATH_FFT_SAMPLE_HT20_40, +}; + +struct fft_sample_tlv { + u8 type; /* see ath_fft_sample */ + __be16 length; + /* type dependent data follows */ +} __packed; + +struct fft_sample_ht20 { + struct fft_sample_tlv tlv; + + u8 max_exp; + + __be16 freq; + s8 rssi; + s8 noise; + + __be16 max_magnitude; + u8 max_index; + u8 bitmap_weight; + + __be64 tsf; + + u8 data[SPECTRAL_HT20_NUM_BINS]; +} __packed; + +struct fft_sample_ht20_40 { + struct fft_sample_tlv tlv; + + u8 channel_type; + __be16 freq; + + s8 lower_rssi; + s8 upper_rssi; + + __be64 tsf; + + s8 lower_noise; + s8 upper_noise; + + __be16 lower_max_magnitude; + __be16 upper_max_magnitude; + + u8 lower_max_index; + u8 upper_max_index; + + u8 lower_bitmap_weight; + u8 upper_bitmap_weight; + + u8 max_exp; + + u8 data[SPECTRAL_HT20_40_NUM_BINS]; +} __packed; + +#endif /* SPECTRAL_COMMON_H */ -- GitLab From 855aed1220d2c94425ab01a85fe7a6f5c436940f Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Sat, 2 Aug 2014 09:12:54 +0300 Subject: [PATCH 0058/9167] ath10k: add spectral scan feature Adds the spectral scan feature for ath10k. The spectral scan is triggered by configuring a mode through a debugfs control file. Samples can be gathered via another relay debugfs file. Essentially, to try it out: ip link set dev wlan0 up echo background > /sys/kernel/debug/ieee80211/phy0/ath10k/spectral_scan_ctl echo trigger > /sys/kernel/debug/ieee80211/phy0/ath10k/spectral_scan_ctl iw dev wlan0 scan echo disable > /sys/kernel/debug/ieee80211/phy0/ath10k/spectral_scan_ctl cat /sys/kernel/debug/ieee80211/phy0/ath10k/spectral_scan0 > samples This feature is still experimental. Based on the original RFC patch of Sven Eckelmann. Signed-off-by: Simon Wunderlich Signed-off-by: Mathias Kretschmer Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/Kconfig | 1 + drivers/net/wireless/ath/ath10k/Makefile | 1 + drivers/net/wireless/ath/ath10k/core.c | 10 + drivers/net/wireless/ath/ath10k/core.h | 11 + drivers/net/wireless/ath/ath10k/mac.c | 8 + drivers/net/wireless/ath/ath10k/spectral.c | 561 +++++++++++++++++++++ drivers/net/wireless/ath/ath10k/spectral.h | 90 ++++ drivers/net/wireless/ath/ath10k/wmi.c | 105 +++- drivers/net/wireless/ath/ath10k/wmi.h | 97 ++++ drivers/net/wireless/ath/spectral_common.h | 25 + 10 files changed, 908 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/ath/ath10k/spectral.c create mode 100644 drivers/net/wireless/ath/ath10k/spectral.h diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig index a6f5285235af..1053bb5f2cdc 100644 --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig @@ -25,6 +25,7 @@ config ATH10K_DEBUG config ATH10K_DEBUGFS bool "Atheros ath10k debugfs support" depends on ATH10K + select RELAY ---help--- Enabled debugfs support diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile index a4179f49ee1f..2cfb63ca9327 100644 --- a/drivers/net/wireless/ath/ath10k/Makefile +++ b/drivers/net/wireless/ath/ath10k/Makefile @@ -10,6 +10,7 @@ ath10k_core-y += mac.o \ wmi.o \ bmi.o +ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index bef797d5f4d3..440c3ff03aec 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1000,9 +1000,17 @@ static void ath10k_core_register_work(struct work_struct *work) goto err_unregister_mac; } + status = ath10k_spectral_create(ar); + if (status) { + ath10k_err("failed to initialize spectral\n"); + goto err_debug_destroy; + } + set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); return; +err_debug_destroy: + ath10k_debug_destroy(ar); err_unregister_mac: ath10k_mac_unregister(ar); err_release_fw: @@ -1046,6 +1054,8 @@ void ath10k_core_unregister(struct ath10k *ar) ath10k_core_free_firmware_files(ar); + ath10k_spectral_destroy(ar); + ath10k_debug_destroy(ar); } EXPORT_SYMBOL(ath10k_core_unregister); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index ded3af2266d0..d5c95d46e841 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -31,6 +31,7 @@ #include "../ath.h" #include "../regd.h" #include "../dfs_pattern_detector.h" +#include "spectral.h" #define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) @@ -237,6 +238,7 @@ struct ath10k_vif { bool is_started; bool is_up; + bool spectral_enabled; u32 aid; u8 bssid[ETH_ALEN]; @@ -499,6 +501,15 @@ struct ath10k { #ifdef CONFIG_ATH10K_DEBUGFS struct ath10k_debug debug; #endif + + struct { + /* relay(fs) channel for spectral scan */ + struct rchan *rfs_chan_spec_scan; + + /* spectral_mode and spec_config are protected by conf_mutex */ + enum ath10k_spectral_mode mode; + struct ath10k_spec_scan config; + } spectral; }; struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index b76efe25f54b..3c7942030361 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2499,6 +2499,8 @@ static int ath10k_start(struct ieee80211_hw *hw) ar->num_started_vdevs = 0; ath10k_regd_update(ar); + ath10k_spectral_start(ar); + mutex_unlock(&ar->conf_mutex); return 0; @@ -2909,8 +2911,14 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, dev_kfree_skb_any(arvif->beacon); arvif->beacon = NULL; } + spin_unlock_bh(&ar->data_lock); + ret = ath10k_spectral_vif_stop(arvif); + if (ret) + ath10k_warn("failed to stop spectral for vdev %i: %d\n", + arvif->vdev_id, ret); + ar->free_vdev_map |= 1 << (arvif->vdev_id); list_del(&arvif->list); diff --git a/drivers/net/wireless/ath/ath10k/spectral.c b/drivers/net/wireless/ath/ath10k/spectral.c new file mode 100644 index 000000000000..a53afc23864f --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/spectral.c @@ -0,0 +1,561 @@ +/* + * Copyright (c) 2013 Qualcomm Atheros, Inc. + * + * 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 "core.h" +#include "debug.h" + +static void send_fft_sample(struct ath10k *ar, + const struct fft_sample_tlv *fft_sample_tlv) +{ + int length; + + if (!ar->spectral.rfs_chan_spec_scan) + return; + + length = __be16_to_cpu(fft_sample_tlv->length) + + sizeof(*fft_sample_tlv); + relay_write(ar->spectral.rfs_chan_spec_scan, fft_sample_tlv, length); +} + +static uint8_t get_max_exp(s8 max_index, u16 max_magnitude, size_t bin_len, + u8 *data) +{ + int dc_pos; + u8 max_exp; + + dc_pos = bin_len / 2; + + /* peak index outside of bins */ + if (dc_pos < max_index || -dc_pos >= max_index) + return 0; + + for (max_exp = 0; max_exp < 8; max_exp++) { + if (data[dc_pos + max_index] == (max_magnitude >> max_exp)) + break; + } + + /* max_exp not found */ + if (data[dc_pos + max_index] != (max_magnitude >> max_exp)) + return 0; + + return max_exp; +} + +int ath10k_spectral_process_fft(struct ath10k *ar, + struct wmi_single_phyerr_rx_event *event, + 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; + u8 chain_idx, *bins; + int dc_pos; + + fft_sample = (struct fft_sample_ath10k *)&buf; + + if (bin_len < 64 || bin_len > SPECTRAL_ATH10K_MAX_NUM_BINS) + return -EINVAL; + + reg0 = __le32_to_cpu(fftr->reg0); + reg1 = __le32_to_cpu(fftr->reg1); + + length = sizeof(*fft_sample) - sizeof(struct fft_sample_tlv) + bin_len; + fft_sample->tlv.type = ATH_FFT_SAMPLE_ATH10K; + fft_sample->tlv.length = __cpu_to_be16(length); + + /* 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) { + case 20: + fft_sample->chan_width_mhz = 22; + break; + case 40: + fft_sample->chan_width_mhz = 44; + break; + case 80: + /* TODO: As experiments with an analogue sender and various + * configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz) + * show, the particular configuration of 80 MHz/64 bins does + * not match with the other smaples at all. Until the reason + * for that is found, don't report these samples. + */ + if (bin_len == 64) + return -EINVAL; + fft_sample->chan_width_mhz = 88; + break; + default: + fft_sample->chan_width_mhz = event->hdr.chan_width_mhz; + } + + fft_sample->relpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB); + fft_sample->avgpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB); + + 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; + + 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); + 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; + } + + bins = (u8 *)fftr; + bins += sizeof(*fftr); + + fft_sample->tsf = __cpu_to_be64(tsf); + + /* max_exp has been directly reported by previous hardware (ath9k), + * maybe its possible to get it by other means? + */ + fft_sample->max_exp = get_max_exp(fft_sample->max_index, peak_mag, + bin_len, bins); + + memcpy(fft_sample->data, bins, bin_len); + + /* DC value (value in the middle) is the blind spot of the spectral + * sample and invalid, interpolate it. + */ + dc_pos = bin_len / 2; + fft_sample->data[dc_pos] = (fft_sample->data[dc_pos + 1] + + fft_sample->data[dc_pos - 1]) / 2; + + send_fft_sample(ar, &fft_sample->tlv); + + return 0; +} + +static struct ath10k_vif *ath10k_get_spectral_vdev(struct ath10k *ar) +{ + struct ath10k_vif *arvif; + + lockdep_assert_held(&ar->conf_mutex); + + if (list_empty(&ar->arvifs)) + return NULL; + + /* if there already is a vif doing spectral, return that. */ + list_for_each_entry(arvif, &ar->arvifs, list) + if (arvif->spectral_enabled) + return arvif; + + /* otherwise, return the first vif. */ + return list_first_entry(&ar->arvifs, typeof(*arvif), list); +} + +static int ath10k_spectral_scan_trigger(struct ath10k *ar) +{ + struct ath10k_vif *arvif; + int res; + int vdev_id; + + lockdep_assert_held(&ar->conf_mutex); + + arvif = ath10k_get_spectral_vdev(ar); + if (!arvif) + return -ENODEV; + vdev_id = arvif->vdev_id; + + if (ar->spectral.mode == SPECTRAL_DISABLED) + return 0; + + res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, + WMI_SPECTRAL_TRIGGER_CMD_CLEAR, + WMI_SPECTRAL_ENABLE_CMD_ENABLE); + if (res < 0) + return res; + + res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, + WMI_SPECTRAL_TRIGGER_CMD_TRIGGER, + WMI_SPECTRAL_ENABLE_CMD_ENABLE); + if (res < 0) + return res; + + return 0; +} + +static int ath10k_spectral_scan_config(struct ath10k *ar, + enum ath10k_spectral_mode mode) +{ + struct wmi_vdev_spectral_conf_arg arg; + struct ath10k_vif *arvif; + int vdev_id, count, res = 0; + + lockdep_assert_held(&ar->conf_mutex); + + arvif = ath10k_get_spectral_vdev(ar); + if (!arvif) + return -ENODEV; + + vdev_id = arvif->vdev_id; + + arvif->spectral_enabled = (mode != SPECTRAL_DISABLED); + ar->spectral.mode = mode; + + res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, + WMI_SPECTRAL_TRIGGER_CMD_CLEAR, + WMI_SPECTRAL_ENABLE_CMD_DISABLE); + if (res < 0) { + ath10k_warn("failed to enable spectral scan: %d\n", res); + return res; + } + + if (mode == SPECTRAL_DISABLED) + return 0; + + if (mode == SPECTRAL_BACKGROUND) + count = WMI_SPECTRAL_COUNT_DEFAULT; + else + count = max_t(u8, 1, ar->spectral.config.count); + + arg.vdev_id = vdev_id; + arg.scan_count = count; + arg.scan_period = WMI_SPECTRAL_PERIOD_DEFAULT; + arg.scan_priority = WMI_SPECTRAL_PRIORITY_DEFAULT; + arg.scan_fft_size = ar->spectral.config.fft_size; + arg.scan_gc_ena = WMI_SPECTRAL_GC_ENA_DEFAULT; + arg.scan_restart_ena = WMI_SPECTRAL_RESTART_ENA_DEFAULT; + arg.scan_noise_floor_ref = WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT; + arg.scan_init_delay = WMI_SPECTRAL_INIT_DELAY_DEFAULT; + arg.scan_nb_tone_thr = WMI_SPECTRAL_NB_TONE_THR_DEFAULT; + arg.scan_str_bin_thr = WMI_SPECTRAL_STR_BIN_THR_DEFAULT; + arg.scan_wb_rpt_mode = WMI_SPECTRAL_WB_RPT_MODE_DEFAULT; + arg.scan_rssi_rpt_mode = WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT; + arg.scan_rssi_thr = WMI_SPECTRAL_RSSI_THR_DEFAULT; + arg.scan_pwr_format = WMI_SPECTRAL_PWR_FORMAT_DEFAULT; + arg.scan_rpt_mode = WMI_SPECTRAL_RPT_MODE_DEFAULT; + arg.scan_bin_scale = WMI_SPECTRAL_BIN_SCALE_DEFAULT; + arg.scan_dbm_adj = WMI_SPECTRAL_DBM_ADJ_DEFAULT; + arg.scan_chn_mask = WMI_SPECTRAL_CHN_MASK_DEFAULT; + + res = ath10k_wmi_vdev_spectral_conf(ar, &arg); + if (res < 0) { + ath10k_warn("failed to configure spectral scan: %d\n", res); + return res; + } + + return 0; +} + +static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + char *mode = ""; + unsigned int len; + enum ath10k_spectral_mode spectral_mode; + + mutex_lock(&ar->conf_mutex); + spectral_mode = ar->spectral.mode; + mutex_unlock(&ar->conf_mutex); + + switch (spectral_mode) { + case SPECTRAL_DISABLED: + mode = "disable"; + break; + case SPECTRAL_BACKGROUND: + mode = "background"; + break; + case SPECTRAL_MANUAL: + mode = "manual"; + break; + } + + len = strlen(mode); + return simple_read_from_buffer(user_buf, count, ppos, mode, len); +} + +static ssize_t write_file_spec_scan_ctl(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + char buf[32]; + ssize_t len; + int res; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + + mutex_lock(&ar->conf_mutex); + + if (strncmp("trigger", buf, 7) == 0) { + if (ar->spectral.mode == SPECTRAL_MANUAL || + ar->spectral.mode == SPECTRAL_BACKGROUND) { + /* reset the configuration to adopt possibly changed + * debugfs parameters + */ + res = ath10k_spectral_scan_config(ar, + ar->spectral.mode); + if (res < 0) { + ath10k_warn("failed to reconfigure spectral scan: %d\n", + res); + } + res = ath10k_spectral_scan_trigger(ar); + if (res < 0) { + ath10k_warn("failed to trigger spectral scan: %d\n", + res); + } + } else { + res = -EINVAL; + } + } else if (strncmp("background", buf, 9) == 0) { + res = ath10k_spectral_scan_config(ar, SPECTRAL_BACKGROUND); + } else if (strncmp("manual", buf, 6) == 0) { + res = ath10k_spectral_scan_config(ar, SPECTRAL_MANUAL); + } else if (strncmp("disable", buf, 7) == 0) { + res = ath10k_spectral_scan_config(ar, SPECTRAL_DISABLED); + } else { + res = -EINVAL; + } + + mutex_unlock(&ar->conf_mutex); + + if (res < 0) + return res; + + return count; +} + +static const struct file_operations fops_spec_scan_ctl = { + .read = read_file_spec_scan_ctl, + .write = write_file_spec_scan_ctl, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_spectral_count(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + char buf[32]; + unsigned int len; + u8 spectral_count; + + mutex_lock(&ar->conf_mutex); + spectral_count = ar->spectral.config.count; + mutex_unlock(&ar->conf_mutex); + + len = sprintf(buf, "%d\n", spectral_count); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t write_file_spectral_count(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + unsigned long val; + char buf[32]; + ssize_t len; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + if (val < 0 || val > 255) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + ar->spectral.config.count = val; + mutex_unlock(&ar->conf_mutex); + + return count; +} + +static const struct file_operations fops_spectral_count = { + .read = read_file_spectral_count, + .write = write_file_spectral_count, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t read_file_spectral_bins(struct file *file, + char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + char buf[32]; + unsigned int len, bins, fft_size, bin_scale; + + mutex_lock(&ar->conf_mutex); + + fft_size = ar->spectral.config.fft_size; + bin_scale = WMI_SPECTRAL_BIN_SCALE_DEFAULT; + bins = 1 << (fft_size - bin_scale); + + mutex_unlock(&ar->conf_mutex); + + len = sprintf(buf, "%d\n", bins); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t write_file_spectral_bins(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct ath10k *ar = file->private_data; + unsigned long val; + char buf[32]; + ssize_t len; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + buf[len] = '\0'; + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + if (val < 64 || val > SPECTRAL_ATH10K_MAX_NUM_BINS) + return -EINVAL; + + if (!is_power_of_2(val)) + return -EINVAL; + + mutex_lock(&ar->conf_mutex); + ar->spectral.config.fft_size = ilog2(val); + ar->spectral.config.fft_size += WMI_SPECTRAL_BIN_SCALE_DEFAULT; + mutex_unlock(&ar->conf_mutex); + + return count; +} + +static const struct file_operations fops_spectral_bins = { + .read = read_file_spectral_bins, + .write = write_file_spectral_bins, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static struct dentry *create_buf_file_handler(const char *filename, + struct dentry *parent, + umode_t mode, + struct rchan_buf *buf, + int *is_global) +{ + struct dentry *buf_file; + + buf_file = debugfs_create_file(filename, mode, parent, buf, + &relay_file_operations); + *is_global = 1; + return buf_file; +} + +static int remove_buf_file_handler(struct dentry *dentry) +{ + debugfs_remove(dentry); + + return 0; +} + +static struct rchan_callbacks rfs_spec_scan_cb = { + .create_buf_file = create_buf_file_handler, + .remove_buf_file = remove_buf_file_handler, +}; + +int ath10k_spectral_start(struct ath10k *ar) +{ + struct ath10k_vif *arvif; + + lockdep_assert_held(&ar->conf_mutex); + + list_for_each_entry(arvif, &ar->arvifs, list) + arvif->spectral_enabled = 0; + + ar->spectral.mode = SPECTRAL_DISABLED; + ar->spectral.config.count = WMI_SPECTRAL_COUNT_DEFAULT; + ar->spectral.config.fft_size = WMI_SPECTRAL_FFT_SIZE_DEFAULT; + + return 0; +} + +int ath10k_spectral_vif_stop(struct ath10k_vif *arvif) +{ + if (!arvif->spectral_enabled) + return 0; + + return ath10k_spectral_scan_config(arvif->ar, SPECTRAL_DISABLED); +} + +int ath10k_spectral_create(struct ath10k *ar) +{ + ar->spectral.rfs_chan_spec_scan = relay_open("spectral_scan", + ar->debug.debugfs_phy, + 1024, 256, + &rfs_spec_scan_cb, NULL); + debugfs_create_file("spectral_scan_ctl", + S_IRUSR | S_IWUSR, + ar->debug.debugfs_phy, ar, + &fops_spec_scan_ctl); + debugfs_create_file("spectral_count", + S_IRUSR | S_IWUSR, + ar->debug.debugfs_phy, ar, + &fops_spectral_count); + debugfs_create_file("spectral_bins", + S_IRUSR | S_IWUSR, + ar->debug.debugfs_phy, ar, + &fops_spectral_bins); + + return 0; +} + +void ath10k_spectral_destroy(struct ath10k *ar) +{ + if (ar->spectral.rfs_chan_spec_scan) { + relay_close(ar->spectral.rfs_chan_spec_scan); + ar->spectral.rfs_chan_spec_scan = NULL; + } +} diff --git a/drivers/net/wireless/ath/ath10k/spectral.h b/drivers/net/wireless/ath/ath10k/spectral.h new file mode 100644 index 000000000000..ddc57c557272 --- /dev/null +++ b/drivers/net/wireless/ath/ath10k/spectral.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2013 Qualcomm Atheros, Inc. + * + * 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 SPECTRAL_H +#define SPECTRAL_H + +#include "../spectral_common.h" + +/** + * struct ath10k_spec_scan - parameters for Atheros spectral scan + * + * @count: number of scan results requested for manual mode + * @fft_size: number of bins to be requested = 2^(fft_size - bin_scale) + */ +struct ath10k_spec_scan { + u8 count; + u8 fft_size; +}; + +/* enum ath10k_spectral_mode: + * + * @SPECTRAL_DISABLED: spectral mode is disabled + * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with + * something else. + * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples + * is performed manually. + */ +enum ath10k_spectral_mode { + SPECTRAL_DISABLED = 0, + SPECTRAL_BACKGROUND, + SPECTRAL_MANUAL, +}; + +#ifdef CONFIG_ATH10K_DEBUGFS + +int ath10k_spectral_process_fft(struct ath10k *ar, + struct wmi_single_phyerr_rx_event *event, + 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); +int ath10k_spectral_create(struct ath10k *ar); +void ath10k_spectral_destroy(struct ath10k *ar); + +#else + +static inline int +ath10k_spectral_process_fft(struct ath10k *ar, + struct wmi_single_phyerr_rx_event *event, + struct phyerr_fft_report *fftr, + size_t bin_len, u64 tsf) +{ + return 0; +} + +static inline int ath10k_spectral_start(struct ath10k *ar) +{ + return 0; +} + +static inline int ath10k_spectral_vif_stop(struct ath10k_vif *arvif) +{ + return 0; +} + +static inline int ath10k_spectral_create(struct ath10k *ar) +{ + return 0; +} + +static inline void ath10k_spectral_destroy(struct ath10k *ar) +{ +} + +#endif /* CONFIG_ATH10K_DEBUGFS */ + +#endif /* SPECTRAL_H */ diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index b09661db9447..fffb15b1b50b 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -1780,7 +1780,54 @@ static void ath10k_wmi_event_spectral_scan(struct ath10k *ar, struct wmi_single_phyerr_rx_event *event, u64 tsf) { - ath10k_dbg(ATH10K_DBG_WMI, "wmi event spectral scan\n"); + int buf_len, tlv_len, res, i = 0; + struct phyerr_tlv *tlv; + u8 *tlv_buf; + struct phyerr_fft_report *fftr; + size_t fftr_len; + + buf_len = __le32_to_cpu(event->hdr.buf_len); + + while (i < buf_len) { + if (i + sizeof(*tlv) > buf_len) { + ath10k_warn("failed to parse phyerr tlv header at byte %d\n", + i); + return; + } + + tlv = (struct phyerr_tlv *)&event->bufp[i]; + tlv_len = __le16_to_cpu(tlv->len); + tlv_buf = &event->bufp[i + sizeof(*tlv)]; + + if (i + sizeof(*tlv) + tlv_len > buf_len) { + ath10k_warn("failed to parse phyerr tlv payload at byte %d\n", + i); + return; + } + + switch (tlv->tag) { + case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: + if (sizeof(*fftr) > tlv_len) { + ath10k_warn("failed to parse fft report at byte %d\n", + i); + return; + } + + fftr_len = tlv_len - sizeof(*fftr); + fftr = (struct phyerr_fft_report *)tlv_buf; + res = ath10k_spectral_process_fft(ar, event, + fftr, fftr_len, + tsf); + if (res < 0) { + ath10k_warn("failed to process fft report: %d\n", + res); + return; + } + break; + } + + i += sizeof(*tlv) + tlv_len; + } } static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) @@ -3576,6 +3623,62 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar, ar->wmi.cmd->vdev_install_key_cmdid); } +int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, + const struct wmi_vdev_spectral_conf_arg *arg) +{ + struct wmi_vdev_spectral_conf_cmd *cmd; + struct sk_buff *skb; + u32 cmdid; + + skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data; + cmd->vdev_id = __cpu_to_le32(arg->vdev_id); + cmd->scan_count = __cpu_to_le32(arg->scan_count); + cmd->scan_period = __cpu_to_le32(arg->scan_period); + cmd->scan_priority = __cpu_to_le32(arg->scan_priority); + cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size); + cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena); + cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena); + cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref); + cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay); + cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr); + cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr); + cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode); + cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode); + cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr); + cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format); + cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode); + cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale); + cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj); + cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask); + + cmdid = ar->wmi.cmd->vdev_spectral_scan_configure_cmdid; + return ath10k_wmi_cmd_send(ar, skb, cmdid); +} + +int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, + u32 enable) +{ + struct wmi_vdev_spectral_enable_cmd *cmd; + struct sk_buff *skb; + u32 cmdid; + + skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data; + cmd->vdev_id = __cpu_to_le32(vdev_id); + cmd->trigger_cmd = __cpu_to_le32(trigger); + cmd->enable_cmd = __cpu_to_le32(enable); + + cmdid = ar->wmi.cmd->vdev_spectral_scan_enable_cmdid; + return ath10k_wmi_cmd_send(ar, skb, cmdid); +} + int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, const u8 peer_addr[ETH_ALEN]) { diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index c9ac11cbc5d2..1d8dda3240a5 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -2247,6 +2247,7 @@ struct wmi_comb_phyerr_rx_event { #define PHYERR_TLV_SIG 0xBB #define PHYERR_TLV_TAG_SEARCH_FFT_REPORT 0xFB #define PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY 0xF8 +#define PHYERR_TLV_TAG_SPECTRAL_SUMMARY_REPORT 0xF9 struct phyerr_radar_report { __le32 reg0; /* RADAR_REPORT_REG0_* */ @@ -3645,6 +3646,98 @@ struct wmi_vdev_simple_event { /* unsupported VDEV combination */ #define WMI_INIFIED_VDEV_START_RESPONSE_NOT_SUPPORTED 0x2 +/* TODO: please add more comments if you have in-depth information */ +struct wmi_vdev_spectral_conf_cmd { + __le32 vdev_id; + + /* number of fft samples to send (0 for infinite) */ + __le32 scan_count; + __le32 scan_period; + __le32 scan_priority; + + /* number of bins in the FFT: 2^(fft_size - bin_scale) */ + __le32 scan_fft_size; + __le32 scan_gc_ena; + __le32 scan_restart_ena; + __le32 scan_noise_floor_ref; + __le32 scan_init_delay; + __le32 scan_nb_tone_thr; + __le32 scan_str_bin_thr; + __le32 scan_wb_rpt_mode; + __le32 scan_rssi_rpt_mode; + __le32 scan_rssi_thr; + __le32 scan_pwr_format; + + /* rpt_mode: Format of FFT report to software for spectral scan + * triggered FFTs: + * 0: No FFT report (only spectral scan summary report) + * 1: 2-dword summary of metrics for each completed FFT + spectral + * scan summary report + * 2: 2-dword summary of metrics for each completed FFT + + * 1x- oversampled bins(in-band) per FFT + spectral scan summary + * report + * 3: 2-dword summary of metrics for each completed FFT + + * 2x- oversampled bins (all) per FFT + spectral scan summary + */ + __le32 scan_rpt_mode; + __le32 scan_bin_scale; + __le32 scan_dbm_adj; + __le32 scan_chn_mask; +} __packed; + +struct wmi_vdev_spectral_conf_arg { + u32 vdev_id; + u32 scan_count; + u32 scan_period; + u32 scan_priority; + u32 scan_fft_size; + u32 scan_gc_ena; + u32 scan_restart_ena; + u32 scan_noise_floor_ref; + u32 scan_init_delay; + u32 scan_nb_tone_thr; + u32 scan_str_bin_thr; + u32 scan_wb_rpt_mode; + u32 scan_rssi_rpt_mode; + u32 scan_rssi_thr; + u32 scan_pwr_format; + u32 scan_rpt_mode; + u32 scan_bin_scale; + u32 scan_dbm_adj; + u32 scan_chn_mask; +}; + +#define WMI_SPECTRAL_ENABLE_DEFAULT 0 +#define WMI_SPECTRAL_COUNT_DEFAULT 0 +#define WMI_SPECTRAL_PERIOD_DEFAULT 35 +#define WMI_SPECTRAL_PRIORITY_DEFAULT 1 +#define WMI_SPECTRAL_FFT_SIZE_DEFAULT 7 +#define WMI_SPECTRAL_GC_ENA_DEFAULT 1 +#define WMI_SPECTRAL_RESTART_ENA_DEFAULT 0 +#define WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT -96 +#define WMI_SPECTRAL_INIT_DELAY_DEFAULT 80 +#define WMI_SPECTRAL_NB_TONE_THR_DEFAULT 12 +#define WMI_SPECTRAL_STR_BIN_THR_DEFAULT 8 +#define WMI_SPECTRAL_WB_RPT_MODE_DEFAULT 0 +#define WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT 0 +#define WMI_SPECTRAL_RSSI_THR_DEFAULT 0xf0 +#define WMI_SPECTRAL_PWR_FORMAT_DEFAULT 0 +#define WMI_SPECTRAL_RPT_MODE_DEFAULT 2 +#define WMI_SPECTRAL_BIN_SCALE_DEFAULT 1 +#define WMI_SPECTRAL_DBM_ADJ_DEFAULT 1 +#define WMI_SPECTRAL_CHN_MASK_DEFAULT 1 + +struct wmi_vdev_spectral_enable_cmd { + __le32 vdev_id; + __le32 trigger_cmd; + __le32 enable_cmd; +} __packed; + +#define WMI_SPECTRAL_TRIGGER_CMD_TRIGGER 1 +#define WMI_SPECTRAL_TRIGGER_CMD_CLEAR 2 +#define WMI_SPECTRAL_ENABLE_CMD_ENABLE 1 +#define WMI_SPECTRAL_ENABLE_CMD_DISABLE 2 + /* Beacon processing related command and event structures */ struct wmi_bcn_tx_hdr { __le32 vdev_id; @@ -4517,6 +4610,10 @@ int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, u32 param_id, u32 param_value); int ath10k_wmi_vdev_install_key(struct ath10k *ar, const struct wmi_vdev_install_key_arg *arg); +int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, + const struct wmi_vdev_spectral_conf_arg *arg); +int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, + u32 enable); int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, const u8 peer_addr[ETH_ALEN]); int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, diff --git a/drivers/net/wireless/ath/spectral_common.h b/drivers/net/wireless/ath/spectral_common.h index b9ab722747bd..0d742acb1599 100644 --- a/drivers/net/wireless/ath/spectral_common.h +++ b/drivers/net/wireless/ath/spectral_common.h @@ -20,6 +20,11 @@ #define SPECTRAL_HT20_NUM_BINS 56 #define SPECTRAL_HT20_40_NUM_BINS 128 +/* TODO: could possibly be 512, but no samples this large + * could be acquired so far. + */ +#define SPECTRAL_ATH10K_MAX_NUM_BINS 256 + /* FFT sample format given to userspace via debugfs. * * Please keep the type/length at the front position and change @@ -31,6 +36,7 @@ enum ath_fft_sample_type { ATH_FFT_SAMPLE_HT20 = 1, ATH_FFT_SAMPLE_HT20_40, + ATH_FFT_SAMPLE_ATH10K, }; struct fft_sample_tlv { @@ -85,4 +91,23 @@ struct fft_sample_ht20_40 { u8 data[SPECTRAL_HT20_40_NUM_BINS]; } __packed; +struct fft_sample_ath10k { + struct fft_sample_tlv tlv; + u8 chan_width_mhz; + __be16 freq1; + __be16 freq2; + __be16 noise; + __be16 max_magnitude; + __be16 total_gain_db; + __be16 base_pwr_db; + __be64 tsf; + s8 max_index; + u8 rssi; + u8 relpwr_db; + u8 avgpwr_db; + u8 max_exp; + + u8 data[0]; +} __packed; + #endif /* SPECTRAL_COMMON_H */ -- GitLab From 17dc0b8068f9f01c56b0ade5c36b4c45a3339dda Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Fri, 1 Aug 2014 21:41:15 +0530 Subject: [PATCH 0059/9167] ath6kl: convert a driver to use module_usb_driver() This converts a driver in drivers/net/* to use the module_usb_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/usb.c | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index c44325856b81..a6a5e40b3e98 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -1229,26 +1229,7 @@ static struct usb_driver ath6kl_usb_driver = { .disable_hub_initiated_lpm = 1, }; -static int ath6kl_usb_init(void) -{ - int ret; - - ret = usb_register(&ath6kl_usb_driver); - if (ret) { - ath6kl_err("usb registration failed: %d\n", ret); - return ret; - } - - return 0; -} - -static void ath6kl_usb_exit(void) -{ - usb_deregister(&ath6kl_usb_driver); -} - -module_init(ath6kl_usb_init); -module_exit(ath6kl_usb_exit); +module_usb_driver(ath6kl_usb_driver); MODULE_AUTHOR("Atheros Communications, Inc."); MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); -- GitLab From 83f45fc360c8e16a330474860ebda872d1384c8c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 09:10:18 +0200 Subject: [PATCH 0060/9167] drm: Don't grab an fb reference for the idr The current refcounting scheme is that the fb lookup idr also holds a reference. This works out nicely bacause thus far we've always explicitly cleaned up idr entries for framebuffers: - Userspace fbs get removed in the rmfb ioctl or when the drm file gets closed. - Kernel fbs (for fbdev emulation) get cleaned up by the driver code at module unload time. But now i915 also reconstructs the bios fbs for a smooth transition. And that fb is purely transitional and should get removed immmediately once all crtcs stop using it. Of course if the i915 fbdev code decides to reuse it as the main fbdev fb then it shouldn't be cleaned up, but in that case the fbdev code will grab it's own reference. The problem is now that we also want to register that takeover fb in the idr, so that userspace can do a smooth transition (animated maybe even!) itself. But currently we have no one who will clean up the idr reference once that fb isn't useful any more, and so essentially leak it. Fix this by no longer holding a full fb reference for the idr, but instead just have a weak reference using kref_get_unless_zero. But that requires us to synchronize and clean up with the idr and fb_lock in drm_framebuffer_free, so add that. It's a bit ugly that we have to unconditionally grab the fb_lock, but without that someone might creep through a race. This leak was caught by the fb leak check in drm_mode_config_cleanup. Originally the leak was introduced in commit 46f297fb83d4f9a6f6891964beb184664341a28b Author: Jesse Barnes Date: Fri Mar 7 08:57:48 2014 -0800 drm/i915: add plane_config fetching infrastructure v2 Cc: Jesse Barnes Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77511 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 46 +++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index fa2be249999c..33ff631c8d23 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -515,9 +515,6 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, if (ret) goto out; - /* Grab the idr reference. */ - drm_framebuffer_reference(fb); - dev->mode_config.num_fb++; list_add(&fb->head, &dev->mode_config.fb_list); out: @@ -527,10 +524,34 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, } EXPORT_SYMBOL(drm_framebuffer_init); +/* dev->mode_config.fb_lock must be held! */ +static void __drm_framebuffer_unregister(struct drm_device *dev, + struct drm_framebuffer *fb) +{ + mutex_lock(&dev->mode_config.idr_mutex); + idr_remove(&dev->mode_config.crtc_idr, fb->base.id); + mutex_unlock(&dev->mode_config.idr_mutex); + + fb->base.id = 0; +} + static void drm_framebuffer_free(struct kref *kref) { struct drm_framebuffer *fb = container_of(kref, struct drm_framebuffer, refcount); + struct drm_device *dev = fb->dev; + + /* + * The lookup idr holds a weak reference, which has not necessarily been + * removed at this point. Check for that. + */ + mutex_lock(&dev->mode_config.fb_lock); + if (fb->base.id) { + /* Mark fb as reaped and drop idr ref. */ + __drm_framebuffer_unregister(dev, fb); + } + mutex_unlock(&dev->mode_config.fb_lock); + fb->funcs->destroy(fb); } @@ -567,8 +588,10 @@ struct drm_framebuffer *drm_framebuffer_lookup(struct drm_device *dev, mutex_lock(&dev->mode_config.fb_lock); fb = __drm_framebuffer_lookup(dev, id); - if (fb) - drm_framebuffer_reference(fb); + if (fb) { + if (!kref_get_unless_zero(&fb->refcount)) + fb = NULL; + } mutex_unlock(&dev->mode_config.fb_lock); return fb; @@ -612,19 +635,6 @@ static void __drm_framebuffer_unreference(struct drm_framebuffer *fb) kref_put(&fb->refcount, drm_framebuffer_free_bug); } -/* dev->mode_config.fb_lock must be held! */ -static void __drm_framebuffer_unregister(struct drm_device *dev, - struct drm_framebuffer *fb) -{ - mutex_lock(&dev->mode_config.idr_mutex); - idr_remove(&dev->mode_config.crtc_idr, fb->base.id); - mutex_unlock(&dev->mode_config.idr_mutex); - - fb->base.id = 0; - - __drm_framebuffer_unreference(fb); -} - /** * drm_framebuffer_unregister_private - unregister a private fb from the lookup idr * @fb: fb to unregister -- GitLab From ea6763c104c93acb6554659fe4a3c9e9328a4b51 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 11:36:38 +0200 Subject: [PATCH 0061/9167] video/fbdev: Always built-in video= cmdline parsing In drm/i915 we want to get at the video= cmdline modes even when we don't have fbdev support enabled, so that users can always override the kernel's initial mode selection. But that gives us a direct depency upon the parsing code in the fbdev subsystem. Since it's so little code just extract these 2 functions and always build them in. Whiel at it fix the checkpatch fail in this code. v2: Also move fb_mode_option. Spotted by the kbuild. v3: Review from Geert: - Keep the old copyright notice from fb_mem.c, although I have no idea what exactly applies. - Only compile this when needed. Cc: Geert Uytterhoeven Cc: Plagniol-Villard Cc: Tomi Valkeinen Cc: linux-fbdev@vger.kernel.org Signed-off-by: Daniel Vetter -- I prefer if we can merge this through drm-next since we'll use it there in follow-up patches. -Daniel --- drivers/video/fbdev/Kconfig | 4 + drivers/video/fbdev/core/Makefile | 1 + drivers/video/fbdev/core/fb_cmdline.c | 110 ++++++++++++++++++++++++++ drivers/video/fbdev/core/fbmem.c | 92 --------------------- drivers/video/fbdev/core/modedb.c | 3 - 5 files changed, 115 insertions(+), 95 deletions(-) create mode 100644 drivers/video/fbdev/core/fb_cmdline.c diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 59c98bfd5a8a..f1458c95a688 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -4,6 +4,7 @@ menuconfig FB tristate "Support for frame buffer devices" + select FB_CMDLINE ---help--- The frame buffer device provides an abstraction for the graphics hardware. It represents the frame buffer of some video hardware and @@ -52,6 +53,9 @@ config FIRMWARE_EDID combination with certain motherboards and monitors are known to suffer from this problem. +config FB_CMDLINE + bool + config FB_DDC tristate depends on FB diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile index fa306538dac2..67f28e20a892 100644 --- a/drivers/video/fbdev/core/Makefile +++ b/drivers/video/fbdev/core/Makefile @@ -1,4 +1,5 @@ obj-y += fb_notify.o +obj-$(CONFIG_FB_CMDLINE) += fb_cmdline.o obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o diff --git a/drivers/video/fbdev/core/fb_cmdline.c b/drivers/video/fbdev/core/fb_cmdline.c new file mode 100644 index 000000000000..39509ccd92f1 --- /dev/null +++ b/drivers/video/fbdev/core/fb_cmdline.c @@ -0,0 +1,110 @@ +/* + * linux/drivers/video/fb_cmdline.c + * + * Copyright (C) 2014 Intel Corp + * Copyright (C) 1994 Martin Schaller + * + * 2001 - Documented with DocBook + * - Brad Douglas + * + * 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. + * + * Authors: + * Vetter + */ +#include +#include + +static char *video_options[FB_MAX] __read_mostly; +static int ofonly __read_mostly; + +const char *fb_mode_option; +EXPORT_SYMBOL_GPL(fb_mode_option); + +/** + * fb_get_options - get kernel boot parameters + * @name: framebuffer name as it would appear in + * the boot parameter line + * (video=:) + * @option: the option will be stored here + * + * NOTE: Needed to maintain backwards compatibility + */ +int fb_get_options(const char *name, char **option) +{ + char *opt, *options = NULL; + int retval = 0; + int name_len = strlen(name), i; + + if (name_len && ofonly && strncmp(name, "offb", 4)) + retval = 1; + + if (name_len && !retval) { + for (i = 0; i < FB_MAX; i++) { + if (video_options[i] == NULL) + continue; + if (!video_options[i][0]) + continue; + opt = video_options[i]; + if (!strncmp(name, opt, name_len) && + opt[name_len] == ':') + options = opt + name_len + 1; + } + } + /* No match, pass global option */ + if (!options && option && fb_mode_option) + options = kstrdup(fb_mode_option, GFP_KERNEL); + if (options && !strncmp(options, "off", 3)) + retval = 1; + + if (option) + *option = options; + + return retval; +} +EXPORT_SYMBOL(fb_get_options); + +/** + * video_setup - process command line options + * @options: string of options + * + * Process command line options for frame buffer subsystem. + * + * NOTE: This function is a __setup and __init function. + * It only stores the options. Drivers have to call + * fb_get_options() as necessary. + * + * Returns zero. + * + */ +static int __init video_setup(char *options) +{ + int i, global = 0; + + if (!options || !*options) + global = 1; + + if (!global && !strncmp(options, "ofonly", 6)) { + ofonly = 1; + global = 1; + } + + if (!global && !strchr(options, ':')) { + fb_mode_option = options; + global = 1; + } + + if (!global) { + for (i = 0; i < FB_MAX; i++) { + if (video_options[i] == NULL) { + video_options[i] = options; + break; + } + } + } + + return 1; +} +__setup("video=", video_setup); diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index b5e85f6c1c26..0705d8883ede 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -1908,96 +1908,4 @@ int fb_new_modelist(struct fb_info *info) return err; } -static char *video_options[FB_MAX] __read_mostly; -static int ofonly __read_mostly; - -/** - * fb_get_options - get kernel boot parameters - * @name: framebuffer name as it would appear in - * the boot parameter line - * (video=:) - * @option: the option will be stored here - * - * NOTE: Needed to maintain backwards compatibility - */ -int fb_get_options(const char *name, char **option) -{ - char *opt, *options = NULL; - int retval = 0; - int name_len = strlen(name), i; - - if (name_len && ofonly && strncmp(name, "offb", 4)) - retval = 1; - - if (name_len && !retval) { - for (i = 0; i < FB_MAX; i++) { - if (video_options[i] == NULL) - continue; - if (!video_options[i][0]) - continue; - opt = video_options[i]; - if (!strncmp(name, opt, name_len) && - opt[name_len] == ':') - options = opt + name_len + 1; - } - } - /* No match, pass global option */ - if (!options && option && fb_mode_option) - options = kstrdup(fb_mode_option, GFP_KERNEL); - if (options && !strncmp(options, "off", 3)) - retval = 1; - - if (option) - *option = options; - - return retval; -} -EXPORT_SYMBOL(fb_get_options); - -#ifndef MODULE -/** - * video_setup - process command line options - * @options: string of options - * - * Process command line options for frame buffer subsystem. - * - * NOTE: This function is a __setup and __init function. - * It only stores the options. Drivers have to call - * fb_get_options() as necessary. - * - * Returns zero. - * - */ -static int __init video_setup(char *options) -{ - int i, global = 0; - - if (!options || !*options) - global = 1; - - if (!global && !strncmp(options, "ofonly", 6)) { - ofonly = 1; - global = 1; - } - - if (!global && !strchr(options, ':')) { - fb_mode_option = options; - global = 1; - } - - if (!global) { - for (i = 0; i < FB_MAX; i++) { - if (video_options[i] == NULL) { - video_options[i] = options; - break; - } - - } - } - - return 1; -} -__setup("video=", video_setup); -#endif - MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c index a9a907c440d7..388f7971494b 100644 --- a/drivers/video/fbdev/core/modedb.c +++ b/drivers/video/fbdev/core/modedb.c @@ -29,9 +29,6 @@ #define DPRINTK(fmt, args...) #endif -const char *fb_mode_option; -EXPORT_SYMBOL_GPL(fb_mode_option); - /* * Standard video mode definitions (taken from XFree86) */ -- GitLab From eaf99c749d43ae74ac7ffece5512f3c73f01dfd2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 6 Aug 2014 10:08:32 +0200 Subject: [PATCH 0062/9167] drm: Perform cmdline mode parsing during connector initialisation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit i915.ko has a custom fbdev initialisation routine that aims to preserve the current mode set by the BIOS, unless overruled by the user. The user's wishes are determined by what, if any, mode is specified on the command line (via the video= parameter). However, that command line mode is first parsed by drm_fb_helper_initial_config() which is called after i915.ko's custom initial_config() as a fallback method. So in order for us to honour it, we need to move the cmdline parser earlier. If we perform the connector cmdline parsing as soon as we initialise the connector, that cmdline mode and forced status is then available even if the fbdev helper is not compiled in or never called. We also then expose the cmdline user mode in the connector mode lists. v2: Rebase after connector->name upheaval. v3: Adapt mga200 to look for the cmdline mode in the new place. Nicely simplifies things while at that. v4: Fix checkpatch. v5: Select FB_CMDLINE to adapt to the changed fbdev patch. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=73154 Signed-off-by: Chris Wilson (v2) Cc: Jesse Barnes Cc: Ville Syrjälä Cc: Daniel Vetter Reviewed-by: Jesse Barnes (v2) Cc: dri-devel@lists.freedesktop.org Cc: Julia Lemire Cc: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/drm_crtc.c | 55 ++++++++++++++++++++++ drivers/gpu/drm/drm_fb_helper.c | 64 ++------------------------ drivers/gpu/drm/drm_modes.c | 1 + drivers/gpu/drm/drm_probe_helper.c | 17 +++++++ drivers/gpu/drm/mgag200/mgag200_mode.c | 21 ++------- include/drm/drm_crtc.h | 1 + include/drm/drm_fb_helper.h | 1 - 8 files changed, 83 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 31894c8c1773..367f5dd23291 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -8,6 +8,7 @@ menuconfig DRM tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU && HAS_DMA select HDMI + select FB_CMDLINE select I2C select I2C_ALGOBIT select DMA_SHARED_BUFFER diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 33ff631c8d23..66d3bfb8d264 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -862,6 +862,59 @@ static void drm_mode_remove(struct drm_connector *connector, drm_mode_destroy(connector->dev, mode); } +/** + * 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 + * extracts the user's specified mode (or enable/disable status) for a + * particular connector. This is typically only used during the early fbdev + * setup. + */ +static void drm_connector_get_cmdline_mode(struct drm_connector *connector) +{ + struct drm_cmdline_mode *mode = &connector->cmdline_mode; + char *option = NULL; + + if (fb_get_options(connector->name, &option)) + return; + + if (!drm_mode_parse_command_line_for_connector(option, + connector, + mode)) + return; + + if (mode->force) { + const char *s; + + switch (mode->force) { + case DRM_FORCE_OFF: + s = "OFF"; + break; + case DRM_FORCE_ON_DIGITAL: + s = "ON - dig"; + break; + default: + case DRM_FORCE_ON: + s = "ON"; + break; + } + + DRM_INFO("forcing %s connector %s\n", connector->name, s); + connector->force = mode->force; + } + + DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", + connector->name, + mode->xres, mode->yres, + mode->refresh_specified ? mode->refresh : 60, + mode->rb ? " reduced blanking" : "", + mode->margins ? " with margins" : "", + mode->interlace ? " interlaced" : ""); +} + /** * drm_connector_init - Init a preallocated connector * @dev: DRM device @@ -914,6 +967,8 @@ int drm_connector_init(struct drm_device *dev, connector->edid_blob_ptr = NULL; connector->status = connector_status_unknown; + drm_connector_get_cmdline_mode(connector); + list_add_tail(&connector->head, &dev->mode_config.connector_list); dev->mode_config.num_connector++; diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 3144db9dc0f1..3a6b6635e3f5 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -171,60 +171,6 @@ int drm_fb_helper_remove_one_connector(struct drm_fb_helper *fb_helper, } EXPORT_SYMBOL(drm_fb_helper_remove_one_connector); -static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper) -{ - struct drm_fb_helper_connector *fb_helper_conn; - int i; - - for (i = 0; i < fb_helper->connector_count; i++) { - struct drm_cmdline_mode *mode; - struct drm_connector *connector; - char *option = NULL; - - fb_helper_conn = fb_helper->connector_info[i]; - connector = fb_helper_conn->connector; - mode = &fb_helper_conn->cmdline_mode; - - /* do something on return - turn off connector maybe */ - if (fb_get_options(connector->name, &option)) - continue; - - if (drm_mode_parse_command_line_for_connector(option, - connector, - mode)) { - if (mode->force) { - const char *s; - switch (mode->force) { - case DRM_FORCE_OFF: - s = "OFF"; - break; - case DRM_FORCE_ON_DIGITAL: - s = "ON - dig"; - break; - default: - case DRM_FORCE_ON: - s = "ON"; - break; - } - - DRM_INFO("forcing %s connector %s\n", - connector->name, s); - connector->force = mode->force; - } - - DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", - connector->name, - mode->xres, mode->yres, - mode->refresh_specified ? mode->refresh : 60, - mode->rb ? " reduced blanking" : "", - mode->margins ? " with margins" : "", - mode->interlace ? " interlaced" : ""); - } - - } - return 0; -} - static void drm_fb_helper_save_lut_atomic(struct drm_crtc *crtc, struct drm_fb_helper *helper) { uint16_t *r_base, *g_base, *b_base; @@ -1013,7 +959,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i]; struct drm_cmdline_mode *cmdline_mode; - cmdline_mode = &fb_helper_conn->cmdline_mode; + cmdline_mode = &fb_helper_conn->connector->cmdline_mode; if (cmdline_mode->bpp_specified) { switch (cmdline_mode->bpp) { @@ -1260,9 +1206,7 @@ EXPORT_SYMBOL(drm_has_preferred_mode); static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector) { - struct drm_cmdline_mode *cmdline_mode; - cmdline_mode = &fb_connector->cmdline_mode; - return cmdline_mode->specified; + return fb_connector->connector->cmdline_mode.specified; } struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn, @@ -1272,7 +1216,7 @@ struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *f struct drm_display_mode *mode = NULL; bool prefer_non_interlace; - cmdline_mode = &fb_helper_conn->cmdline_mode; + cmdline_mode = &fb_helper_conn->connector->cmdline_mode; if (cmdline_mode->specified == false) return mode; @@ -1657,8 +1601,6 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) struct drm_device *dev = fb_helper->dev; int count = 0; - drm_fb_helper_parse_command_line(fb_helper); - mutex_lock(&dev->mode_config.mutex); count = drm_fb_helper_probe_connector_modes(fb_helper, dev->mode_config.max_width, diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index bedf1894e17e..d1b7d2006529 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -1259,6 +1259,7 @@ drm_mode_create_from_cmdline_mode(struct drm_device *dev, if (!mode) return NULL; + mode->type |= DRM_MODE_TYPE_USERDEF; drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); return mode; } diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index db7d250f7ac7..6857e9ad6339 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -82,6 +82,22 @@ static void drm_mode_validate_flag(struct drm_connector *connector, return; } +static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) +{ + struct drm_display_mode *mode; + + if (!connector->cmdline_mode.specified) + return 0; + + mode = drm_mode_create_from_cmdline_mode(connector->dev, + &connector->cmdline_mode); + if (mode == NULL) + return 0; + + drm_mode_probed_add(connector, mode); + return 1; +} + static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector, uint32_t maxX, uint32_t maxY, bool merge_type_bits) { @@ -141,6 +157,7 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect if (count == 0 && connector->status == connector_status_connected) count = drm_add_modes_noedid(connector, 1024, 768); + count += drm_helper_probe_add_cmdline_mode(connector); if (count == 0) goto prune; diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 45f04dea0ac2..83485ab81ce8 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1483,11 +1483,7 @@ static int mga_vga_mode_valid(struct drm_connector *connector, { struct drm_device *dev = connector->dev; struct mga_device *mdev = (struct mga_device*)dev->dev_private; - struct mga_fbdev *mfbdev = mdev->mfbdev; - struct drm_fb_helper *fb_helper = &mfbdev->helper; - struct drm_fb_helper_connector *fb_helper_conn = NULL; int bpp = 32; - int i = 0; if (IS_G200_SE(mdev)) { if (mdev->unique_rev_id == 0x01) { @@ -1537,21 +1533,14 @@ static int mga_vga_mode_valid(struct drm_connector *connector, } /* Validate the mode input by the user */ - for (i = 0; i < fb_helper->connector_count; i++) { - if (fb_helper->connector_info[i]->connector == connector) { - /* Found the helper for this connector */ - fb_helper_conn = fb_helper->connector_info[i]; - if (fb_helper_conn->cmdline_mode.specified) { - if (fb_helper_conn->cmdline_mode.bpp_specified) { - bpp = fb_helper_conn->cmdline_mode.bpp; - } - } - } + if (connector->cmdline_mode.specified) { + if (connector->cmdline_mode.bpp_specified) + bpp = connector->cmdline_mode.bpp; } if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) { - if (fb_helper_conn) - fb_helper_conn->cmdline_mode.specified = false; + if (connector->cmdline_mode.specified) + connector->cmdline_mode.specified = false; return MODE_BAD; } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index f1105d0da059..c530b4920a09 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -548,6 +548,7 @@ struct drm_connector { void *helper_private; /* forced on connector */ + struct drm_cmdline_mode cmdline_mode; enum drm_connector_force force; bool override_edid; uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index bfd329d613c4..f4ad254e3488 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -77,7 +77,6 @@ struct drm_fb_helper_funcs { struct drm_fb_helper_connector { struct drm_connector *connector; - struct drm_cmdline_mode cmdline_mode; }; struct drm_fb_helper { -- GitLab From ddde43711fdde505ac413102faa2352704cd858a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:02:50 +0300 Subject: [PATCH 0063/9167] drm: Warn when leaking flip events on close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Warn when there are events on the file_priv->event_list just before file_priv gets freed. This can occur if the driver doesn't clean up pending page flip events in ->preclose(). Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/drm_fops.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 8f91062db5b6..0fa4dadac4c6 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -529,6 +529,8 @@ int drm_release(struct inode *inode, struct file *filp) if (drm_core_check_feature(dev, DRIVER_PRIME)) drm_prime_destroy_file_private(&file_priv->prime); + WARN_ON(!list_empty(&file_priv->event_list)); + put_pid(file_priv->pid); kfree(file_priv); -- GitLab From e6ae8687a87b1fe5c25e824c8ad300f5587eb622 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 6 Aug 2014 13:16:59 -0400 Subject: [PATCH 0064/9167] drm: idiot-proof vblank After spending slightly more time than I'd care to admit debugging the various and presumably spectacular way things fail when you pass too low a value to drm_vblank_init() (thanks console-lock for not letting me see the carnage!), I decided it might be a good idea to add some sanity checking. Signed-off-by: Rob Clark Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 0de123afdb34..6f16a104d6d0 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -730,6 +730,8 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp); */ u32 drm_vblank_count(struct drm_device *dev, int crtc) { + if (WARN_ON(crtc >= dev->num_crtcs)) + return 0; return atomic_read(&dev->vblank[crtc].count); } EXPORT_SYMBOL(drm_vblank_count); @@ -752,6 +754,9 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, { u32 cur_vblank; + if (WARN_ON(crtc >= dev->num_crtcs)) + return 0; + /* Read timestamp from slot of _vblank_time ringbuffer * that corresponds to current vblank count. Retry if * count has incremented during readout. This works like @@ -927,6 +932,9 @@ int drm_vblank_get(struct drm_device *dev, int crtc) unsigned long irqflags; int ret = 0; + if (WARN_ON(crtc >= dev->num_crtcs)) + return -EINVAL; + spin_lock_irqsave(&dev->vbl_lock, irqflags); /* Going from 0->1 means we have to enable interrupts again */ if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) { @@ -975,6 +983,9 @@ void drm_vblank_put(struct drm_device *dev, int crtc) { BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0); + if (WARN_ON(crtc >= dev->num_crtcs)) + return; + /* Last user schedules interrupt disable */ if (atomic_dec_and_test(&dev->vblank[crtc].refcount) && (drm_vblank_offdelay > 0)) @@ -1019,6 +1030,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc) unsigned long irqflags; unsigned int seq; + if (WARN_ON(crtc >= dev->num_crtcs)) + return; + spin_lock_irqsave(&dev->vbl_lock, irqflags); vblank_disable_and_save(dev, crtc); wake_up(&dev->vblank[crtc].queue); @@ -1078,6 +1092,9 @@ void drm_vblank_on(struct drm_device *dev, int crtc) { unsigned long irqflags; + if (WARN_ON(crtc >= dev->num_crtcs)) + return; + spin_lock_irqsave(&dev->vbl_lock, irqflags); /* re-enable interrupts if there's are users left */ if (atomic_read(&dev->vblank[crtc].refcount) != 0) @@ -1131,6 +1148,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) /* vblank is not initialized (IRQ not installed ?), or has been freed */ if (!dev->num_crtcs) return; + + if (WARN_ON(crtc >= dev->num_crtcs)) + return; + /* * To avoid all the problems that might happen if interrupts * were enabled/disabled around or between these calls, we just @@ -1439,6 +1460,9 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) if (!dev->num_crtcs) return false; + if (WARN_ON(crtc >= dev->num_crtcs)) + return false; + /* Need timestamp lock to prevent concurrent execution with * vblank enable/disable, as this would cause inconsistent * or corrupted timestamps and vblank counts. -- GitLab From 7ffd7a68511c710b84db3548a1997fd2625f580a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:44 +0300 Subject: [PATCH 0065/9167] drm: Always reject drm_vblank_get() after drm_vblank_off() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure drm_vblank_get() never succeeds when called between drm_vblank_off() and drm_vblank_on(). Borrow a trick from the old drm_vblank_{pre,post}_modeset() functions and just bump the refcount in drm_vblank_off() and drop it in drm_vblank_on(). When drm_vblank_get() encounters a >0 refcount and the vblank interrupt is already disabled it will simply return -EINVAL. Hopefully the use of inmodeset won't conflict badly with drm_vblank_{pre,post}_modeset(). For i915 there's a window between drm_vblank_off() and marking the crtc as inactive where the current code still allows drm_vblank_get(). v2: Describe what drm_vblank_get() does to explain how a simple refcount bump manages to fix things (Daniel) Reviewed-by: Matt Roper Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 0de123afdb34..b16a63622bad 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1039,6 +1039,15 @@ void drm_vblank_off(struct drm_device *dev, int crtc) } spin_unlock(&dev->event_lock); + /* + * Prevent subsequent drm_vblank_get() from re-enabling + * the vblank interrupt by bumping the refcount. + */ + if (!dev->vblank[crtc].inmodeset) { + atomic_inc(&dev->vblank[crtc].refcount); + dev->vblank[crtc].inmodeset = 1; + } + spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } EXPORT_SYMBOL(drm_vblank_off); @@ -1079,6 +1088,11 @@ void drm_vblank_on(struct drm_device *dev, int crtc) unsigned long irqflags; spin_lock_irqsave(&dev->vbl_lock, irqflags); + /* Drop our private "prevent drm_vblank_get" refcount */ + if (dev->vblank[crtc].inmodeset) { + atomic_dec(&dev->vblank[crtc].refcount); + dev->vblank[crtc].inmodeset = 0; + } /* re-enable interrupts if there's are users left */ if (atomic_read(&dev->vblank[crtc].refcount) != 0) WARN_ON(drm_vblank_enable(dev, crtc)); -- GitLab From 08c71e5e817a956389af5da5e99ab3e26d5c673d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:45 +0300 Subject: [PATCH 0066/9167] drm/i915: Warn if drm_vblank_get() still works after drm_vblank_off() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v2: Drop the drm_vblank_off() (Daniel) Use drm_crtc_vblank_{get,put}() Reviewed-by: Matt Roper Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 99eb7cad62a8..8f6b932d8e79 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1341,6 +1341,12 @@ static void assert_sprites_disabled(struct drm_i915_private *dev_priv, } } +static void assert_vblank_disabled(struct drm_crtc *crtc) +{ + if (WARN_ON(drm_crtc_vblank_get(crtc) == 0)) + drm_crtc_vblank_put(crtc); +} + static void ibx_assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) { u32 val; @@ -3905,6 +3911,8 @@ static void intel_crtc_enable_planes(struct drm_crtc *crtc) int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; + assert_vblank_disabled(crtc); + drm_vblank_on(dev, pipe); intel_enable_primary_hw_plane(dev_priv, plane, pipe); @@ -3954,6 +3962,8 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc) 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) -- GitLab From 844b03f27739135fe1fed2fef06da0ffc4c7a081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:46 +0300 Subject: [PATCH 0067/9167] drm: Don't clear vblank timestamps when vblank interrupt is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clearing the timestamps causes us to send zeroed timestamps to userspace if they get sent out in response to the drm_vblank_off(). It's better to send the very latest timestamp and count instead. Testcase: igt/kms_flip/modeset-vs-vblank-race Reviewed-by: Matt Roper Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index b16a63622bad..65d2da9b604b 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -55,14 +55,6 @@ */ #define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 -/* - * Clear vblank timestamp buffer for a crtc. - */ -static void clear_vblank_timestamps(struct drm_device *dev, int crtc) -{ - memset(dev->vblank[crtc].time, 0, sizeof(dev->vblank[crtc].time)); -} - /* * Disable vblank irq's on crtc, make sure that last vblank count * of hardware and corresponding consistent software vblank counter @@ -131,9 +123,6 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) smp_mb__after_atomic(); } - /* Invalidate all timestamps while vblank irq's are off. */ - clear_vblank_timestamps(dev, crtc); - spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); } -- GitLab From 13b030af54a5e307cbcccdf5479873fbc4b7f185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:47 +0300 Subject: [PATCH 0068/9167] drm: Move drm_update_vblank_count() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move drm_update_vblank_count() to avoid forward a declaration. No functional change. Reviewed-by: Matt Roper Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 128 +++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 65d2da9b604b..af965174b083 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -55,6 +55,70 @@ */ #define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 +/** + * drm_update_vblank_count - update the master vblank counter + * @dev: DRM device + * @crtc: counter to update + * + * Call back into the driver to update the appropriate vblank counter + * (specified by @crtc). Deal with wraparound, if it occurred, and + * update the last read value so we can deal with wraparound on the next + * call if necessary. + * + * Only necessary when going from off->on, to account for frames we + * didn't get an interrupt for. + * + * Note: caller must hold dev->vbl_lock since this reads & writes + * device vblank fields. + */ +static void drm_update_vblank_count(struct drm_device *dev, int crtc) +{ + u32 cur_vblank, diff, tslot, rc; + struct timeval t_vblank; + + /* + * Interrupts were disabled prior to this call, so deal with counter + * wrap if needed. + * NOTE! It's possible we lost a full dev->max_vblank_count events + * here if the register is small or we had vblank interrupts off for + * a long time. + * + * We repeat the hardware vblank counter & timestamp query until + * we get consistent results. This to prevent races between gpu + * updating its hardware counter while we are retrieving the + * corresponding vblank timestamp. + */ + do { + cur_vblank = dev->driver->get_vblank_counter(dev, crtc); + rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); + } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); + + /* Deal with counter wrap */ + diff = cur_vblank - dev->vblank[crtc].last; + if (cur_vblank < dev->vblank[crtc].last) { + diff += dev->max_vblank_count; + + DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", + crtc, dev->vblank[crtc].last, cur_vblank, diff); + } + + DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", + crtc, diff); + + /* Reinitialize corresponding vblank timestamp if high-precision query + * available. Skip this step if query unsupported or failed. Will + * reinitialize delayed at next vblank interrupt in that case. + */ + if (rc) { + tslot = atomic_read(&dev->vblank[crtc].count) + diff; + vblanktimestamp(dev, crtc, tslot) = t_vblank; + } + + smp_mb__before_atomic(); + atomic_add(diff, &dev->vblank[crtc].count); + smp_mb__after_atomic(); +} + /* * Disable vblank irq's on crtc, make sure that last vblank count * of hardware and corresponding consistent software vblank counter @@ -798,70 +862,6 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc, } EXPORT_SYMBOL(drm_send_vblank_event); -/** - * drm_update_vblank_count - update the master vblank counter - * @dev: DRM device - * @crtc: counter to update - * - * Call back into the driver to update the appropriate vblank counter - * (specified by @crtc). Deal with wraparound, if it occurred, and - * update the last read value so we can deal with wraparound on the next - * call if necessary. - * - * Only necessary when going from off->on, to account for frames we - * didn't get an interrupt for. - * - * Note: caller must hold dev->vbl_lock since this reads & writes - * device vblank fields. - */ -static void drm_update_vblank_count(struct drm_device *dev, int crtc) -{ - u32 cur_vblank, diff, tslot, rc; - struct timeval t_vblank; - - /* - * Interrupts were disabled prior to this call, so deal with counter - * wrap if needed. - * NOTE! It's possible we lost a full dev->max_vblank_count events - * here if the register is small or we had vblank interrupts off for - * a long time. - * - * We repeat the hardware vblank counter & timestamp query until - * we get consistent results. This to prevent races between gpu - * updating its hardware counter while we are retrieving the - * corresponding vblank timestamp. - */ - do { - cur_vblank = dev->driver->get_vblank_counter(dev, crtc); - rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); - } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); - - /* Deal with counter wrap */ - diff = cur_vblank - dev->vblank[crtc].last; - if (cur_vblank < dev->vblank[crtc].last) { - diff += dev->max_vblank_count; - - DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", - crtc, dev->vblank[crtc].last, cur_vblank, diff); - } - - DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", - crtc, diff); - - /* Reinitialize corresponding vblank timestamp if high-precision query - * available. Skip this step if query unsupported or failed. Will - * reinitialize delayed at next vblank interrupt in that case. - */ - if (rc) { - tslot = atomic_read(&dev->vblank[crtc].count) + diff; - vblanktimestamp(dev, crtc, tslot) = t_vblank; - } - - smp_mb__before_atomic(); - atomic_add(diff, &dev->vblank[crtc].count); - smp_mb__after_atomic(); -} - /** * drm_vblank_enable - enable the vblank interrupt on a CRTC * @dev: DRM device -- GitLab From 812e7465a7decf3cca0b5f71977a25eecd9626a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:48 +0300 Subject: [PATCH 0069/9167] drm: Have the vblank counter account for the time between vblank irq disable and drm_vblank_off() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the vblank irq has already been disabled (via the disable timer) when we call drm_vblank_off() sample the counter and timestamp one last time. This will make the sure that the user space visible counter will account for time between vblank irq disable and drm_vblank_off(). Reviewed-by: Matt Roper Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index af965174b083..1f86f6c6ecc6 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -140,6 +140,19 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) */ spin_lock_irqsave(&dev->vblank_time_lock, irqflags); + /* + * If the vblank interrupt was already disbled update the count + * and timestamp to maintain the appearance that the counter + * has been ticking all along until this time. This makes the + * count account for the entire time between drm_vblank_on() and + * drm_vblank_off(). + */ + if (!dev->vblank[crtc].enabled) { + drm_update_vblank_count(dev, crtc); + spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); + return; + } + dev->driver->disable_vblank(dev, crtc); dev->vblank[crtc].enabled = false; -- GitLab From f8ad028cc033f75fc479ca1c30e2ea4ba56e5269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:49 +0300 Subject: [PATCH 0070/9167] drm: Avoid random vblank counter jumps if the hardware counter has been reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When drm_vblank_on() is called the hardware vblank counter may have been reset, so we can't trust that the old values sampled prior to drm_vblank_off() have anything to do with the new values. So update the .last count in drm_vblank_on() to make the first drm_vblank_enable() consider that as the reference point. This will correct the user space visible counter to account for the time between drm_vblank_on() and the first drm_vblank_enable() calls. For extra safety subtract one from the .last count in drm_vblank_on() to make sure that user space will never see the same counter value before and after modeset. Reviewed-by: Matt Roper Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 1f86f6c6ecc6..fc1525a499d9 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1095,6 +1095,18 @@ void drm_vblank_on(struct drm_device *dev, int crtc) atomic_dec(&dev->vblank[crtc].refcount); dev->vblank[crtc].inmodeset = 0; } + + /* + * sample the current counter to avoid random jumps + * when drm_vblank_enable() applies the diff + * + * -1 to make sure user will never see the same + * vblank counter value before and after a modeset + */ + dev->vblank[crtc].last = + (dev->driver->get_vblank_counter(dev, crtc) - 1) & + dev->max_vblank_count; + /* re-enable interrupts if there's are users left */ if (atomic_read(&dev->vblank[crtc].refcount) != 0) WARN_ON(drm_vblank_enable(dev, crtc)); -- GitLab From 8a51d5bef07f1c8c59de20089fb27ea39d395f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:50 +0300 Subject: [PATCH 0071/9167] drm: Reduce the amount of dev->vblank[crtc] in the code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Declare a local struct drm_vblank_crtc * and use that instead of having to do dig it out via 'dev->vblank[crtc]' everywhere. Performed with the following coccinelle incantation, and a few manual whitespace cleanups: @@ identifier func,member; expression num_crtcs; struct drm_device *dev; unsigned int crtc; @@ func (...) { + struct drm_vblank_crtc *vblank; ... if (crtc >= num_crtcs) return ...; + vblank = &dev->vblank[crtc]; <+... ( - dev->vblank[crtc].member + vblank->member | - &(dev->vblank[crtc]) + vblank ) ...+> } @@ struct drm_device *dev; int crtc; identifier member; expression num_crtcs; @@ for (crtc = 0; crtc < num_crtcs; crtc++) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; + <+... ( - dev->vblank[crtc].member + vblank->member | - &(dev->vblank[crtc]) + vblank ) ...+> } @@ identifier func,member; @@ func (struct drm_device *dev, int crtc, ...) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; <+... ( - dev->vblank[crtc].member + vblank->member | - &(dev->vblank[crtc]) + vblank ) ...+> } v2: Rebased Reviewed-by: Matt Roper Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 134 ++++++++++++++++++++++---------------- 1 file changed, 79 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index fc1525a499d9..b4460bf0e0e4 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -73,6 +73,7 @@ */ static void drm_update_vblank_count(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; u32 cur_vblank, diff, tslot, rc; struct timeval t_vblank; @@ -94,12 +95,12 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); /* Deal with counter wrap */ - diff = cur_vblank - dev->vblank[crtc].last; - if (cur_vblank < dev->vblank[crtc].last) { + diff = cur_vblank - vblank->last; + if (cur_vblank < vblank->last) { diff += dev->max_vblank_count; DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n", - crtc, dev->vblank[crtc].last, cur_vblank, diff); + crtc, vblank->last, cur_vblank, diff); } DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", @@ -110,12 +111,12 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) * reinitialize delayed at next vblank interrupt in that case. */ if (rc) { - tslot = atomic_read(&dev->vblank[crtc].count) + diff; + tslot = atomic_read(&vblank->count) + diff; vblanktimestamp(dev, crtc, tslot) = t_vblank; } smp_mb__before_atomic(); - atomic_add(diff, &dev->vblank[crtc].count); + atomic_add(diff, &vblank->count); smp_mb__after_atomic(); } @@ -127,6 +128,7 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) */ static void vblank_disable_and_save(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; unsigned long irqflags; u32 vblcount; s64 diff_ns; @@ -147,14 +149,14 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * count account for the entire time between drm_vblank_on() and * drm_vblank_off(). */ - if (!dev->vblank[crtc].enabled) { + if (!vblank->enabled) { drm_update_vblank_count(dev, crtc); spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); return; } dev->driver->disable_vblank(dev, crtc); - dev->vblank[crtc].enabled = false; + vblank->enabled = false; /* No further vblank irq's will be processed after * this point. Get current hardware vblank count and @@ -169,9 +171,9 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * delayed gpu counter increment. */ do { - dev->vblank[crtc].last = dev->driver->get_vblank_counter(dev, crtc); + vblank->last = dev->driver->get_vblank_counter(dev, crtc); vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); - } while (dev->vblank[crtc].last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc); + } while (vblank->last != dev->driver->get_vblank_counter(dev, crtc) && (--count) && vblrc); if (!count) vblrc = 0; @@ -179,7 +181,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) /* Compute time difference to stored timestamp of last vblank * as updated by last invocation of drm_handle_vblank() in vblank irq. */ - vblcount = atomic_read(&dev->vblank[crtc].count); + vblcount = atomic_read(&vblank->count); diff_ns = timeval_to_ns(&tvblank) - timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); @@ -196,7 +198,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * hope for the best. */ if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { - atomic_inc(&dev->vblank[crtc].count); + atomic_inc(&vblank->count); smp_mb__after_atomic(); } @@ -236,8 +238,10 @@ void drm_vblank_cleanup(struct drm_device *dev) return; for (crtc = 0; crtc < dev->num_crtcs; crtc++) { - del_timer_sync(&dev->vblank[crtc].disable_timer); - vblank_disable_fn((unsigned long)&dev->vblank[crtc]); + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; + + del_timer_sync(&vblank->disable_timer); + vblank_disable_fn((unsigned long)vblank); } kfree(dev->vblank); @@ -270,11 +274,13 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) goto err; for (i = 0; i < num_crtcs; i++) { - dev->vblank[i].dev = dev; - dev->vblank[i].crtc = i; - init_waitqueue_head(&dev->vblank[i].queue); - setup_timer(&dev->vblank[i].disable_timer, vblank_disable_fn, - (unsigned long)&dev->vblank[i]); + struct drm_vblank_crtc *vblank = &dev->vblank[i]; + + vblank->dev = dev; + vblank->crtc = i; + init_waitqueue_head(&vblank->queue); + setup_timer(&vblank->disable_timer, vblank_disable_fn, + (unsigned long)vblank); } DRM_INFO("Supports vblank timestamp caching Rev 2 (21.10.2013).\n"); @@ -426,9 +432,11 @@ int drm_irq_uninstall(struct drm_device *dev) if (dev->num_crtcs) { spin_lock_irqsave(&dev->vbl_lock, irqflags); for (i = 0; i < dev->num_crtcs; i++) { - wake_up(&dev->vblank[i].queue); - dev->vblank[i].enabled = false; - dev->vblank[i].last = + struct drm_vblank_crtc *vblank = &dev->vblank[i]; + + wake_up(&vblank->queue); + vblank->enabled = false; + vblank->last = dev->driver->get_vblank_counter(dev, i); } spin_unlock_irqrestore(&dev->vbl_lock, irqflags); @@ -796,7 +804,9 @@ EXPORT_SYMBOL(drm_get_last_vbltimestamp); */ u32 drm_vblank_count(struct drm_device *dev, int crtc) { - return atomic_read(&dev->vblank[crtc].count); + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; + + return atomic_read(&vblank->count); } EXPORT_SYMBOL(drm_vblank_count); @@ -816,6 +826,7 @@ EXPORT_SYMBOL(drm_vblank_count); u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, struct timeval *vblanktime) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; u32 cur_vblank; /* Read timestamp from slot of _vblank_time ringbuffer @@ -824,10 +835,10 @@ u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, * a seqlock. */ do { - cur_vblank = atomic_read(&dev->vblank[crtc].count); + cur_vblank = atomic_read(&vblank->count); *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); smp_rmb(); - } while (cur_vblank != atomic_read(&dev->vblank[crtc].count)); + } while (cur_vblank != atomic_read(&vblank->count)); return cur_vblank; } @@ -882,13 +893,14 @@ EXPORT_SYMBOL(drm_send_vblank_event); */ static int drm_vblank_enable(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; int ret = 0; assert_spin_locked(&dev->vbl_lock); spin_lock(&dev->vblank_time_lock); - if (!dev->vblank[crtc].enabled) { + if (!vblank->enabled) { /* * Enable vblank irqs under vblank_time_lock protection. * All vblank count & timestamp updates are held off @@ -899,9 +911,9 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc) ret = dev->driver->enable_vblank(dev, crtc); DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); if (ret) - atomic_dec(&dev->vblank[crtc].refcount); + atomic_dec(&vblank->refcount); else { - dev->vblank[crtc].enabled = true; + vblank->enabled = true; drm_update_vblank_count(dev, crtc); } } @@ -926,16 +938,17 @@ static int drm_vblank_enable(struct drm_device *dev, int crtc) */ int drm_vblank_get(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; unsigned long irqflags; int ret = 0; spin_lock_irqsave(&dev->vbl_lock, irqflags); /* Going from 0->1 means we have to enable interrupts again */ - if (atomic_add_return(1, &dev->vblank[crtc].refcount) == 1) { + if (atomic_add_return(1, &vblank->refcount) == 1) { ret = drm_vblank_enable(dev, crtc); } else { - if (!dev->vblank[crtc].enabled) { - atomic_dec(&dev->vblank[crtc].refcount); + if (!vblank->enabled) { + atomic_dec(&vblank->refcount); ret = -EINVAL; } } @@ -975,12 +988,14 @@ EXPORT_SYMBOL(drm_crtc_vblank_get); */ void drm_vblank_put(struct drm_device *dev, int crtc) { - BUG_ON(atomic_read(&dev->vblank[crtc].refcount) == 0); + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; + + BUG_ON(atomic_read(&vblank->refcount) == 0); /* Last user schedules interrupt disable */ - if (atomic_dec_and_test(&dev->vblank[crtc].refcount) && + if (atomic_dec_and_test(&vblank->refcount) && (drm_vblank_offdelay > 0)) - mod_timer(&dev->vblank[crtc].disable_timer, + mod_timer(&vblank->disable_timer, jiffies + ((drm_vblank_offdelay * HZ)/1000)); } EXPORT_SYMBOL(drm_vblank_put); @@ -1016,6 +1031,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_put); */ void drm_vblank_off(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; struct drm_pending_vblank_event *e, *t; struct timeval now; unsigned long irqflags; @@ -1023,7 +1039,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc) spin_lock_irqsave(&dev->vbl_lock, irqflags); vblank_disable_and_save(dev, crtc); - wake_up(&dev->vblank[crtc].queue); + wake_up(&vblank->queue); /* Send any queued vblank events, lest the natives grow disquiet */ seq = drm_vblank_count_and_time(dev, crtc, &now); @@ -1045,9 +1061,9 @@ void drm_vblank_off(struct drm_device *dev, int crtc) * Prevent subsequent drm_vblank_get() from re-enabling * the vblank interrupt by bumping the refcount. */ - if (!dev->vblank[crtc].inmodeset) { - atomic_inc(&dev->vblank[crtc].refcount); - dev->vblank[crtc].inmodeset = 1; + if (!vblank->inmodeset) { + atomic_inc(&vblank->refcount); + vblank->inmodeset = 1; } spin_unlock_irqrestore(&dev->vbl_lock, irqflags); @@ -1087,13 +1103,14 @@ EXPORT_SYMBOL(drm_crtc_vblank_off); */ void drm_vblank_on(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; unsigned long irqflags; spin_lock_irqsave(&dev->vbl_lock, irqflags); /* Drop our private "prevent drm_vblank_get" refcount */ - if (dev->vblank[crtc].inmodeset) { - atomic_dec(&dev->vblank[crtc].refcount); - dev->vblank[crtc].inmodeset = 0; + if (vblank->inmodeset) { + atomic_dec(&vblank->refcount); + vblank->inmodeset = 0; } /* @@ -1103,12 +1120,12 @@ void drm_vblank_on(struct drm_device *dev, int crtc) * -1 to make sure user will never see the same * vblank counter value before and after a modeset */ - dev->vblank[crtc].last = + vblank->last = (dev->driver->get_vblank_counter(dev, crtc) - 1) & dev->max_vblank_count; /* re-enable interrupts if there's are users left */ - if (atomic_read(&dev->vblank[crtc].refcount) != 0) + if (atomic_read(&vblank->refcount) != 0) WARN_ON(drm_vblank_enable(dev, crtc)); spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } @@ -1156,6 +1173,8 @@ EXPORT_SYMBOL(drm_crtc_vblank_on); */ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; + /* vblank is not initialized (IRQ not installed ?), or has been freed */ if (!dev->num_crtcs) return; @@ -1166,10 +1185,10 @@ void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) * to avoid corrupting the count if multiple, mismatch calls occur), * so that interrupts remain enabled in the interim. */ - if (!dev->vblank[crtc].inmodeset) { - dev->vblank[crtc].inmodeset = 0x1; + if (!vblank->inmodeset) { + vblank->inmodeset = 0x1; if (drm_vblank_get(dev, crtc) == 0) - dev->vblank[crtc].inmodeset |= 0x2; + vblank->inmodeset |= 0x2; } } EXPORT_SYMBOL(drm_vblank_pre_modeset); @@ -1184,21 +1203,22 @@ EXPORT_SYMBOL(drm_vblank_pre_modeset); */ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; unsigned long irqflags; /* vblank is not initialized (IRQ not installed ?), or has been freed */ if (!dev->num_crtcs) return; - if (dev->vblank[crtc].inmodeset) { + if (vblank->inmodeset) { spin_lock_irqsave(&dev->vbl_lock, irqflags); dev->vblank_disable_allowed = true; spin_unlock_irqrestore(&dev->vbl_lock, irqflags); - if (dev->vblank[crtc].inmodeset & 0x2) + if (vblank->inmodeset & 0x2) drm_vblank_put(dev, crtc); - dev->vblank[crtc].inmodeset = 0; + vblank->inmodeset = 0; } } EXPORT_SYMBOL(drm_vblank_post_modeset); @@ -1333,6 +1353,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_vblank_crtc *vblank; union drm_wait_vblank *vblwait = data; int ret; unsigned int flags, seq, crtc, high_crtc; @@ -1362,6 +1383,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, if (crtc >= dev->num_crtcs) return -EINVAL; + vblank = &dev->vblank[crtc]; + ret = drm_vblank_get(dev, crtc); if (ret) { DRM_DEBUG("failed to acquire vblank counter, %d\n", ret); @@ -1394,11 +1417,11 @@ int drm_wait_vblank(struct drm_device *dev, void *data, DRM_DEBUG("waiting on vblank count %d, crtc %d\n", vblwait->request.sequence, crtc); - dev->vblank[crtc].last_wait = vblwait->request.sequence; - DRM_WAIT_ON(ret, dev->vblank[crtc].queue, 3 * HZ, + vblank->last_wait = vblwait->request.sequence; + DRM_WAIT_ON(ret, vblank->queue, 3 * HZ, (((drm_vblank_count(dev, crtc) - vblwait->request.sequence) <= (1 << 23)) || - !dev->vblank[crtc].enabled || + !vblank->enabled || !dev->irq_enabled)); if (ret != -EINTR) { @@ -1459,6 +1482,7 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc) */ bool drm_handle_vblank(struct drm_device *dev, int crtc) { + struct drm_vblank_crtc *vblank = &dev->vblank[crtc]; u32 vblcount; s64 diff_ns; struct timeval tvblank; @@ -1474,7 +1498,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) spin_lock_irqsave(&dev->vblank_time_lock, irqflags); /* Vblank irq handling disabled. Nothing to do. */ - if (!dev->vblank[crtc].enabled) { + if (!vblank->enabled) { spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); return false; } @@ -1484,7 +1508,7 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) */ /* Get current timestamp and count. */ - vblcount = atomic_read(&dev->vblank[crtc].count); + vblcount = atomic_read(&vblank->count); drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); /* Compute time difference to timestamp of last vblank */ @@ -1508,14 +1532,14 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) * the timestamp computed above. */ smp_mb__before_atomic(); - atomic_inc(&dev->vblank[crtc].count); + atomic_inc(&vblank->count); smp_mb__after_atomic(); } else { DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", crtc, (int) diff_ns); } - wake_up(&dev->vblank[crtc].queue); + wake_up(&vblank->queue); drm_handle_vblank_events(dev, crtc); spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); -- GitLab From 56cc279b29c7b204fe7d0943509ae209b8b128db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:51 +0300 Subject: [PATCH 0072/9167] drm: Fix deadlock between event_lock and vbl_lock/vblank_time_lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently both drm_irq.c and several drivers call drm_vblank_put() while holding event_lock. Now that drm_vblank_put() can disable the vblank interrupt directly it may need to grab vbl_lock and vblank_time_lock. That causes deadlocks since we take the locks in the opposite order in two places in drm_irq.c. So let's make sure the locking order is always event_lock->vbl_lock->vblank_time_lock. In drm_vblank_off() pull up event_lock from underneath vbl_lock. Hold the event_lock across the whole operation to make sure we only send out the events that were on the queue when we disabled the interrupt, and not ones that got added just after (assuming drm_vblank_on() already managed to get called somewhere between). To sort the other deadlock pull the event_lock out from drm_handle_vblank_events() into drm_handle_vblank() to be taken outside vblank_time_lock. Add the appropriate assert_spin_locked() to drm_handle_vblank_events(). Reviewed-by: Matt Roper Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 47 +++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index b4460bf0e0e4..9353609c6770 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1037,14 +1037,25 @@ void drm_vblank_off(struct drm_device *dev, int crtc) unsigned long irqflags; unsigned int seq; - spin_lock_irqsave(&dev->vbl_lock, irqflags); + spin_lock_irqsave(&dev->event_lock, irqflags); + + spin_lock(&dev->vbl_lock); vblank_disable_and_save(dev, crtc); wake_up(&vblank->queue); + /* + * Prevent subsequent drm_vblank_get() from re-enabling + * the vblank interrupt by bumping the refcount. + */ + if (!vblank->inmodeset) { + atomic_inc(&vblank->refcount); + vblank->inmodeset = 1; + } + spin_unlock(&dev->vbl_lock); + /* Send any queued vblank events, lest the natives grow disquiet */ seq = drm_vblank_count_and_time(dev, crtc, &now); - spin_lock(&dev->event_lock); list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { if (e->pipe != crtc) continue; @@ -1055,18 +1066,7 @@ void drm_vblank_off(struct drm_device *dev, int crtc) drm_vblank_put(dev, e->pipe); send_vblank_event(dev, e, seq, &now); } - spin_unlock(&dev->event_lock); - - /* - * Prevent subsequent drm_vblank_get() from re-enabling - * the vblank interrupt by bumping the refcount. - */ - if (!vblank->inmodeset) { - atomic_inc(&vblank->refcount); - vblank->inmodeset = 1; - } - - spin_unlock_irqrestore(&dev->vbl_lock, irqflags); + spin_unlock_irqrestore(&dev->event_lock, irqflags); } EXPORT_SYMBOL(drm_vblank_off); @@ -1446,12 +1446,11 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc) { struct drm_pending_vblank_event *e, *t; struct timeval now; - unsigned long flags; unsigned int seq; - seq = drm_vblank_count_and_time(dev, crtc, &now); + assert_spin_locked(&dev->event_lock); - spin_lock_irqsave(&dev->event_lock, flags); + seq = drm_vblank_count_and_time(dev, crtc, &now); list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { if (e->pipe != crtc) @@ -1467,8 +1466,6 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc) send_vblank_event(dev, e, seq, &now); } - spin_unlock_irqrestore(&dev->event_lock, flags); - trace_drm_vblank_event(crtc, seq); } @@ -1491,15 +1488,18 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) if (!dev->num_crtcs) return false; + spin_lock_irqsave(&dev->event_lock, irqflags); + /* Need timestamp lock to prevent concurrent execution with * vblank enable/disable, as this would cause inconsistent * or corrupted timestamps and vblank counts. */ - spin_lock_irqsave(&dev->vblank_time_lock, irqflags); + spin_lock(&dev->vblank_time_lock); /* Vblank irq handling disabled. Nothing to do. */ if (!vblank->enabled) { - spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); + spin_unlock(&dev->vblank_time_lock); + spin_unlock_irqrestore(&dev->event_lock, irqflags); return false; } @@ -1539,10 +1539,13 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc) crtc, (int) diff_ns); } + spin_unlock(&dev->vblank_time_lock); + wake_up(&vblank->queue); drm_handle_vblank_events(dev, crtc); - spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); + spin_unlock_irqrestore(&dev->event_lock, irqflags); + return true; } EXPORT_SYMBOL(drm_handle_vblank); -- GitLab From ffe7c73a8d4f0caeebd5d220ddbf7126a4daca1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:52 +0300 Subject: [PATCH 0073/9167] drm: Fix race between drm_vblank_off() and drm_queue_vblank_event() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently it's possible that the following will happen: 1. drm_wait_vblank() calls drm_vblank_get() 2. drm_vblank_off() gets called 3. drm_wait_vblank() calls drm_queue_vblank_event() which adds the event to the queue event though vblank interrupts are currently disabled (and may not be re-enabled ever again). To fix the problem, add another vblank->enabled check into drm_queue_vblank_event(). drm_vblank_off() holds event_lock around the vblank disable, so no further locking needs to be added to drm_queue_vblank_event(). vblank disable from another source is not possible since drm_wait_vblank() already holds a vblank reference. Reviewed-by: Matt Roper Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 9353609c6770..b2428cb0c64d 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1270,6 +1270,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, union drm_wait_vblank *vblwait, struct drm_file *file_priv) { + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; struct drm_pending_vblank_event *e; struct timeval now; unsigned long flags; @@ -1293,6 +1294,18 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, spin_lock_irqsave(&dev->event_lock, flags); + /* + * drm_vblank_off() might have been called after we called + * drm_vblank_get(). drm_vblank_off() holds event_lock + * around the vblank disable, so no need for further locking. + * The reference from drm_vblank_get() protects against + * vblank disable from another source. + */ + if (!vblank->enabled) { + ret = -EINVAL; + goto err_unlock; + } + if (file_priv->event_space < sizeof e->event) { ret = -EBUSY; goto err_unlock; -- GitLab From 4ed0ce3d0bccd74416ba6beb33a8a79d1617e97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:53 +0300 Subject: [PATCH 0074/9167] drm: Disable vblank interrupt immediately when drm_vblank_offdelay<0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make drm_vblank_put() disable the vblank interrupt immediately when the refcount drops to zero and drm_vblank_offdelay<0. v2: Preserve the current drm_vblank_offdelay==0 'never disable' behaviur Reviewed-by: Matt Roper Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 1 + drivers/gpu/drm/drm_drv.c | 4 ++-- drivers/gpu/drm/drm_irq.c | 11 +++++++---- include/drm/drmP.h | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 1d3756d3176c..55923d00bd52 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3386,6 +3386,7 @@ void (*disable_vblank) (struct drm_device *dev, int crtc); by scheduling a timer. The delay is accessible through the vblankoffdelay module parameter or the drm_vblank_offdelay global variable and expressed in milliseconds. Its default value is 5000 ms. + Zero means never disable, and a negative value means disable immediately. When a vertical blanking interrupt occurs drivers only need to call the diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 92bc6b1d9646..db03e16ca817 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -39,7 +39,7 @@ unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); -unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ +int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ @@ -53,7 +53,7 @@ MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); MODULE_PARM_DESC(debug, "Enable debug output"); -MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); +MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs] (0: never disable, <0: disable immediately)"); MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); MODULE_PARM_DESC(timestamp_monotonic, "Use monotonic timestamps"); diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index b2428cb0c64d..99145c4d536b 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -993,10 +993,13 @@ void drm_vblank_put(struct drm_device *dev, int crtc) BUG_ON(atomic_read(&vblank->refcount) == 0); /* Last user schedules interrupt disable */ - if (atomic_dec_and_test(&vblank->refcount) && - (drm_vblank_offdelay > 0)) - mod_timer(&vblank->disable_timer, - jiffies + ((drm_vblank_offdelay * HZ)/1000)); + if (atomic_dec_and_test(&vblank->refcount)) { + if (drm_vblank_offdelay < 0) + vblank_disable_fn((unsigned long)vblank); + else if (drm_vblank_offdelay > 0) + mod_timer(&vblank->disable_timer, + jiffies + ((drm_vblank_offdelay * HZ)/1000)); + } } EXPORT_SYMBOL(drm_vblank_put); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index a57646382086..24b32d453c60 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1345,7 +1345,7 @@ extern void drm_put_dev(struct drm_device *dev); extern void drm_unplug_dev(struct drm_device *dev); extern unsigned int drm_debug; -extern unsigned int drm_vblank_offdelay; +extern int drm_vblank_offdelay; extern unsigned int drm_timestamp_precision; extern unsigned int drm_timestamp_monotonic; -- GitLab From 00185e667009dda907887a4f84fbd02c6e651a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:54 +0300 Subject: [PATCH 0075/9167] drm: Add dev->vblank_disable_immediate flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a flag to drm_device which will cause the vblank code to bypass the disable timer and always disable the vblank interrupt immediately when the last reference is dropped. v2: Add some notes about the flag to the kernel doc Reviewed-by: Matt Roper Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 6 ++++++ drivers/gpu/drm/drm_irq.c | 2 +- include/drm/drmP.h | 10 ++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 55923d00bd52..583edbffff1a 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3387,6 +3387,12 @@ void (*disable_vblank) (struct drm_device *dev, int crtc); module parameter or the drm_vblank_offdelay global variable and expressed in milliseconds. Its default value is 5000 ms. Zero means never disable, and a negative value means disable immediately. + Drivers may override the behaviour by setting the + drm_device + vblank_disable_immediate flag, which when set + causes vblank interrupts to be disabled immediately regardless of the + drm_vblank_offdelay value. The flag should only be set if there's a + properly working hardware vblank counter present. When a vertical blanking interrupt occurs drivers only need to call the diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 99145c4d536b..8dbcc3f892d5 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -994,7 +994,7 @@ void drm_vblank_put(struct drm_device *dev, int crtc) /* Last user schedules interrupt disable */ if (atomic_dec_and_test(&vblank->refcount)) { - if (drm_vblank_offdelay < 0) + if (dev->vblank_disable_immediate || drm_vblank_offdelay < 0) vblank_disable_fn((unsigned long)vblank); else if (drm_vblank_offdelay > 0) mod_timer(&vblank->disable_timer, diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 24b32d453c60..17a5c10474bd 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1074,6 +1074,16 @@ struct drm_device { */ bool vblank_disable_allowed; + /* + * If true, vblank interrupt will be disabled immediately when the + * refcount drops to zero, as opposed to via the vblank disable + * timer. + * This can be set to true it the hardware has a working vblank + * counter and the driver uses drm_vblank_on() and drm_vblank_off() + * appropriately. + */ + bool vblank_disable_immediate; + /* array of size num_crtcs */ struct drm_vblank_crtc *vblank; -- GitLab From 21da27005f79d72499bb809616b15fd2c5c15319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:55 +0300 Subject: [PATCH 0076/9167] drm/i915: Opt out of vblank disable timer on >gen2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that the vblank races are plugged, we can opt out of using the vblank disable timer and just let vblank interrupts get disabled immediately when the last reference is dropped. Gen2 is the exception since it has no hardware frame counter. Reviewed-by: Matt Roper Reviewed-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 6ef9d6fabf80..845f0f6c1eeb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -4680,6 +4680,14 @@ void intel_irq_init(struct drm_device *dev) dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ } + /* + * Opt out of the vblank disable timer on everything except gen2. + * Gen2 doesn't have a hardware frame counter and so depends on + * vblank interrupts to produce sane vblank seuquence numbers. + */ + if (!IS_GEN2(dev)) + dev->vblank_disable_immediate = true; + if (drm_core_check_feature(dev, DRIVER_MODESET)) { dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; -- GitLab From cd19e52aee922ffe5c50b6ed67acd58cc1b2738b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:56 +0300 Subject: [PATCH 0077/9167] drm: Kick start vblank interrupts at drm_vblank_on() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the user is interested in getting accurate vblank sequence numbers all the time they may disable the vblank disable timer entirely. In that case it seems appropriate to kick start the vblank interrupts already from drm_vblank_on(). v2: Adapt to the drm_vblank_offdelay ==0 vs <0 changes Reviewed-by: Matt Roper Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 8dbcc3f892d5..af33df1adc6d 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1126,9 +1126,12 @@ void drm_vblank_on(struct drm_device *dev, int crtc) vblank->last = (dev->driver->get_vblank_counter(dev, crtc) - 1) & dev->max_vblank_count; - - /* re-enable interrupts if there's are users left */ - if (atomic_read(&vblank->refcount) != 0) + /* + * re-enable interrupts if there are users left, or the + * user wishes vblank interrupts to be enabled all the time. + */ + if (atomic_read(&vblank->refcount) != 0 || + (!dev->vblank_disable_immediate && drm_vblank_offdelay == 0)) WARN_ON(drm_vblank_enable(dev, crtc)); spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } -- GitLab From d297e1037327884fe9545f434d720fd3e8f18c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:50:01 +0300 Subject: [PATCH 0078/9167] drm/i915: Update scanline_offset only for active crtcs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update_scanline_offset() in intel_sanitize_crtc() was supposed to be called only for active crtcs. But due to some underrun patches it now gets updated for all crtcs on gmch platforms. Move the update_scanline_offset() to the very beginning of intel_sanitize_crtc() where we update the vblank state. This seems like a better place anyway since the scanline offset ought to be up to date before we might need to consult it. So before any vblanky stuff happens. Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8f6b932d8e79..de40a44e0ca0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12719,9 +12719,10 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); /* restore vblank interrupts to correct state */ - if (crtc->active) + if (crtc->active) { + update_scanline_offset(crtc); drm_vblank_on(dev, crtc->pipe); - else + } else drm_vblank_off(dev, crtc->pipe); /* We need to sanitize the plane -> pipe mapping first because this will @@ -12820,8 +12821,6 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) */ crtc->cpu_fifo_underrun_disabled = true; crtc->pch_fifo_underrun_disabled = true; - - update_scanline_offset(crtc); } } -- GitLab From 96a9fdd778037799f63c9ae272ec915dd3ad83dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:50:02 +0300 Subject: [PATCH 0079/9167] drm: Fix confusing debug message in drm_update_vblank_count() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that drm_update_vblank_count() can be called even when we're not about to enable the vblank interrupts we shouldn't print debug messages stating otherwise. Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index af33df1adc6d..62dee812d28a 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -103,7 +103,7 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) crtc, vblank->last, cur_vblank, diff); } - DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", + DRM_DEBUG("updating vblank count on crtc %d, missed %d\n", crtc, diff); /* Reinitialize corresponding vblank timestamp if high-precision query -- GitLab From c50d7521617d823d769b280bc499e19e364434ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:49:59 +0300 Subject: [PATCH 0080/9167] drm: Store the vblank timestamp when adjusting the counter during disable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During vblank disable the code tries to guess based on the timestamps whether we just missed one vblank or not. And if so it increments the counter. However it forgets to store the new timestamp to the approriate slot in our timestamp ring buffer. So anyone querying the timestamp for the resulting sequence number would get a stale timestamp. Fix it up by storing the new timestamp. Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 62dee812d28a..aa9b06495067 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -198,6 +198,13 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) * hope for the best. */ if ((vblrc > 0) && (abs64(diff_ns) > 1000000)) { + /* Store new timestamp in ringbuffer. */ + vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; + + /* Increment cooked vblank count. This also atomically commits + * the timestamp computed above. + */ + smp_mb__before_atomic(); atomic_inc(&vblank->count); smp_mb__after_atomic(); } -- GitLab From 79a093aea44f11fda0a5b4dbe4c1e29b2f586f4e Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Wed, 6 Aug 2014 03:22:44 +0200 Subject: [PATCH 0081/9167] drm: Remove drm_vblank_cleanup from drm_vblank_init error path. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drm_vblank_cleanup() would operate on non-existent dev->vblank data structure, as failure to allocate that data structure is what triggers the error path in the first place. Signed-off-by: Mario Kleiner Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index aa9b06495067..6473089e5fd3 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -303,7 +303,7 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) return 0; err: - drm_vblank_cleanup(dev); + dev->num_crtcs = 0; return ret; } EXPORT_SYMBOL(drm_vblank_init); -- GitLab From 2f29c16889ae71b42aefbe235867d88f8c892548 Mon Sep 17 00:00:00 2001 From: Murilo Opsfelder Araujo Date: Tue, 8 Jul 2014 01:22:00 +0100 Subject: [PATCH 0082/9167] staging: iio: accel: sca3000_core.c: Adjust code to fit 80-chars limit Signed-off-by: Murilo Opsfelder Araujo Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/sca3000_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index ed30e32e60de..1ce037af7f2a 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -506,7 +506,8 @@ static int sca3000_read_raw(struct iio_dev *indio_dev, mutex_unlock(&st->lock); return ret; } - *val = ((st->rx[0] & 0x3F) << 3) | ((st->rx[1] & 0xE0) >> 5); + *val = ((st->rx[0] & 0x3F) << 3) | + ((st->rx[1] & 0xE0) >> 5); } mutex_unlock(&st->lock); return IIO_VAL_INT; -- GitLab From d7b79519faa926a9d6d1cdebfddea7a58a9951f3 Mon Sep 17 00:00:00 2001 From: Murilo Opsfelder Araujo Date: Tue, 8 Jul 2014 01:22:00 +0100 Subject: [PATCH 0083/9167] staging: iio: accel: Add blank lines between declarations and code This patch adds missing blank lines between declarations and code and fixes lines starting by spaces, satisfying checkpatch.pl. Signed-off-by: Murilo Opsfelder Araujo Signed-off-by: Jonathan Cameron --- drivers/staging/iio/accel/adis16201_core.c | 5 +++-- drivers/staging/iio/accel/adis16203_core.c | 2 ++ drivers/staging/iio/accel/adis16204_core.c | 1 + drivers/staging/iio/accel/adis16209_core.c | 1 + drivers/staging/iio/accel/adis16240_core.c | 1 + drivers/staging/iio/accel/lis3l02dq_core.c | 4 ++++ drivers/staging/iio/accel/lis3l02dq_ring.c | 1 + drivers/staging/iio/accel/sca3000_core.c | 1 + 8 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 50ba1fa7f98a..7eae5fd0f393 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -111,6 +111,7 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, int bits; s16 val16; u8 addr; + switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: switch (chan->type) { @@ -131,8 +132,8 @@ static int adis16201_write_raw(struct iio_dev *indio_dev, } static const struct iio_chan_spec adis16201_channels[] = { - ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 0, 12), - ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 0, 12), + ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT, ADIS16201_SCAN_SUPPLY, 0, 12), + ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT, ADIS16201_SCAN_TEMP, 0, 12), ADIS_ACCEL_CHAN(X, ADIS16201_XACCL_OUT, ADIS16201_SCAN_ACC_X, BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14), ADIS_ACCEL_CHAN(Y, ADIS16201_YACCL_OUT, ADIS16201_SCAN_ACC_Y, diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index f472137b0069..fbbe93f26bbe 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -37,6 +37,7 @@ static int adis16203_write_raw(struct iio_dev *indio_dev, struct adis *st = iio_priv(indio_dev); /* currently only one writable parameter which keeps this simple */ u8 addr = adis16203_addresses[chan->scan_index]; + return adis_write_reg_16(st, addr, val & 0x3FFF); } @@ -50,6 +51,7 @@ static int adis16203_read_raw(struct iio_dev *indio_dev, int bits; u8 addr; s16 val16; + switch (mask) { case IIO_CHAN_INFO_RAW: return adis_single_conversion(indio_dev, chan, diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 19eaebc77d7a..4c8acbc2e44e 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -119,6 +119,7 @@ static int adis16204_write_raw(struct iio_dev *indio_dev, int bits; s16 val16; u8 addr; + switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: switch (chan->type) { diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index 374dc6edbcf5..b2c7aeda75f0 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -44,6 +44,7 @@ static int adis16209_write_raw(struct iio_dev *indio_dev, int bits; s16 val16; u8 addr; + switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: switch (chan->type) { diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index 74ace2a8769d..205d6d0a2206 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -163,6 +163,7 @@ static int adis16240_write_raw(struct iio_dev *indio_dev, int bits = 10; s16 val16; u8 addr; + switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: val16 = val & ((1 << bits) - 1); diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index 898653c09279..f5e145caffa9 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -212,6 +212,7 @@ static int lis3l02dq_write_thresh(struct iio_dev *indio_dev, int val, int val2) { u16 value = val; + return lis3l02dq_spi_write_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, value); @@ -226,6 +227,7 @@ static int lis3l02dq_write_raw(struct iio_dev *indio_dev, int ret = -EINVAL, reg; u8 uval; s8 sval; + switch (mask) { case IIO_CHAN_INFO_CALIBBIAS: if (val > 255 || val < -256) @@ -302,6 +304,7 @@ static ssize_t lis3l02dq_read_frequency(struct device *dev, struct iio_dev *indio_dev = dev_to_iio_dev(dev); int ret, len = 0; s8 t; + ret = lis3l02dq_spi_read_reg_8(indio_dev, LIS3L02DQ_REG_CTRL_1_ADDR, (u8 *)&t); @@ -565,6 +568,7 @@ static int lis3l02dq_read_event_config(struct iio_dev *indio_dev, u8 val; int ret; u8 mask = (1 << (chan->channel2*2 + (dir == IIO_EV_DIR_RISING))); + ret = lis3l02dq_spi_read_reg_8(indio_dev, LIS3L02DQ_REG_WAKE_UP_CFG_ADDR, &val); diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index bf33fdead479..1d934ee3bb5f 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -19,6 +19,7 @@ static inline u16 combine_8_to_16(u8 lower, u8 upper) { u16 _lower = lower; u16 _upper = upper; + return _lower | (_upper << 8); } diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 1ce037af7f2a..e4e56391487a 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -714,6 +714,7 @@ static int sca3000_read_thresh(struct iio_dev *indio_dev, int ret, i; struct sca3000_state *st = iio_priv(indio_dev); int num = chan->channel2; + mutex_lock(&st->lock); ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]); mutex_unlock(&st->lock); -- GitLab From 889c558095e96312d81b4084567c11a52b285393 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 8 Jun 2014 21:12:00 +0100 Subject: [PATCH 0084/9167] iio: fix error return code Convert a zero return value on error to a negative one, as returned elsewhere in the function. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // ( if@p1 (\(ret < 0\|ret != 0\)) { ... return ret; } | ret@p1 = 0 ) ... when != ret = e1 when != &ret *if(...) { ... when != ret = e2 when forall return ret; } // Signed-off-by: Julia Lawall Signed-off-by: Jonathan Cameron --- drivers/iio/adc/xilinx-xadc-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index fd2745c62943..196e269e48d1 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -1201,12 +1201,16 @@ static int xadc_probe(struct platform_device *pdev) goto err_device_free; xadc->convst_trigger = xadc_alloc_trigger(indio_dev, "convst"); - if (IS_ERR(xadc->convst_trigger)) + if (IS_ERR(xadc->convst_trigger)) { + ret = PTR_ERR(xadc->convst_trigger); goto err_triggered_buffer_cleanup; + } xadc->samplerate_trigger = xadc_alloc_trigger(indio_dev, "samplerate"); - if (IS_ERR(xadc->samplerate_trigger)) + if (IS_ERR(xadc->samplerate_trigger)) { + ret = PTR_ERR(xadc->samplerate_trigger); goto err_free_convst_trigger; + } } xadc->clk = devm_clk_get(&pdev->dev, NULL); -- GitLab From ce9d475607e7bf48b066603700afdb4811cec9b6 Mon Sep 17 00:00:00 2001 From: Oussama Jabbari Date: Sun, 8 Jun 2014 18:06:00 +0100 Subject: [PATCH 0085/9167] staging: iio: adis16060: Fix coding style problem This patch fixes a warning from checkpatch.pl script : "WARNING: Missing a blank line after declarations" Signed-off-by: Oussama Jabbari Signed-off-by: Jonathan Cameron --- drivers/staging/iio/gyro/adis16060_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index d5d395c2e3e4..4c5869dd8223 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -180,6 +180,7 @@ static int adis16060_w_probe(struct spi_device *spi) int ret; struct iio_dev *indio_dev = adis16060_iio_dev; struct adis16060_state *st; + if (!indio_dev) { ret = -ENODEV; goto error_ret; -- GitLab From 124e1b1d0924ca51ded8bb6f52844b2bc9e485f7 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 8 May 2014 22:58:00 +0100 Subject: [PATCH 0086/9167] iio: accel: kxcjk-1013: support runtime pm In an effort to improve raw read performance and at the same time enter low power state at every possible chance. For raw reads, it will keep the system powered on for a default or user specified time, via autosuspend_delay attribute of device power. This will help read multiple samples without power on/off sequence. For triggers it will keep the system on till, requested to be turned off by trigger state by utilizing run time PM usage counters. When runtime pm is not enabled, then it keeps the chip in operation mode always. Signed-off-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxcjk-1013.c | 206 +++++++++++++++++++++++++-------- 1 file changed, 156 insertions(+), 50 deletions(-) diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index 7941cf2d31ee..b32bdd10e0c4 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -71,15 +73,17 @@ #define KXCJK1013_DATA_MASK_12_BIT 0x0FFF #define KXCJK1013_MAX_STARTUP_TIME_US 100000 +#define KXCJK1013_SLEEP_DELAY_MS 2000 + struct kxcjk1013_data { struct i2c_client *client; struct iio_trigger *trig; bool trig_mode; struct mutex mutex; s16 buffer[8]; - int power_state; u8 odr_bits; bool active_high_intr; + bool trigger_on; }; enum kxcjk1013_axis { @@ -138,6 +142,25 @@ static int kxcjk1013_set_mode(struct kxcjk1013_data *data, return 0; } +static int kxcjk1013_get_mode(struct kxcjk1013_data *data, + enum kxcjk1013_mode *mode) +{ + int ret; + + ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); + return ret; + } + + if (ret & KXCJK1013_REG_CTRL1_BIT_PC1) + *mode = OPERATION; + else + *mode = STANDBY; + + return 0; +} + static int kxcjk1013_chip_init(struct kxcjk1013_data *data) { int ret; @@ -201,6 +224,41 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) return ret; } + ret = kxcjk1013_set_mode(data, OPERATION); + if (ret < 0) + return ret; + + return 0; +} + +static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(odr_start_up_times); ++i) { + if (odr_start_up_times[i].odr_bits == data->odr_bits) + return odr_start_up_times[i].usec; + } + + return KXCJK1013_MAX_STARTUP_TIME_US; +} + +static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on) +{ + int ret; + + if (on) + ret = pm_runtime_get_sync(&data->client->dev); + else { + pm_runtime_mark_last_busy(&data->client->dev); + ret = pm_runtime_put_autosuspend(&data->client->dev); + } + if (ret < 0) { + dev_err(&data->client->dev, + "Failed: kxcjk1013_set_power_state for %d\n", on); + return ret; + } + return 0; } @@ -208,6 +266,11 @@ static int kxcjk1013_chip_setup_interrupt(struct kxcjk1013_data *data, bool status) { int ret; + enum kxcjk1013_mode store_mode; + + ret = kxcjk1013_get_mode(data, &store_mode); + if (ret < 0) + return ret; /* This is requirement by spec to change state to STANDBY */ ret = kxcjk1013_set_mode(data, STANDBY); @@ -250,7 +313,13 @@ static int kxcjk1013_chip_setup_interrupt(struct kxcjk1013_data *data, return ret; } - return ret; + if (store_mode == OPERATION) { + ret = kxcjk1013_set_mode(data, OPERATION); + if (ret < 0) + return ret; + } + + return 0; } static int kxcjk1013_convert_freq_to_bit(int val, int val2) @@ -271,6 +340,11 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) { int ret; int odr_bits; + enum kxcjk1013_mode store_mode; + + ret = kxcjk1013_get_mode(data, &store_mode); + if (ret < 0) + return ret; odr_bits = kxcjk1013_convert_freq_to_bit(val, val2); if (odr_bits < 0) @@ -290,9 +364,7 @@ static int kxcjk1013_set_odr(struct kxcjk1013_data *data, int val, int val2) data->odr_bits = odr_bits; - /* Check, if the ODR is changed after data enable */ - if (data->power_state) { - /* Set the state back to operation */ + if (store_mode == OPERATION) { ret = kxcjk1013_set_mode(data, OPERATION); if (ret < 0) return ret; @@ -331,18 +403,6 @@ static int kxcjk1013_get_acc_reg(struct kxcjk1013_data *data, int axis) return ret; } -static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(odr_start_up_times); ++i) { - if (odr_start_up_times[i].odr_bits == data->odr_bits) - return odr_start_up_times[i].usec; - } - - return KXCJK1013_MAX_STARTUP_TIME_US; -} - static int kxcjk1013_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -356,29 +416,25 @@ static int kxcjk1013_read_raw(struct iio_dev *indio_dev, if (iio_buffer_enabled(indio_dev)) ret = -EBUSY; else { - int sleep_val; - - ret = kxcjk1013_set_mode(data, OPERATION); + ret = kxcjk1013_set_power_state(data, true); if (ret < 0) { mutex_unlock(&data->mutex); return ret; } - ++data->power_state; - sleep_val = kxcjk1013_get_startup_times(data); - if (sleep_val < 20000) - usleep_range(sleep_val, 20000); - else - msleep_interruptible(sleep_val/1000); ret = kxcjk1013_get_acc_reg(data, chan->scan_index); - if (--data->power_state == 0) - kxcjk1013_set_mode(data, STANDBY); + if (ret < 0) { + kxcjk1013_set_power_state(data, false); + mutex_unlock(&data->mutex); + return ret; + } + *val = sign_extend32(ret >> 4, 11); + ret = kxcjk1013_set_power_state(data, false); } mutex_unlock(&data->mutex); if (ret < 0) return ret; - *val = sign_extend32(ret >> 4, 11); return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: @@ -520,20 +576,21 @@ static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig, { struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); struct kxcjk1013_data *data = iio_priv(indio_dev); + int ret; + + if (state && data->trigger_on) + return 0; mutex_lock(&data->mutex); - if (state) { - kxcjk1013_chip_setup_interrupt(data, true); - kxcjk1013_set_mode(data, OPERATION); - ++data->power_state; - } else { - if (--data->power_state) { + ret = kxcjk1013_chip_setup_interrupt(data, state); + if (!ret) { + ret = kxcjk1013_set_power_state(data, state); + if (ret < 0) { mutex_unlock(&data->mutex); - return 0; + return ret; } - kxcjk1013_chip_setup_interrupt(data, false); - kxcjk1013_set_mode(data, STANDBY); } + data->trigger_on = state; mutex_unlock(&data->mutex); return 0; @@ -661,14 +718,25 @@ static int kxcjk1013_probe(struct i2c_client *client, } } - ret = devm_iio_device_register(&client->dev, indio_dev); + ret = iio_device_register(indio_dev); if (ret < 0) { dev_err(&client->dev, "unable to register iio device\n"); goto err_buffer_cleanup; } + ret = pm_runtime_set_active(&client->dev); + if (ret) + goto err_iio_unregister; + + pm_runtime_enable(&client->dev); + pm_runtime_set_autosuspend_delay(&client->dev, + KXCJK1013_SLEEP_DELAY_MS); + pm_runtime_use_autosuspend(&client->dev); + return 0; +err_iio_unregister: + iio_device_unregister(indio_dev); err_buffer_cleanup: if (data->trig_mode) iio_triggered_buffer_cleanup(indio_dev); @@ -687,6 +755,12 @@ static int kxcjk1013_remove(struct i2c_client *client) struct iio_dev *indio_dev = i2c_get_clientdata(client); struct kxcjk1013_data *data = iio_priv(indio_dev); + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + pm_runtime_put_noidle(&client->dev); + + iio_device_unregister(indio_dev); + if (data->trig_mode) { iio_triggered_buffer_cleanup(indio_dev); iio_trigger_unregister(data->trig); @@ -705,35 +779,67 @@ static int kxcjk1013_suspend(struct device *dev) { struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); struct kxcjk1013_data *data = iio_priv(indio_dev); + int ret; mutex_lock(&data->mutex); - kxcjk1013_set_mode(data, STANDBY); + ret = kxcjk1013_set_mode(data, STANDBY); mutex_unlock(&data->mutex); - return 0; + return ret; } static int kxcjk1013_resume(struct device *dev) { struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); struct kxcjk1013_data *data = iio_priv(indio_dev); + int ret = 0; mutex_lock(&data->mutex); + /* Check, if the suspend occured while active */ + if (data->trigger_on) + ret = kxcjk1013_set_mode(data, OPERATION); + mutex_unlock(&data->mutex); - if (data->power_state) - kxcjk1013_set_mode(data, OPERATION); + return ret; +} +#endif - mutex_unlock(&data->mutex); +#ifdef CONFIG_PM_RUNTIME +static int kxcjk1013_runtime_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct kxcjk1013_data *data = iio_priv(indio_dev); - return 0; + return kxcjk1013_set_mode(data, STANDBY); } -static SIMPLE_DEV_PM_OPS(kxcjk1013_pm_ops, kxcjk1013_suspend, kxcjk1013_resume); -#define KXCJK1013_PM_OPS (&kxcjk1013_pm_ops) -#else -#define KXCJK1013_PM_OPS NULL +static int kxcjk1013_runtime_resume(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct kxcjk1013_data *data = iio_priv(indio_dev); + int ret; + int sleep_val; + + ret = kxcjk1013_set_mode(data, OPERATION); + if (ret < 0) + return ret; + + sleep_val = kxcjk1013_get_startup_times(data); + if (sleep_val < 20000) + usleep_range(sleep_val, 20000); + else + msleep_interruptible(sleep_val/1000); + + return 0; +} #endif +static const struct dev_pm_ops kxcjk1013_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(kxcjk1013_suspend, kxcjk1013_resume) + SET_RUNTIME_PM_OPS(kxcjk1013_runtime_suspend, + kxcjk1013_runtime_resume, NULL) +}; + static const struct acpi_device_id kx_acpi_match[] = { {"KXCJ1013", 0}, { }, @@ -751,7 +857,7 @@ static struct i2c_driver kxcjk1013_driver = { .driver = { .name = KXCJK1013_DRV_NAME, .acpi_match_table = ACPI_PTR(kx_acpi_match), - .pm = KXCJK1013_PM_OPS, + .pm = &kxcjk1013_pm_ops, }, .probe = kxcjk1013_probe, .remove = kxcjk1013_remove, -- GitLab From a735e3d7f03ab40d746290954baaf535719d9025 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 8 May 2014 22:58:00 +0100 Subject: [PATCH 0087/9167] iio: accel: kxcjk-1013: Set adjustable range This chip can support 3 different ranges. Allowing range specification. Signed-off-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/kxcjk-1013.c | 100 +++++++++++++++++++++++++++++++-- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c index b32bdd10e0c4..57c515bf0fd2 100644 --- a/drivers/iio/accel/kxcjk-1013.c +++ b/drivers/iio/accel/kxcjk-1013.c @@ -82,6 +82,7 @@ struct kxcjk1013_data { struct mutex mutex; s16 buffer[8]; u8 odr_bits; + u8 range; bool active_high_intr; bool trigger_on; }; @@ -97,6 +98,12 @@ enum kxcjk1013_mode { OPERATION, }; +enum kxcjk1013_range { + KXCJK1013_RANGE_2G, + KXCJK1013_RANGE_4G, + KXCJK1013_RANGE_8G, +}; + static const struct { int val; int val2; @@ -116,6 +123,14 @@ static const struct { {0x02, 21000}, {0x03, 11000}, {0x04, 6400}, {0x05, 3900}, {0x06, 2700}, {0x07, 2100} }; +static const struct { + u16 scale; + u8 gsel_0; + u8 gsel_1; +} KXCJK1013_scale_table[] = { {9582, 0, 0}, + {19163, 1, 0}, + {38326, 0, 1} }; + static int kxcjk1013_set_mode(struct kxcjk1013_data *data, enum kxcjk1013_mode mode) { @@ -161,6 +176,32 @@ static int kxcjk1013_get_mode(struct kxcjk1013_data *data, return 0; } +static int kxcjk1013_set_range(struct kxcjk1013_data *data, int range_index) +{ + int ret; + + ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_CTRL1); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_ctrl1\n"); + return ret; + } + + ret |= (KXCJK1013_scale_table[range_index].gsel_0 << 3); + ret |= (KXCJK1013_scale_table[range_index].gsel_1 << 4); + + ret = i2c_smbus_write_byte_data(data->client, + KXCJK1013_REG_CTRL1, + ret); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_ctrl1\n"); + return ret; + } + + data->range = range_index; + + return 0; +} + static int kxcjk1013_chip_init(struct kxcjk1013_data *data) { int ret; @@ -183,10 +224,6 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) return ret; } - /* Setting range to 4G */ - ret |= KXCJK1013_REG_CTRL1_BIT_GSEL0; - ret &= ~KXCJK1013_REG_CTRL1_BIT_GSEL1; - /* Set 12 bit mode */ ret |= KXCJK1013_REG_CTRL1_BIT_RES; @@ -197,6 +234,14 @@ static int kxcjk1013_chip_init(struct kxcjk1013_data *data) return ret; } + /* Setting range to 4G */ + ret = kxcjk1013_set_range(data, KXCJK1013_RANGE_4G); + if (ret < 0) + return ret; + + data->range = KXCJK1013_RANGE_4G; + + ret = i2c_smbus_read_byte_data(data->client, KXCJK1013_REG_DATA_CTRL); if (ret < 0) { dev_err(&data->client->dev, "Error reading reg_data_ctrl\n"); @@ -403,6 +448,40 @@ static int kxcjk1013_get_acc_reg(struct kxcjk1013_data *data, int axis) return ret; } +static int kxcjk1013_set_scale(struct kxcjk1013_data *data, int val) +{ + int ret, i; + enum kxcjk1013_mode store_mode; + + + for (i = 0; i < ARRAY_SIZE(KXCJK1013_scale_table); ++i) { + if (KXCJK1013_scale_table[i].scale == val) { + + ret = kxcjk1013_get_mode(data, &store_mode); + if (ret < 0) + return ret; + + ret = kxcjk1013_set_mode(data, STANDBY); + if (ret < 0) + return ret; + + ret = kxcjk1013_set_range(data, i); + if (ret < 0) + return ret; + + if (store_mode == OPERATION) { + ret = kxcjk1013_set_mode(data, OPERATION); + if (ret) + return ret; + } + + return 0; + } + } + + return -EINVAL; +} + static int kxcjk1013_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -439,7 +518,7 @@ static int kxcjk1013_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: *val = 0; - *val2 = 19163; /* range +-4g (4/2047*9.806650) */ + *val2 = KXCJK1013_scale_table[data->range].scale; return IIO_VAL_INT_PLUS_MICRO; case IIO_CHAN_INFO_SAMP_FREQ: @@ -466,6 +545,14 @@ static int kxcjk1013_write_raw(struct iio_dev *indio_dev, ret = kxcjk1013_set_odr(data, val, val2); mutex_unlock(&data->mutex); break; + case IIO_CHAN_INFO_SCALE: + if (val) + return -EINVAL; + + mutex_lock(&data->mutex); + ret = kxcjk1013_set_scale(data, val2); + mutex_unlock(&data->mutex); + break; default: ret = -EINVAL; } @@ -487,8 +574,11 @@ static int kxcjk1013_validate_trigger(struct iio_dev *indio_dev, static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( "0.781000 1.563000 3.125000 6.250000 12.500000 25 50 100 200 400 800 1600"); +static IIO_CONST_ATTR(in_accel_scale_available, "0.009582 0.019163 0.038326"); + static struct attribute *kxcjk1013_attributes[] = { &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_const_attr_in_accel_scale_available.dev_attr.attr, NULL, }; -- GitLab From bd7fe5b7191836a229981fdd83845a528ee9f846 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 8 May 2014 22:57:00 +0100 Subject: [PATCH 0088/9167] iio: accel: BMC150 accel support This change implements BMC150 accelerometer driver. A BMC150 package consist of a compass and an accelerometer. This driver only implements accelerometer part. Spec downloaded from: http://ae-bst.resource.bosch.com/media/products/dokumente/bmc150/BST-BMC150-DS000-03.pdf This sensor chip supports many advanced features, but this driver implements minimum feature set which is a must to be useful. This driver can be enhanced incrementally. If the sensor vendor wants to update full featured version, they can substitute or enhance this driver when they get chance. Signed-off-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/iio/accel/Kconfig | 13 + drivers/iio/accel/Makefile | 1 + drivers/iio/accel/bmc150-accel.c | 1307 ++++++++++++++++++++++++++++++ 3 files changed, 1321 insertions(+) create mode 100644 drivers/iio/accel/bmc150-accel.c diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 12addf272a61..5704d6bc2267 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -17,6 +17,19 @@ config BMA180 To compile this driver as a module, choose M here: the module will be called bma180. +config BMC150_ACCEL + tristate "Bosch BMC150 Accelerometer Driver" + depends on I2C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for the Bosch BMC150 accelerometer. + Currently this only supports the device via an i2c interface. + + This is a combo module with both accelerometer and magnetometer. + This driver is only implementing accelerometer part, which has + its own address and register map. + config HID_SENSOR_ACCEL_3D depends on HID_SENSOR_HUB select IIO_BUFFER diff --git a/drivers/iio/accel/Makefile b/drivers/iio/accel/Makefile index 6578ca1a8e09..a593996c6539 100644 --- a/drivers/iio/accel/Makefile +++ b/drivers/iio/accel/Makefile @@ -4,6 +4,7 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_BMA180) += bma180.o +obj-$(CONFIG_BMC150_ACCEL) += bmc150-accel.o obj-$(CONFIG_HID_SENSOR_ACCEL_3D) += hid-sensor-accel-3d.o obj-$(CONFIG_KXCJK1013) += kxcjk-1013.o obj-$(CONFIG_KXSD9) += kxsd9.o diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c new file mode 100644 index 000000000000..23ae33496214 --- /dev/null +++ b/drivers/iio/accel/bmc150-accel.c @@ -0,0 +1,1307 @@ +/* + * BMC150 3-axis accelerometer driver + * Copyright (c) 2014, 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BMC150_ACCEL_DRV_NAME "bmc150_accel" +#define BMC150_ACCEL_IRQ_NAME "bmc150_accel_event" +#define BMC150_ACCEL_GPIO_NAME "bmc150_accel_int" + +#define BMC150_ACCEL_REG_CHIP_ID 0x00 +#define BMC150_ACCEL_CHIP_ID_VAL 0xFA + +#define BMC150_ACCEL_REG_INT_STATUS_2 0x0B +#define BMC150_ACCEL_ANY_MOTION_MASK 0x07 +#define BMC150_ACCEL_ANY_MOTION_BIT_SIGN BIT(3) + +#define BMC150_ACCEL_REG_PMU_LPW 0x11 +#define BMC150_ACCEL_PMU_MODE_MASK 0xE0 +#define BMC150_ACCEL_PMU_MODE_SHIFT 5 +#define BMC150_ACCEL_PMU_BIT_SLEEP_DUR_MASK 0x17 +#define BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT 1 + +#define BMC150_ACCEL_REG_PMU_RANGE 0x0F + +#define BMC150_ACCEL_DEF_RANGE_2G 0x03 +#define BMC150_ACCEL_DEF_RANGE_4G 0x05 +#define BMC150_ACCEL_DEF_RANGE_8G 0x08 +#define BMC150_ACCEL_DEF_RANGE_16G 0x0C + +/* Default BW: 125Hz */ +#define BMC150_ACCEL_REG_PMU_BW 0x10 +#define BMC150_ACCEL_DEF_BW 125 + +#define BMC150_ACCEL_REG_INT_MAP_0 0x19 +#define BMC150_ACCEL_INT_MAP_0_BIT_SLOPE BIT(2) + +#define BMC150_ACCEL_REG_INT_MAP_1 0x1A +#define BMC150_ACCEL_INT_MAP_1_BIT_DATA BIT(0) + +#define BMC150_ACCEL_REG_INT_RST_LATCH 0x21 +#define BMC150_ACCEL_INT_MODE_LATCH_RESET 0x80 +#define BMC150_ACCEL_INT_MODE_LATCH_INT 0x0F +#define BMC150_ACCEL_INT_MODE_NON_LATCH_INT 0x00 + +#define BMC150_ACCEL_REG_INT_EN_0 0x16 +#define BMC150_ACCEL_INT_EN_BIT_SLP_X BIT(0) +#define BMC150_ACCEL_INT_EN_BIT_SLP_Y BIT(1) +#define BMC150_ACCEL_INT_EN_BIT_SLP_Z BIT(2) + +#define BMC150_ACCEL_REG_INT_EN_1 0x17 +#define BMC150_ACCEL_INT_EN_BIT_DATA_EN BIT(4) + +#define BMC150_ACCEL_REG_INT_OUT_CTRL 0x20 +#define BMC150_ACCEL_INT_OUT_CTRL_INT1_LVL BIT(0) + +#define BMC150_ACCEL_REG_INT_5 0x27 +#define BMC150_ACCEL_SLOPE_DUR_MASK 0x03 + +#define BMC150_ACCEL_REG_INT_6 0x28 +#define BMC150_ACCEL_SLOPE_THRES_MASK 0xFF + +/* Slope duration in terms of number of samples */ +#define BMC150_ACCEL_DEF_SLOPE_DURATION 2 +/* in terms of multiples of g's/LSB, based on range */ +#define BMC150_ACCEL_DEF_SLOPE_THRESHOLD 5 + +#define BMC150_ACCEL_REG_XOUT_L 0x02 + +#define BMC150_ACCEL_MAX_STARTUP_TIME_MS 100 + +/* Sleep Duration values */ +#define BMC150_ACCEL_SLEEP_500_MICRO 0x05 +#define BMC150_ACCEL_SLEEP_1_MS 0x06 +#define BMC150_ACCEL_SLEEP_2_MS 0x07 +#define BMC150_ACCEL_SLEEP_4_MS 0x08 +#define BMC150_ACCEL_SLEEP_6_MS 0x09 +#define BMC150_ACCEL_SLEEP_10_MS 0x0A +#define BMC150_ACCEL_SLEEP_25_MS 0x0B +#define BMC150_ACCEL_SLEEP_50_MS 0x0C +#define BMC150_ACCEL_SLEEP_100_MS 0x0D +#define BMC150_ACCEL_SLEEP_500_MS 0x0E +#define BMC150_ACCEL_SLEEP_1_SEC 0x0F + +#define BMC150_ACCEL_REG_TEMP 0x08 +#define BMC150_ACCEL_TEMP_CENTER_VAL 24 + +#define BMC150_ACCEL_AXIS_TO_REG(axis) (BMC150_ACCEL_REG_XOUT_L + (axis * 2)) +#define BMC150_AUTO_SUSPEND_DELAY_MS 2000 + +enum bmc150_accel_axis { + AXIS_X, + AXIS_Y, + AXIS_Z, +}; + +enum bmc150_power_modes { + BMC150_ACCEL_SLEEP_MODE_NORMAL, + BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, + BMC150_ACCEL_SLEEP_MODE_LPM, + BMC150_ACCEL_SLEEP_MODE_SUSPEND = 0x04, +}; + +struct bmc150_accel_data { + struct i2c_client *client; + struct iio_trigger *dready_trig; + struct iio_trigger *motion_trig; + struct mutex mutex; + s16 buffer[8]; + u8 bw_bits; + u32 slope_dur; + u32 slope_thres; + u32 range; + int ev_enable_state; + bool dready_trigger_on; + bool motion_trigger_on; + int64_t timestamp; +}; + +static const struct { + int val; + int val2; + u8 bw_bits; +} bmc150_accel_samp_freq_table[] = { {7, 810000, 0x08}, + {15, 630000, 0x09}, + {31, 250000, 0x0A}, + {62, 500000, 0x0B}, + {125, 0, 0x0C}, + {250, 0, 0x0D}, + {500, 0, 0x0E}, + {1000, 0, 0x0F} }; + +static const struct { + int bw_bits; + int msec; +} bmc150_accel_sample_upd_time[] = { {0x08, 64}, + {0x09, 32}, + {0x0A, 16}, + {0x0B, 8}, + {0x0C, 4}, + {0x0D, 2}, + {0x0E, 1}, + {0x0F, 1} }; + +static const struct { + int scale; + int range; +} bmc150_accel_scale_table[] = { {9610, BMC150_ACCEL_DEF_RANGE_2G}, + {19122, BMC150_ACCEL_DEF_RANGE_4G}, + {38344, BMC150_ACCEL_DEF_RANGE_8G}, + {77057, BMC150_ACCEL_DEF_RANGE_16G} }; + +static const struct { + int sleep_dur; + int reg_value; +} bmc150_accel_sleep_value_table[] = { {0, 0}, + {500, BMC150_ACCEL_SLEEP_500_MICRO}, + {1000, BMC150_ACCEL_SLEEP_1_MS}, + {2000, BMC150_ACCEL_SLEEP_2_MS}, + {4000, BMC150_ACCEL_SLEEP_4_MS}, + {6000, BMC150_ACCEL_SLEEP_6_MS}, + {10000, BMC150_ACCEL_SLEEP_10_MS}, + {25000, BMC150_ACCEL_SLEEP_25_MS}, + {50000, BMC150_ACCEL_SLEEP_50_MS}, + {100000, BMC150_ACCEL_SLEEP_100_MS}, + {500000, BMC150_ACCEL_SLEEP_500_MS}, + {1000000, BMC150_ACCEL_SLEEP_1_SEC} }; + + +static int bmc150_accel_set_mode(struct bmc150_accel_data *data, + enum bmc150_power_modes mode, + int dur_us) +{ + int i; + int ret; + u8 lpw_bits; + int dur_val = -1; + + if (dur_us > 0) { + for (i = 0; i < ARRAY_SIZE(bmc150_accel_sleep_value_table); + ++i) { + if (bmc150_accel_sleep_value_table[i].sleep_dur == + dur_us) + dur_val = + bmc150_accel_sleep_value_table[i].reg_value; + } + } else + dur_val = 0; + + if (dur_val < 0) + return -EINVAL; + + lpw_bits = mode << BMC150_ACCEL_PMU_MODE_SHIFT; + lpw_bits |= (dur_val << BMC150_ACCEL_PMU_BIT_SLEEP_DUR_SHIFT); + + dev_dbg(&data->client->dev, "Set Mode bits %x\n", lpw_bits); + + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_PMU_LPW, lpw_bits); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_pmu_lpw\n"); + return ret; + } + + return 0; +} + +static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val, + int val2) +{ + int i; + int ret; + + for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) { + if (bmc150_accel_samp_freq_table[i].val == val && + bmc150_accel_samp_freq_table[i].val2 == val2) { + ret = i2c_smbus_write_byte_data( + data->client, + BMC150_ACCEL_REG_PMU_BW, + bmc150_accel_samp_freq_table[i].bw_bits); + if (ret < 0) + return ret; + + data->bw_bits = + bmc150_accel_samp_freq_table[i].bw_bits; + return 0; + } + } + + return -EINVAL; +} + +static int bmc150_accel_chip_init(struct bmc150_accel_data *data) +{ + int ret; + + ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_CHIP_ID); + if (ret < 0) { + dev_err(&data->client->dev, + "Error: Reading chip id\n"); + return ret; + } + + dev_dbg(&data->client->dev, "Chip Id %x\n", ret); + if (ret != BMC150_ACCEL_CHIP_ID_VAL) { + dev_err(&data->client->dev, "Invalid chip %x\n", ret); + return -ENODEV; + } + + ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0); + if (ret < 0) + return ret; + + /* Set Bandwidth */ + ret = bmc150_accel_set_bw(data, BMC150_ACCEL_DEF_BW, 0); + if (ret < 0) + return ret; + + /* Set Default Range */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_PMU_RANGE, + BMC150_ACCEL_DEF_RANGE_4G); + if (ret < 0) { + dev_err(&data->client->dev, + "Error writing reg_pmu_range\n"); + return ret; + } + + data->range = BMC150_ACCEL_DEF_RANGE_4G; + + /* Set default slope duration */ + ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_int_5\n"); + return ret; + } + data->slope_dur |= BMC150_ACCEL_DEF_SLOPE_DURATION; + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_5, + data->slope_dur); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_5\n"); + return ret; + } + dev_dbg(&data->client->dev, "slope_dur %x\n", data->slope_dur); + + /* Set default slope thresholds */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_6, + BMC150_ACCEL_DEF_SLOPE_THRESHOLD); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_6\n"); + return ret; + } + data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD; + dev_dbg(&data->client->dev, "slope_thres %x\n", data->slope_thres); + + /* Set default as latched interrupts */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_RST_LATCH, + BMC150_ACCEL_INT_MODE_LATCH_INT | + BMC150_ACCEL_INT_MODE_LATCH_RESET); + if (ret < 0) { + dev_err(&data->client->dev, + "Error writing reg_int_rst_latch\n"); + return ret; + } + + return 0; +} + +static int bmc150_accel_setup_any_motion_interrupt( + struct bmc150_accel_data *data, + bool status) +{ + int ret; + + /* Enable/Disable INT1 mapping */ + ret = i2c_smbus_read_byte_data(data->client, + BMC150_ACCEL_REG_INT_MAP_0); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_int_map_0\n"); + return ret; + } + if (status) + ret |= BMC150_ACCEL_INT_MAP_0_BIT_SLOPE; + else + ret &= ~BMC150_ACCEL_INT_MAP_0_BIT_SLOPE; + + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_MAP_0, + ret); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_map_0\n"); + return ret; + } + + if (status) { + /* Set slope duration (no of samples) */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_5, + data->slope_dur); + if (ret < 0) { + dev_err(&data->client->dev, "Error write reg_int_5\n"); + return ret; + } + + /* Set slope thresholds */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_6, + data->slope_thres); + if (ret < 0) { + dev_err(&data->client->dev, "Error write reg_int_6\n"); + return ret; + } + + /* + * New data interrupt is always non-latched, + * which will have higher priority, so no need + * to set latched mode, we will be flooded anyway with INTR + */ + if (!data->dready_trigger_on) { + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_RST_LATCH, + BMC150_ACCEL_INT_MODE_LATCH_INT | + BMC150_ACCEL_INT_MODE_LATCH_RESET); + if (ret < 0) { + dev_err(&data->client->dev, + "Error writing reg_int_rst_latch\n"); + return ret; + } + } + + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_EN_0, + BMC150_ACCEL_INT_EN_BIT_SLP_X | + BMC150_ACCEL_INT_EN_BIT_SLP_Y | + BMC150_ACCEL_INT_EN_BIT_SLP_Z); + } else + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_EN_0, + 0); + + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_en_0\n"); + return ret; + } + + return 0; +} + +static int bmc150_accel_setup_new_data_interrupt(struct bmc150_accel_data *data, + bool status) +{ + int ret; + + /* Enable/Disable INT1 mapping */ + ret = i2c_smbus_read_byte_data(data->client, + BMC150_ACCEL_REG_INT_MAP_1); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_int_map_1\n"); + return ret; + } + if (status) + ret |= BMC150_ACCEL_INT_MAP_1_BIT_DATA; + else + ret &= ~BMC150_ACCEL_INT_MAP_1_BIT_DATA; + + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_MAP_1, + ret); + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_map_1\n"); + return ret; + } + + if (status) { + /* + * Set non latched mode interrupt and clear any latched + * interrupt + */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_RST_LATCH, + BMC150_ACCEL_INT_MODE_NON_LATCH_INT | + BMC150_ACCEL_INT_MODE_LATCH_RESET); + if (ret < 0) { + dev_err(&data->client->dev, + "Error writing reg_int_rst_latch\n"); + return ret; + } + + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_EN_1, + BMC150_ACCEL_INT_EN_BIT_DATA_EN); + + } else { + /* Restore default interrupt mode */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_RST_LATCH, + BMC150_ACCEL_INT_MODE_LATCH_INT | + BMC150_ACCEL_INT_MODE_LATCH_RESET); + if (ret < 0) { + dev_err(&data->client->dev, + "Error writing reg_int_rst_latch\n"); + return ret; + } + + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_EN_1, + 0); + } + + if (ret < 0) { + dev_err(&data->client->dev, "Error writing reg_int_en_1\n"); + return ret; + } + + return 0; +} + +static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val, + int *val2) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bmc150_accel_samp_freq_table); ++i) { + if (bmc150_accel_samp_freq_table[i].bw_bits == data->bw_bits) { + *val = bmc150_accel_samp_freq_table[i].val; + *val2 = bmc150_accel_samp_freq_table[i].val2; + return IIO_VAL_INT_PLUS_MICRO; + } + } + + return -EINVAL; +} + +static int bmc150_accel_get_startup_times(struct bmc150_accel_data *data) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bmc150_accel_sample_upd_time); ++i) { + if (bmc150_accel_sample_upd_time[i].bw_bits == data->bw_bits) + return bmc150_accel_sample_upd_time[i].msec; + } + + return BMC150_ACCEL_MAX_STARTUP_TIME_MS; +} + +static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on) +{ + int ret; + + if (on) + ret = pm_runtime_get_sync(&data->client->dev); + else { + pm_runtime_mark_last_busy(&data->client->dev); + ret = pm_runtime_put_autosuspend(&data->client->dev); + } + if (ret < 0) { + dev_err(&data->client->dev, + "Failed: bmc150_accel_set_power_state for %d\n", on); + return ret; + } + + return 0; +} + +static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val) +{ + int ret, i; + + for (i = 0; i < ARRAY_SIZE(bmc150_accel_scale_table); ++i) { + if (bmc150_accel_scale_table[i].scale == val) { + ret = i2c_smbus_write_byte_data( + data->client, + BMC150_ACCEL_REG_PMU_RANGE, + bmc150_accel_scale_table[i].range); + if (ret < 0) { + dev_err(&data->client->dev, + "Error writing pmu_range\n"); + return ret; + } + + data->range = bmc150_accel_scale_table[i].range; + return 0; + } + } + + return -EINVAL; +} + +static int bmc150_accel_get_temp(struct bmc150_accel_data *data, int *val) +{ + int ret; + + mutex_lock(&data->mutex); + + ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_TEMP); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_temp\n"); + mutex_unlock(&data->mutex); + return ret; + } + *val = sign_extend32(ret, 7); + + mutex_unlock(&data->mutex); + + return IIO_VAL_INT; +} + +static int bmc150_accel_get_axis(struct bmc150_accel_data *data, int axis, + int *val) +{ + int ret; + + mutex_lock(&data->mutex); + ret = bmc150_accel_set_power_state(data, true); + if (ret < 0) { + mutex_unlock(&data->mutex); + return ret; + } + + ret = i2c_smbus_read_word_data(data->client, + BMC150_ACCEL_AXIS_TO_REG(axis)); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading axis %d\n", axis); + bmc150_accel_set_power_state(data, false); + mutex_unlock(&data->mutex); + return ret; + } + *val = sign_extend32(ret >> 4, 11); + ret = bmc150_accel_set_power_state(data, false); + mutex_unlock(&data->mutex); + if (ret < 0) + return ret; + + return IIO_VAL_INT; +} + +static int bmc150_accel_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct bmc150_accel_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + switch (chan->type) { + case IIO_TEMP: + return bmc150_accel_get_temp(data, val); + case IIO_ACCEL: + if (iio_buffer_enabled(indio_dev)) + return -EBUSY; + else + return bmc150_accel_get_axis(data, + chan->scan_index, + val); + default: + return -EINVAL; + } + case IIO_CHAN_INFO_OFFSET: + if (chan->type == IIO_TEMP) { + *val = BMC150_ACCEL_TEMP_CENTER_VAL; + return IIO_VAL_INT; + } else + return -EINVAL; + case IIO_CHAN_INFO_SCALE: + *val = 0; + switch (chan->type) { + case IIO_TEMP: + *val2 = 500000; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_ACCEL: + { + int i; + + for (i = 0; i < ARRAY_SIZE(bmc150_accel_scale_table); + ++i) { + if (bmc150_accel_scale_table[i].range == + data->range) { + *val2 = + bmc150_accel_scale_table[i].scale; + return IIO_VAL_INT_PLUS_MICRO; + } + } + return -EINVAL; + } + default: + return -EINVAL; + } + case IIO_CHAN_INFO_SAMP_FREQ: + mutex_lock(&data->mutex); + ret = bmc150_accel_get_bw(data, val, val2); + mutex_unlock(&data->mutex); + return ret; + default: + return -EINVAL; + } +} + +static int bmc150_accel_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct bmc150_accel_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + mutex_lock(&data->mutex); + ret = bmc150_accel_set_bw(data, val, val2); + mutex_unlock(&data->mutex); + break; + case IIO_CHAN_INFO_SCALE: + if (val) + return -EINVAL; + + mutex_lock(&data->mutex); + ret = bmc150_accel_set_scale(data, val2); + mutex_unlock(&data->mutex); + return ret; + default: + ret = -EINVAL; + } + + return ret; +} + +static int bmc150_accel_read_event(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int *val, int *val2) +{ + struct bmc150_accel_data *data = iio_priv(indio_dev); + + *val2 = 0; + switch (info) { + case IIO_EV_INFO_VALUE: + *val = data->slope_thres; + break; + case IIO_EV_INFO_PERIOD: + *val = data->slope_dur & BMC150_ACCEL_SLOPE_DUR_MASK; + break; + default: + return -EINVAL; + } + + return IIO_VAL_INT; +} + +static int bmc150_accel_write_event(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, + int val, int val2) +{ + struct bmc150_accel_data *data = iio_priv(indio_dev); + + if (data->ev_enable_state) + return -EBUSY; + + switch (info) { + case IIO_EV_INFO_VALUE: + data->slope_thres = val; + break; + case IIO_EV_INFO_PERIOD: + data->slope_dur &= ~BMC150_ACCEL_SLOPE_DUR_MASK; + data->slope_dur |= val & BMC150_ACCEL_SLOPE_DUR_MASK; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int bmc150_accel_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + + struct bmc150_accel_data *data = iio_priv(indio_dev); + + return data->ev_enable_state; +} + +static int bmc150_accel_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + int state) +{ + struct bmc150_accel_data *data = iio_priv(indio_dev); + int ret; + + if (state && data->ev_enable_state) + return 0; + + mutex_lock(&data->mutex); + + if (!state && data->motion_trigger_on) { + data->ev_enable_state = 0; + mutex_unlock(&data->mutex); + return 0; + } + + /* + * We will expect the enable and disable to do operation in + * in reverse order. This will happen here anyway as our + * resume operation uses sync mode runtime pm calls, the + * suspend operation will be delayed by autosuspend delay + * So the disable operation will still happen in reverse of + * enable operation. When runtime pm is disabled the mode + * is always on so sequence doesn't matter + */ + + ret = bmc150_accel_set_power_state(data, state); + if (ret < 0) { + mutex_unlock(&data->mutex); + return ret; + } + + ret = bmc150_accel_setup_any_motion_interrupt(data, state); + if (ret < 0) { + mutex_unlock(&data->mutex); + return ret; + } + + data->ev_enable_state = state; + mutex_unlock(&data->mutex); + + return 0; +} + +static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev, + struct iio_trigger *trig) +{ + struct bmc150_accel_data *data = iio_priv(indio_dev); + + if (data->dready_trig != trig && data->motion_trig != trig) + return -EINVAL; + + return 0; +} + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( + "7.810000 15.630000 31.250000 62.500000 125 250 500 1000"); + +static struct attribute *bmc150_accel_attributes[] = { + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + NULL, +}; + +static const struct attribute_group bmc150_accel_attrs_group = { + .attrs = bmc150_accel_attributes, +}; + +static const struct iio_event_spec bmc150_accel_event = { + .type = IIO_EV_TYPE_ROC, + .dir = IIO_EV_DIR_RISING | IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE) | + BIT(IIO_EV_INFO_PERIOD) +}; + +#define BMC150_ACCEL_CHANNEL(_axis) { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##_axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = AXIS_##_axis, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 12, \ + .storagebits = 16, \ + .shift = 4, \ + }, \ + .event_spec = &bmc150_accel_event, \ + .num_event_specs = 1 \ +} + +static const struct iio_chan_spec bmc150_accel_channels[] = { + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .scan_index = -1, + }, + BMC150_ACCEL_CHANNEL(X), + BMC150_ACCEL_CHANNEL(Y), + BMC150_ACCEL_CHANNEL(Z), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +static const struct iio_info bmc150_accel_info = { + .attrs = &bmc150_accel_attrs_group, + .read_raw = bmc150_accel_read_raw, + .write_raw = bmc150_accel_write_raw, + .read_event_value = bmc150_accel_read_event, + .write_event_value = bmc150_accel_write_event, + .write_event_config = bmc150_accel_write_event_config, + .read_event_config = bmc150_accel_read_event_config, + .validate_trigger = bmc150_accel_validate_trigger, + .driver_module = THIS_MODULE, +}; + +static irqreturn_t bmc150_accel_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct bmc150_accel_data *data = iio_priv(indio_dev); + int bit, ret, i = 0; + + mutex_lock(&data->mutex); + for_each_set_bit(bit, indio_dev->buffer->scan_mask, + indio_dev->masklength) { + ret = i2c_smbus_read_word_data(data->client, + BMC150_ACCEL_AXIS_TO_REG(bit)); + if (ret < 0) { + mutex_unlock(&data->mutex); + goto err_read; + } + data->buffer[i++] = ret; + } + mutex_unlock(&data->mutex); + + iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, + data->timestamp); +err_read: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int bmc150_accel_trig_try_reen(struct iio_trigger *trig) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct bmc150_accel_data *data = iio_priv(indio_dev); + int ret; + + /* new data interrupts don't need ack */ + if (data->dready_trigger_on) + return 0; + + mutex_lock(&data->mutex); + /* clear any latched interrupt */ + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_RST_LATCH, + BMC150_ACCEL_INT_MODE_LATCH_INT | + BMC150_ACCEL_INT_MODE_LATCH_RESET); + mutex_unlock(&data->mutex); + if (ret < 0) { + dev_err(&data->client->dev, + "Error writing reg_int_rst_latch\n"); + return ret; + } + + return 0; +} + +static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); + struct bmc150_accel_data *data = iio_priv(indio_dev); + int ret; + + mutex_lock(&data->mutex); + + if (!state && data->ev_enable_state && data->motion_trigger_on) { + data->motion_trigger_on = false; + mutex_unlock(&data->mutex); + return 0; + } + + /* + * Refer to comment in bmc150_accel_write_event_config for + * enable/disable operation order + */ + ret = bmc150_accel_set_power_state(data, state); + if (ret < 0) { + mutex_unlock(&data->mutex); + return ret; + } + if (data->motion_trig == trig) + ret = bmc150_accel_setup_any_motion_interrupt(data, state); + else + ret = bmc150_accel_setup_new_data_interrupt(data, state); + if (ret < 0) { + mutex_unlock(&data->mutex); + return ret; + } + if (data->motion_trig == trig) + data->motion_trigger_on = state; + else + data->dready_trigger_on = state; + + mutex_unlock(&data->mutex); + + return ret; +} + +static const struct iio_trigger_ops bmc150_accel_trigger_ops = { + .set_trigger_state = bmc150_accel_data_rdy_trigger_set_state, + .try_reenable = bmc150_accel_trig_try_reen, + .owner = THIS_MODULE, +}; + +static irqreturn_t bmc150_accel_event_handler(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct bmc150_accel_data *data = iio_priv(indio_dev); + int ret; + int dir; + + ret = i2c_smbus_read_byte_data(data->client, + BMC150_ACCEL_REG_INT_STATUS_2); + if (ret < 0) { + dev_err(&data->client->dev, "Error reading reg_int_status_2\n"); + goto ack_intr_status; + } + + if (ret & BMC150_ACCEL_ANY_MOTION_BIT_SIGN) + dir = IIO_EV_DIR_FALLING; + else + dir = IIO_EV_DIR_RISING; + + if (ret & BMC150_ACCEL_ANY_MOTION_MASK) + iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, + 0, + IIO_MOD_X_OR_Y_OR_Z, + IIO_EV_TYPE_ROC, + IIO_EV_DIR_EITHER), + data->timestamp); +ack_intr_status: + if (!data->dready_trigger_on) + ret = i2c_smbus_write_byte_data(data->client, + BMC150_ACCEL_REG_INT_RST_LATCH, + BMC150_ACCEL_INT_MODE_LATCH_INT | + BMC150_ACCEL_INT_MODE_LATCH_RESET); + + return IRQ_HANDLED; +} + +static irqreturn_t bmc150_accel_data_rdy_trig_poll(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct bmc150_accel_data *data = iio_priv(indio_dev); + + data->timestamp = iio_get_time_ns(); + + if (data->dready_trigger_on) + iio_trigger_poll(data->dready_trig); + else if (data->motion_trigger_on) + iio_trigger_poll(data->motion_trig); + + if (data->ev_enable_state) + return IRQ_WAKE_THREAD; + else + return IRQ_HANDLED; +} + +static int bmc150_accel_acpi_gpio_probe(struct i2c_client *client, + struct bmc150_accel_data *data) +{ + const struct acpi_device_id *id; + struct device *dev; + struct gpio_desc *gpio; + int ret; + + if (!client) + return -EINVAL; + + dev = &client->dev; + if (!ACPI_HANDLE(dev)) + return -ENODEV; + + id = acpi_match_device(dev->driver->acpi_match_table, dev); + if (!id) + return -ENODEV; + + /* data ready gpio interrupt pin */ + gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0); + if (IS_ERR(gpio)) { + dev_err(dev, "Failed: acpi gpio get index\n"); + return PTR_ERR(gpio); + } + + ret = gpiod_direction_input(gpio); + if (ret) + return ret; + + ret = gpiod_to_irq(gpio); + + dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); + + return ret; +} + +static int bmc150_accel_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct bmc150_accel_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + data->client = client; + + ret = bmc150_accel_chip_init(data); + if (ret < 0) + return ret; + + mutex_init(&data->mutex); + + indio_dev->dev.parent = &client->dev; + indio_dev->channels = bmc150_accel_channels; + indio_dev->num_channels = ARRAY_SIZE(bmc150_accel_channels); + indio_dev->name = BMC150_ACCEL_DRV_NAME; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &bmc150_accel_info; + + if (client->irq < 0) + client->irq = bmc150_accel_acpi_gpio_probe(client, data); + + if (client->irq >= 0) { + ret = devm_request_threaded_irq( + &client->dev, client->irq, + bmc150_accel_data_rdy_trig_poll, + bmc150_accel_event_handler, + IRQF_TRIGGER_RISING, + BMC150_ACCEL_IRQ_NAME, + indio_dev); + if (ret) + return ret; + + data->dready_trig = devm_iio_trigger_alloc(&client->dev, + "%s-dev%d", + indio_dev->name, + indio_dev->id); + if (!data->dready_trig) + return -ENOMEM; + + data->motion_trig = devm_iio_trigger_alloc(&client->dev, + "%s-any-motion-dev%d", + indio_dev->name, + indio_dev->id); + if (!data->motion_trig) + return -ENOMEM; + + data->dready_trig->dev.parent = &client->dev; + data->dready_trig->ops = &bmc150_accel_trigger_ops; + iio_trigger_set_drvdata(data->dready_trig, indio_dev); + ret = iio_trigger_register(data->dready_trig); + if (ret) + return ret; + + data->motion_trig->dev.parent = &client->dev; + data->motion_trig->ops = &bmc150_accel_trigger_ops; + iio_trigger_set_drvdata(data->motion_trig, indio_dev); + ret = iio_trigger_register(data->motion_trig); + if (ret) { + data->motion_trig = NULL; + goto err_trigger_unregister; + } + + ret = iio_triggered_buffer_setup(indio_dev, + &iio_pollfunc_store_time, + bmc150_accel_trigger_handler, + NULL); + if (ret < 0) { + dev_err(&client->dev, + "Failed: iio triggered buffer setup\n"); + goto err_trigger_unregister; + } + } + + ret = iio_device_register(indio_dev); + if (ret < 0) { + dev_err(&client->dev, "Unable to register iio device\n"); + goto err_buffer_cleanup; + } + + ret = pm_runtime_set_active(&client->dev); + if (ret) + goto err_iio_unregister; + + pm_runtime_enable(&client->dev); + pm_runtime_set_autosuspend_delay(&client->dev, + BMC150_AUTO_SUSPEND_DELAY_MS); + pm_runtime_use_autosuspend(&client->dev); + + return 0; + +err_iio_unregister: + iio_device_unregister(indio_dev); +err_buffer_cleanup: + if (data->dready_trig) + iio_triggered_buffer_cleanup(indio_dev); +err_trigger_unregister: + if (data->dready_trig) + iio_trigger_unregister(data->dready_trig); + if (data->motion_trig) + iio_trigger_unregister(data->motion_trig); + + return ret; +} + +static int bmc150_accel_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct bmc150_accel_data *data = iio_priv(indio_dev); + + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); + pm_runtime_put_noidle(&client->dev); + + iio_device_unregister(indio_dev); + + if (data->dready_trig) { + iio_triggered_buffer_cleanup(indio_dev); + iio_trigger_unregister(data->dready_trig); + iio_trigger_unregister(data->motion_trig); + } + + mutex_lock(&data->mutex); + bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, 0); + mutex_unlock(&data->mutex); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int bmc150_accel_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct bmc150_accel_data *data = iio_priv(indio_dev); + + mutex_lock(&data->mutex); + bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0); + mutex_unlock(&data->mutex); + + return 0; +} + +static int bmc150_accel_resume(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct bmc150_accel_data *data = iio_priv(indio_dev); + + mutex_lock(&data->mutex); + if (data->dready_trigger_on || data->motion_trigger_on || + data->ev_enable_state) + bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0); + mutex_unlock(&data->mutex); + + return 0; +} +#endif + +#ifdef CONFIG_PM_RUNTIME +static int bmc150_accel_runtime_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct bmc150_accel_data *data = iio_priv(indio_dev); + + dev_dbg(&data->client->dev, __func__); + + return bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_SUSPEND, 0); +} + +static int bmc150_accel_runtime_resume(struct device *dev) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); + struct bmc150_accel_data *data = iio_priv(indio_dev); + int ret; + int sleep_val; + + dev_dbg(&data->client->dev, __func__); + + ret = bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0); + if (ret < 0) + return ret; + + sleep_val = bmc150_accel_get_startup_times(data); + if (sleep_val < 20) + usleep_range(sleep_val * 1000, 20000); + else + msleep_interruptible(sleep_val); + + return 0; +} +#endif + +static const struct dev_pm_ops bmc150_accel_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(bmc150_accel_suspend, bmc150_accel_resume) + SET_RUNTIME_PM_OPS(bmc150_accel_runtime_suspend, + bmc150_accel_runtime_resume, NULL) +}; + +static const struct acpi_device_id bmc150_accel_acpi_match[] = { + {"BSBA0150", 0}, + {"BMC150A", 0}, + { }, +}; +MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match); + +static const struct i2c_device_id bmc150_accel_id[] = { + {"bmc150_accel", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, bmc150_accel_id); + +static struct i2c_driver bmc150_accel_driver = { + .driver = { + .name = BMC150_ACCEL_DRV_NAME, + .acpi_match_table = ACPI_PTR(bmc150_accel_acpi_match), + .pm = &bmc150_accel_pm_ops, + }, + .probe = bmc150_accel_probe, + .remove = bmc150_accel_remove, + .id_table = bmc150_accel_id, +}; +module_i2c_driver(bmc150_accel_driver); + +MODULE_AUTHOR("Srinivas Pandruvada "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("BMC150 accelerometer driver"); -- GitLab From 7144045d2ac4cfa9594f392c6468c3d384041c06 Mon Sep 17 00:00:00 2001 From: Srinivas Pandruvada Date: Thu, 8 May 2014 22:57:00 +0100 Subject: [PATCH 0089/9167] iio: accel: BMC150 accel documentation Added any-motion trigger documentation. Signed-off-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- Documentation/ABI/testing/sysfs-bus-iio-accel-bmc150 | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-accel-bmc150 diff --git a/Documentation/ABI/testing/sysfs-bus-iio-accel-bmc150 b/Documentation/ABI/testing/sysfs-bus-iio-accel-bmc150 new file mode 100644 index 000000000000..99847a913af7 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-accel-bmc150 @@ -0,0 +1,7 @@ +What: /sys/bus/iio/devices/triggerX/name = "bmc150_accel-any-motion-devX" +KernelVersion: 3.17 +Contact: linux-iio@vger.kernel.org +Description: + The BMC150 accelerometer kernel module provides an additional trigger, + which sets driver in a mode, where data is pushed to the buffer + only when there is any motion. -- GitLab From 913b864686746e10c32ed65c04f70d886c4c0c76 Mon Sep 17 00:00:00 2001 From: Angelo Compagnucci Date: Sat, 8 Mar 2014 18:38:00 +0000 Subject: [PATCH 0090/9167] iio: adc: Add TI ADC128S052 This patch adds support for ADC128S052 from TI. Signed-off-by: Angelo Compagnucci Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 10 ++ drivers/iio/adc/Makefile | 1 + drivers/iio/adc/ti-adc128s052.c | 179 ++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+) create mode 100644 drivers/iio/adc/ti-adc128s052.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 11b048a59fde..3ea56a39b9d2 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -216,6 +216,16 @@ config TI_ADC081C This driver can also be built as a module. If so, the module will be called ti-adc081c. +config TI_ADC128S052 + tristate "Texas Instruments ADC128S052" + depends on SPI + help + If you say yes here you get support for Texas Instruments ADC128S052 + chip. + + This driver can also be built as a module. If so, the module will be + called ti-adc128s052. + config TI_AM335X_ADC tristate "TI's AM335X ADC driver" depends on MFD_TI_AM335X_TSCADC diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index ad81b512aa3d..9cc37f66f9d0 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_MCP3422) += mcp3422.o obj-$(CONFIG_MEN_Z188_ADC) += men_z188_adc.o obj-$(CONFIG_NAU7802) += nau7802.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o +obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o diff --git a/drivers/iio/adc/ti-adc128s052.c b/drivers/iio/adc/ti-adc128s052.c new file mode 100644 index 000000000000..655cb564ec54 --- /dev/null +++ b/drivers/iio/adc/ti-adc128s052.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2014 Angelo Compagnucci + * + * Driver for Texas Instruments' ADC128S052 ADC chip. + * Datasheet can be found here: + * http://www.ti.com/lit/ds/symlink/adc128s052.pdf + * + * 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 + +struct adc128 { + struct spi_device *spi; + + struct regulator *reg; + struct mutex lock; + + u8 buffer[2] ____cacheline_aligned; +}; + +static int adc128_adc_conversion(struct adc128 *adc, u8 channel) +{ + int ret; + + mutex_lock(&adc->lock); + + adc->buffer[0] = channel << 3; + adc->buffer[1] = 0; + + ret = spi_write(adc->spi, &adc->buffer, 2); + if (ret < 0) { + mutex_unlock(&adc->lock); + return ret; + } + + ret = spi_read(adc->spi, &adc->buffer, 2); + + mutex_unlock(&adc->lock); + + if (ret < 0) + return ret; + + return ((adc->buffer[0] << 8 | adc->buffer[1]) & 0xFFF); +} + +static int adc128_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, int *val, + int *val2, long mask) +{ + struct adc128 *adc = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + + ret = adc128_adc_conversion(adc, channel->channel); + if (ret < 0) + return ret; + + *val = ret; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + + ret = regulator_get_voltage(adc->reg); + if (ret < 0) + return ret; + + *val = ret / 1000; + *val2 = 12; + return IIO_VAL_FRACTIONAL_LOG2; + + default: + return -EINVAL; + } + +} + +#define ADC128_VOLTAGE_CHANNEL(num) \ + { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (num), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \ + } + +static const struct iio_chan_spec adc128_channels[] = { + ADC128_VOLTAGE_CHANNEL(0), + ADC128_VOLTAGE_CHANNEL(1), + ADC128_VOLTAGE_CHANNEL(2), + ADC128_VOLTAGE_CHANNEL(3), + ADC128_VOLTAGE_CHANNEL(4), + ADC128_VOLTAGE_CHANNEL(5), + ADC128_VOLTAGE_CHANNEL(6), + ADC128_VOLTAGE_CHANNEL(7), +}; + +static const struct iio_info adc128_info = { + .read_raw = adc128_read_raw, + .driver_module = THIS_MODULE, +}; + +static int adc128_probe(struct spi_device *spi) +{ + struct iio_dev *indio_dev; + struct adc128 *adc; + int ret; + + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); + if (!indio_dev) + return -ENOMEM; + + adc = iio_priv(indio_dev); + adc->spi = spi; + + spi_set_drvdata(spi, indio_dev); + + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &adc128_info; + + indio_dev->channels = adc128_channels; + indio_dev->num_channels = ARRAY_SIZE(adc128_channels); + + adc->reg = devm_regulator_get(&spi->dev, "vref"); + if (IS_ERR(adc->reg)) + return PTR_ERR(adc->reg); + + ret = regulator_enable(adc->reg); + if (ret < 0) + return ret; + + mutex_init(&adc->lock); + + ret = iio_device_register(indio_dev); + + return ret; +} + +static int adc128_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct adc128 *adc = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + regulator_disable(adc->reg); + + return 0; +} + +static const struct spi_device_id adc128_id[] = { + { "adc128s052", 0}, + { } +}; +MODULE_DEVICE_TABLE(spi, adc128_id); + +static struct spi_driver adc128_driver = { + .driver = { + .name = "adc128s052", + .owner = THIS_MODULE, + }, + .probe = adc128_probe, + .remove = adc128_remove, + .id_table = adc128_id, +}; +module_spi_driver(adc128_driver); + +MODULE_AUTHOR("Angelo Compagnucci "); +MODULE_DESCRIPTION("Texas Instruments ADC128S052"); +MODULE_LICENSE("GPL v2"); -- GitLab From 84e93b38c2a93c59b23349b1e31de1a3657fa4c0 Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Sat, 8 Mar 2014 11:00:00 +0000 Subject: [PATCH 0091/9167] staging: iio: ad9951: Use devm_iio_device_register This patch introduces the use of devm_iio_device_register and does away with the unregister in the remove function. The remove function is no longer required and is completely removed. Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Jonathan Cameron --- drivers/staging/iio/frequency/ad9951.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/staging/iio/frequency/ad9951.c b/drivers/staging/iio/frequency/ad9951.c index 5e8990a0210b..d465db0e9c0b 100644 --- a/drivers/staging/iio/frequency/ad9951.c +++ b/drivers/staging/iio/frequency/ad9951.c @@ -175,7 +175,7 @@ static int ad9951_probe(struct spi_device *spi) idev->info = &ad9951_info; idev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(idev); + ret = devm_iio_device_register(&spi->dev, idev); if (ret) return ret; spi->max_speed_hz = 2000000; @@ -186,20 +186,12 @@ static int ad9951_probe(struct spi_device *spi) return 0; } -static int ad9951_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - - return 0; -} - static struct spi_driver ad9951_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, }, .probe = ad9951_probe, - .remove = ad9951_remove, }; module_spi_driver(ad9951_driver); -- GitLab From af097e86312f2a2ec83d9d2497425f5d61592953 Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Sat, 8 Mar 2014 10:58:00 +0000 Subject: [PATCH 0092/9167] staging:iio:ad9852: Use devm_iio_device_register This patch introduces the use of devm_iio_device_register and does away with the unregister in the remove function. Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Jonathan Cameron --- drivers/staging/iio/frequency/ad9852.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/drivers/staging/iio/frequency/ad9852.c b/drivers/staging/iio/frequency/ad9852.c index 11e4367375d2..af2f2cc7a2f1 100644 --- a/drivers/staging/iio/frequency/ad9852.c +++ b/drivers/staging/iio/frequency/ad9852.c @@ -218,7 +218,7 @@ static int ad9852_probe(struct spi_device *spi) idev->info = &ad9852_info; idev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(idev); + ret = devm_iio_device_register(&spi->dev, idev); if (ret) return ret; spi->max_speed_hz = 2000000; @@ -230,20 +230,12 @@ static int ad9852_probe(struct spi_device *spi) return 0; } -static int ad9852_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - - return 0; -} - static struct spi_driver ad9852_driver = { .driver = { .name = DRV_NAME, .owner = THIS_MODULE, }, .probe = ad9852_probe, - .remove = ad9852_remove, }; module_spi_driver(ad9852_driver); -- GitLab From 44d6f2ef94f9825e6eb9072f1611e0ea4cd81fa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Heiko=20St=C3=BCbner?= Date: Wed, 23 Jul 2014 22:24:00 +0100 Subject: [PATCH 0093/9167] iio: adc: add driver for Rockchip saradc The ADC is a 3-channel signal-ended 10-bit Successive Approximation Register (SAR) A/D Converter. It uses the supply and ground as its reference and converts the analog input signal into 10-bit binary digital codes. Signed-off-by: Heiko Stuebner Reviewed-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- drivers/iio/adc/Kconfig | 10 + drivers/iio/adc/Makefile | 1 + drivers/iio/adc/rockchip_saradc.c | 317 ++++++++++++++++++++++++++++++ 3 files changed, 328 insertions(+) create mode 100644 drivers/iio/adc/rockchip_saradc.c diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 3ea56a39b9d2..6655fd41acd9 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -206,6 +206,16 @@ config NAU7802 To compile this driver as a module, choose M here: the module will be called nau7802. +config ROCKCHIP_SARADC + tristate "Rockchip SARADC driver" + depends on ARCH_ROCKCHIP || (ARM && COMPILE_TEST) + help + Say yes here to build support for the SARADC found in SoCs from + Rockchip. + + To compile this driver as a module, choose M here: the + module will be called rockchip_saradc. + config TI_ADC081C tristate "Texas Instruments ADC081C021/027" depends on I2C diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 9cc37f66f9d0..cb88a6a23b8f 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_ROCKCHIP_SARADC) += rockchip_saradc.o obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c new file mode 100644 index 000000000000..1fad9647cef4 --- /dev/null +++ b/drivers/iio/adc/rockchip_saradc.c @@ -0,0 +1,317 @@ +/* + * Rockchip Successive Approximation Register (SAR) A/D Converter + * Copyright (C) 2014 ROCKCHIP, 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. + * + * 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 + +#define SARADC_DATA 0x00 +#define SARADC_DATA_MASK 0x3ff + +#define SARADC_STAS 0x04 +#define SARADC_STAS_BUSY BIT(0) + +#define SARADC_CTRL 0x08 +#define SARADC_CTRL_IRQ_STATUS BIT(6) +#define SARADC_CTRL_IRQ_ENABLE BIT(5) +#define SARADC_CTRL_POWER_CTRL BIT(3) +#define SARADC_CTRL_CHN_MASK 0x7 + +#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 { + void __iomem *regs; + struct clk *pclk; + struct clk *clk; + struct completion completion; + struct regulator *vref; + u16 last_val; +}; + +static int rockchip_saradc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct rockchip_saradc *info = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + mutex_lock(&indio_dev->mlock); + + reinit_completion(&info->completion); + + /* 8 clock periods as delay between power up and start cmd */ + writel_relaxed(8, info->regs + SARADC_DLY_PU_SOC); + + /* Select the channel to be used and trigger conversion */ + writel(SARADC_CTRL_POWER_CTRL + | (chan->channel & SARADC_CTRL_CHN_MASK) + | SARADC_CTRL_IRQ_ENABLE, + info->regs + SARADC_CTRL); + + if (!wait_for_completion_timeout(&info->completion, + SARADC_TIMEOUT)) { + writel_relaxed(0, info->regs + SARADC_CTRL); + mutex_unlock(&indio_dev->mlock); + return -ETIMEDOUT; + } + + *val = info->last_val; + mutex_unlock(&indio_dev->mlock); + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + ret = regulator_get_voltage(info->vref); + if (ret < 0) { + dev_err(&indio_dev->dev, "failed to get voltage\n"); + return ret; + } + + *val = ret / 1000; + *val2 = SARADC_BITS; + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static irqreturn_t rockchip_saradc_isr(int irq, void *dev_id) +{ + struct rockchip_saradc *info = (struct rockchip_saradc *)dev_id; + + /* Read value */ + info->last_val = readl_relaxed(info->regs + SARADC_DATA); + info->last_val &= SARADC_DATA_MASK; + + /* Clear irq & power down adc */ + writel_relaxed(0, info->regs + SARADC_CTRL); + + complete(&info->completion); + + return IRQ_HANDLED; +} + +static const struct iio_info rockchip_saradc_iio_info = { + .read_raw = rockchip_saradc_read_raw, + .driver_module = THIS_MODULE, +}; + +#define ADC_CHANNEL(_index, _id) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = _index, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .datasheet_name = _id, \ +} + +static const struct iio_chan_spec rockchip_saradc_iio_channels[] = { + ADC_CHANNEL(0, "adc0"), + ADC_CHANNEL(1, "adc1"), + ADC_CHANNEL(2, "adc2"), +}; + +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; + int ret; + int irq; + u32 rate; + + if (!np) + return -ENODEV; + + indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); + if (!indio_dev) { + dev_err(&pdev->dev, "failed allocating iio device\n"); + return -ENOMEM; + } + info = iio_priv(indio_dev); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + info->regs = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(info->regs)) + return PTR_ERR(info->regs); + + init_completion(&info->completion); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "no irq resource?\n"); + return irq; + } + + ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr, + 0, dev_name(&pdev->dev), info); + if (ret < 0) { + dev_err(&pdev->dev, "failed requesting irq %d\n", irq); + return ret; + } + + info->pclk = devm_clk_get(&pdev->dev, "apb_pclk"); + if (IS_ERR(info->pclk)) { + dev_err(&pdev->dev, "failed to get pclk\n"); + return PTR_ERR(info->pclk); + } + + info->clk = devm_clk_get(&pdev->dev, "saradc"); + if (IS_ERR(info->clk)) { + dev_err(&pdev->dev, "failed to get adc clock\n"); + return PTR_ERR(info->clk); + } + + info->vref = devm_regulator_get(&pdev->dev, "vref"); + if (IS_ERR(info->vref)) { + dev_err(&pdev->dev, "failed to get regulator, %ld\n", + PTR_ERR(info->vref)); + return PTR_ERR(info->vref); + } + + /* + * Use a default of 1MHz for the converter clock. + * This may become user-configurable in the future. + */ + ret = clk_set_rate(info->clk, 1000000); + if (ret < 0) { + dev_err(&pdev->dev, "failed to set adc clk rate, %d\n", ret); + return ret; + } + + ret = regulator_enable(info->vref); + if (ret < 0) { + dev_err(&pdev->dev, "failed to enable vref regulator\n"); + return ret; + } + + ret = clk_prepare_enable(info->pclk); + if (ret < 0) { + dev_err(&pdev->dev, "failed to enable pclk\n"); + goto err_reg_voltage; + } + + ret = clk_prepare_enable(info->clk); + if (ret < 0) { + dev_err(&pdev->dev, "failed to enable converter clock\n"); + goto err_pclk; + } + + platform_set_drvdata(pdev, indio_dev); + + indio_dev->name = dev_name(&pdev->dev); + indio_dev->dev.parent = &pdev->dev; + indio_dev->dev.of_node = pdev->dev.of_node; + 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); + + ret = iio_device_register(indio_dev); + if (ret) + goto err_clk; + + return 0; + +err_clk: + clk_disable_unprepare(info->clk); +err_pclk: + clk_disable_unprepare(info->pclk); +err_reg_voltage: + regulator_disable(info->vref); + return ret; +} + +static int rockchip_saradc_remove(struct platform_device *pdev) +{ + struct iio_dev *indio_dev = platform_get_drvdata(pdev); + struct rockchip_saradc *info = iio_priv(indio_dev); + + iio_device_unregister(indio_dev); + clk_disable_unprepare(info->clk); + clk_disable_unprepare(info->pclk); + regulator_disable(info->vref); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int rockchip_saradc_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct rockchip_saradc *info = iio_priv(indio_dev); + + clk_disable_unprepare(info->clk); + clk_disable_unprepare(info->pclk); + regulator_disable(info->vref); + + return 0; +} + +static int rockchip_saradc_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct rockchip_saradc *info = iio_priv(indio_dev); + int ret; + + ret = regulator_enable(info->vref); + if (ret) + return ret; + + ret = clk_prepare_enable(info->pclk); + if (ret) + return ret; + + ret = clk_prepare_enable(info->clk); + if (ret) + return ret; + + return ret; +} +#endif + +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, + .driver = { + .name = "rockchip-saradc", + .owner = THIS_MODULE, + .of_match_table = rockchip_saradc_match, + .pm = &rockchip_saradc_pm_ops, + }, +}; + +module_platform_driver(rockchip_saradc_driver); -- GitLab From 249535d894216f5dcd922accfb435d32d417d56f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 28 Jul 2014 13:44:00 +0100 Subject: [PATCH 0094/9167] iio: adc: exynos_adc: add support for s3c64xx adc The ADC in s3c64xx is almost the same as exynosv1, but has a different 'select' method. Adding this here will be helpful to move over the existing s3c64xx platform from the legacy plat-samsung/adc driver to the new exynos-adc. Signed-off-by: Arnd Bergmann Signed-off-by: Chanwoo Choi Signed-off-by: Jonathan Cameron --- .../bindings/arm/samsung/exynos-adc.txt | 2 ++ drivers/iio/adc/exynos_adc.c | 28 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt index adc61b095bd1..d3dad46c97dd 100644 --- a/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt @@ -16,6 +16,8 @@ Required properties: future controllers. Must be "samsung,exynos3250-adc" for controllers compatible with ADC of Exynos3250. + Must be "samsung,s3c6410-adc" for + the ADC in s3c6410 and compatibles - reg: Contains ADC register address range (base address and length) and the address of the phy enable register. - interrupts: Contains the interrupt information for the timer. The diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index fc9dfc23ecb7..62631a778b1f 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -40,7 +40,7 @@ #include #include -/* EXYNOS4412/5250 ADC_V1 registers definitions */ +/* S3C/EXYNOS4412/5250 ADC_V1 registers definitions */ #define ADC_V1_CON(x) ((x) + 0x00) #define ADC_V1_DLY(x) ((x) + 0x08) #define ADC_V1_DATX(x) ((x) + 0x0C) @@ -61,6 +61,9 @@ #define ADC_V1_CON_PRSCLV(x) (((x) & 0xFF) << 6) #define ADC_V1_CON_STANDBY (1u << 2) +/* Bit definitions for S3C2410 ADC */ +#define ADC_S3C2410_CON_SELMUX(x) (((x) & 7) << 3) + /* Bit definitions for ADC_V2 */ #define ADC_V2_CON1_SOFT_RESET (1u << 2) @@ -217,6 +220,26 @@ static const struct exynos_adc_data exynos_adc_v1_data = { .start_conv = exynos_adc_v1_start_conv, }; +static void exynos_adc_s3c64xx_start_conv(struct exynos_adc *info, + unsigned long addr) +{ + u32 con1; + + con1 = readl(ADC_V1_CON(info->regs)); + con1 &= ~ADC_S3C2410_CON_SELMUX(0x7); + con1 |= ADC_S3C2410_CON_SELMUX(addr); + writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs)); +} + +static struct exynos_adc_data const exynos_adc_s3c64xx_data = { + .num_channels = MAX_ADC_V1_CHANNELS, + + .init_hw = exynos_adc_v1_init_hw, + .exit_hw = exynos_adc_v1_exit_hw, + .clear_irq = exynos_adc_v1_clear_irq, + .start_conv = exynos_adc_s3c64xx_start_conv, +}; + static void exynos_adc_v2_init_hw(struct exynos_adc *info) { u32 con1, con2; @@ -285,6 +308,9 @@ static const struct exynos_adc_data exynos3250_adc_data = { static const struct of_device_id exynos_adc_match[] = { { + .compatible = "samsung,s3c6410-adc", + .data = &exynos_adc_s3c64xx_data, + }, { .compatible = "samsung,exynos-adc-v1", .data = &exynos_adc_v1_data, }, { -- GitLab From 145b0a5d18565615724045dbc2ada32324faa395 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 28 Jul 2014 13:44:00 +0100 Subject: [PATCH 0095/9167] iio: adc: exynos_adc: Add support for s3c24xx ADC This patch add support for s3c2410/s3c2416/s3c2440/s3c2443 ADC. The s3c24xx is alomost same as ADCv1. But, There are a little difference as following: - ADCMUX register address - ADCDAT mask (10 bit or 12 bit ADC resolution according to SoC version) - s3c24xx/s3c64xx has not included ADC_PHY enable register Signed-off-by: Chanwoo Choi Acked-by: Arnd Bergmann Signed-off-by: Jonathan Cameron --- .../bindings/arm/samsung/exynos-adc.txt | 16 ++- drivers/iio/adc/Kconfig | 2 +- drivers/iio/adc/exynos_adc.c | 109 ++++++++++++++++-- 3 files changed, 114 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt b/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt index d3dad46c97dd..709efaa30841 100644 --- a/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt +++ b/Documentation/devicetree/bindings/arm/samsung/exynos-adc.txt @@ -11,15 +11,25 @@ New driver handles the following Required properties: - compatible: Must be "samsung,exynos-adc-v1" - for exynos4412/5250 controllers. + for exynos4412/5250 and s5pv210 controllers. Must be "samsung,exynos-adc-v2" for future controllers. Must be "samsung,exynos3250-adc" for controllers compatible with ADC of Exynos3250. + Must be "samsung,s3c2410-adc" for + the ADC in s3c2410 and compatibles + Must be "samsung,s3c2416-adc" for + the ADC in s3c2416 and compatibles + Must be "samsung,s3c2440-adc" for + the ADC in s3c2440 and compatibles + Must be "samsung,s3c2443-adc" for + the ADC in s3c2443 and compatibles Must be "samsung,s3c6410-adc" for the ADC in s3c6410 and compatibles -- reg: Contains ADC register address range (base address and - length) and the address of the phy enable register. +- reg: List of ADC register address range + - The base address and range of ADC register + - The base address and range of ADC_PHY register (every + SoC except for s3c24xx/s3c64xx ADC) - interrupts: Contains the interrupt information for the timer. The format is being dependent on which interrupt controller the Samsung device uses. diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 6655fd41acd9..88bdc8f612e2 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -129,7 +129,7 @@ config AT91_ADC config EXYNOS_ADC tristate "Exynos ADC driver support" - depends on ARCH_EXYNOS || (OF && COMPILE_TEST) + depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST) help Core support for the ADC block found in the Samsung EXYNOS series of SoCs for drivers such as the touchscreen and hwmon to use to share diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index 62631a778b1f..c59012d2d06f 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -47,6 +47,9 @@ #define ADC_V1_INTCLR(x) ((x) + 0x18) #define ADC_V1_MUX(x) ((x) + 0x1c) +/* S3C2410 ADC registers definitions */ +#define ADC_S3C2410_MUX(x) ((x) + 0x18) + /* Future ADC_V2 registers definitions */ #define ADC_V2_CON1(x) ((x) + 0x00) #define ADC_V2_CON2(x) ((x) + 0x04) @@ -63,6 +66,8 @@ /* Bit definitions for S3C2410 ADC */ #define ADC_S3C2410_CON_SELMUX(x) (((x) & 7) << 3) +#define ADC_S3C2410_DATX_MASK 0x3FF +#define ADC_S3C2416_CON_RES_SEL (1u << 3) /* Bit definitions for ADC_V2 */ #define ADC_V2_CON1_SOFT_RESET (1u << 2) @@ -80,6 +85,7 @@ /* Bit definitions common for ADC_V1 and ADC_V2 */ #define ADC_CON_EN_START (1u << 0) +#define ADC_CON_EN_START_MASK (0x3 << 0) #define ADC_DATX_MASK 0xFFF #define EXYNOS_ADC_TIMEOUT (msecs_to_jiffies(100)) @@ -103,6 +109,8 @@ struct exynos_adc { struct exynos_adc_data { int num_channels; bool needs_sclk; + bool needs_adc_phy; + u32 mask; void (*init_hw)(struct exynos_adc *info); void (*exit_hw)(struct exynos_adc *info); @@ -174,7 +182,8 @@ static void exynos_adc_v1_init_hw(struct exynos_adc *info) { u32 con1; - writel(1, info->enable_reg); + if (info->data->needs_adc_phy) + writel(1, info->enable_reg); /* set default prescaler values and Enable prescaler */ con1 = ADC_V1_CON_PRSCLV(49) | ADC_V1_CON_PRSCEN; @@ -188,7 +197,8 @@ static void exynos_adc_v1_exit_hw(struct exynos_adc *info) { u32 con; - writel(0, info->enable_reg); + if (info->data->needs_adc_phy) + writel(0, info->enable_reg); con = readl(ADC_V1_CON(info->regs)); con |= ADC_V1_CON_STANDBY; @@ -213,6 +223,8 @@ static void exynos_adc_v1_start_conv(struct exynos_adc *info, static const struct exynos_adc_data exynos_adc_v1_data = { .num_channels = MAX_ADC_V1_CHANNELS, + .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ + .needs_adc_phy = true, .init_hw = exynos_adc_v1_init_hw, .exit_hw = exynos_adc_v1_exit_hw, @@ -220,6 +232,53 @@ static const struct exynos_adc_data exynos_adc_v1_data = { .start_conv = exynos_adc_v1_start_conv, }; +static void exynos_adc_s3c2416_start_conv(struct exynos_adc *info, + unsigned long addr) +{ + u32 con1; + + /* Enable 12 bit ADC resolution */ + con1 = readl(ADC_V1_CON(info->regs)); + con1 |= ADC_S3C2416_CON_RES_SEL; + writel(con1, ADC_V1_CON(info->regs)); + + /* Select channel for S3C2416 */ + writel(addr, ADC_S3C2410_MUX(info->regs)); + + con1 = readl(ADC_V1_CON(info->regs)); + writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs)); +} + +static struct exynos_adc_data const exynos_adc_s3c2416_data = { + .num_channels = MAX_ADC_V1_CHANNELS, + .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ + + .init_hw = exynos_adc_v1_init_hw, + .exit_hw = exynos_adc_v1_exit_hw, + .start_conv = exynos_adc_s3c2416_start_conv, +}; + +static void exynos_adc_s3c2443_start_conv(struct exynos_adc *info, + unsigned long addr) +{ + u32 con1; + + /* Select channel for S3C2433 */ + writel(addr, ADC_S3C2410_MUX(info->regs)); + + con1 = readl(ADC_V1_CON(info->regs)); + writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs)); +} + +static struct exynos_adc_data const exynos_adc_s3c2443_data = { + .num_channels = MAX_ADC_V1_CHANNELS, + .mask = ADC_S3C2410_DATX_MASK, /* 10 bit ADC resolution */ + + .init_hw = exynos_adc_v1_init_hw, + .exit_hw = exynos_adc_v1_exit_hw, + .start_conv = exynos_adc_s3c2443_start_conv, +}; + static void exynos_adc_s3c64xx_start_conv(struct exynos_adc *info, unsigned long addr) { @@ -231,8 +290,18 @@ static void exynos_adc_s3c64xx_start_conv(struct exynos_adc *info, writel(con1 | ADC_CON_EN_START, ADC_V1_CON(info->regs)); } +static struct exynos_adc_data const exynos_adc_s3c24xx_data = { + .num_channels = MAX_ADC_V1_CHANNELS, + .mask = ADC_S3C2410_DATX_MASK, /* 10 bit ADC resolution */ + + .init_hw = exynos_adc_v1_init_hw, + .exit_hw = exynos_adc_v1_exit_hw, + .start_conv = exynos_adc_s3c64xx_start_conv, +}; + static struct exynos_adc_data const exynos_adc_s3c64xx_data = { .num_channels = MAX_ADC_V1_CHANNELS, + .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ .init_hw = exynos_adc_v1_init_hw, .exit_hw = exynos_adc_v1_exit_hw, @@ -244,7 +313,8 @@ static void exynos_adc_v2_init_hw(struct exynos_adc *info) { u32 con1, con2; - writel(1, info->enable_reg); + if (info->data->needs_adc_phy) + writel(1, info->enable_reg); con1 = ADC_V2_CON1_SOFT_RESET; writel(con1, ADC_V2_CON1(info->regs)); @@ -261,7 +331,8 @@ static void exynos_adc_v2_exit_hw(struct exynos_adc *info) { u32 con; - writel(0, info->enable_reg); + if (info->data->needs_adc_phy) + writel(0, info->enable_reg); con = readl(ADC_V2_CON1(info->regs)); con &= ~ADC_CON_EN_START; @@ -289,6 +360,8 @@ static void exynos_adc_v2_start_conv(struct exynos_adc *info, static const struct exynos_adc_data exynos_adc_v2_data = { .num_channels = MAX_ADC_V2_CHANNELS, + .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ + .needs_adc_phy = true, .init_hw = exynos_adc_v2_init_hw, .exit_hw = exynos_adc_v2_exit_hw, @@ -298,7 +371,9 @@ static const struct exynos_adc_data exynos_adc_v2_data = { static const struct exynos_adc_data exynos3250_adc_data = { .num_channels = MAX_EXYNOS3250_ADC_CHANNELS, + .mask = ADC_DATX_MASK, /* 12 bit ADC resolution */ .needs_sclk = true, + .needs_adc_phy = true, .init_hw = exynos_adc_v2_init_hw, .exit_hw = exynos_adc_v2_exit_hw, @@ -308,6 +383,18 @@ static const struct exynos_adc_data exynos3250_adc_data = { static const struct of_device_id exynos_adc_match[] = { { + .compatible = "samsung,s3c2410-adc", + .data = &exynos_adc_s3c24xx_data, + }, { + .compatible = "samsung,s3c2416-adc", + .data = &exynos_adc_s3c2416_data, + }, { + .compatible = "samsung,s3c2440-adc", + .data = &exynos_adc_s3c24xx_data, + }, { + .compatible = "samsung,s3c2443-adc", + .data = &exynos_adc_s3c2443_data, + }, { .compatible = "samsung,s3c6410-adc", .data = &exynos_adc_s3c64xx_data, }, { @@ -373,9 +460,10 @@ static int exynos_read_raw(struct iio_dev *indio_dev, static irqreturn_t exynos_adc_isr(int irq, void *dev_id) { struct exynos_adc *info = (struct exynos_adc *)dev_id; + u32 mask = info->data->mask; /* Read value */ - info->value = readl(ADC_V1_DATX(info->regs)) & ADC_DATX_MASK; + info->value = readl(ADC_V1_DATX(info->regs)) & mask; /* clear irq */ if (info->data->clear_irq) @@ -468,10 +556,13 @@ static int exynos_adc_probe(struct platform_device *pdev) if (IS_ERR(info->regs)) return PTR_ERR(info->regs); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - info->enable_reg = devm_ioremap_resource(&pdev->dev, mem); - if (IS_ERR(info->enable_reg)) - return PTR_ERR(info->enable_reg); + + if (info->data->needs_adc_phy) { + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + info->enable_reg = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(info->enable_reg)) + return PTR_ERR(info->enable_reg); + } irq = platform_get_irq(pdev, 0); if (irq < 0) { -- GitLab From cf4f7fc3e7336e2e946880890e60ed36178889ea Mon Sep 17 00:00:00 2001 From: Fabio Falzoi Date: Mon, 4 Aug 2014 17:08:07 +0200 Subject: [PATCH 0096/9167] ASoC: fsl-ssi: Support for SND_SOC_DAIFMT_CBM_CFS Add SND_SOC_DAIFMT_CBM_CFS support for Freescale architecture. Successfully tested on i.MX 6Quad Wandboard and UDOO boards connected to the pcm1792a codec. In CBM_CFS mode, when using a sample size of 16 bits, we cannot use CCSR_SSI_SCR_I2S_MODE_MASTER since we get a frame sync every 16 bits. Signed-off-by: Michael Trimarchi Signed-off-by: Fabio Falzoi Tested-by: Angelo Adamo Acked-by: Timur Tabi Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_ssi.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 87eb5776a39b..2fc3e6683e4f 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -259,6 +259,11 @@ static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private) SND_SOC_DAIFMT_CBS_CFS; } +static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi_private *ssi_private) +{ + return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == + SND_SOC_DAIFMT_CBM_CFS; +} /** * fsl_ssi_isr: SSI interrupt handler * @@ -705,6 +710,23 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, } } + if (!fsl_ssi_is_ac97(ssi_private)) { + u8 i2smode; + /* + * Switch to normal net mode in order to have a frame sync + * signal every 32 bits instead of 16 bits + */ + if (fsl_ssi_is_i2s_cbm_cfs(ssi_private) && sample_size == 16) + i2smode = CCSR_SSI_SCR_I2S_MODE_NORMAL | + CCSR_SSI_SCR_NET; + else + i2smode = ssi_private->i2s_mode; + + regmap_update_bits(regs, CCSR_SSI_SCR, + CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, + channels == 1 ? 0 : i2smode); + } + /* * FIXME: The documentation says that SxCCR[WL] should not be * modified while the SSI is enabled. The only time this can @@ -724,11 +746,6 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK, wl); - if (!fsl_ssi_is_ac97(ssi_private)) - regmap_update_bits(regs, CCSR_SSI_SCR, - CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, - channels == 1 ? 0 : ssi_private->i2s_mode); - return 0; } @@ -780,6 +797,7 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFS: case SND_SOC_DAIFMT_CBS_CFS: ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; regmap_update_bits(regs, CCSR_SSI_STCCR, @@ -853,6 +871,11 @@ static int _fsl_ssi_set_dai_fmt(struct fsl_ssi_private *ssi_private, case SND_SOC_DAIFMT_CBM_CFM: scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; break; + case SND_SOC_DAIFMT_CBM_CFS: + strcr &= ~CCSR_SSI_STCR_TXDIR; + strcr |= CCSR_SSI_STCR_TFDIR; + scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; + break; default: return -EINVAL; } -- GitLab From 7cdca1784c6e1c9bacf053847676df53eec7b5ea Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Fri, 8 Aug 2014 09:43:00 +0100 Subject: [PATCH 0097/9167] iio:buffer: Wrong sized allocation of demux table elements. The size of the allocation is currently set to the size of the pointer rather than the structure we should actually be allocating. Signed-off-by: Jonathan Cameron Reported-by: kbuild@01.org Reported-by: Dan Carpenter Acked-by: Lars-Peter Clausen --- drivers/iio/industrialio-buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index 84a952931f9f..ec82cb0bea38 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -951,7 +951,7 @@ static int iio_buffer_add_demux(struct iio_buffer *buffer, (*p)->to + (*p)->length == out_loc) { (*p)->length += length; } else { - *p = kmalloc(sizeof(*p), GFP_KERNEL); + *p = kmalloc(sizeof(**p), GFP_KERNEL); if (*p == NULL) return -ENOMEM; (*p)->from = in_loc; -- GitLab From f769cd247d2be5af377adf82882eddd1dce183c4 Mon Sep 17 00:00:00 2001 From: Vandana Kannan Date: Tue, 5 Aug 2014 07:51:22 -0700 Subject: [PATCH 0098/9167] drm/i915: Set M2_N2 registers during mode set For Gen < 8, set M2_N2 registers on every mode set. This is required to make sure M2_N2 registers are set during boot, resume from sleep for cross- checking the state. The register is set only if DRRS is supported. v2: Patch rebased v3: Daniel's review comments - Removed HAS_DRRS(dev) and added bool has_drrs to pipe_config to track drrs support v4: Jesse's review comments - Made changes to set m2_n2 in intel_dp_set_m_n() Signed-off-by: Vandana Kannan Cc: Daniel Vetter Cc: Jesse Barnes Signed-off-by: Rodrigo Vivi Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 28 +++++++++++++++++++++------- drivers/gpu/drm/i915/intel_dp.c | 18 +++--------------- drivers/gpu/drm/i915/intel_drv.h | 3 ++- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 018fb7222f60..acee1416eb93 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -91,11 +91,11 @@ static int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_i915_gem_object *obj); -static void intel_dp_set_m_n(struct intel_crtc *crtc); static void i9xx_set_pipeconf(struct intel_crtc *intel_crtc); static void intel_set_pipe_timings(struct intel_crtc *intel_crtc); static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, - struct intel_link_m_n *m_n); + struct intel_link_m_n *m_n, + struct intel_link_m_n *m2_n2); 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); @@ -3980,7 +3980,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->config.has_pch_encoder) { intel_cpu_transcoder_set_m_n(intel_crtc, - &intel_crtc->config.fdi_m_n); + &intel_crtc->config.fdi_m_n, NULL); } ironlake_set_pipeconf(crtc); @@ -4093,7 +4093,7 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) if (intel_crtc->config.has_pch_encoder) { intel_cpu_transcoder_set_m_n(intel_crtc, - &intel_crtc->config.fdi_m_n); + &intel_crtc->config.fdi_m_n, NULL); } haswell_set_pipeconf(crtc); @@ -5509,7 +5509,8 @@ static void intel_pch_transcoder_set_m_n(struct intel_crtc *crtc, } static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, - struct intel_link_m_n *m_n) + struct intel_link_m_n *m_n, + struct intel_link_m_n *m2_n2) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -5521,6 +5522,18 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, I915_WRITE(PIPE_DATA_N1(transcoder), m_n->gmch_n); I915_WRITE(PIPE_LINK_M1(transcoder), m_n->link_m); I915_WRITE(PIPE_LINK_N1(transcoder), m_n->link_n); + /* M2_N2 registers to be set only for gen < 8 (M2_N2 available + * for gen < 8) and if DRRS is supported (to make sure the + * registers are not unnecessarily accessed). + */ + if (m2_n2 && INTEL_INFO(dev)->gen < 8 && + crtc->config.has_drrs) { + I915_WRITE(PIPE_DATA_M2(transcoder), + TU_SIZE(m2_n2->tu) | m2_n2->gmch_m); + I915_WRITE(PIPE_DATA_N2(transcoder), m2_n2->gmch_n); + I915_WRITE(PIPE_LINK_M2(transcoder), m2_n2->link_m); + I915_WRITE(PIPE_LINK_N2(transcoder), m2_n2->link_n); + } } else { I915_WRITE(PIPE_DATA_M_G4X(pipe), TU_SIZE(m_n->tu) | m_n->gmch_m); I915_WRITE(PIPE_DATA_N_G4X(pipe), m_n->gmch_n); @@ -5529,12 +5542,13 @@ static void intel_cpu_transcoder_set_m_n(struct intel_crtc *crtc, } } -static void intel_dp_set_m_n(struct intel_crtc *crtc) +void intel_dp_set_m_n(struct intel_crtc *crtc) { if (crtc->config.has_pch_encoder) intel_pch_transcoder_set_m_n(crtc, &crtc->config.dp_m_n); else - intel_cpu_transcoder_set_m_n(crtc, &crtc->config.dp_m_n); + intel_cpu_transcoder_set_m_n(crtc, &crtc->config.dp_m_n, + &crtc->config.dp_m2_n2); } static void vlv_update_pll(struct intel_crtc *crtc) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 805b6f63df0f..3ea5cef9bbe6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -828,20 +828,6 @@ intel_dp_set_clock(struct intel_encoder *encoder, } } -static void -intel_dp_set_m2_n2(struct intel_crtc *crtc, struct intel_link_m_n *m_n) -{ - struct drm_device *dev = crtc->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - enum transcoder transcoder = crtc->config.cpu_transcoder; - - I915_WRITE(PIPE_DATA_M2(transcoder), - TU_SIZE(m_n->tu) | m_n->gmch_m); - I915_WRITE(PIPE_DATA_N2(transcoder), m_n->gmch_n); - I915_WRITE(PIPE_LINK_M2(transcoder), m_n->link_m); - I915_WRITE(PIPE_LINK_N2(transcoder), m_n->link_n); -} - bool intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_config *pipe_config) @@ -867,6 +853,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, pipe_config->has_pch_encoder = true; pipe_config->has_dp_encoder = true; + pipe_config->has_drrs = false; pipe_config->has_audio = intel_dp->has_audio; if (is_edp(intel_dp) && intel_connector->panel.fixed_mode) { @@ -970,6 +957,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, if (intel_connector->panel.downclock_mode != NULL && intel_dp->drrs_state.type == SEAMLESS_DRRS_SUPPORT) { + pipe_config->has_drrs = true; intel_link_compute_m_n(bpp, lane_count, intel_connector->panel.downclock_mode->clock, pipe_config->port_clock, @@ -4389,7 +4377,7 @@ void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) val = I915_READ(reg); if (index > DRRS_HIGH_RR) { val |= PIPECONF_EDP_RR_MODE_SWITCH; - intel_dp_set_m2_n2(intel_crtc, &config->dp_m2_n2); + intel_dp_set_m_n(intel_crtc); } else { val &= ~PIPECONF_EDP_RR_MODE_SWITCH; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 4b2664bd5b81..7a3cac095afe 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -324,6 +324,7 @@ struct intel_crtc_config { /* m2_n2 for eDP downclock */ struct intel_link_m_n dp_m2_n2; + bool has_drrs; /* * Frequence the dpll for the port should run at. Differs from the @@ -877,6 +878,7 @@ void hsw_enable_pc8(struct drm_i915_private *dev_priv); void hsw_disable_pc8(struct drm_i915_private *dev_priv); void intel_dp_get_m_n(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config); +void intel_dp_set_m_n(struct intel_crtc *crtc); int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n); void ironlake_check_encoder_dotclock(const struct intel_crtc_config *pipe_config, @@ -892,7 +894,6 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode, int intel_format_to_fourcc(int format); void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc); - /* intel_dp.c */ void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port, -- GitLab From b95af8bee524974768681b2b92235e1e1e21bf1a Mon Sep 17 00:00:00 2001 From: Vandana Kannan Date: Tue, 5 Aug 2014 07:51:23 -0700 Subject: [PATCH 0099/9167] drm/i915: State readout and cross-checking for dp_m2_n2 Adding relevant read out comparison code, in check_crtc_state, for the new member of crtc_config, dp_m2_n2, which was introduced to store link_m_n values for a DP downclock mode (if available). Suggested by Daniel. v2: Changed patch title. Daniel's review comments incorporated. Added relevant state readout code for M2_N2. dp_m2_n2 comparison to be done only when high RR is not in use (This is because alternate m_n register programming will be done only when low RR is being used). v3: Modified call to get_m2_n2 which had dp_m_n as param by mistake. Compare dp_m_n and dp_m2_n2 for gen 7 and below. compare the structures based on DRRS state for gen 8 and above. Save and restore M2 N2 registers for gen 7 and below v4: For Gen>=8, check M_N registers against dp_m_n and dp_m2_n2 as there is only one set of M_N registers v5: Removed the chunk which saves and restores M2_N2 registers. Modified get_m_n() to get M2_N2 registers as well. Modified the macro which compares hw.dp_m_n against sw.dp_m2_n2/sw.dp_m_n for gen > 8. v6: Added check to compare dp_m2_n2 only when DRRS is enabled v7: Modified drrs check to use has_drrs v8: Add has_drrs check before reading M2_N2 registers Signed-off-by: Vandana Kannan Cc: Daniel Vetter Cc: Jani Nikula Cc: Jesse Barnes Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 75 +++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index acee1416eb93..620a89961d36 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7149,7 +7149,8 @@ static void intel_pch_transcoder_get_m_n(struct intel_crtc *crtc, static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc, enum transcoder transcoder, - struct intel_link_m_n *m_n) + struct intel_link_m_n *m_n, + struct intel_link_m_n *m2_n2) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -7163,6 +7164,20 @@ static void intel_cpu_transcoder_get_m_n(struct intel_crtc *crtc, m_n->gmch_n = I915_READ(PIPE_DATA_N1(transcoder)); m_n->tu = ((I915_READ(PIPE_DATA_M1(transcoder)) & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; + /* Read M2_N2 registers only for gen < 8 (M2_N2 available for + * gen < 8) and if DRRS is supported (to make sure the + * registers are not unnecessarily read). + */ + if (m2_n2 && INTEL_INFO(dev)->gen < 8 && + crtc->config.has_drrs) { + m2_n2->link_m = I915_READ(PIPE_LINK_M2(transcoder)); + m2_n2->link_n = I915_READ(PIPE_LINK_N2(transcoder)); + m2_n2->gmch_m = I915_READ(PIPE_DATA_M2(transcoder)) + & ~TU_SIZE_MASK; + m2_n2->gmch_n = I915_READ(PIPE_DATA_N2(transcoder)); + m2_n2->tu = ((I915_READ(PIPE_DATA_M2(transcoder)) + & TU_SIZE_MASK) >> TU_SIZE_SHIFT) + 1; + } } else { m_n->link_m = I915_READ(PIPE_LINK_M_G4X(pipe)); m_n->link_n = I915_READ(PIPE_LINK_N_G4X(pipe)); @@ -7181,14 +7196,15 @@ void intel_dp_get_m_n(struct intel_crtc *crtc, intel_pch_transcoder_get_m_n(crtc, &pipe_config->dp_m_n); else intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder, - &pipe_config->dp_m_n); + &pipe_config->dp_m_n, + &pipe_config->dp_m2_n2); } static void ironlake_get_fdi_m_n_config(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config) { intel_cpu_transcoder_get_m_n(crtc, pipe_config->cpu_transcoder, - &pipe_config->fdi_m_n); + &pipe_config->fdi_m_n, NULL); } static void ironlake_get_pfit_config(struct intel_crtc *crtc, @@ -10005,6 +10021,15 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc, pipe_config->dp_m_n.gmch_m, pipe_config->dp_m_n.gmch_n, pipe_config->dp_m_n.link_m, pipe_config->dp_m_n.link_n, pipe_config->dp_m_n.tu); + + DRM_DEBUG_KMS("dp: %i, gmch_m2: %u, gmch_n2: %u, link_m2: %u, link_n2: %u, tu2: %u\n", + pipe_config->has_dp_encoder, + pipe_config->dp_m2_n2.gmch_m, + pipe_config->dp_m2_n2.gmch_n, + pipe_config->dp_m2_n2.link_m, + pipe_config->dp_m2_n2.link_n, + pipe_config->dp_m2_n2.tu); + DRM_DEBUG_KMS("requested mode:\n"); drm_mode_debug_printmodeline(&pipe_config->requested_mode); DRM_DEBUG_KMS("adjusted mode:\n"); @@ -10385,6 +10410,22 @@ intel_pipe_config_compare(struct drm_device *dev, return false; \ } +/* This is required for BDW+ where there is only one set of registers for + * switching between high and low RR. + * This macro can be used whenever a comparison has to be made between one + * hw state and multiple sw state variables. + */ +#define PIPE_CONF_CHECK_I_ALT(name, alt_name) \ + if ((current_config->name != pipe_config->name) && \ + (current_config->alt_name != pipe_config->name)) { \ + DRM_ERROR("mismatch in " #name " " \ + "(expected %i or %i, found %i)\n", \ + current_config->name, \ + current_config->alt_name, \ + pipe_config->name); \ + return false; \ + } + #define PIPE_CONF_CHECK_FLAGS(name, mask) \ if ((current_config->name ^ pipe_config->name) & (mask)) { \ DRM_ERROR("mismatch in " #name "(" #mask ") " \ @@ -10417,11 +10458,28 @@ intel_pipe_config_compare(struct drm_device *dev, PIPE_CONF_CHECK_I(fdi_m_n.tu); PIPE_CONF_CHECK_I(has_dp_encoder); - PIPE_CONF_CHECK_I(dp_m_n.gmch_m); - PIPE_CONF_CHECK_I(dp_m_n.gmch_n); - PIPE_CONF_CHECK_I(dp_m_n.link_m); - PIPE_CONF_CHECK_I(dp_m_n.link_n); - PIPE_CONF_CHECK_I(dp_m_n.tu); + + if (INTEL_INFO(dev)->gen < 8) { + PIPE_CONF_CHECK_I(dp_m_n.gmch_m); + PIPE_CONF_CHECK_I(dp_m_n.gmch_n); + PIPE_CONF_CHECK_I(dp_m_n.link_m); + PIPE_CONF_CHECK_I(dp_m_n.link_n); + PIPE_CONF_CHECK_I(dp_m_n.tu); + + if (current_config->has_drrs) { + PIPE_CONF_CHECK_I(dp_m2_n2.gmch_m); + PIPE_CONF_CHECK_I(dp_m2_n2.gmch_n); + PIPE_CONF_CHECK_I(dp_m2_n2.link_m); + PIPE_CONF_CHECK_I(dp_m2_n2.link_n); + PIPE_CONF_CHECK_I(dp_m2_n2.tu); + } + } else { + PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_m, dp_m2_n2.gmch_m); + PIPE_CONF_CHECK_I_ALT(dp_m_n.gmch_n, dp_m2_n2.gmch_n); + PIPE_CONF_CHECK_I_ALT(dp_m_n.link_m, dp_m2_n2.link_m); + PIPE_CONF_CHECK_I_ALT(dp_m_n.link_n, dp_m2_n2.link_n); + PIPE_CONF_CHECK_I_ALT(dp_m_n.tu, dp_m2_n2.tu); + } PIPE_CONF_CHECK_I(adjusted_mode.crtc_hdisplay); PIPE_CONF_CHECK_I(adjusted_mode.crtc_htotal); @@ -10507,6 +10565,7 @@ intel_pipe_config_compare(struct drm_device *dev, #undef PIPE_CONF_CHECK_X #undef PIPE_CONF_CHECK_I +#undef PIPE_CONF_CHECK_I_ALT #undef PIPE_CONF_CHECK_FLAGS #undef PIPE_CONF_CHECK_CLOCK_FUZZY #undef PIPE_CONF_QUIRK -- GitLab From 020178a1bcadf20b9d057988984f374c905d542e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 22 May 2014 19:36:03 +0300 Subject: [PATCH 0100/9167] drm: Add drm_crtc_vblank_waitqueue() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a small static inline helper to grab the vblank wait queue based on the drm_crtc. This is useful for drivers to do internal vblank waits using wait_event() & co. v2: Pimp commit message (Daniel) Add kernel doc (Daniel) Suggested-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 1 + include/drm/drmP.h | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 1d3756d3176c..972759489376 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3400,6 +3400,7 @@ void (*disable_vblank) (struct drm_device *dev, int crtc); Vertical Blanking and Interrupt Handling Functions Reference !Edrivers/gpu/drm/drm_irq.c +!Iinclude/drm/drmP.h drm_crtc_vblank_waitqueue diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d3d9be6b83ef..bb44c1ee557d 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1344,6 +1344,17 @@ extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, extern void drm_calc_timestamping_constants(struct drm_crtc *crtc, const struct drm_display_mode *mode); +/** + * drm_crtc_vblank_waitqueue - get vblank waitqueue for the CRTC + * @crtc: which CRTC's vblank waitqueue to retrieve + * + * This function returns a pointer to the vblank waitqueue for the CRTC. + * Drivers can use this to implement vblank waits using wait_event() & co. + */ +static inline wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc) +{ + return &crtc->dev->vblank[drm_crtc_index(crtc)].queue; +} /* Modesetting support */ extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); -- GitLab From 210871b67cd201c198b61ca80e1c51cd4b58c051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 22 May 2014 19:00:50 +0300 Subject: [PATCH 0101/9167] drm/i915: Kill intel_crtc->vbl_wait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Share the waitqueue that drm_irq uses when performing the vblank evade trick for atomic pipe updates. v2: Keep intel_pipe_handle_vblank() (Chris) Suggested-by: Daniel Vetter Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 5 ----- drivers/gpu/drm/i915/intel_display.c | 2 -- drivers/gpu/drm/i915/intel_drv.h | 2 -- drivers/gpu/drm/i915/intel_sprite.c | 5 +++-- 4 files changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 390ccc2a3096..0e44c433cfc3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1989,14 +1989,9 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, u32 pm_iir) static bool intel_pipe_handle_vblank(struct drm_device *dev, enum pipe pipe) { - struct intel_crtc *crtc; - if (!drm_handle_vblank(dev, pipe)) return false; - crtc = to_intel_crtc(intel_get_crtc_for_pipe(dev, pipe)); - wake_up(&crtc->vbl_wait); - return true; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 620a89961d36..a9b351d1ff88 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11870,8 +11870,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) intel_crtc->cursor_base = ~0; intel_crtc->cursor_cntl = ~0; - init_waitqueue_head(&intel_crtc->vbl_wait); - BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7a3cac095afe..3198de3007be 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -425,8 +425,6 @@ struct intel_crtc { struct intel_pipe_wm active; } wm; - wait_queue_head_t vbl_wait; - int scanline_offset; struct intel_mmio_flip mmio_flip; }; diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 168c6652cda1..d34a5696ffb6 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -53,6 +53,7 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl enum pipe pipe = crtc->pipe; long timeout = msecs_to_jiffies_timeout(1); int scanline, min, max, vblank_start; + wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base); DEFINE_WAIT(wait); WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex)); @@ -81,7 +82,7 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl * other CPUs can see the task state update by the time we * read the scanline. */ - prepare_to_wait(&crtc->vbl_wait, &wait, TASK_UNINTERRUPTIBLE); + prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); scanline = intel_get_crtc_scanline(crtc); if (scanline < min || scanline > max) @@ -100,7 +101,7 @@ static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl local_irq_disable(); } - finish_wait(&crtc->vbl_wait, &wait); + finish_wait(wq, &wait); drm_vblank_put(dev, pipe); -- GitLab From 4811ff4f2388727a161ea49c2b0ddca95e44c7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:07 +0300 Subject: [PATCH 0102/9167] drm/i915: Add chv_power_wells[] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add chv_power_wells[] so we can start to build up the power well support for chv. Just the "always on" well there initialy. Signed-off-by: Ville Syrjälä Tested-by: Rafael Barbalho Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 615e341682c3..7dbd7892b968 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6574,6 +6574,15 @@ static struct i915_power_well vlv_power_wells[] = { }, }; +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, + }, +}; + static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, enum punit_power_well power_well_id) { @@ -6610,6 +6619,8 @@ int intel_power_domains_init(struct drm_i915_private *dev_priv) } 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 { -- GitLab From 5d6f7ea752228788eddce0b9e268fa1f0eabdd7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:08 +0300 Subject: [PATCH 0103/9167] drm/i915: Add chv cmnlane power wells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHV has two display PHYs so there are also two cmnlane power wells. Add the approriate code to power the wells up/down. Like on VLV we do the cmnreset assert/deassert and the DPLL refclock enabling at approriate times. This code actually works on my bsw. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 89 +++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e4d7607da2c4..c3338ca4ab17 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -514,6 +514,7 @@ enum punit_power_well { PUNIT_POWER_WELL_DPIO_TX_C_LANES_23 = 9, PUNIT_POWER_WELL_DPIO_RX0 = 10, PUNIT_POWER_WELL_DPIO_RX1 = 11, + PUNIT_POWER_WELL_DPIO_CMN_D = 12, PUNIT_POWER_WELL_NUM, }; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 7dbd7892b968..8a78015dd51e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6254,6 +6254,64 @@ static void vlv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, 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, + PHY_COM_LANE_RESET_DEASSERT(phy, I915_READ(DISPLAY_PHY_CONTROL))); +} + +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, + PHY_COM_LANE_RESET_ASSERT(phy, I915_READ(DISPLAY_PHY_CONTROL))); + + vlv_set_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) { @@ -6445,6 +6503,18 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) | \ 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)) + 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, @@ -6452,6 +6522,13 @@ static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { .is_enabled = i9xx_always_on_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", @@ -6581,6 +6658,18 @@ static struct i915_power_well chv_power_wells[] = { .domains = VLV_ALWAYS_ON_POWER_DOMAINS, .ops = &i9xx_always_on_power_well_ops, }, + { + .name = "dpio-common-bc", + .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS, + .data = PUNIT_POWER_WELL_DPIO_CMN_BC, + .ops = &chv_dpio_cmn_power_well_ops, + }, + { + .name = "dpio-common-d", + .domains = CHV_DPIO_CMN_D_POWER_DOMAINS, + .data = PUNIT_POWER_WELL_DPIO_CMN_D, + .ops = &chv_dpio_cmn_power_well_ops, + }, }; static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, -- GitLab From a74d782c74644b2e50b3db61e115831cdc3e9010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:09 +0300 Subject: [PATCH 0104/9167] drm/i915: Kill intel_reset_dpio() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both VLV and CHV handle the cmnreset stuff in the power well code now, so intel_reset_dpio() is no longer needed. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 31 ---------------------------- 1 file changed, 31 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a9b351d1ff88..c0575ea1e196 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1513,34 +1513,6 @@ static void intel_init_dpio(struct drm_device *dev) } } -static void intel_reset_dpio(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - - if (IS_CHERRYVIEW(dev)) { - enum dpio_phy phy; - u32 val; - - for (phy = DPIO_PHY0; phy < I915_NUM_PHYS_VLV; phy++) { - /* 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); - - /* - * Deassert common lane reset for PHY. - * - * This should only be done on init and resume from S3 - * with both PLLs disabled, or we risk losing DPIO and - * PLL synchronization. - */ - val = I915_READ(DISPLAY_PHY_CONTROL); - I915_WRITE(DISPLAY_PHY_CONTROL, - PHY_COM_LANE_RESET_DEASSERT(phy, val)); - } - } -} - static void vlv_enable_pll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; @@ -12615,8 +12587,6 @@ void intel_modeset_init_hw(struct drm_device *dev) intel_init_clock_gating(dev); - intel_reset_dpio(dev); - intel_enable_gt_powersave(dev); } @@ -12687,7 +12657,6 @@ void intel_modeset_init(struct drm_device *dev) } intel_init_dpio(dev); - intel_reset_dpio(dev); intel_shared_dpll_init(dev); -- GitLab From f07057d13c62c5b925725c6e03a0c4d1c0244bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:10 +0300 Subject: [PATCH 0105/9167] drm/i915: Add disp2d power well for chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not sure if it's still there since chv has per-pipe power wells. At least with current Punit this doesn't work. Also the display irq handling would need to be adjusted for pipe C. So leave the code iffed out for now. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak 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 8a78015dd51e..dc8719f29d03 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6658,6 +6658,14 @@ static struct i915_power_well chv_power_wells[] = { .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, + }, +#endif { .name = "dpio-common-bc", .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS, -- GitLab From 26972b0a80091ccece1cbd9422772ae625a612f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:11 +0300 Subject: [PATCH 0106/9167] drm/i915: Add per-pipe power wells for chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHV has a power well for each pipe. Add the code to deal with them. The Punit in current hardware doesn't seem ready for this yet, so leave it iffed out. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 12 +++ drivers/gpu/drm/i915/intel_pm.c | 126 ++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c3338ca4ab17..9d54aee6f8c8 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -501,6 +501,18 @@ #define DSPFREQSTAT_MASK (0x3 << DSPFREQSTAT_SHIFT) #define DSPFREQGUAR_SHIFT 14 #define DSPFREQGUAR_MASK (0x3 << DSPFREQGUAR_SHIFT) +#define _DP_SSC(val, pipe) ((val) << (2 * (pipe))) +#define DP_SSC_MASK(pipe) _DP_SSC(0x3, (pipe)) +#define DP_SSC_PWR_ON(pipe) _DP_SSC(0x0, (pipe)) +#define DP_SSC_CLK_GATE(pipe) _DP_SSC(0x1, (pipe)) +#define DP_SSC_RESET(pipe) _DP_SSC(0x2, (pipe)) +#define DP_SSC_PWR_GATE(pipe) _DP_SSC(0x3, (pipe)) +#define _DP_SSS(val, pipe) ((val) << (2 * (pipe) + 16)) +#define DP_SSS_MASK(pipe) _DP_SSS(0x3, (pipe)) +#define DP_SSS_PWR_ON(pipe) _DP_SSS(0x0, (pipe)) +#define DP_SSS_CLK_GATE(pipe) _DP_SSS(0x1, (pipe)) +#define DP_SSS_RESET(pipe) _DP_SSS(0x2, (pipe)) +#define DP_SSS_PWR_GATE(pipe) _DP_SSS(0x3, (pipe)) /* See the PUNIT HAS v0.8 for the below bits */ enum punit_power_well { diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index dc8719f29d03..95b3ca5964e9 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6312,6 +6312,95 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, 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) { @@ -6503,6 +6592,18 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); 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) | \ @@ -6522,6 +6623,13 @@ static const struct i915_power_well_ops i9xx_always_on_power_well_ops = { .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, @@ -6665,6 +6773,24 @@ static struct i915_power_well chv_power_wells[] = { .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", -- GitLab From 8258356537871cf579868002552a0ed1762b0487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:12 +0300 Subject: [PATCH 0107/9167] drm/i915: Add chv port B and C TX wells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the TX wells for ports B and C just like on VLV. Again Punit doesn't seem ready (or the wells don't even exist anymore) so leave it iffed out. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 95b3ca5964e9..59157635d418 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6804,6 +6804,36 @@ static struct i915_power_well chv_power_wells[] = { .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, + }, +#endif }; static struct i915_power_well *lookup_power_well(struct drm_i915_private *dev_priv, -- GitLab From 2ce147f36dc5a1f3b49abd8ce3164ad0f04ec863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:13 +0300 Subject: [PATCH 0108/9167] drm/i915: Add chv port D TX wells MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the TX wells for port D. The Punit subsystem numbers are a total guess at this time. Also I'm not sure these even exist. Certainly the Punit in current hardware doesn't deal with these. Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 4 ++++ drivers/gpu/drm/i915/intel_pm.c | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 9d54aee6f8c8..e01a1a0b9613 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -527,6 +527,10 @@ enum punit_power_well { PUNIT_POWER_WELL_DPIO_RX0 = 10, PUNIT_POWER_WELL_DPIO_RX1 = 11, PUNIT_POWER_WELL_DPIO_CMN_D = 12, + /* FIXME: guesswork below */ + PUNIT_POWER_WELL_DPIO_TX_D_LANES_01 = 13, + PUNIT_POWER_WELL_DPIO_TX_D_LANES_23 = 14, + PUNIT_POWER_WELL_DPIO_RX2 = 15, PUNIT_POWER_WELL_NUM, }; diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 59157635d418..f4a1837c231c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6616,6 +6616,15 @@ EXPORT_SYMBOL_GPL(i915_get_cdclk_freq); 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, @@ -6833,6 +6842,20 @@ static struct i915_power_well chv_power_wells[] = { .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 }; -- GitLab From 026b96e293fbe48153ae868308e341f226d76c46 Mon Sep 17 00:00:00 2001 From: Rafael Barbalho Date: Mon, 28 Jul 2014 19:56:27 +0100 Subject: [PATCH 0109/9167] drm/i915: Fix read back of plane stride register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the specifications bit 6 is actually valid in the stride register. Cc: Jesse Barnes Cc: Ville Syrjälä Signed-off-by: Rafael Barbalho 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 c0575ea1e196..71957e7184ef 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6211,7 +6211,7 @@ static void i9xx_get_plane_config(struct intel_crtc *crtc, crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1; val = I915_READ(DSPSTRIDE(pipe)); - crtc->base.primary->fb->pitches[0] = val & 0xffffff80; + crtc->base.primary->fb->pitches[0] = val & 0xffffffc0; aligned_height = intel_align_height(dev, crtc->base.primary->fb->height, plane_config->tiled); @@ -7247,7 +7247,7 @@ static void ironlake_get_plane_config(struct intel_crtc *crtc, crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1; val = I915_READ(DSPSTRIDE(pipe)); - crtc->base.primary->fb->pitches[0] = val & 0xffffff80; + crtc->base.primary->fb->pitches[0] = val & 0xffffffc0; aligned_height = intel_align_height(dev, crtc->base.primary->fb->height, plane_config->tiled); -- GitLab From a5043453aa2412ece984373294529d177324c901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:18 +0300 Subject: [PATCH 0110/9167] drm/i915: Split a few long debug prints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split some WM debug prints to multiple lines. This shouldn't hurt grappability since the important part is at the start and the rest is just repeated stuff for each pipe. Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index f4a1837c231c..a318cd5ad8ed 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1387,7 +1387,8 @@ static void valleyview_update_wm(struct drm_crtc *crtc) plane_sr = cursor_sr = 0; } - DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", + DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, " + "B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", planea_wm, cursora_wm, planeb_wm, cursorb_wm, plane_sr, cursor_sr); @@ -1443,7 +1444,8 @@ static void g4x_update_wm(struct drm_crtc *crtc) plane_sr = cursor_sr = 0; } - DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", + DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, " + "B: plane=%d, cursor=%d, SR: plane=%d, cursor=%d\n", planea_wm, cursora_wm, planeb_wm, cursorb_wm, plane_sr, cursor_sr); -- GitLab From aad3d14d25c33c8e510c41aaaf2668e8d32811ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:25 +0300 Subject: [PATCH 0111/9167] drm/i915: Add DP training pattern 3 for CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHV supports DP training pattern 3. Add the required stuff. Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_dp.c | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e01a1a0b9613..e355fc8d4d59 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3489,6 +3489,8 @@ enum punit_power_well { #define DP_LINK_TRAIN_OFF (3 << 28) #define DP_LINK_TRAIN_MASK (3 << 28) #define DP_LINK_TRAIN_SHIFT 28 +#define DP_LINK_TRAIN_PAT_3_CHV (1 << 14) +#define DP_LINK_TRAIN_MASK_CHV ((3 << 28)|(1<<14)) /* CPT Link training mode */ #define DP_LINK_TRAIN_PAT_1_CPT (0 << 8) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3ea5cef9bbe6..0aa219dff19c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2959,7 +2959,10 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, } } else { - *DP &= ~DP_LINK_TRAIN_MASK; + if (IS_CHERRYVIEW(dev)) + *DP &= ~DP_LINK_TRAIN_MASK_CHV; + else + *DP &= ~DP_LINK_TRAIN_MASK; switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { case DP_TRAINING_PATTERN_DISABLE: @@ -2972,8 +2975,12 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, *DP |= DP_LINK_TRAIN_PAT_2; break; case DP_TRAINING_PATTERN_3: - DRM_ERROR("DP training pattern 3 not supported\n"); - *DP |= DP_LINK_TRAIN_PAT_2; + if (IS_CHERRYVIEW(dev)) { + *DP |= DP_LINK_TRAIN_PAT_3_CHV; + } else { + DRM_ERROR("DP training pattern 3 not supported\n"); + *DP |= DP_LINK_TRAIN_PAT_2; + } break; } } @@ -3260,7 +3267,10 @@ intel_dp_link_down(struct intel_dp *intel_dp) DP &= ~DP_LINK_TRAIN_MASK_CPT; I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); } else { - DP &= ~DP_LINK_TRAIN_MASK; + if (IS_CHERRYVIEW(dev)) + DP &= ~DP_LINK_TRAIN_MASK_CHV; + else + DP &= ~DP_LINK_TRAIN_MASK; I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); } POSTING_READ(intel_dp->output_reg); -- GitLab From dcfc3552136fb6996e19b9f6980dc5a6721defd5 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:16 +0100 Subject: [PATCH 0112/9167] drm/i915: Specify when the PLL hw state fields are valid Not all those fields are valid on a given platform. Make it explicit. Unions could also be used, but were cluttering some code paths with if/else ladders. v2: Don't use anonymous unions (Daniel) Signed-off-by: Damien Lespiau 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 c70b2b67282e..c3beb08813c6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -197,10 +197,13 @@ enum intel_dpll_id { #define I915_NUM_PLLS 2 struct intel_dpll_hw_state { + /* i9xx, pch plls */ uint32_t dpll; uint32_t dpll_md; uint32_t fp0; uint32_t fp1; + + /* hsw, bdw */ uint32_t wrpll; }; -- GitLab From 74dd69280bc3f3e84d46b2a0f78901a0d9b4562c Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:17 +0100 Subject: [PATCH 0113/9167] drm/i915: Add a space to the shared DPLL debug message 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 71957e7184ef..0b8769b9422f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1778,7 +1778,7 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc) if (WARN_ON(pll->refcount == 0)) return; - DRM_DEBUG_KMS("enable %s (active %d, on? %d)for crtc %d\n", + DRM_DEBUG_KMS("enable %s (active %d, on? %d) for crtc %d\n", pll->name, pll->active, pll->on, crtc->base.base.id); -- GitLab From 7d2c81751c858442387fa5158d4cd80c2190d739 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:18 +0100 Subject: [PATCH 0114/9167] drm/i915: Extract the HSW DDI selection code into its own function Future platform will slightly change that. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0b8769b9422f..c3bb5f7fd21b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7607,6 +7607,22 @@ static int haswell_crtc_mode_set(struct drm_crtc *crtc, return 0; } +static void haswell_get_ddi_pll(struct drm_i915_private *dev_priv, + enum port port, + struct intel_crtc_config *pipe_config) +{ + pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port)); + + switch (pipe_config->ddi_pll_sel) { + case PORT_CLK_SEL_WRPLL1: + pipe_config->shared_dpll = DPLL_ID_WRPLL1; + break; + case PORT_CLK_SEL_WRPLL2: + pipe_config->shared_dpll = DPLL_ID_WRPLL2; + break; + } +} + static void haswell_get_ddi_port_state(struct intel_crtc *crtc, struct intel_crtc_config *pipe_config) { @@ -7620,16 +7636,7 @@ static void haswell_get_ddi_port_state(struct intel_crtc *crtc, port = (tmp & TRANS_DDI_PORT_MASK) >> TRANS_DDI_PORT_SHIFT; - pipe_config->ddi_pll_sel = I915_READ(PORT_CLK_SEL(port)); - - switch (pipe_config->ddi_pll_sel) { - case PORT_CLK_SEL_WRPLL1: - pipe_config->shared_dpll = DPLL_ID_WRPLL1; - break; - case PORT_CLK_SEL_WRPLL2: - pipe_config->shared_dpll = DPLL_ID_WRPLL2; - break; - } + haswell_get_ddi_pll(dev_priv, port, pipe_config); if (pipe_config->shared_dpll >= 0) { pll = &dev_priv->shared_dplls[pipe_config->shared_dpll]; -- GitLab From 143b307c43dcfeae41a3b6c24a29fae4c70884f4 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:19 +0100 Subject: [PATCH 0115/9167] drm/i915: Extract the HSW/BDW shared dpll init code So we can easily provide an alternate implementation in the future. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 5db0b5552e39..ee7a74c6e93a 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1248,10 +1248,8 @@ static const char * const hsw_ddi_pll_names[] = { "WRPLL 2", }; -void intel_ddi_pll_init(struct drm_device *dev) +static void hsw_shared_dplls_init(struct drm_i915_private *dev_priv) { - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t val = I915_READ(LCPLL_CTL); int i; dev_priv->num_shared_dpll = 2; @@ -1264,6 +1262,14 @@ void intel_ddi_pll_init(struct drm_device *dev) dev_priv->shared_dplls[i].get_hw_state = hsw_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); /* 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. -- GitLab From ea155f32cea99f17371bec00ee9c8e3713a15d4f Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:20 +0100 Subject: [PATCH 0116/9167] drm/i915: Restrict hsw_dp_set_ddi_pll_sel() to HSW/BDW Future platform will use config->ddi_pll_sel in a different way. Signed-off-by: Damien Lespiau 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 0aa219dff19c..16fcfc67f014 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -964,7 +964,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, &pipe_config->dp_m2_n2); } - if (HAS_DDI(dev)) + 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 bf9584bd0e99bd284e115ea8eba9b02a5a2d7b4d Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:21 +0100 Subject: [PATCH 0117/9167] drm/i915: Fix stale comment for intel_ddi_pll_select() Since the run-time PM on DPMS series, this function has an outdated comment. Refresh it a bit. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ee7a74c6e93a..3b6375d3e422 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -709,10 +709,11 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */, } /* - * Tries to find a PLL for the CRTC. If it finds, it increases the refcount and - * stores it in intel_crtc->ddi_pll_sel, so other mode sets won't be able to - * steal the selected PLL. You need to call intel_ddi_pll_enable to actually - * enable the PLL. + * Tries to find a *shared* PLL for the CRTC and store it in + * intel_crtc->ddi_pll_sel. + * + * For private DPLLs, compute_config() should do the selection for us. This + * function should be folded into compute_config() eventually. */ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) { -- GitLab From 0220ab6e00785da008bb3736737b877d45858608 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:22 +0100 Subject: [PATCH 0118/9167] drm/i915: Split the BDW/HSW specific shared pll selection We'll need a different algorithm to select the shared DPLL. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 39 +++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3b6375d3e422..09599851f1a8 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -708,23 +708,10 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */, *r2_out = best.r2; } -/* - * Tries to find a *shared* PLL for the CRTC and store it in - * intel_crtc->ddi_pll_sel. - * - * For private DPLLs, compute_config() should do the selection for us. This - * function should be folded into compute_config() eventually. - */ -bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) +static bool +hsw_ddi_pll_select(struct intel_crtc *intel_crtc, int output, int clock) { - struct drm_crtc *crtc = &intel_crtc->base; - struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); - int type = intel_encoder->type; - int clock = intel_crtc->config.port_clock; - - intel_put_shared_dpll(intel_crtc); - - if (type == INTEL_OUTPUT_HDMI) { + if (output == INTEL_OUTPUT_HDMI) { struct intel_shared_dpll *pll; uint32_t val; unsigned p, n2, r2; @@ -750,6 +737,26 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc) return true; } + +/* + * Tries to find a *shared* PLL for the CRTC and store it in + * intel_crtc->ddi_pll_sel. + * + * For private DPLLs, compute_config() should do the selection for us. This + * function should be folded into compute_config() eventually. + */ +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 type = intel_encoder->type; + int clock = intel_crtc->config.port_clock; + + intel_put_shared_dpll(intel_crtc); + + return hsw_ddi_pll_select(intel_crtc, type, clock); +} + void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) { struct drm_i915_private *dev_priv = crtc->dev->dev_private; -- GitLab From d664c0cece2dd410d8134aa820112e471e3592dd Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:23 +0100 Subject: [PATCH 0119/9167] drm/i915: Make intel_ddi_calculate_wrpll() HSW/BDW specific Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 09599851f1a8..eb8e494ce569 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -644,8 +644,8 @@ void intel_ddi_clock_get(struct intel_encoder *encoder, } static void -intel_ddi_calculate_wrpll(int clock /* in Hz */, - unsigned *r2_out, unsigned *n2_out, unsigned *p_out) +hsw_ddi_calculate_wrpll(int clock /* in Hz */, + unsigned *r2_out, unsigned *n2_out, unsigned *p_out) { uint64_t freq2k; unsigned p, n2, r2; @@ -709,14 +709,16 @@ intel_ddi_calculate_wrpll(int clock /* in Hz */, } static bool -hsw_ddi_pll_select(struct intel_crtc *intel_crtc, int output, int clock) +hsw_ddi_pll_select(struct intel_crtc *intel_crtc, + struct intel_encoder *intel_encoder, + int clock) { - if (output == INTEL_OUTPUT_HDMI) { + if (intel_encoder->type == INTEL_OUTPUT_HDMI) { struct intel_shared_dpll *pll; uint32_t val; unsigned p, n2, r2; - intel_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); + hsw_ddi_calculate_wrpll(clock * 1000, &r2, &n2, &p); val = WRPLL_PLL_ENABLE | WRPLL_PLL_LCPLL | WRPLL_DIVIDER_REFERENCE(r2) | WRPLL_DIVIDER_FEEDBACK(n2) | @@ -749,12 +751,11 @@ 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 type = intel_encoder->type; int clock = intel_crtc->config.port_clock; intel_put_shared_dpll(intel_crtc); - return hsw_ddi_pll_select(intel_crtc, type, clock); + return hsw_ddi_pll_select(intel_crtc, intel_encoder, clock); } void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) -- GitLab From ad13d6048f5002f1c5ab21c71a5ee136a2d8e889 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 29 Jul 2014 18:06:24 +0100 Subject: [PATCH 0120/9167] drm/i915: Split the CDCLK retrieval per-platform This is only going to get worse, so split it now to avoid adding more cases to the if/else ladder. Suggested-by: Daniel Vetter Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 55 ++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index eb8e494ce569..b5870fd920ff 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1192,31 +1192,52 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) } } -int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) +static int bdw_get_cdclk_freq(struct drm_i915_private *dev_priv) +{ + uint32_t lcpll = I915_READ(LCPLL_CTL); + uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; + + if (lcpll & LCPLL_CD_SOURCE_FCLK) + return 800000; + else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT) + return 450000; + else if (freq == LCPLL_CLK_FREQ_450) + return 450000; + else if (freq == LCPLL_CLK_FREQ_54O_BDW) + return 540000; + else if (freq == LCPLL_CLK_FREQ_337_5_BDW) + return 337500; + else + return 675000; +} + +static int hsw_get_cdclk_freq(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; uint32_t lcpll = I915_READ(LCPLL_CTL); uint32_t freq = lcpll & LCPLL_CLK_FREQ_MASK; - if (lcpll & LCPLL_CD_SOURCE_FCLK) { + if (lcpll & LCPLL_CD_SOURCE_FCLK) return 800000; - } else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT) { + else if (I915_READ(FUSE_STRAP) & HSW_CDCLK_LIMIT) return 450000; - } else if (freq == LCPLL_CLK_FREQ_450) { + else if (freq == LCPLL_CLK_FREQ_450) return 450000; - } else if (IS_HASWELL(dev)) { - if (IS_ULT(dev)) - return 337500; - else - return 540000; - } else { - if (freq == LCPLL_CLK_FREQ_54O_BDW) - return 540000; - else if (freq == LCPLL_CLK_FREQ_337_5_BDW) - return 337500; - else - return 675000; - } + else if (IS_ULT(dev)) + return 337500; + else + return 540000; +} + +int intel_ddi_get_cdclk_freq(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + + if (IS_BROADWELL(dev)) + return bdw_get_cdclk_freq(dev_priv); + + /* Haswell */ + return hsw_get_cdclk_freq(dev_priv); } static void hsw_ddi_pll_enable(struct drm_i915_private *dev_priv, -- GitLab From 3d51278af91f8e96077dad3a4c1cc0b19fa8ca25 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 29 Jul 2014 20:57:08 +0200 Subject: [PATCH 0121/9167] drm/i915: Make ddi_clock_gate() HSW/BDW specific Turns out we were again way too naive and optimistic, of course things will change. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index b5870fd920ff..3634575534b4 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -587,8 +587,8 @@ static int intel_ddi_calc_wrpll_link(struct drm_i915_private *dev_priv, return (refclk * n * 100) / (p * r); } -void intel_ddi_clock_get(struct intel_encoder *encoder, - struct intel_crtc_config *pipe_config) +static void hsw_ddi_clock_get(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) { struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; int link_clock = 0; @@ -643,6 +643,12 @@ void intel_ddi_clock_get(struct intel_encoder *encoder, pipe_config->adjusted_mode.crtc_clock = pipe_config->port_clock; } +void intel_ddi_clock_get(struct intel_encoder *encoder, + struct intel_crtc_config *pipe_config) +{ + hsw_ddi_clock_get(encoder, pipe_config); +} + static void hsw_ddi_calculate_wrpll(int clock /* in Hz */, unsigned *r2_out, unsigned *n2_out, unsigned *p_out) @@ -1480,7 +1486,7 @@ void intel_ddi_get_config(struct intel_encoder *encoder, dev_priv->vbt.edp_bpp = pipe_config->pipe_bpp; } - intel_ddi_clock_get(encoder, pipe_config); + hsw_ddi_clock_get(encoder, pipe_config); } static void intel_ddi_destroy(struct drm_encoder *encoder) -- GitLab From 06ffc7789e76a095e85814dbcf7b660344f6b679 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Thu, 17 Jul 2014 17:43:46 -0300 Subject: [PATCH 0122/9167] d rm/i915: freeze display before the interrupts and GT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we started using intel_runtime_pm_disable_interrupts() at normal (non-runtime) suspend/resume, we had to remove a WARN from ironlake_disable_display_irq to avoid a case where we were doing the correct thing and the WARN was not really needed. The problem is that the WARN was useful in other cases, and its removal can hide some bugs that we would catch automatically. To be able to add back the WARN, we have to call intel_crtc_control() before interrupts are disabled, which is what this patch currently does. Also notice that Ville's patch from the Watermarks series "drm/i915: Leave interrupts enabled while disabling crtcs during suspend" also did a change that's equivalent to the one we're doing on this patch, with the exception that its original patch, when applied to the current tree, procduces a WARN. Related commits: commit daa390e5ee45cc051d6bf37b296901f2f92b002d Author: Jesse Barnes drm/i915: don't warn if IRQs are disabled when shutting down display IRQs commit e11aa362308f5de467ce355a2a2471321b15a35c Author: Jesse Barnes drm/i915: use runtime irq suspend/resume in freeze/thaw Note that the function part of this patch has already been done 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) with the fixup commit 09b64267c1f72f2670fcde9f11e5453ce365ca23 Author: Dave Airlie Date: Wed Jul 23 14:25:24 2014 +1000 drm/i915: don't suspend gt until after we disable irqs and display (v2) so all that's left from Paulo's patch is reinstating the WARNING. Cc: Ville Syrjälä Cc: Jesse Barnes Signed-off-by: Paulo Zanoni Reviewed-by: Jesse Barnes [danvet: Explain conflict resolution with Dave's DP MST patches with a note in the commit message.] 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 0e44c433cfc3..379cfb5dc731 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -151,7 +151,7 @@ ironlake_disable_display_irq(struct drm_i915_private *dev_priv, u32 mask) { assert_spin_locked(&dev_priv->irq_lock); - if (!intel_irqs_enabled(dev_priv)) + if (WARN_ON(!intel_irqs_enabled(dev_priv))) return; if ((dev_priv->irq_mask & mask) != mask) { -- GitLab From 383c5a6a4682f6816fb5a07aebd89c5813c3d1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:03:57 +0300 Subject: [PATCH 0123/9167] drm/i915: Add cdclk change support for chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks like the Punit is supposed to support the 400MHz cdclk directly on chv, so we don't need the vlv tricks. FIXME: Punit doesn't seem ready for this yet on current hw Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 4 +++ drivers/gpu/drm/i915/intel_display.c | 50 ++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index e355fc8d4d59..697c04976cd3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -497,6 +497,10 @@ #define BUNIT_REG_BISOC 0x11 #define PUNIT_REG_DSPFREQ 0x36 +#define DSPFREQSTAT_SHIFT_CHV 24 +#define DSPFREQSTAT_MASK_CHV (0x1f << DSPFREQSTAT_SHIFT_CHV) +#define DSPFREQGUAR_SHIFT_CHV 8 +#define DSPFREQGUAR_MASK_CHV (0x1f << DSPFREQGUAR_SHIFT_CHV) #define DSPFREQSTAT_SHIFT 30 #define DSPFREQSTAT_MASK (0x3 << DSPFREQSTAT_SHIFT) #define DSPFREQGUAR_SHIFT 14 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c3bb5f7fd21b..fdf5ec88866a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4501,6 +4501,47 @@ static void valleyview_set_cdclk(struct drm_device *dev, int cdclk) vlv_update_cdclk(dev); } +static void cherryview_set_cdclk(struct drm_device *dev, int cdclk) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 val, cmd; + + WARN_ON(dev_priv->display.get_display_clock_speed(dev) != dev_priv->vlv_cdclk_freq); + + switch (cdclk) { + case 400000: + cmd = 3; + break; + case 333333: + case 320000: + cmd = 2; + break; + case 266667: + cmd = 1; + break; + case 200000: + cmd = 0; + break; + default: + WARN_ON(1); + return; + } + + mutex_lock(&dev_priv->rps.hw_lock); + val = vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ); + val &= ~DSPFREQGUAR_MASK_CHV; + val |= (cmd << DSPFREQGUAR_SHIFT_CHV); + vlv_punit_write(dev_priv, PUNIT_REG_DSPFREQ, val); + if (wait_for((vlv_punit_read(dev_priv, PUNIT_REG_DSPFREQ) & + DSPFREQSTAT_MASK_CHV) == (cmd << DSPFREQSTAT_SHIFT_CHV), + 50)) { + DRM_ERROR("timed out waiting for CDclk change\n"); + } + mutex_unlock(&dev_priv->rps.hw_lock); + + vlv_update_cdclk(dev); +} + static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv, int max_pixclk) { @@ -4569,8 +4610,13 @@ static void valleyview_modeset_global_resources(struct drm_device *dev) int max_pixclk = intel_mode_max_pixclk(dev_priv); int req_cdclk = valleyview_calc_cdclk(dev_priv, max_pixclk); - if (req_cdclk != dev_priv->vlv_cdclk_freq) - valleyview_set_cdclk(dev, req_cdclk); + if (req_cdclk != dev_priv->vlv_cdclk_freq) { + if (IS_CHERRYVIEW(dev)) + cherryview_set_cdclk(dev, req_cdclk); + else + valleyview_set_cdclk(dev, req_cdclk); + } + modeset_update_crtc_power_domains(dev); } -- GitLab From d49a340d6eb6de45c1a886b71469d110f2dbb57b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:03:58 +0300 Subject: [PATCH 0124/9167] drm/i915: Disable cdclk changes for chv until Punit is ready MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Punit seems a bit WIP still. Disable cdclk changes until we have hardware where it works. Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fdf5ec88866a..a7d0c88a620d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4548,6 +4548,10 @@ static int valleyview_calc_cdclk(struct drm_i915_private *dev_priv, int vco = valleyview_get_vco(dev_priv); int freq_320 = (vco << 1) % 320000 != 0 ? 333333 : 320000; + /* FIXME: Punit isn't quite ready yet */ + if (IS_CHERRYVIEW(dev_priv->dev)) + return 400000; + /* * Really only a few cases to deal with, as only 4 CDclks are supported: * 200MHz @@ -5283,6 +5287,10 @@ static int valleyview_get_display_clock_speed(struct drm_device *dev) u32 val; int divider; + /* FIXME: Punit isn't quite ready yet */ + if (IS_CHERRYVIEW(dev)) + return 400000; + mutex_lock(&dev_priv->dpio_lock); val = vlv_cck_read(dev_priv, CCK_DISPLAY_CLOCK_CONTROL); mutex_unlock(&dev_priv->dpio_lock); -- GitLab From d17ec4ced6c0907f80f51677a44236da94ecd92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:03:59 +0300 Subject: [PATCH 0125/9167] drm/i915: Leave DPLL ref clocks on MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We enable the DPLL refclock already when bringing up the cmnlane power well, so also leave it on when otherwise disabling the DPLL. Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes 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 a7d0c88a620d..6ca53b372a4c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1684,7 +1684,7 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) assert_pipe_disabled(dev_priv, pipe); /* Set PLL en = 0 */ - val = DPLL_SSC_REF_CLOCK_CHV; + val = DPLL_SSC_REF_CLOCK_CHV | DPLL_REFA_CLK_ENABLE_VLV; if (pipe != PIPE_A) val |= DPLL_INTEGRATED_CRI_CLK_VLV; I915_WRITE(DPLL(pipe), val); -- GitLab From 1ae0d1377fda91367b27596001c82e877ec2057e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:00 +0300 Subject: [PATCH 0126/9167] drm/i915: Split chv_update_pll() apart MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split chv_update_pll() into two parts ala: commit bdd4b6a655749970cc632aafc5fd596c07b60b1c Author: Daniel Vetter Date: Thu Apr 24 23:55:11 2014 +0200 drm/i915: Extract vlv_prepare_pll Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 30 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6ca53b372a4c..60ba6962026b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -100,6 +100,7 @@ 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 struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe) { @@ -4642,8 +4643,12 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) is_dsi = intel_pipe_has_type(crtc, INTEL_OUTPUT_DSI); - if (!is_dsi && !IS_CHERRYVIEW(dev)) - vlv_prepare_pll(intel_crtc); + if (!is_dsi) { + if (IS_CHERRYVIEW(dev)) + chv_prepare_pll(intel_crtc); + else + vlv_prepare_pll(intel_crtc); + } /* Set up the display plane register */ dspcntr = DISPPLANE_GAMMA_ENABLE; @@ -5691,6 +5696,18 @@ static void vlv_prepare_pll(struct intel_crtc *crtc) } static void chv_update_pll(struct intel_crtc *crtc) +{ + crtc->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; + + crtc->config.dpll_hw_state.dpll_md = + (crtc->config.pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; +} + +static void chv_prepare_pll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -5701,15 +5718,6 @@ static void chv_update_pll(struct intel_crtc *crtc) u32 bestn, bestm1, bestm2, bestp1, bestp2, bestm2_frac; int refclk; - crtc->config.dpll_hw_state.dpll = DPLL_SSC_REF_CLOCK_CHV | - DPLL_REFA_CLK_ENABLE_VLV | DPLL_VGA_MODE_DIS | - DPLL_VCO_ENABLE; - if (pipe != PIPE_A) - crtc->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; - bestn = crtc->config.dpll.n; bestm2_frac = crtc->config.dpll.m2 & 0x3fffff; bestm1 = crtc->config.dpll.m1; -- GitLab From 625695f8c3383765fd8974616aa57ffdbc644f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:02 +0300 Subject: [PATCH 0127/9167] drm/i915: Call intel_{dp, hdmi}_prepare for chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHV was forgotten the intel_{dp,hdmi}_prepare() were introduced (or the chv patches were still in flight?). Call these when enabling the ports. Things tend to work much better when we actually write something to the port registers :) Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 2 ++ drivers/gpu/drm/i915/intel_hdmi.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 16fcfc67f014..33a45a819525 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2281,6 +2281,8 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder) enum pipe pipe = intel_crtc->pipe; u32 val; + intel_dp_prepare(encoder); + mutex_lock(&dev_priv->dpio_lock); /* program left/right clock distribution */ diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index f9151f6641d9..df25b740b348 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1260,6 +1260,8 @@ static void chv_hdmi_pre_pll_enable(struct intel_encoder *encoder) enum pipe pipe = intel_crtc->pipe; u32 val; + intel_hdmi_prepare(encoder); + mutex_lock(&dev_priv->dpio_lock); /* program left/right clock distribution */ -- GitLab From 1fb44505f6c547742fcbcba4d3999fb324b5f587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Sat, 28 Jun 2014 02:04:03 +0300 Subject: [PATCH 0128/9167] drm/i915: Clarify CHV swing margin/deemph bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHV display PHY registes have two swing margin/deemph settings. Make it clear which ones we're using. Signed-off-by: Ville Syrjälä Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 8 ++++++-- drivers/gpu/drm/i915/intel_dp.c | 4 ++-- drivers/gpu/drm/i915/intel_hdmi.c | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 697c04976cd3..35553aa0a82f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -855,8 +855,8 @@ enum punit_power_well { #define _VLV_TX_DW2_CH0 0x8288 #define _VLV_TX_DW2_CH1 0x8488 -#define DPIO_SWING_MARGIN_SHIFT 16 -#define DPIO_SWING_MARGIN_MASK (0xff << DPIO_SWING_MARGIN_SHIFT) +#define DPIO_SWING_MARGIN000_SHIFT 16 +#define DPIO_SWING_MARGIN000_MASK (0xff << DPIO_SWING_MARGIN000_SHIFT) #define DPIO_UNIQ_TRANS_SCALE_SHIFT 8 #define VLV_TX_DW2(ch) _PORT(ch, _VLV_TX_DW2_CH0, _VLV_TX_DW2_CH1) @@ -864,12 +864,16 @@ enum punit_power_well { #define _VLV_TX_DW3_CH1 0x848c /* The following bit for CHV phy */ #define DPIO_TX_UNIQ_TRANS_SCALE_EN (1<<27) +#define DPIO_SWING_MARGIN101_SHIFT 16 +#define DPIO_SWING_MARGIN101_MASK (0xff << DPIO_SWING_MARGIN101_SHIFT) #define VLV_TX_DW3(ch) _PORT(ch, _VLV_TX_DW3_CH0, _VLV_TX_DW3_CH1) #define _VLV_TX_DW4_CH0 0x8290 #define _VLV_TX_DW4_CH1 0x8490 #define DPIO_SWING_DEEMPH9P5_SHIFT 24 #define DPIO_SWING_DEEMPH9P5_MASK (0xff << DPIO_SWING_DEEMPH9P5_SHIFT) +#define DPIO_SWING_DEEMPH6P0_SHIFT 16 +#define DPIO_SWING_DEEMPH6P0_MASK (0xff << DPIO_SWING_DEEMPH6P0_SHIFT) #define VLV_TX_DW4(ch) _PORT(ch, _VLV_TX_DW4_CH0, _VLV_TX_DW4_CH1) #define _VLV_TX3_DW4_CH0 0x690 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 33a45a819525..95b972736733 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2649,8 +2649,8 @@ static uint32_t intel_chv_signal_levels(struct intel_dp *intel_dp) /* Program swing margin */ for (i = 0; i < 4; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i)); - val &= ~DPIO_SWING_MARGIN_MASK; - val |= margin_reg_value << DPIO_SWING_MARGIN_SHIFT; + val &= ~DPIO_SWING_MARGIN000_MASK; + val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT; vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val); } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index df25b740b348..5f47d359a991 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -1431,8 +1431,8 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder) for (i = 0; i < 4; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i)); - val &= ~DPIO_SWING_MARGIN_MASK; - val |= 102 << DPIO_SWING_MARGIN_SHIFT; + val &= ~DPIO_SWING_MARGIN000_MASK; + val |= 102 << DPIO_SWING_MARGIN000_SHIFT; vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val); } -- GitLab From 7f0c860533ff2de4b3bb84f71d5ce238fffe4d63 Mon Sep 17 00:00:00 2001 From: Shobhit Kumar Date: Wed, 30 Jul 2014 20:34:57 +0530 Subject: [PATCH 0129/9167] drm/i915: Add support for Video Burst Mode for MIPI DSI v2: Updated the error log as suggested by Imre Signed-off-by: Shobhit Kumar Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_bios.h | 3 +- drivers/gpu/drm/i915/intel_dsi.c | 22 ++++++++----- drivers/gpu/drm/i915/intel_dsi.h | 2 ++ drivers/gpu/drm/i915/intel_dsi_panel_vbt.c | 38 ++++++++++++++++++++-- drivers/gpu/drm/i915/intel_dsi_pll.c | 9 ++--- 5 files changed, 57 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h index b98667796337..905999bee2ac 100644 --- a/drivers/gpu/drm/i915/intel_bios.h +++ b/drivers/gpu/drm/i915/intel_bios.h @@ -802,7 +802,8 @@ struct mipi_config { u16 rsvd4; - u8 rsvd5[5]; + u8 rsvd5; + u32 target_burst_mode_freq; u32 dsi_ddr_clk; u32 bridge_ref_clk; diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index 670c29a7b5dd..aea8f3383c26 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -423,9 +423,11 @@ static u16 txclkesc(u32 divider, unsigned int us) } /* return pixels in terms of txbyteclkhs */ -static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count) +static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count, + u16 burst_mode_ratio) { - return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp, 8), lane_count); + return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp * burst_mode_ratio, + 8 * 100), lane_count); } static void set_dsi_timings(struct drm_encoder *encoder, @@ -451,10 +453,12 @@ static void set_dsi_timings(struct drm_encoder *encoder, vbp = mode->vtotal - mode->vsync_end; /* horizontal values are in terms of high speed byte clock */ - hactive = txbyteclkhs(hactive, bpp, lane_count); - hfp = txbyteclkhs(hfp, bpp, lane_count); - hsync = txbyteclkhs(hsync, bpp, lane_count); - hbp = txbyteclkhs(hbp, bpp, lane_count); + hactive = txbyteclkhs(hactive, bpp, lane_count, + intel_dsi->burst_mode_ratio); + hfp = txbyteclkhs(hfp, bpp, lane_count, intel_dsi->burst_mode_ratio); + hsync = txbyteclkhs(hsync, bpp, lane_count, + intel_dsi->burst_mode_ratio); + hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio); I915_WRITE(MIPI_HACTIVE_AREA_COUNT(pipe), hactive); I915_WRITE(MIPI_HFP_COUNT(pipe), hfp); @@ -541,12 +545,14 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) intel_dsi->video_mode_format == VIDEO_MODE_BURST) { I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe), txbyteclkhs(adjusted_mode->htotal, bpp, - intel_dsi->lane_count) + 1); + intel_dsi->lane_count, + intel_dsi->burst_mode_ratio) + 1); } else { I915_WRITE(MIPI_HS_TX_TIMEOUT(pipe), txbyteclkhs(adjusted_mode->vtotal * adjusted_mode->htotal, - bpp, intel_dsi->lane_count) + 1); + bpp, intel_dsi->lane_count, + intel_dsi->burst_mode_ratio) + 1); } I915_WRITE(MIPI_LP_RX_TIMEOUT(pipe), intel_dsi->lp_rx_timeout); I915_WRITE(MIPI_TURN_AROUND_TIMEOUT(pipe), intel_dsi->turn_arnd_val); diff --git a/drivers/gpu/drm/i915/intel_dsi.h b/drivers/gpu/drm/i915/intel_dsi.h index fd51867fd0d3..657eb5c1b9d8 100644 --- a/drivers/gpu/drm/i915/intel_dsi.h +++ b/drivers/gpu/drm/i915/intel_dsi.h @@ -116,6 +116,8 @@ struct intel_dsi { u16 clk_hs_to_lp_count; u16 init_count; + u32 pclk; + u16 burst_mode_ratio; /* all delays in ms */ u16 backlight_off_delay; diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c index 47c7584a4aa0..f6bdd44069ce 100644 --- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c +++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c @@ -271,6 +271,8 @@ static bool generic_init(struct intel_dsi_device *dsi) u32 ths_prepare_ns, tclk_trail_ns; u32 tclk_prepare_clkzero, ths_prepare_hszero; u32 lp_to_hs_switch, hs_to_lp_switch; + u32 pclk, computed_ddr; + u16 burst_mode_ratio; DRM_DEBUG_KMS("\n"); @@ -284,8 +286,6 @@ static bool generic_init(struct intel_dsi_device *dsi) else if (intel_dsi->pixel_format == VID_MODE_FORMAT_RGB565) bits_per_pixel = 16; - bitrate = (mode->clock * bits_per_pixel) / intel_dsi->lane_count; - intel_dsi->operation_mode = mipi_config->is_cmd_mode; intel_dsi->video_mode_format = mipi_config->video_transfer_mode; intel_dsi->escape_clk_div = mipi_config->byte_clk_sel; @@ -297,6 +297,40 @@ static bool generic_init(struct intel_dsi_device *dsi) intel_dsi->video_frmt_cfg_bits = mipi_config->bta_enabled ? DISABLE_VIDEO_BTA : 0; + pclk = mode->clock; + + /* Burst Mode Ratio + * Target ddr frequency from VBT / non burst ddr freq + * multiply by 100 to preserve remainder + */ + if (intel_dsi->video_mode_format == VIDEO_MODE_BURST) { + if (mipi_config->target_burst_mode_freq) { + computed_ddr = + (pclk * bits_per_pixel) / intel_dsi->lane_count; + + if (mipi_config->target_burst_mode_freq < + computed_ddr) { + DRM_ERROR("Burst mode freq is less than computed\n"); + return false; + } + + burst_mode_ratio = DIV_ROUND_UP( + mipi_config->target_burst_mode_freq * 100, + computed_ddr); + + pclk = DIV_ROUND_UP(pclk * burst_mode_ratio, 100); + } else { + DRM_ERROR("Burst mode target is not set\n"); + return false; + } + } else + burst_mode_ratio = 100; + + intel_dsi->burst_mode_ratio = burst_mode_ratio; + intel_dsi->pclk = pclk; + + bitrate = (pclk * bits_per_pixel) / intel_dsi->lane_count; + switch (intel_dsi->escape_clk_div) { case 0: tlpx_ns = 50; diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index d8bb1ea2f0da..06fad93a68c8 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -134,8 +134,7 @@ static u32 dsi_rr_formula(const struct drm_display_mode *mode, #else /* Get DSI clock from pixel clock */ -static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode, - int pixel_format, int lane_count) +static u32 dsi_clk_from_pclk(u32 pclk, int pixel_format, int lane_count) { u32 dsi_clk_khz; u32 bpp; @@ -156,7 +155,7 @@ static u32 dsi_clk_from_pclk(const struct drm_display_mode *mode, /* DSI data rate = pixel clock * bits per pixel / lane count pixel clock is converted from KHz to Hz */ - dsi_clk_khz = DIV_ROUND_CLOSEST(mode->clock * bpp, lane_count); + dsi_clk_khz = DIV_ROUND_CLOSEST(pclk * bpp, lane_count); return dsi_clk_khz; } @@ -228,14 +227,12 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) static void vlv_configure_dsi_pll(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); - const struct drm_display_mode *mode = &intel_crtc->config.adjusted_mode; struct intel_dsi *intel_dsi = enc_to_intel_dsi(&encoder->base); int ret; struct dsi_mnp dsi_mnp; u32 dsi_clk; - dsi_clk = dsi_clk_from_pclk(mode, intel_dsi->pixel_format, + dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format, intel_dsi->lane_count); ret = dsi_calc_mnp(dsi_clk, &dsi_mnp); -- GitLab From 7f3de8336fc8c44bede43c57e40448171b12ef68 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Jul 2014 22:34:27 +0200 Subject: [PATCH 0130/9167] drm/i915: Align intel_dsi*.c files a bit I'm not really that insisting on checkpath compliance, but ragged function paramter alignment does get me. Please adjust your editor to just do this for you. Cc: Shobhit Kumar Cc: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dsi.c | 24 ++++++++++++------------ drivers/gpu/drm/i915/intel_dsi_cmd.c | 2 +- drivers/gpu/drm/i915/intel_dsi_pll.c | 8 ++++---- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dsi.c b/drivers/gpu/drm/i915/intel_dsi.c index aea8f3383c26..5bd9e09ad3c5 100644 --- a/drivers/gpu/drm/i915/intel_dsi.c +++ b/drivers/gpu/drm/i915/intel_dsi.c @@ -184,7 +184,7 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder) /* update the hw state for DPLL */ intel_crtc->config.dpll_hw_state.dpll = DPLL_INTEGRATED_CLOCK_VLV | - DPLL_REFA_CLK_ENABLE_VLV; + DPLL_REFA_CLK_ENABLE_VLV; tmp = I915_READ(DSPCLK_GATE_D); tmp |= DPOUNIT_CLOCK_GATE_DISABLE; @@ -259,8 +259,8 @@ static void intel_dsi_disable(struct intel_encoder *encoder) temp = I915_READ(MIPI_CTRL(pipe)); temp &= ~ESCAPE_CLOCK_DIVIDER_MASK; I915_WRITE(MIPI_CTRL(pipe), temp | - intel_dsi->escape_clk_div << - ESCAPE_CLOCK_DIVIDER_SHIFT); + intel_dsi->escape_clk_div << + ESCAPE_CLOCK_DIVIDER_SHIFT); I915_WRITE(MIPI_EOT_DISABLE(pipe), CLOCKSTOP); @@ -297,7 +297,7 @@ static void intel_dsi_clear_device_ready(struct intel_encoder *encoder) usleep_range(2000, 2500); if (wait_for(((I915_READ(MIPI_PORT_CTRL(pipe)) & AFE_LATCHOUT) - == 0x00000), 30)) + == 0x00000), 30)) DRM_ERROR("DSI LP not going Low\n"); val = I915_READ(MIPI_PORT_CTRL(pipe)); @@ -427,7 +427,7 @@ static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count, u16 burst_mode_ratio) { return DIV_ROUND_UP(DIV_ROUND_UP(pixels * bpp * burst_mode_ratio, - 8 * 100), lane_count); + 8 * 100), lane_count); } static void set_dsi_timings(struct drm_encoder *encoder, @@ -454,10 +454,10 @@ static void set_dsi_timings(struct drm_encoder *encoder, /* horizontal values are in terms of high speed byte clock */ hactive = txbyteclkhs(hactive, bpp, lane_count, - intel_dsi->burst_mode_ratio); + intel_dsi->burst_mode_ratio); hfp = txbyteclkhs(hfp, bpp, lane_count, intel_dsi->burst_mode_ratio); hsync = txbyteclkhs(hsync, bpp, lane_count, - intel_dsi->burst_mode_ratio); + intel_dsi->burst_mode_ratio); hbp = txbyteclkhs(hbp, bpp, lane_count, intel_dsi->burst_mode_ratio); I915_WRITE(MIPI_HACTIVE_AREA_COUNT(pipe), hactive); @@ -582,7 +582,7 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) * XXX: write MIPI_STOP_STATE_STALL? */ I915_WRITE(MIPI_HIGH_LOW_SWITCH_COUNT(pipe), - intel_dsi->hs_to_lp_count); + intel_dsi->hs_to_lp_count); /* XXX: low power clock equivalence in terms of byte clock. the number * of byte clocks occupied in one low power clock. based on txbyteclkhs @@ -607,10 +607,10 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder) * 64 like 1366 x 768. Enable RANDOM resolution support for such * panels by default */ I915_WRITE(MIPI_VIDEO_MODE_FORMAT(pipe), - intel_dsi->video_frmt_cfg_bits | - intel_dsi->video_mode_format | - IP_TG_CONFIG | - RANDOM_DPI_DISPLAY_RESOLUTION); + intel_dsi->video_frmt_cfg_bits | + intel_dsi->video_mode_format | + IP_TG_CONFIG | + RANDOM_DPI_DISPLAY_RESOLUTION); } static void intel_dsi_pre_pll_enable(struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/intel_dsi_cmd.c b/drivers/gpu/drm/i915/intel_dsi_cmd.c index 7f1430ac8543..f4767fd2ebeb 100644 --- a/drivers/gpu/drm/i915/intel_dsi_cmd.c +++ b/drivers/gpu/drm/i915/intel_dsi_cmd.c @@ -430,7 +430,7 @@ void wait_for_dsi_fifo_empty(struct intel_dsi *intel_dsi) u32 mask; mask = LP_CTRL_FIFO_EMPTY | HS_CTRL_FIFO_EMPTY | - LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY; + LP_DATA_FIFO_EMPTY | HS_DATA_FIFO_EMPTY; if (wait_for((I915_READ(MIPI_GEN_FIFO_STAT(pipe)) & mask) == mask, 100)) DRM_ERROR("DPI FIFOs are not empty\n"); diff --git a/drivers/gpu/drm/i915/intel_dsi_pll.c b/drivers/gpu/drm/i915/intel_dsi_pll.c index 06fad93a68c8..fa7a6ca34cd6 100644 --- a/drivers/gpu/drm/i915/intel_dsi_pll.c +++ b/drivers/gpu/drm/i915/intel_dsi_pll.c @@ -190,7 +190,7 @@ static int dsi_calc_mnp(u32 dsi_clk, struct dsi_mnp *dsi_mnp) for (m = 62; m <= 92; m++) { for (p = 2; p <= 6; p++) { /* Find the optimal m and p divisors - with minimal error +/- the required clock */ + with minimal error +/- the required clock */ calc_dsi_clk = (m * ref_clk) / p; if (calc_dsi_clk == target_dsi_clk) { calc_m = m; @@ -233,7 +233,7 @@ static void vlv_configure_dsi_pll(struct intel_encoder *encoder) u32 dsi_clk; dsi_clk = dsi_clk_from_pclk(intel_dsi->pclk, intel_dsi->pixel_format, - intel_dsi->lane_count); + intel_dsi->lane_count); ret = dsi_calc_mnp(dsi_clk, &dsi_mnp); if (ret) { @@ -315,8 +315,8 @@ static void assert_bpp_mismatch(int pixel_format, int pipe_bpp) } WARN(bpp != pipe_bpp, - "bpp match assertion failure (expected %d, current %d)\n", - bpp, pipe_bpp); + "bpp match assertion failure (expected %d, current %d)\n", + bpp, pipe_bpp); } u32 vlv_get_dsi_pclk(struct intel_encoder *encoder, int pipe_bpp) -- GitLab From da46f936bb0396f6a0fb87c2786f541e9f19a73c Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Fri, 1 Aug 2014 02:04:45 -0700 Subject: [PATCH 0131/9167] drm/i915: Introduce FBC False Color for debug purposes. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this bit enabled, HW changes the color when compressing frames for debug purposes. ALthough the simple way to enable a single bit is over intel_reg_write, this value is overwriten on next update_fbc so depending on the workload it is not possible to set this bit with intel-gpu-tools. So this patch introduces a persistent way to enable false color over debugfs. v2: Use DEFINE_SIMPLE_ATTRIBUTE as Daniel suggested v3: (Ville) only do false color for IVB+ since according to spec bit is MBZ before IVB. v4: We don't have FBC on valleyview nor on cherryview (Ben) v5: s/!HAS_PCH_SPLIT/!HAS_FBC (Ville) Cc: Ville Syrjälä Reviewed-by: Ben Widawsky Signed-off-by: Rodrigo Vivi Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 42 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 3 +++ 4 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9e737b771c40..aea1a819c775 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1433,6 +1433,47 @@ static int i915_fbc_status(struct seq_file *m, void *unused) return 0; } +static int i915_fbc_fc_get(void *data, u64 *val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (INTEL_INFO(dev)->gen < 7 || !HAS_FBC(dev)) + return -ENODEV; + + drm_modeset_lock_all(dev); + *val = dev_priv->fbc.false_color; + drm_modeset_unlock_all(dev); + + return 0; +} + +static int i915_fbc_fc_set(void *data, u64 val) +{ + struct drm_device *dev = data; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 reg; + + if (INTEL_INFO(dev)->gen < 7 || !HAS_FBC(dev)) + return -ENODEV; + + drm_modeset_lock_all(dev); + + reg = I915_READ(ILK_DPFC_CONTROL); + dev_priv->fbc.false_color = val; + + I915_WRITE(ILK_DPFC_CONTROL, val ? + (reg | FBC_CTL_FALSE_COLOR) : + (reg & ~FBC_CTL_FALSE_COLOR)); + + drm_modeset_unlock_all(dev); + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(i915_fbc_fc_fops, + i915_fbc_fc_get, i915_fbc_fc_set, + "%llu\n"); + static int i915_ips_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; @@ -3957,6 +3998,7 @@ static const struct i915_debugfs_files { {"i915_pri_wm_latency", &i915_pri_wm_latency_fops}, {"i915_spr_wm_latency", &i915_spr_wm_latency_fops}, {"i915_cur_wm_latency", &i915_cur_wm_latency_fops}, + {"i915_fbc_false_color", &i915_fbc_fc_fops}, }; void intel_display_crc_init(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c3beb08813c6..ce30bb3ed566 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -637,6 +637,8 @@ struct i915_fbc { struct drm_mm_node compressed_fb; struct drm_mm_node *compressed_llb; + bool false_color; + struct intel_fbc_work { struct delayed_work work; struct drm_crtc *crtc; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 35553aa0a82f..ca37febbc2ae 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1540,6 +1540,7 @@ enum punit_power_well { /* Framebuffer compression for Ironlake */ #define ILK_DPFC_CB_BASE 0x43200 #define ILK_DPFC_CONTROL 0x43208 +#define FBC_CTL_FALSE_COLOR (1<<10) /* The bit 28-8 is reserved */ #define DPFC_RESERVED (0x1FFFFF00) #define ILK_DPFC_RECOMP_CTL 0x4320c diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index a318cd5ad8ed..ab80df2909e0 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -309,6 +309,9 @@ static void gen7_enable_fbc(struct drm_crtc *crtc) dpfc_ctl |= IVB_DPFC_CTL_FENCE_EN; + if (dev_priv->fbc.false_color) + dpfc_ctl |= FBC_CTL_FALSE_COLOR; + I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); if (IS_IVYBRIDGE(dev)) { -- GitLab From ce4dd49e97813740bd2b03ecdc51521be10f3bf1 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 1 Aug 2014 11:07:54 +0100 Subject: [PATCH 0132/9167] drm/i915: Gather the HDMI level shifter logic into one place The knowledge about the HDMI/DVI DDI translation table was scattered around. - info->hdmi_level_shift was initialized with 6, the index of the 800 mV, 0dB translation - A check on the VBT value was done to ensure it wasn't overflowing the translation table (< 0xC) - The actual programming was done in intel_ddi.c As we need to change that knowledge for Broadwell, let's gather everything into one place. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ drivers/gpu/drm/i915/intel_bios.c | 13 +++++-------- drivers/gpu/drm/i915/intel_ddi.c | 14 +++++++++++++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ce30bb3ed566..0d7e55f2a8a2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1232,6 +1232,12 @@ enum modeset_restore { }; struct ddi_vbt_port_info { + /* + * This is an index in the HDMI/DVI DDI buffer translation table. + * The special value HDMI_LEVEL_SHIFT_UNKNOWN means the VBT didn't + * populate this field. + */ +#define HDMI_LEVEL_SHIFT_UNKNOWN 0xff uint8_t hdmi_level_shift; uint8_t supports_dvi:1; diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index a66955037e4e..031c5657255d 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -976,12 +976,10 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port, if (bdb->version >= 158) { /* The VBT HDMI level shift values match the table we have. */ hdmi_level_shift = child->raw[7] & 0xF; - if (hdmi_level_shift < 0xC) { - DRM_DEBUG_KMS("VBT HDMI level shift for port %c: %d\n", - port_name(port), - hdmi_level_shift); - info->hdmi_level_shift = hdmi_level_shift; - } + DRM_DEBUG_KMS("VBT HDMI level shift for port %c: %d\n", + port_name(port), + hdmi_level_shift); + info->hdmi_level_shift = hdmi_level_shift; } } @@ -1114,8 +1112,7 @@ init_vbt_defaults(struct drm_i915_private *dev_priv) struct ddi_vbt_port_info *info = &dev_priv->vbt.ddi_port_info[port]; - /* Recommended BSpec default: 800mV 0dB. */ - info->hdmi_level_shift = 6; + info->hdmi_level_shift = HDMI_LEVEL_SHIFT_UNKNOWN; info->supports_dvi = (port != PORT_A && port != PORT_E); info->supports_hdmi = info->supports_dvi; diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3634575534b4..3af8340b21ec 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -145,7 +145,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) { struct drm_i915_private *dev_priv = dev->dev_private; u32 reg; - int i; + int i, n_hdmi_entries, hdmi_800mV_0dB; int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; const u32 *ddi_translations_fdi; const u32 *ddi_translations_dp; @@ -156,15 +156,21 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; ddi_translations_edp = bdw_ddi_translations_edp; + n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); + hdmi_800mV_0dB = 6; } else if (IS_HASWELL(dev)) { ddi_translations_fdi = hsw_ddi_translations_fdi; ddi_translations_dp = hsw_ddi_translations_dp; ddi_translations_edp = hsw_ddi_translations_dp; + n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); + hdmi_800mV_0dB = 6; } else { WARN(1, "ddi translation table missing\n"); ddi_translations_edp = bdw_ddi_translations_dp; ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; + n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); + hdmi_800mV_0dB = 6; } switch (port) { @@ -193,6 +199,12 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) I915_WRITE(reg, ddi_translations[i]); reg += 4; } + + /* Choose a good default if VBT is badly populated */ + if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN || + hdmi_level >= n_hdmi_entries) + hdmi_level = hdmi_800mV_0dB; + /* Entry 9 is for HDMI: */ for (i = 0; i < 2; i++) { I915_WRITE(reg, hsw_ddi_translations_hdmi[hdmi_level * 2 + i]); -- GitLab From a26aa8baee6c274fc23efccf46e891e63c8d0a30 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 1 Aug 2014 11:07:55 +0100 Subject: [PATCH 0133/9167] drm/i915/bdw: Provide the BDW specific HDMI buffer translation table Among the changes, the tables has only 10 entries instead of 12 on HSW and the index the the 800mV/0dB entry has changed. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 3af8340b21ec..75ac0b29aa3e 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -111,6 +111,20 @@ static const u32 bdw_ddi_translations_fdi[] = { 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/ }; +static const u32 bdw_ddi_translations_hdmi[] = { + /* Idx NT mV diff T mV diff db */ + 0x00FFFFFF, 0x0007000E, /* 0: 400 400 0 */ + 0x00D75FFF, 0x000E000A, /* 1: 400 600 3.5 */ + 0x00BEFFFF, 0x00140006, /* 2: 400 800 6 */ + 0x00FFFFFF, 0x0009000D, /* 3: 450 450 0 */ + 0x00FFFFFF, 0x000E000A, /* 4: 600 600 0 */ + 0x00D7FFFF, 0x00140006, /* 5: 600 800 2.5 */ + 0x80CB2FFF, 0x001B0002, /* 6: 600 1000 4.5 */ + 0x00FFFFFF, 0x00140006, /* 7: 800 800 0 */ + 0x80E79FFF, 0x001B0002, /* 8: 800 1000 2 */ + 0x80FFFFFF, 0x001B0002, /* 9: 1000 1000 0 */ +}; + enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; @@ -150,18 +164,21 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) const u32 *ddi_translations_fdi; const u32 *ddi_translations_dp; const u32 *ddi_translations_edp; + const u32 *ddi_translations_hdmi; const u32 *ddi_translations; 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; - n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); - hdmi_800mV_0dB = 6; + ddi_translations_hdmi = bdw_ddi_translations_hdmi; + n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); + hdmi_800mV_0dB = 7; } else if (IS_HASWELL(dev)) { ddi_translations_fdi = hsw_ddi_translations_fdi; ddi_translations_dp = hsw_ddi_translations_dp; ddi_translations_edp = hsw_ddi_translations_dp; + ddi_translations_hdmi = hsw_ddi_translations_hdmi; n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); hdmi_800mV_0dB = 6; } else { @@ -169,8 +186,9 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) ddi_translations_edp = bdw_ddi_translations_dp; ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; - n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); - hdmi_800mV_0dB = 6; + ddi_translations_hdmi = bdw_ddi_translations_hdmi; + n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); + hdmi_800mV_0dB = 7; } switch (port) { @@ -207,7 +225,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) /* Entry 9 is for HDMI: */ for (i = 0; i < 2; i++) { - I915_WRITE(reg, hsw_ddi_translations_hdmi[hdmi_level * 2 + i]); + I915_WRITE(reg, ddi_translations_hdmi[hdmi_level * 2 + i]); reg += 4; } } -- GitLab From 156ae28c9f327d2c026e91cfacb5e224bb760d66 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 1 Aug 2014 11:07:56 +0100 Subject: [PATCH 0134/9167] drm/i915/bdw: Remove the HDMI/DVI entry from the DP/eDP/FDI tables We always write entries 0 to 8 from the DDI translation tables and then entry 9 for HDMI/DVI with the help of the VBT. We then don't need the failsafe HDMI entry in the DP/eDP/FDI tables. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 75ac0b29aa3e..694e1c6118aa 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -82,7 +82,6 @@ static const u32 bdw_ddi_translations_edp[] = { 0x00BEEFFF, 0x000A000C, 0x00FFFFFF, 0x0005000F, 0x00DB6FFF, 0x000A000C, - 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/ }; static const u32 bdw_ddi_translations_dp[] = { @@ -95,7 +94,6 @@ static const u32 bdw_ddi_translations_dp[] = { 0x80CB2FFF, 0x001B0002, 0x00F7DFFF, 0x00180004, 0x80D75FFF, 0x001B0002, - 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/ }; static const u32 bdw_ddi_translations_fdi[] = { @@ -108,7 +106,6 @@ static const u32 bdw_ddi_translations_fdi[] = { 0x00C30FFF, 0x000C0000, 0x00FFFFFF, 0x00070006, 0x00D75FFF, 0x000C0000, - 0x00FFFFFF, 0x00140006 /* HDMI parameters 800mV 0dB*/ }; static const u32 bdw_ddi_translations_hdmi[] = { -- GitLab From ac921bdde92a354e8c59ea185dff26dc2611ee81 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 1 Aug 2014 11:07:57 +0100 Subject: [PATCH 0135/9167] drm/i915: Remove now useless comments about the translation values We used to carry a default HDMI value in entry 9, but this entry got removed for both HSW and BDW. Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 694e1c6118aa..ca1f9a8a7d03 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -33,7 +33,7 @@ * automatically adapt to HDMI connections as well */ static const u32 hsw_ddi_translations_dp[] = { - 0x00FFFFFF, 0x0006000E, /* DP parameters */ + 0x00FFFFFF, 0x0006000E, 0x00D75FFF, 0x0005000A, 0x00C30FFF, 0x00040006, 0x80AAAFFF, 0x000B0000, @@ -45,7 +45,7 @@ static const u32 hsw_ddi_translations_dp[] = { }; static const u32 hsw_ddi_translations_fdi[] = { - 0x00FFFFFF, 0x0007000E, /* FDI parameters */ + 0x00FFFFFF, 0x0007000E, 0x00D75FFF, 0x000F000A, 0x00C30FFF, 0x00060006, 0x00AAAFFF, 0x001E0000, @@ -73,7 +73,7 @@ static const u32 hsw_ddi_translations_hdmi[] = { }; static const u32 bdw_ddi_translations_edp[] = { - 0x00FFFFFF, 0x00000012, /* eDP parameters */ + 0x00FFFFFF, 0x00000012, 0x00EBAFFF, 0x00020011, 0x00C71FFF, 0x0006000F, 0x00AAAFFF, 0x000E000A, @@ -85,7 +85,7 @@ static const u32 bdw_ddi_translations_edp[] = { }; static const u32 bdw_ddi_translations_dp[] = { - 0x00FFFFFF, 0x0007000E, /* DP parameters */ + 0x00FFFFFF, 0x0007000E, 0x00D75FFF, 0x000E000A, 0x00BEFFFF, 0x00140006, 0x80B2CFFF, 0x001B0002, @@ -97,7 +97,7 @@ static const u32 bdw_ddi_translations_dp[] = { }; static const u32 bdw_ddi_translations_fdi[] = { - 0x00FFFFFF, 0x0001000E, /* FDI parameters */ + 0x00FFFFFF, 0x0001000E, 0x00D75FFF, 0x0004000A, 0x00C30FFF, 0x00070006, 0x00AAAFFF, 0x000C0000, -- GitLab From 7fad3594bf2c66843c7d1e09005ff845a94524ab Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 1 Aug 2014 16:19:54 -0300 Subject: [PATCH 0136/9167] drm/i915: remove duplicate register defines cat i915_reg.h | sort | uniq -d | grep define Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ca37febbc2ae..7f9a81087ebc 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3756,7 +3756,6 @@ enum punit_power_well { #define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9) #define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8) #define PIPE_DPST_EVENT_STATUS (1UL<<7) -#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) #define PIPE_A_PSR_STATUS_VLV (1UL<<6) #define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6) #define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5) @@ -5431,7 +5430,6 @@ enum punit_power_well { #define VLV_GTLC_ALLOWWAKEERR (1 << 1) #define VLV_GTLC_PW_MEDIA_STATUS_MASK (1 << 5) #define VLV_GTLC_PW_RENDER_STATUS_MASK (1 << 7) -#define VLV_GTLC_SURVIVABILITY_REG 0x130098 #define FORCEWAKE_MT 0xa188 /* multi-threaded */ #define FORCEWAKE_KERNEL 0x1 #define FORCEWAKE_USER 0x2 -- GitLab From 4079b8d1c3e38b6f18fb31e2997fa25276feea07 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 5 Aug 2014 10:39:42 +0100 Subject: [PATCH 0137/9167] drm/i915: Demote the DRRS messages to debug messages While those messages are interesting, there aren't _that_ interesting. We don't need them in the kernel logs by default. Signed-off-by: Damien Lespiau 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 95b972736733..3b88255d87dc 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4429,7 +4429,7 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port, } if (dev_priv->vbt.drrs_type != SEAMLESS_DRRS_SUPPORT) { - DRM_INFO("VBT doesn't support DRRS\n"); + DRM_DEBUG_KMS("VBT doesn't support DRRS\n"); return NULL; } @@ -4437,7 +4437,7 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port, (dev, fixed_mode, connector); if (!downclock_mode) { - DRM_INFO("DRRS not supported\n"); + DRM_DEBUG_KMS("DRRS not supported\n"); return NULL; } @@ -4448,7 +4448,7 @@ intel_dp_drrs_init(struct intel_digital_port *intel_dig_port, intel_dp->drrs_state.type = dev_priv->vbt.drrs_type; intel_dp->drrs_state.refresh_rate_type = DRRS_HIGH_RR; - DRM_INFO("seamless DRRS supported for eDP panel.\n"); + DRM_DEBUG_KMS("seamless DRRS supported for eDP panel.\n"); return downclock_mode; } -- GitLab From b2784e151903628a086d2ee12cf943690216cd6c Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Tue, 5 Aug 2014 11:29:37 +0100 Subject: [PATCH 0138/9167] drm/i915: Introduce a for_each_intel_encoder() macro Following the established idom, let's provide a macro to iterate through the encoders. spatch helps, once more, for the substitution: @@ iterator name list_for_each_entry; iterator name for_each_intel_encoder; struct intel_encoder * encoder; struct drm_device * dev; @@ -list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { +for_each_intel_encoder(dev, encoder) { ... } I also modified a few call sites by hand where a pointer to mode_config was directly used (to avoid overflowing 80 chars). Signed-off-by: Damien Lespiau [danvet: Wrap paramters correctly in the macro and remove spurious space checkpatch noticed.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +- drivers/gpu/drm/i915/i915_drv.h | 5 +++ drivers/gpu/drm/i915/i915_irq.c | 8 ++-- drivers/gpu/drm/i915/intel_display.c | 59 ++++++++++------------------ drivers/gpu/drm/i915/intel_hdmi.c | 2 +- drivers/gpu/drm/i915/intel_lvds.c | 3 +- 6 files changed, 31 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index aea1a819c775..330caa1ab9f9 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -2708,8 +2708,7 @@ static int i9xx_pipe_crc_auto_source(struct drm_device *dev, enum pipe pipe, *source = INTEL_PIPE_CRC_SOURCE_PIPE; drm_modeset_lock_all(dev); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { if (!encoder->base.crtc) continue; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 0d7e55f2a8a2..73d2308e2377 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -171,6 +171,11 @@ enum hpd_pin { #define for_each_intel_crtc(dev, intel_crtc) \ list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list, base.head) +#define for_each_intel_encoder(dev, intel_encoder) \ + list_for_each_entry(intel_encoder, \ + &(dev)->mode_config.encoder_list, \ + base.head) + #define for_each_encoder_on_crtc(dev, __crtc, intel_encoder) \ list_for_each_entry((intel_encoder), &(dev)->mode_config.encoder_list, base.head) \ if ((intel_encoder)->base.crtc == (__crtc)) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 379cfb5dc731..87abe8679495 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -3522,18 +3522,17 @@ static void cherryview_irq_preinstall(struct drm_device *dev) static void ibx_hpd_irq_setup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *intel_encoder; u32 hotplug_irqs, hotplug, enabled_irqs = 0; if (HAS_PCH_IBX(dev)) { hotplug_irqs = SDE_HOTPLUG_MASK; - list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) + for_each_intel_encoder(dev, intel_encoder) if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) enabled_irqs |= hpd_ibx[intel_encoder->hpd_pin]; } else { hotplug_irqs = SDE_HOTPLUG_MASK_CPT; - list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) + for_each_intel_encoder(dev, intel_encoder) if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) enabled_irqs |= hpd_cpt[intel_encoder->hpd_pin]; } @@ -4452,7 +4451,6 @@ static int i965_irq_postinstall(struct drm_device *dev) static void i915_hpd_irq_setup(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *intel_encoder; u32 hotplug_en; @@ -4463,7 +4461,7 @@ static void i915_hpd_irq_setup(struct drm_device *dev) hotplug_en &= ~HOTPLUG_INT_EN_MASK; /* Note HDMI and DP share hotplug bits */ /* enable bits are the same for all generations */ - list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) + for_each_intel_encoder(dev, intel_encoder) if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) hotplug_en |= hpd_mask_i915[intel_encoder->hpd_pin]; /* Programming the CRT detection parameters tends diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 60ba6962026b..f32a94544940 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6405,7 +6405,6 @@ static bool i9xx_get_pipe_config(struct intel_crtc *crtc, static void ironlake_init_pch_refclk(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder; u32 val, final; bool has_lvds = false; @@ -6415,8 +6414,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev) bool can_ssc = false; /* We need to take the global config into account */ - list_for_each_entry(encoder, &mode_config->encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { switch (encoder->type) { case INTEL_OUTPUT_LVDS: has_panel = true; @@ -6723,11 +6721,10 @@ static void lpt_disable_clkout_dp(struct drm_device *dev) static void lpt_init_pch_refclk(struct drm_device *dev) { - struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder; bool has_vga = false; - list_for_each_entry(encoder, &mode_config->encoder_list, base.head) { + for_each_intel_encoder(dev, encoder) { switch (encoder->type) { case INTEL_OUTPUT_ANALOG: has_vga = true; @@ -9902,8 +9899,7 @@ static void intel_modeset_update_staged_output_state(struct drm_device *dev) to_intel_encoder(connector->base.encoder); } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { encoder->new_crtc = to_intel_crtc(encoder->base.crtc); } @@ -9934,8 +9930,7 @@ static void intel_modeset_commit_output_state(struct drm_device *dev) connector->base.encoder = &connector->new_encoder->base; } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { encoder->base.crtc = &encoder->new_crtc->base; } @@ -10105,8 +10100,7 @@ static bool check_single_encoder_cloning(struct intel_crtc *crtc, struct drm_device *dev = crtc->base.dev; struct intel_encoder *source_encoder; - list_for_each_entry(source_encoder, - &dev->mode_config.encoder_list, base.head) { + for_each_intel_encoder(dev, source_encoder) { if (source_encoder->new_crtc != crtc) continue; @@ -10122,8 +10116,7 @@ static bool check_encoder_cloning(struct intel_crtc *crtc) struct drm_device *dev = crtc->base.dev; struct intel_encoder *encoder; - list_for_each_entry(encoder, - &dev->mode_config.encoder_list, base.head) { + for_each_intel_encoder(dev, encoder) { if (encoder->new_crtc != crtc) continue; @@ -10207,8 +10200,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, * adjust it according to limitations or connector properties, and also * a chance to reject the mode entirely. */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { if (&encoder->new_crtc->base != crtc) continue; @@ -10286,8 +10278,7 @@ intel_modeset_affected_pipes(struct drm_crtc *crtc, unsigned *modeset_pipes, 1 << connector->new_encoder->new_crtc->pipe; } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { if (encoder->base.crtc == &encoder->new_crtc->base) continue; @@ -10361,8 +10352,7 @@ intel_modeset_update_state(struct drm_device *dev, unsigned prepare_pipes) struct intel_crtc *intel_crtc; struct drm_connector *connector; - list_for_each_entry(intel_encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, intel_encoder) { if (!intel_encoder->base.crtc) continue; @@ -10636,8 +10626,7 @@ check_encoder_state(struct drm_device *dev) struct intel_encoder *encoder; struct intel_connector *connector; - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { bool enabled = false; bool active = false; enum pipe pipe, tracked_pipe; @@ -10716,8 +10705,7 @@ check_crtc_state(struct drm_device *dev) WARN(crtc->active && !crtc->base.enabled, "active crtc, but not enabled in sw tracking\n"); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { if (encoder->base.crtc != &crtc->base) continue; enabled = true; @@ -10739,8 +10727,7 @@ check_crtc_state(struct drm_device *dev) if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) active = crtc->active; - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { enum pipe pipe; if (encoder->base.crtc != &crtc->base) continue; @@ -11108,7 +11095,7 @@ static void intel_set_config_restore_state(struct drm_device *dev, } count = 0; - list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { + for_each_intel_encoder(dev, encoder) { encoder->new_crtc = to_intel_crtc(config->save_encoder_crtcs[count++]); } @@ -11267,8 +11254,7 @@ intel_modeset_stage_output_state(struct drm_device *dev, } /* Check for any encoders that needs to be disabled. */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { int num_connectors = 0; list_for_each_entry(connector, &dev->mode_config.connector_list, @@ -11301,9 +11287,7 @@ intel_modeset_stage_output_state(struct drm_device *dev, for_each_intel_crtc(dev, crtc) { crtc->new_enabled = false; - list_for_each_entry(encoder, - &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { if (encoder->new_crtc == crtc) { crtc->new_enabled = true; break; @@ -11340,7 +11324,7 @@ static void disable_crtc_nofb(struct intel_crtc *crtc) connector->new_encoder = NULL; } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { + for_each_intel_encoder(dev, encoder) { if (encoder->new_crtc == crtc) encoder->new_crtc = NULL; } @@ -11972,8 +11956,7 @@ static int intel_encoder_clones(struct intel_encoder *encoder) int index_mask = 0; int entry = 0; - list_for_each_entry(source_encoder, - &dev->mode_config.encoder_list, base.head) { + for_each_intel_encoder(dev, source_encoder) { if (encoders_cloneable(encoder, source_encoder)) index_mask |= (1 << entry); @@ -12162,7 +12145,7 @@ static void intel_setup_outputs(struct drm_device *dev) intel_edp_psr_init(dev); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { + for_each_intel_encoder(dev, encoder) { encoder->base.possible_crtcs = encoder->crtc_mask; encoder->base.possible_clones = intel_encoder_clones(encoder); @@ -13056,8 +13039,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) intel_display_power_get(dev_priv, POWER_DOMAIN_PLLS); } - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { pipe = 0; if (encoder->get_hw_state(encoder, &pipe)) { @@ -13121,8 +13103,7 @@ void intel_modeset_setup_hw_state(struct drm_device *dev, } /* HW state is read out, now we need to sanitize this mess. */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { intel_sanitize_encoder(encoder); } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 5f47d359a991..9169786dbbc3 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -885,7 +885,7 @@ static bool hdmi_12bpc_possible(struct intel_crtc *crtc) if (HAS_GMCH_DISPLAY(dev)) return false; - list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { + for_each_intel_encoder(dev, encoder) { if (encoder->new_crtc != crtc) continue; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 881361c0f27e..1987491723a5 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -823,8 +823,7 @@ bool intel_is_dual_link_lvds(struct drm_device *dev) struct intel_encoder *encoder; struct intel_lvds_encoder *lvds_encoder; - list_for_each_entry(encoder, &dev->mode_config.encoder_list, - base.head) { + for_each_intel_encoder(dev, encoder) { if (encoder->type == INTEL_OUTPUT_LVDS) { lvds_encoder = to_lvds_encoder(&encoder->base); -- GitLab From 76eebda727c76b5712f6ce75a45a9917d3873a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 5 Aug 2014 11:26:52 +0530 Subject: [PATCH 0139/9167] drm/i915: Add 180 degree sprite rotation support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sprite planes (in fact all display planes starting from gen4) support 180 degree rotation. Add the relevant low level bits to the sprite code to make use of that feature. The upper layers are not yet plugged in. v2: HSW handles the rotated buffer offset automagically v3: BDW also handles the rotated buffer offset automagically Testcase: igt/kms_rotation_crc Cc: dri-devel@lists.freedesktop.org Signed-off-by: Ville Syrjälä Signed-off-by: Sagar Kamble Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 3 +++ drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_sprite.c | 38 +++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7f9a81087ebc..5ebac620bbcd 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4218,6 +4218,7 @@ enum punit_power_well { #define DVS_YUV_ORDER_UYVY (1<<16) #define DVS_YUV_ORDER_YVYU (2<<16) #define DVS_YUV_ORDER_VYUY (3<<16) +#define DVS_ROTATE_180 (1<<15) #define DVS_DEST_KEY (1<<2) #define DVS_TRICKLE_FEED_DISABLE (1<<14) #define DVS_TILED (1<<10) @@ -4288,6 +4289,7 @@ enum punit_power_well { #define SPRITE_YUV_ORDER_UYVY (1<<16) #define SPRITE_YUV_ORDER_YVYU (2<<16) #define SPRITE_YUV_ORDER_VYUY (3<<16) +#define SPRITE_ROTATE_180 (1<<15) #define SPRITE_TRICKLE_FEED_DISABLE (1<<14) #define SPRITE_INT_GAMMA_ENABLE (1<<13) #define SPRITE_TILED (1<<10) @@ -4361,6 +4363,7 @@ enum punit_power_well { #define SP_YUV_ORDER_UYVY (1<<16) #define SP_YUV_ORDER_YVYU (2<<16) #define SP_YUV_ORDER_VYUY (3<<16) +#define SP_ROTATE_180 (1<<15) #define SP_TILED (1<<10) #define _SPALINOFF (VLV_DISPLAY_BASE + 0x72184) #define _SPASTRIDE (VLV_DISPLAY_BASE + 0x72188) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 3198de3007be..b63df4416301 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -448,6 +448,7 @@ struct intel_plane { unsigned int crtc_w, crtc_h; uint32_t src_x, src_y; uint32_t src_w, src_h; + unsigned int rotation; /* Since we need to change the watermarks before/after * enabling/disabling the planes, we need to store the parameters here diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index d34a5696ffb6..f4d10c4b2781 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -164,6 +164,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, sprctl &= ~SP_PIXFORMAT_MASK; sprctl &= ~SP_YUV_BYTE_ORDER_MASK; sprctl &= ~SP_TILED; + sprctl &= ~SP_ROTATE_180; switch (fb->pixel_format) { case DRM_FORMAT_YUYV: @@ -236,6 +237,14 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc, fb->pitches[0]); linear_offset -= sprsurf_offset; + if (intel_plane->rotation == BIT(DRM_ROTATE_180)) { + sprctl |= SP_ROTATE_180; + + x += src_w; + y += src_h; + linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; + } + atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); intel_update_primary_plane(intel_crtc); @@ -365,6 +374,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, sprctl &= ~SPRITE_RGB_ORDER_RGBX; sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK; sprctl &= ~SPRITE_TILED; + sprctl &= ~SPRITE_ROTATE_180; switch (fb->pixel_format) { case DRM_FORMAT_XBGR8888: @@ -427,6 +437,18 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, pixel_size, fb->pitches[0]); linear_offset -= sprsurf_offset; + if (intel_plane->rotation == BIT(DRM_ROTATE_180)) { + sprctl |= SPRITE_ROTATE_180; + + /* HSW and BDW does this automagically in hardware */ + if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) { + x += src_w; + y += src_h; + linear_offset += src_h * fb->pitches[0] + + src_w * pixel_size; + } + } + atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); intel_update_primary_plane(intel_crtc); @@ -572,6 +594,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, dvscntr &= ~DVS_RGB_ORDER_XBGR; dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; dvscntr &= ~DVS_TILED; + dvscntr &= ~DVS_ROTATE_180; switch (fb->pixel_format) { case DRM_FORMAT_XBGR8888: @@ -629,6 +652,14 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, pixel_size, fb->pitches[0]); linear_offset -= dvssurf_offset; + if (intel_plane->rotation == BIT(DRM_ROTATE_180)) { + dvscntr |= DVS_ROTATE_180; + + x += src_w; + y += src_h; + linear_offset += src_h * fb->pitches[0] + src_w * pixel_size; + } + atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count); intel_update_primary_plane(intel_crtc); @@ -896,6 +927,9 @@ 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, + intel_plane->rotation); + hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale); BUG_ON(hscale < 0); @@ -934,6 +968,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 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, + 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 || @@ -1311,6 +1348,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) intel_plane->pipe = pipe; intel_plane->plane = plane; + intel_plane->rotation = BIT(DRM_ROTATE_0); possible_crtcs = (1 << pipe); ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs, &intel_plane_funcs, -- GitLab From e57465f35192246b6587c3bc89b5ed96a8fdfb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 5 Aug 2014 11:26:53 +0530 Subject: [PATCH 0140/9167] drm/i915: Make intel_plane_restore() return an error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Propagate the error from intel_update_plane() up through intel_plane_restore() to the caller. This will be used for rollback purposes when setting properties fails. Cc: dri-devel@lists.freedesktop.org Signed-off-by: Ville Syrjälä Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_drv.h | 2 +- drivers/gpu/drm/i915/intel_sprite.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b63df4416301..79782094c8f9 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1086,7 +1086,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob); int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane); void intel_flush_primary_plane(struct drm_i915_private *dev_priv, enum plane plane); -void intel_plane_restore(struct drm_plane *plane); +int intel_plane_restore(struct drm_plane *plane); void intel_plane_disable(struct drm_plane *plane); int intel_sprite_set_colorkey(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index f4d10c4b2781..611826209c99 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1218,18 +1218,18 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data, return ret; } -void intel_plane_restore(struct drm_plane *plane) +int intel_plane_restore(struct drm_plane *plane) { struct intel_plane *intel_plane = to_intel_plane(plane); if (!plane->crtc || !plane->fb) - return; + return 0; - intel_update_plane(plane, plane->crtc, plane->fb, - intel_plane->crtc_x, intel_plane->crtc_y, - intel_plane->crtc_w, intel_plane->crtc_h, - intel_plane->src_x, intel_plane->src_y, - intel_plane->src_w, intel_plane->src_h); + return intel_update_plane(plane, plane->crtc, plane->fb, + intel_plane->crtc_x, intel_plane->crtc_y, + intel_plane->crtc_w, intel_plane->crtc_h, + intel_plane->src_x, intel_plane->src_y, + intel_plane->src_w, intel_plane->src_h); } void intel_plane_disable(struct drm_plane *plane) -- GitLab From 2a297cce2e775812e9d6ca84c3ab92cee5c38e25 Mon Sep 17 00:00:00 2001 From: Sonika Jindal Date: Tue, 5 Aug 2014 11:26:54 +0530 Subject: [PATCH 0141/9167] drm: Add rotation_property to mode_config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Sonika Jindal Reviewed-by: Ville Syrjälä Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- include/drm/drm_crtc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index f1105d0da059..62f73bdbcc47 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -821,6 +821,7 @@ struct drm_mode_config { struct drm_property *dpms_property; struct drm_property *path_property; struct drm_property *plane_type_property; + struct drm_property *rotation_property; /* DVI-I properties */ struct drm_property *dvi_i_subconnector_property; -- GitLab From 7ed6eeeec60c98ec824e27a5052aa249d98bd63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 5 Aug 2014 11:26:55 +0530 Subject: [PATCH 0142/9167] drm/i915: Add rotation property for sprites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sprite planes support 180 degree rotation. The lower layers are now in place, so hook in the standard rotation property to expose the feature to the users. v2: Moving rotation_property to mode_config Cc: dri-devel@lists.freedesktop.org Signed-off-by: Ville Syrjälä Signed-off-by: Sonika Jindal Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_sprite.c | 41 ++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 611826209c99..0bdb00b7c59c 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -1218,6 +1218,30 @@ int intel_sprite_get_colorkey(struct drm_device *dev, void *data, return ret; } +static int intel_plane_set_property(struct drm_plane *plane, + struct drm_property *prop, + uint64_t val) +{ + struct drm_device *dev = plane->dev; + struct intel_plane *intel_plane = to_intel_plane(plane); + uint64_t old_val; + int ret = -ENOENT; + + if (prop == dev->mode_config.rotation_property) { + /* exactly one rotation angle please */ + if (hweight32(val & 0xf) != 1) + return -EINVAL; + + old_val = intel_plane->rotation; + intel_plane->rotation = val; + ret = intel_plane_restore(plane); + if (ret) + intel_plane->rotation = old_val; + } + + return ret; +} + int intel_plane_restore(struct drm_plane *plane) { struct intel_plane *intel_plane = to_intel_plane(plane); @@ -1244,6 +1268,7 @@ static const struct drm_plane_funcs intel_plane_funcs = { .update_plane = intel_update_plane, .disable_plane = intel_disable_plane, .destroy = intel_destroy_plane, + .set_property = intel_plane_set_property, }; static uint32_t ilk_plane_formats[] = { @@ -1354,8 +1379,22 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) &intel_plane_funcs, plane_formats, num_plane_formats, false); - if (ret) + if (ret) { kfree(intel_plane); + goto out; + } + + 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(&intel_plane->base.base, + dev->mode_config.rotation_property, + intel_plane->rotation); + out: return ret; } -- GitLab From 9783de20967a59d7627772bf77fc8066c47bef79 Mon Sep 17 00:00:00 2001 From: Sonika Jindal Date: Tue, 5 Aug 2014 11:26:57 +0530 Subject: [PATCH 0143/9167] drm: Resetting rotation property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reset rotation property to 0. v2: Resetting after disabling the plane Signed-off-by: Sonika Jindal Reviewed-by: Ville Syrjälä Acked-by: Dave Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 3144db9dc0f1..d139eddb3d61 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -345,10 +345,17 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper) drm_warn_on_modeset_not_all_locked(dev); - list_for_each_entry(plane, &dev->mode_config.plane_list, head) + list_for_each_entry(plane, &dev->mode_config.plane_list, head) { if (plane->type != DRM_PLANE_TYPE_PRIMARY) drm_plane_force_disable(plane); + if (dev->mode_config.rotation_property) { + drm_object_property_set_value(&plane->base, + dev->mode_config.rotation_property, + BIT(DRM_ROTATE_0)); + } + } + for (i = 0; i < fb_helper->crtc_count; i++) { struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; struct drm_crtc *crtc = mode_set->crtc; -- GitLab From 0a56067469bde6662ce7c89a3d290171f878bac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 11 Jun 2014 16:51:18 +0300 Subject: [PATCH 0144/9167] drm/i915: Fill out the FWx watermark register defines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add defines for all the watermark registers on modernish gmch platforms. VLV has increased the number of bits available for certain watermaks so expand the masks appropriately. Also vlv and chv have added some extra FW registers. Not sure what happened on chv because a new register called FW9 is now at the offset where FW7 was on vlv, while FW7 and FW8 (another new register) have been moved off somewhere else. Oh well, well just need two defines for FW7 then. v2: Fix DSPHOWM1 offset (Paulo) Reviewed-by: Paulo Zanoni Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 138 ++++++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_pm.c | 11 ++- 2 files changed, 130 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5ebac620bbcd..a87eb18b4c90 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3865,28 +3865,136 @@ enum punit_power_well { #define DSPARB_BEND_SHIFT 9 /* on 855 */ #define DSPARB_AEND_SHIFT 0 +/* pnv/gen4/g4x/vlv/chv */ #define DSPFW1 (dev_priv->info.display_mmio_offset + 0x70034) -#define DSPFW_SR_SHIFT 23 -#define DSPFW_SR_MASK (0x1ff<<23) -#define DSPFW_CURSORB_SHIFT 16 -#define DSPFW_CURSORB_MASK (0x3f<<16) -#define DSPFW_PLANEB_SHIFT 8 -#define DSPFW_PLANEB_MASK (0x7f<<8) -#define DSPFW_PLANEA_MASK (0x7f) +#define DSPFW_SR_SHIFT 23 +#define DSPFW_SR_MASK (0x1ff<<23) +#define DSPFW_CURSORB_SHIFT 16 +#define DSPFW_CURSORB_MASK (0x3f<<16) +#define DSPFW_PLANEB_SHIFT 8 +#define DSPFW_PLANEB_MASK (0x7f<<8) +#define DSPFW_PLANEB_MASK_VLV (0xff<<8) /* vlv/chv */ +#define DSPFW_PLANEA_SHIFT 0 +#define DSPFW_PLANEA_MASK (0x7f<<0) +#define DSPFW_PLANEA_MASK_VLV (0xff<<0) /* vlv/chv */ #define DSPFW2 (dev_priv->info.display_mmio_offset + 0x70038) -#define DSPFW_CURSORA_MASK 0x00003f00 -#define DSPFW_CURSORA_SHIFT 8 -#define DSPFW_PLANEC_MASK (0x7f) +#define DSPFW_FBC_SR_EN (1<<31) /* g4x */ +#define DSPFW_FBC_SR_SHIFT 28 +#define DSPFW_FBC_SR_MASK (0x7<<28) /* g4x */ +#define DSPFW_FBC_HPLL_SR_SHIFT 24 +#define DSPFW_FBC_HPLL_SR_MASK (0xf<<24) /* g4x */ +#define DSPFW_SPRITEB_SHIFT (16) +#define DSPFW_SPRITEB_MASK (0x7f<<16) /* g4x */ +#define DSPFW_SPRITEB_MASK_VLV (0xff<<16) /* vlv/chv */ +#define DSPFW_CURSORA_SHIFT 8 +#define DSPFW_CURSORA_MASK (0x3f<<8) +#define DSPFW_PLANEC_SHIFT_OLD 0 +#define DSPFW_PLANEC_MASK_OLD (0x7f<<0) /* pre-gen4 sprite C */ +#define DSPFW_SPRITEA_SHIFT 0 +#define DSPFW_SPRITEA_MASK (0x7f<<0) /* g4x */ +#define DSPFW_SPRITEA_MASK_VLV (0xff<<0) /* vlv/chv */ #define DSPFW3 (dev_priv->info.display_mmio_offset + 0x7003c) -#define DSPFW_HPLL_SR_EN (1<<31) -#define DSPFW_CURSOR_SR_SHIFT 24 +#define DSPFW_HPLL_SR_EN (1<<31) #define PINEVIEW_SELF_REFRESH_EN (1<<30) +#define DSPFW_CURSOR_SR_SHIFT 24 #define DSPFW_CURSOR_SR_MASK (0x3f<<24) #define DSPFW_HPLL_CURSOR_SHIFT 16 #define DSPFW_HPLL_CURSOR_MASK (0x3f<<16) -#define DSPFW_HPLL_SR_MASK (0x1ff) -#define DSPFW4 (dev_priv->info.display_mmio_offset + 0x70070) -#define DSPFW7 (dev_priv->info.display_mmio_offset + 0x7007c) +#define DSPFW_HPLL_SR_SHIFT 0 +#define DSPFW_HPLL_SR_MASK (0x1ff<<0) + +/* vlv/chv */ +#define DSPFW4 (VLV_DISPLAY_BASE + 0x70070) +#define DSPFW_SPRITEB_WM1_SHIFT 16 +#define DSPFW_SPRITEB_WM1_MASK (0xff<<16) +#define DSPFW_CURSORA_WM1_SHIFT 8 +#define DSPFW_CURSORA_WM1_MASK (0x3f<<8) +#define DSPFW_SPRITEA_WM1_SHIFT 0 +#define DSPFW_SPRITEA_WM1_MASK (0xff<<0) +#define DSPFW5 (VLV_DISPLAY_BASE + 0x70074) +#define DSPFW_PLANEB_WM1_SHIFT 24 +#define DSPFW_PLANEB_WM1_MASK (0xff<<24) +#define DSPFW_PLANEA_WM1_SHIFT 16 +#define DSPFW_PLANEA_WM1_MASK (0xff<<16) +#define DSPFW_CURSORB_WM1_SHIFT 8 +#define DSPFW_CURSORB_WM1_MASK (0x3f<<8) +#define DSPFW_CURSOR_SR_WM1_SHIFT 0 +#define DSPFW_CURSOR_SR_WM1_MASK (0x3f<<0) +#define DSPFW6 (VLV_DISPLAY_BASE + 0x70078) +#define DSPFW_SR_WM1_SHIFT 0 +#define DSPFW_SR_WM1_MASK (0x1ff<<0) +#define DSPFW7 (VLV_DISPLAY_BASE + 0x7007c) +#define DSPFW7_CHV (VLV_DISPLAY_BASE + 0x700b4) /* wtf #1? */ +#define DSPFW_SPRITED_WM1_SHIFT 24 +#define DSPFW_SPRITED_WM1_MASK (0xff<<24) +#define DSPFW_SPRITED_SHIFT 16 +#define DSPFW_SPRITED_MASK (0xff<<16) +#define DSPFW_SPRITEC_WM1_SHIFT 8 +#define DSPFW_SPRITEC_WM1_MASK (0xff<<8) +#define DSPFW_SPRITEC_SHIFT 0 +#define DSPFW_SPRITEC_MASK (0xff<<0) +#define DSPFW8_CHV (VLV_DISPLAY_BASE + 0x700b8) +#define DSPFW_SPRITEF_WM1_SHIFT 24 +#define DSPFW_SPRITEF_WM1_MASK (0xff<<24) +#define DSPFW_SPRITEF_SHIFT 16 +#define DSPFW_SPRITEF_MASK (0xff<<16) +#define DSPFW_SPRITEE_WM1_SHIFT 8 +#define DSPFW_SPRITEE_WM1_MASK (0xff<<8) +#define DSPFW_SPRITEE_SHIFT 0 +#define DSPFW_SPRITEE_MASK (0xff<<0) +#define DSPFW9_CHV (VLV_DISPLAY_BASE + 0x7007c) /* wtf #2? */ +#define DSPFW_PLANEC_WM1_SHIFT 24 +#define DSPFW_PLANEC_WM1_MASK (0xff<<24) +#define DSPFW_PLANEC_SHIFT 16 +#define DSPFW_PLANEC_MASK (0xff<<16) +#define DSPFW_CURSORC_WM1_SHIFT 8 +#define DSPFW_CURSORC_WM1_MASK (0x3f<<16) +#define DSPFW_CURSORC_SHIFT 0 +#define DSPFW_CURSORC_MASK (0x3f<<0) + +/* vlv/chv high order bits */ +#define DSPHOWM (VLV_DISPLAY_BASE + 0x70064) +#define DSPFW_SR_HI_SHIFT 24 +#define DSPFW_SR_HI_MASK (1<<24) +#define DSPFW_SPRITEF_HI_SHIFT 23 +#define DSPFW_SPRITEF_HI_MASK (1<<23) +#define DSPFW_SPRITEE_HI_SHIFT 22 +#define DSPFW_SPRITEE_HI_MASK (1<<22) +#define DSPFW_PLANEC_HI_SHIFT 21 +#define DSPFW_PLANEC_HI_MASK (1<<21) +#define DSPFW_SPRITED_HI_SHIFT 20 +#define DSPFW_SPRITED_HI_MASK (1<<20) +#define DSPFW_SPRITEC_HI_SHIFT 16 +#define DSPFW_SPRITEC_HI_MASK (1<<16) +#define DSPFW_PLANEB_HI_SHIFT 12 +#define DSPFW_PLANEB_HI_MASK (1<<12) +#define DSPFW_SPRITEB_HI_SHIFT 8 +#define DSPFW_SPRITEB_HI_MASK (1<<8) +#define DSPFW_SPRITEA_HI_SHIFT 4 +#define DSPFW_SPRITEA_HI_MASK (1<<4) +#define DSPFW_PLANEA_HI_SHIFT 0 +#define DSPFW_PLANEA_HI_MASK (1<<0) +#define DSPHOWM1 (VLV_DISPLAY_BASE + 0x70068) +#define DSPFW_SR_WM1_HI_SHIFT 24 +#define DSPFW_SR_WM1_HI_MASK (1<<24) +#define DSPFW_SPRITEF_WM1_HI_SHIFT 23 +#define DSPFW_SPRITEF_WM1_HI_MASK (1<<23) +#define DSPFW_SPRITEE_WM1_HI_SHIFT 22 +#define DSPFW_SPRITEE_WM1_HI_MASK (1<<22) +#define DSPFW_PLANEC_WM1_HI_SHIFT 21 +#define DSPFW_PLANEC_WM1_HI_MASK (1<<21) +#define DSPFW_SPRITED_WM1_HI_SHIFT 20 +#define DSPFW_SPRITED_WM1_HI_MASK (1<<20) +#define DSPFW_SPRITEC_WM1_HI_SHIFT 16 +#define DSPFW_SPRITEC_WM1_HI_MASK (1<<16) +#define DSPFW_PLANEB_WM1_HI_SHIFT 12 +#define DSPFW_PLANEB_WM1_HI_MASK (1<<12) +#define DSPFW_SPRITEB_WM1_HI_SHIFT 8 +#define DSPFW_SPRITEB_WM1_HI_MASK (1<<8) +#define DSPFW_SPRITEA_WM1_HI_SHIFT 4 +#define DSPFW_SPRITEA_WM1_HI_MASK (1<<4) +#define DSPFW_PLANEA_WM1_HI_SHIFT 0 +#define DSPFW_PLANEA_WM1_HI_MASK (1<<0) /* drain latency register values*/ #define DRAIN_LATENCY_PRECISION_32 32 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index ab80df2909e0..0f9164d854de 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1400,7 +1400,7 @@ static void valleyview_update_wm(struct drm_crtc *crtc) (plane_sr << DSPFW_SR_SHIFT) | (cursorb_wm << DSPFW_CURSORB_SHIFT) | (planeb_wm << DSPFW_PLANEB_SHIFT) | - planea_wm); + (planea_wm << DSPFW_PLANEA_SHIFT)); I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | (cursora_wm << DSPFW_CURSORA_SHIFT)); @@ -1457,7 +1457,7 @@ static void g4x_update_wm(struct drm_crtc *crtc) (plane_sr << DSPFW_SR_SHIFT) | (cursorb_wm << DSPFW_CURSORB_SHIFT) | (planeb_wm << DSPFW_PLANEB_SHIFT) | - planea_wm); + (planea_wm << DSPFW_PLANEA_SHIFT)); I915_WRITE(DSPFW2, (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | (cursora_wm << DSPFW_CURSORA_SHIFT)); @@ -1531,8 +1531,11 @@ static void i965_update_wm(struct drm_crtc *unused_crtc) /* 965 has limitations... */ I915_WRITE(DSPFW1, (srwm << DSPFW_SR_SHIFT) | - (8 << 16) | (8 << 8) | (8 << 0)); - I915_WRITE(DSPFW2, (8 << 8) | (8 << 0)); + (8 << DSPFW_CURSORB_SHIFT) | + (8 << DSPFW_PLANEB_SHIFT) | + (8 << DSPFW_PLANEA_SHIFT)); + I915_WRITE(DSPFW2, (8 << DSPFW_CURSORA_SHIFT) | + (8 << DSPFW_PLANEC_SHIFT_OLD)); /* update cursor SR watermark */ I915_WRITE(DSPFW3, (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); -- GitLab From 1abc4dc7e2ca7886b6b06bcf2ff1451702c83f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 26 Jun 2014 17:02:37 +0300 Subject: [PATCH 0145/9167] drm/i915: Parametrize VLV_DDL registers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The VLV/CHV DDL registers are uniform, and neatly enough the register offsets are sane so we can easily unify them to a single set of defines and just pass the pipe as the parameter to compute the register offset. Note that we now fill out the drain latency for pipe C on CHV which we didn't do before. The rest of the pipe C watermarks are still untouched but that will be remedied later by adding a proper cherryview_update_wm() function. v2: Add a note about CHV pipe C changes (Paulo) Reviewed-by: Paulo Zanoni Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 54 ++++++++------------------------- drivers/gpu/drm/i915/intel_pm.c | 52 ++++++++++++++----------------- 2 files changed, 36 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a87eb18b4c90..fbdb08f4cd76 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3999,47 +3999,19 @@ enum punit_power_well { /* drain latency register values*/ #define DRAIN_LATENCY_PRECISION_32 32 #define DRAIN_LATENCY_PRECISION_64 64 -#define VLV_DDL1 (VLV_DISPLAY_BASE + 0x70050) -#define DDL_CURSORA_PRECISION_64 (1<<31) -#define DDL_CURSORA_PRECISION_32 (0<<31) -#define DDL_CURSORA_SHIFT 24 -#define DDL_SPRITEB_PRECISION_64 (1<<23) -#define DDL_SPRITEB_PRECISION_32 (0<<23) -#define DDL_SPRITEB_SHIFT 16 -#define DDL_SPRITEA_PRECISION_64 (1<<15) -#define DDL_SPRITEA_PRECISION_32 (0<<15) -#define DDL_SPRITEA_SHIFT 8 -#define DDL_PLANEA_PRECISION_64 (1<<7) -#define DDL_PLANEA_PRECISION_32 (0<<7) -#define DDL_PLANEA_SHIFT 0 - -#define VLV_DDL2 (VLV_DISPLAY_BASE + 0x70054) -#define DDL_CURSORB_PRECISION_64 (1<<31) -#define DDL_CURSORB_PRECISION_32 (0<<31) -#define DDL_CURSORB_SHIFT 24 -#define DDL_SPRITED_PRECISION_64 (1<<23) -#define DDL_SPRITED_PRECISION_32 (0<<23) -#define DDL_SPRITED_SHIFT 16 -#define DDL_SPRITEC_PRECISION_64 (1<<15) -#define DDL_SPRITEC_PRECISION_32 (0<<15) -#define DDL_SPRITEC_SHIFT 8 -#define DDL_PLANEB_PRECISION_64 (1<<7) -#define DDL_PLANEB_PRECISION_32 (0<<7) -#define DDL_PLANEB_SHIFT 0 - -#define VLV_DDL3 (VLV_DISPLAY_BASE + 0x70058) -#define DDL_CURSORC_PRECISION_64 (1<<31) -#define DDL_CURSORC_PRECISION_32 (0<<31) -#define DDL_CURSORC_SHIFT 24 -#define DDL_SPRITEF_PRECISION_64 (1<<23) -#define DDL_SPRITEF_PRECISION_32 (0<<23) -#define DDL_SPRITEF_SHIFT 16 -#define DDL_SPRITEE_PRECISION_64 (1<<15) -#define DDL_SPRITEE_PRECISION_32 (0<<15) -#define DDL_SPRITEE_SHIFT 8 -#define DDL_PLANEC_PRECISION_64 (1<<7) -#define DDL_PLANEC_PRECISION_32 (0<<7) -#define DDL_PLANEC_SHIFT 0 +#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_SHIFT 24 +#define DDL_SPRITE1_PRECISION_64 (1<<23) +#define DDL_SPRITE1_PRECISION_32 (0<<23) +#define DDL_SPRITE1_SHIFT 16 +#define DDL_SPRITE0_PRECISION_64 (1<<15) +#define DDL_SPRITE0_PRECISION_32 (0<<15) +#define DDL_SPRITE0_SHIFT 8 +#define DDL_PLANE_PRECISION_64 (1<<7) +#define DDL_PLANE_PRECISION_32 (0<<7) +#define DDL_PLANE_SHIFT 0 /* FIFO watermark sizes etc */ #define G4X_FIFO_LINE_SIZE 64 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0f9164d854de..2573c6967559 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1313,35 +1313,29 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, static void vlv_update_drain_latency(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int planea_prec, planea_dl, planeb_prec, planeb_dl; - int cursora_prec, cursora_dl, cursorb_prec, cursorb_dl; - int plane_prec_mult, cursor_prec_mult; /* Precision multiplier is - either 16 or 32 */ - - /* For plane A, Cursor A */ - if (vlv_compute_drain_latency(dev, 0, &plane_prec_mult, &planea_dl, - &cursor_prec_mult, &cursora_dl)) { - cursora_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? - DDL_CURSORA_PRECISION_32 : DDL_CURSORA_PRECISION_64; - planea_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? - DDL_PLANEA_PRECISION_32 : DDL_PLANEA_PRECISION_64; - - I915_WRITE(VLV_DDL1, cursora_prec | - (cursora_dl << DDL_CURSORA_SHIFT) | - planea_prec | planea_dl); - } - - /* For plane B, Cursor B */ - if (vlv_compute_drain_latency(dev, 1, &plane_prec_mult, &planeb_dl, - &cursor_prec_mult, &cursorb_dl)) { - cursorb_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_32) ? - DDL_CURSORB_PRECISION_32 : DDL_CURSORB_PRECISION_64; - planeb_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_32) ? - DDL_PLANEB_PRECISION_32 : DDL_PLANEB_PRECISION_64; - - I915_WRITE(VLV_DDL2, cursorb_prec | - (cursorb_dl << DDL_CURSORB_SHIFT) | - planeb_prec | planeb_dl); + enum pipe pipe; + + for_each_pipe(pipe) { + int plane_prec, plane_dl; + int cursor_prec, cursor_dl; + int plane_prec_mult, cursor_prec_mult; + + if (!vlv_compute_drain_latency(dev, pipe, &plane_prec_mult, &plane_dl, + &cursor_prec_mult, &cursor_dl)) + continue; + + /* + * FIXME CHV spec still lists 16 and 32 as the precision + * values. Need to figure out if spec is outdated or what. + */ + cursor_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_64) ? + DDL_CURSOR_PRECISION_64 : DDL_CURSOR_PRECISION_32; + plane_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_64) ? + DDL_PLANE_PRECISION_64 : DDL_PLANE_PRECISION_32; + + I915_WRITE(VLV_DDL(pipe), cursor_prec | + (cursor_dl << DDL_CURSOR_SHIFT) | + plane_prec | (plane_dl << DDL_PLANE_SHIFT)); } } -- GitLab From 41aad816d7061f6cc3d92f39fc655f034bbfb1c0 Mon Sep 17 00:00:00 2001 From: Gajanan Bhat Date: Wed, 16 Jul 2014 18:24:03 +0530 Subject: [PATCH 0146/9167] drm/i915: Update DDL only for current CRTC Instead of looping through all CRTCs, update DDL for current CRTC for which watermark is being updated. CHV is confirmed to have precision of 32/64 which is same as VLV. Reviewed-by: Imre Deak Signed-off-by: Gajanan Bhat Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 2573c6967559..0feeae845f12 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1310,24 +1310,17 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, * latency value. */ -static void vlv_update_drain_latency(struct drm_device *dev) +static void vlv_update_drain_latency(struct drm_crtc *crtc) { + struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - enum pipe pipe; - - for_each_pipe(pipe) { - int plane_prec, plane_dl; - int cursor_prec, cursor_dl; - int plane_prec_mult, cursor_prec_mult; + enum pipe pipe = to_intel_crtc(crtc)->pipe; + int plane_prec, plane_dl; + int cursor_prec, cursor_dl; + int plane_prec_mult, cursor_prec_mult; - if (!vlv_compute_drain_latency(dev, pipe, &plane_prec_mult, &plane_dl, - &cursor_prec_mult, &cursor_dl)) - continue; - - /* - * FIXME CHV spec still lists 16 and 32 as the precision - * values. Need to figure out if spec is outdated or what. - */ + if (vlv_compute_drain_latency(dev, pipe, &plane_prec_mult, &plane_dl, + &cursor_prec_mult, &cursor_dl)) { cursor_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_64) ? DDL_CURSOR_PRECISION_64 : DDL_CURSOR_PRECISION_32; plane_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_64) ? @@ -1352,7 +1345,7 @@ static void valleyview_update_wm(struct drm_crtc *crtc) unsigned int enabled = 0; bool cxsr_enabled; - vlv_update_drain_latency(dev); + vlv_update_drain_latency(crtc); if (g4x_compute_wm0(dev, PIPE_A, &valleyview_wm_info, latency_ns, -- GitLab From 3c2777fd2faa5d1c1d5867baa086f2fd8b05479e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 26 Jun 2014 17:03:06 +0300 Subject: [PATCH 0147/9167] drm/i915: Add cherryview_update_wm() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CHV has a third pipe so we need to compute the watermarks for its planes. Add cherryview_update_wm() to do just that. v2: Rebase on top of Imre's cxsr changes v3: Pass crtc to vlv_update_drain_latency() Reviewed-by: Paulo Zanoni Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 81 ++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 0feeae845f12..da43e30ad60b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1399,6 +1399,85 @@ static void valleyview_update_wm(struct drm_crtc *crtc) intel_set_memory_cxsr(dev_priv, true); } +static void cherryview_update_wm(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + static const int sr_latency_ns = 12000; + struct drm_i915_private *dev_priv = dev->dev_private; + int planea_wm, planeb_wm, planec_wm; + int cursora_wm, cursorb_wm, cursorc_wm; + int plane_sr, cursor_sr; + int ignore_plane_sr, ignore_cursor_sr; + unsigned int enabled = 0; + bool cxsr_enabled; + + vlv_update_drain_latency(crtc); + + if (g4x_compute_wm0(dev, PIPE_A, + &valleyview_wm_info, latency_ns, + &valleyview_cursor_wm_info, latency_ns, + &planea_wm, &cursora_wm)) + enabled |= 1 << PIPE_A; + + if (g4x_compute_wm0(dev, PIPE_B, + &valleyview_wm_info, latency_ns, + &valleyview_cursor_wm_info, latency_ns, + &planeb_wm, &cursorb_wm)) + enabled |= 1 << PIPE_B; + + if (g4x_compute_wm0(dev, PIPE_C, + &valleyview_wm_info, latency_ns, + &valleyview_cursor_wm_info, latency_ns, + &planec_wm, &cursorc_wm)) + enabled |= 1 << PIPE_C; + + if (single_plane_enabled(enabled) && + g4x_compute_srwm(dev, ffs(enabled) - 1, + sr_latency_ns, + &valleyview_wm_info, + &valleyview_cursor_wm_info, + &plane_sr, &ignore_cursor_sr) && + g4x_compute_srwm(dev, ffs(enabled) - 1, + 2*sr_latency_ns, + &valleyview_wm_info, + &valleyview_cursor_wm_info, + &ignore_plane_sr, &cursor_sr)) { + cxsr_enabled = true; + } else { + cxsr_enabled = false; + intel_set_memory_cxsr(dev_priv, false); + plane_sr = cursor_sr = 0; + } + + DRM_DEBUG_KMS("Setting FIFO watermarks - A: plane=%d, cursor=%d, " + "B: plane=%d, cursor=%d, C: plane=%d, cursor=%d, " + "SR: plane=%d, cursor=%d\n", + planea_wm, cursora_wm, + planeb_wm, cursorb_wm, + planec_wm, cursorc_wm, + plane_sr, cursor_sr); + + I915_WRITE(DSPFW1, + (plane_sr << DSPFW_SR_SHIFT) | + (cursorb_wm << DSPFW_CURSORB_SHIFT) | + (planeb_wm << DSPFW_PLANEB_SHIFT) | + (planea_wm << DSPFW_PLANEA_SHIFT)); + I915_WRITE(DSPFW2, + (I915_READ(DSPFW2) & ~DSPFW_CURSORA_MASK) | + (cursora_wm << DSPFW_CURSORA_SHIFT)); + I915_WRITE(DSPFW3, + (I915_READ(DSPFW3) & ~DSPFW_CURSOR_SR_MASK) | + (cursor_sr << DSPFW_CURSOR_SR_SHIFT)); + I915_WRITE(DSPFW9_CHV, + (I915_READ(DSPFW9_CHV) & ~(DSPFW_PLANEC_MASK | + DSPFW_CURSORC_MASK)) | + (planec_wm << DSPFW_PLANEC_SHIFT) | + (cursorc_wm << DSPFW_CURSORC_SHIFT)); + + if (cxsr_enabled) + intel_set_memory_cxsr(dev_priv, true); +} + static void g4x_update_wm(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -7119,7 +7198,7 @@ void intel_init_pm(struct drm_device *dev) else if (INTEL_INFO(dev)->gen == 8) dev_priv->display.init_clock_gating = gen8_init_clock_gating; } else if (IS_CHERRYVIEW(dev)) { - dev_priv->display.update_wm = valleyview_update_wm; + dev_priv->display.update_wm = cherryview_update_wm; dev_priv->display.init_clock_gating = cherryview_init_clock_gating; } else if (IS_VALLEYVIEW(dev)) { -- GitLab From 3dd7b97458e8aa2d8985b46622d226fa635071e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 27 Jun 2014 19:49:57 +0300 Subject: [PATCH 0148/9167] drm/i915: Hack to tie both common lanes together on chv MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It looks like frobbing the cmnreset line on pne PHY disturbs the other PHY on chv. The result is a black screen. On HDMI it's just a flash of black, but DP usually falls over and can't get back up. As a workaround set up the power domains so that both common lane wells power up and down together. I also tried leaving the cmnreset deasserted even the if the power well goes down but that didn't seem acceptable to the PHY. Reviewed-by: Rafael Barbalho Signed-off-by: Ville Syrjälä 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 da43e30ad60b..aaae22815965 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6877,13 +6877,23 @@ static struct i915_power_well chv_power_wells[] = { #endif { .name = "dpio-common-bc", - .domains = CHV_DPIO_CMN_BC_POWER_DOMAINS, + /* + * 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", - .domains = CHV_DPIO_CMN_D_POWER_DOMAINS, + /* + * 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, }, -- GitLab From efd814b73cfcf4ed1cb561561d8df6daccb3ceb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 27 Jun 2014 19:52:13 +0300 Subject: [PATCH 0149/9167] drm/i915: Polish the chv cmnlane resrt macros MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the semi-funky cmnlane assert/deassert macros with something a bit more conventional. Also protect the macro arguments properly (also for PHY_POWERGOOD()). Reviewed-by: Rafael Barbalho Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 7 ++----- drivers/gpu/drm/i915/intel_pm.c | 8 ++++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index fbdb08f4cd76..468ef09d698d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1697,12 +1697,9 @@ enum punit_power_well { #define DPIO_PHY_STATUS (VLV_DISPLAY_BASE + 0x6240) #define DPLL_PORTD_READY_MASK (0xf) #define DISPLAY_PHY_CONTROL (VLV_DISPLAY_BASE + 0x60100) -#define PHY_COM_LANE_RESET_DEASSERT(phy, val) \ - ((phy == DPIO_PHY0) ? (val | 1) : (val | 2)) -#define PHY_COM_LANE_RESET_ASSERT(phy, val) \ - ((phy == DPIO_PHY0) ? (val & ~1) : (val & ~2)) +#define PHY_COM_LANE_RESET_DEASSERT(phy) (1 << (phy)) #define DISPLAY_PHY_STATUS (VLV_DISPLAY_BASE + 0x60104) -#define PHY_POWERGOOD(phy) ((phy == DPIO_PHY0) ? (1<<31) : (1<<30)) +#define PHY_POWERGOOD(phy) (((phy) == DPIO_PHY0) ? (1<<31) : (1<<30)) /* * The i830 generation, in LVDS mode, defines P1 as the bit number set within diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index aaae22815965..42bb329b2d05 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -6359,8 +6359,8 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv, 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, - PHY_COM_LANE_RESET_DEASSERT(phy, I915_READ(DISPLAY_PHY_CONTROL))); + 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, @@ -6380,8 +6380,8 @@ static void chv_dpio_cmn_power_well_disable(struct drm_i915_private *dev_priv, assert_pll_disabled(dev_priv, PIPE_C); } - I915_WRITE(DISPLAY_PHY_CONTROL, - PHY_COM_LANE_RESET_ASSERT(phy, I915_READ(DISPLAY_PHY_CONTROL))); + 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); } -- GitLab From 692ef70c016b5035ad1942ccc2bc4040aa290044 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 5 Aug 2014 07:51:18 -0700 Subject: [PATCH 0150/9167] drm/i915: clean up PPGTT checking logic sanitize_enable_ppgtt is the function that checks all the conditions, honoring a forced ppgtt status or doing auto-detect as necessary. Just make sure it returns the right value in all cases and use that in the macros instead of the confusing intel_enable_ppgtt() function. Signed-off-by: Jesse Barnes Signed-off-by: Rodrigo Vivi [danvet: Don't reenable full ppgtt through the backdoor.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/i915_gem_gtt.c | 11 ----------- drivers/gpu/drm/i915/i915_gem_gtt.h | 1 - 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 73d2308e2377..125a83c70768 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2065,8 +2065,8 @@ struct drm_i915_cmd_table { #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) #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) intel_enable_ppgtt(dev, false) -#define USES_FULL_PPGTT(dev) intel_enable_ppgtt(dev, true) +#define USES_PPGTT(dev) (i915.enable_ppgtt) +#define USES_FULL_PPGTT(dev) (i915.enable_ppgtt == 2) #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 1411613f2174..b4b7cfd226b7 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -33,17 +33,6 @@ static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv); static void chv_setup_private_ppat(struct drm_i915_private *dev_priv); -bool intel_enable_ppgtt(struct drm_device *dev, bool full) -{ - if (i915.enable_ppgtt == 0) - return false; - - if (i915.enable_ppgtt == 1 && full) - return false; - - return true; -} - static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) { if (enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev)) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 8d6f7c18c404..666c938a51e3 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -272,7 +272,6 @@ void i915_gem_init_global_gtt(struct drm_device *dev); void i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start, unsigned long mappable_end, unsigned long end); -bool intel_enable_ppgtt(struct drm_device *dev, bool full); int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); void i915_check_and_clear_faults(struct drm_device *dev); -- GitLab From e2fcdaa9c951c51d558fea2cc020d89b382d702e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 6 Aug 2014 14:02:51 +0300 Subject: [PATCH 0151/9167] drm/i915: Free pending page flip events at .preclose() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If there are pending page flips when the fd gets closed those page flips may have events associated to them. When the page flip eventually completes it will queue the event to file_priv->event_list, but that may be too late and file_priv->event_list has already been cleaned up. Thus we leak a bit of kernel memory in the form of the event structure. To avoid such problems clear out such pending events from intel_crtc->unpin_work at ->preclose(). Any event that already made it to file_priv->event_list will get cleaned up by the drm_release_events() a bit later. We can ignore the file_priv->event_space accounting since file_priv is going away. This is already how drm core deals with pending vblank events, which are maintained by the drm core. What saves us from a total disaster (ie. dereferencing and alrady freed file_priv) is the fact that the fb descruction triggers a modeset and there we wait for pending flips. Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 3 +++ drivers/gpu/drm/i915/intel_display.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/i915/intel_drv.h | 1 + 3 files changed, 26 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2e7f03ad5ee2..c965698a8bac 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1981,6 +1981,9 @@ void i915_driver_preclose(struct drm_device *dev, struct drm_file *file) i915_gem_context_close(dev, file); i915_gem_release(dev, file); mutex_unlock(&dev->struct_mutex); + + if (drm_core_check_feature(dev, DRIVER_MODESET)) + intel_modeset_preclose(dev, file); } void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f32a94544940..24295694e493 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -13470,3 +13470,25 @@ intel_display_print_error_state(struct drm_i915_error_state_buf *m, err_printf(m, " VSYNC: %08x\n", error->transcoder[i].vsync); } } + +void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file) +{ + struct intel_crtc *crtc; + + for_each_intel_crtc(dev, crtc) { + struct intel_unpin_work *work; + unsigned long irqflags; + + spin_lock_irqsave(&dev->event_lock, irqflags); + + work = crtc->unpin_work; + + if (work && work->event && + work->event->base.file_priv == file) { + kfree(work->event); + work->event = NULL; + } + + spin_unlock_irqrestore(&dev->event_lock, irqflags); + } +} diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 79782094c8f9..666ca8a044ea 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -892,6 +892,7 @@ void intel_mode_from_pipe_config(struct drm_display_mode *mode, struct intel_crtc_config *pipe_config); int intel_format_to_fourcc(int format); void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc); +void intel_modeset_preclose(struct drm_device *dev, struct drm_file *file); /* intel_dp.c */ void intel_dp_init(struct drm_device *dev, int output_reg, enum port port); -- GitLab From 0948c2651413d56c90d7ee9c99d75bef82d4c351 Mon Sep 17 00:00:00 2001 From: Gajanan Bhat Date: Thu, 7 Aug 2014 01:58:24 +0530 Subject: [PATCH 0152/9167] drm/i915: Generalize drain latency computation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modify drain latency computation to use it for any plane. Same function can be used for primary, cursor and sprite planes. v2: Adressed review comments by Imre and Ville. - Moved clock round up in separate patch - Added WARN check for clock and pixel size - Simplified bit masking - Use cursor_base instead of reg read v3: Changed to bitwise shorthand operator for plane_dl assignment. Signed-off-by: Gajanan Bhat Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_pm.c | 87 +++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 468ef09d698d..d0cff5630569 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4009,6 +4009,7 @@ enum punit_power_well { #define DDL_PLANE_PRECISION_64 (1<<7) #define DDL_PLANE_PRECISION_32 (0<<7) #define DDL_PLANE_SHIFT 0 +#define DRAIN_LATENCY_MASK 0x7f /* FIFO watermark sizes etc */ #define G4X_FIFO_LINE_SIZE 64 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 42bb329b2d05..de27439636e8 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1271,33 +1271,24 @@ static bool g4x_compute_srwm(struct drm_device *dev, display, cursor); } -static bool vlv_compute_drain_latency(struct drm_device *dev, - int plane, - int *plane_prec_mult, - int *plane_dl, - int *cursor_prec_mult, - int *cursor_dl) +static bool vlv_compute_drain_latency(struct drm_crtc *crtc, + int pixel_size, + int *prec_mult, + int *drain_latency) { - struct drm_crtc *crtc; - int clock, pixel_size; int entries; + int clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; - crtc = intel_get_crtc_for_plane(dev, plane); - if (!intel_crtc_active(crtc)) + if (WARN(clock == 0, "Pixel clock is zero!\n")) return false; - clock = to_intel_crtc(crtc)->config.adjusted_mode.crtc_clock; - pixel_size = crtc->primary->fb->bits_per_pixel / 8; /* BPP */ + if (WARN(pixel_size == 0, "Pixel size is zero!\n")) + return false; entries = (clock / 1000) * pixel_size; - *plane_prec_mult = (entries > 128) ? - DRAIN_LATENCY_PRECISION_64 : DRAIN_LATENCY_PRECISION_32; - *plane_dl = (64 * (*plane_prec_mult) * 4) / entries; - - entries = (clock / 1000) * 4; /* BPP is always 4 for cursor */ - *cursor_prec_mult = (entries > 128) ? - DRAIN_LATENCY_PRECISION_64 : DRAIN_LATENCY_PRECISION_32; - *cursor_dl = (64 * (*cursor_prec_mult) * 4) / entries; + *prec_mult = (entries > 128) ? DRAIN_LATENCY_PRECISION_64 : + DRAIN_LATENCY_PRECISION_32; + *drain_latency = (64 * (*prec_mult) * 4) / entries; return true; } @@ -1312,24 +1303,46 @@ static bool vlv_compute_drain_latency(struct drm_device *dev, static void vlv_update_drain_latency(struct drm_crtc *crtc) { - struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - enum pipe pipe = to_intel_crtc(crtc)->pipe; - int plane_prec, plane_dl; - int cursor_prec, cursor_dl; - int plane_prec_mult, cursor_prec_mult; - - if (vlv_compute_drain_latency(dev, pipe, &plane_prec_mult, &plane_dl, - &cursor_prec_mult, &cursor_dl)) { - cursor_prec = (cursor_prec_mult == DRAIN_LATENCY_PRECISION_64) ? - DDL_CURSOR_PRECISION_64 : DDL_CURSOR_PRECISION_32; - plane_prec = (plane_prec_mult == DRAIN_LATENCY_PRECISION_64) ? - DDL_PLANE_PRECISION_64 : DDL_PLANE_PRECISION_32; - - I915_WRITE(VLV_DDL(pipe), cursor_prec | - (cursor_dl << DDL_CURSOR_SHIFT) | - plane_prec | (plane_dl << DDL_PLANE_SHIFT)); + struct drm_i915_private *dev_priv = crtc->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; + + plane_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_PLANE_PRECISION_64 | + DRAIN_LATENCY_MASK | DDL_CURSOR_PRECISION_64 | + (DRAIN_LATENCY_MASK << DDL_CURSOR_SHIFT)); + + if (!intel_crtc_active(crtc)) { + I915_WRITE(VLV_DDL(pipe), plane_dl); + return; + } + + /* 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_dl |= plane_prec | drain_latency; } + + /* Cursor Drain Latency + * BPP is always 4 for cursor + */ + pixel_size = 4; + + /* 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_dl |= plane_prec | (drain_latency << DDL_CURSOR_SHIFT); + } + + I915_WRITE(VLV_DDL(pipe), plane_dl); } #define single_plane_enabled(mask) is_power_of_2(mask) -- GitLab From a398e9c79eea74ba2f3f24ac08902661682f008c Mon Sep 17 00:00:00 2001 From: Gajanan Bhat Date: Tue, 5 Aug 2014 23:15:54 +0530 Subject: [PATCH 0153/9167] drm/i915: Round-up clock and limit drain latency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Round up clock computation and limit drain latency to maximum of 0x7F. Signed-off-by: Gajanan Bhat Reviewed-by: Ville Syrjälä 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 de27439636e8..19bd7212f4a2 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1285,11 +1285,14 @@ static bool vlv_compute_drain_latency(struct drm_crtc *crtc, if (WARN(pixel_size == 0, "Pixel size is zero!\n")) return false; - entries = (clock / 1000) * pixel_size; + entries = DIV_ROUND_UP(clock, 1000) * pixel_size; *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) + *drain_latency = DRAIN_LATENCY_MASK; + return true; } -- GitLab From 01e184cc85d4516cab0ecea7c2c43a2dd3ad432b Mon Sep 17 00:00:00 2001 From: Gajanan Bhat Date: Thu, 7 Aug 2014 17:03:30 +0530 Subject: [PATCH 0154/9167] drm/i915: Add sprite watermark programming for VLV and CHV MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Program DDL register as part of sprite watermark programming for CHV and VLV. v2: Rename DRAIN_LATENCY_MAX by DRAIN_LATENCY_MASK v3: Addressed review comments by Ville - Changed Sprite DDL definitions to more generic to avoid multiple if-else - Changed bit masking to customary form - Changed to bitwise shorthand operator for sprite_dl assignment Signed-off-by: Gajanan Bhat Reviewed-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 9 +++------ drivers/gpu/drm/i915/intel_pm.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d0cff5630569..7a6cc69cdc2b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4000,12 +4000,9 @@ enum punit_power_well { #define DDL_CURSOR_PRECISION_64 (1<<31) #define DDL_CURSOR_PRECISION_32 (0<<31) #define DDL_CURSOR_SHIFT 24 -#define DDL_SPRITE1_PRECISION_64 (1<<23) -#define DDL_SPRITE1_PRECISION_32 (0<<23) -#define DDL_SPRITE1_SHIFT 16 -#define DDL_SPRITE0_PRECISION_64 (1<<15) -#define DDL_SPRITE0_PRECISION_32 (0<<15) -#define DDL_SPRITE0_SHIFT 8 +#define DDL_SPRITE_PRECISION_64(sprite) (1<<(15+8*(sprite))) +#define DDL_SPRITE_PRECISION_32(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_SHIFT 0 diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 19bd7212f4a2..41de760bf1d4 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -1494,6 +1494,37 @@ static void cherryview_update_wm(struct drm_crtc *crtc) intel_set_memory_cxsr(dev_priv, true); } +static void valleyview_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 drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int pipe = to_intel_plane(plane)->pipe; + int sprite = to_intel_plane(plane)->plane; + int drain_latency; + int plane_prec; + int sprite_dl; + int prec_mult; + + sprite_dl = I915_READ(VLV_DDL(pipe)) & ~(DDL_SPRITE_PRECISION_64(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); + sprite_dl |= plane_prec | + (drain_latency << DDL_SPRITE_SHIFT(sprite)); + } + + I915_WRITE(VLV_DDL(pipe), sprite_dl); +} + static void g4x_update_wm(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -7225,10 +7256,12 @@ void intel_init_pm(struct drm_device *dev) dev_priv->display.init_clock_gating = gen8_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; dev_priv->display.init_clock_gating = cherryview_init_clock_gating; } else if (IS_VALLEYVIEW(dev)) { dev_priv->display.update_wm = valleyview_update_wm; + dev_priv->display.update_sprite_wm = valleyview_update_sprite_wm; dev_priv->display.init_clock_gating = valleyview_init_clock_gating; } else if (IS_PINEVIEW(dev)) { -- GitLab From 403bdd10c815029694046adf5ffde0577cbd2866 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 7 Aug 2014 16:05:39 +0200 Subject: [PATCH 0155/9167] drm/i915: No busy-loop wait_for in the ring init code Doing a 1s wait (tops) with the cpu is a bit excessive. Tune it down like everything else in that code. v2: Also insert the missing space Chris spotted. Cc: Naresh Kumar Kachhi Cc: Chris Wilson Acked-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 16371a444426..117543e58d48 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -476,8 +476,8 @@ static bool stop_ring(struct intel_engine_cs *ring) if (!IS_GEN2(ring->dev)) { I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); - if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { - DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); + if (wait_for((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { + DRM_ERROR("%s : timed out trying to stop ring\n", ring->name); return false; } } -- GitLab From 10f637bf292ba501f9b9e9df6dfe21d8fa521fbd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 29 Jul 2014 13:47:11 +0200 Subject: [PATCH 0156/9167] drm: Add drm_plane/connector_index In the atomic state we'll have an array of states for crtcs, planes and connectors and need to be able to at them by their index. We already have a drm_crtc_index function so add the missing ones for planes and connectors. If it later on turns out that the list walking is too expensive we can add the index to the relevant modeset objects. Rob Clark doesn't like the loops too much, but we can always add an obj->idx parameter later on. And for now reiterating is actually safer since nowadays we have hotpluggable connectors (thanks to DP MST). v2: Fix embarrassing copypasta fail in kerneldoc and header declarations, spotted by Matt Roper. Cc: Matt Roper Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 46 ++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 2 ++ 2 files changed, 48 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 66d3bfb8d264..f3ef461deeb8 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1021,6 +1021,29 @@ void drm_connector_cleanup(struct drm_connector *connector) } EXPORT_SYMBOL(drm_connector_cleanup); +/** + * drm_connector_index - find the index of a registered connector + * @connector: connector to find index for + * + * Given a registered connector, return the index of that connector within a DRM + * device's list of connectors. + */ +unsigned int drm_connector_index(struct drm_connector *connector) +{ + unsigned int index = 0; + struct drm_connector *tmp; + + list_for_each_entry(tmp, &connector->dev->mode_config.connector_list, head) { + if (tmp == connector) + return index; + + index++; + } + + BUG(); +} +EXPORT_SYMBOL(drm_connector_index); + /** * drm_connector_register - register a connector * @connector: the connector to register @@ -1325,6 +1348,29 @@ void drm_plane_cleanup(struct drm_plane *plane) } EXPORT_SYMBOL(drm_plane_cleanup); +/** + * drm_plane_index - find the index of a registered plane + * @plane: plane to find index for + * + * Given a registered plane, return the index of that CRTC within a DRM + * device's list of planes. + */ +unsigned int drm_plane_index(struct drm_plane *plane) +{ + unsigned int index = 0; + struct drm_plane *tmp; + + list_for_each_entry(tmp, &plane->dev->mode_config.plane_list, head) { + if (tmp == plane) + return index; + + index++; + } + + BUG(); +} +EXPORT_SYMBOL(drm_plane_index); + /** * drm_plane_force_disable - Forcibly disable a plane * @plane: plane to disable diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index c530b4920a09..9f18e7022ab3 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -904,6 +904,7 @@ int drm_connector_register(struct drm_connector *connector); void drm_connector_unregister(struct drm_connector *connector); extern void drm_connector_cleanup(struct drm_connector *connector); +extern unsigned int drm_connector_index(struct drm_connector *connector); /* helper to unplug all connectors from sysfs for device */ extern void drm_connector_unplug_all(struct drm_device *dev); @@ -943,6 +944,7 @@ extern int drm_plane_init(struct drm_device *dev, const uint32_t *formats, uint32_t format_count, bool is_primary); extern void drm_plane_cleanup(struct drm_plane *plane); +extern unsigned int drm_plane_index(struct drm_plane *plane); extern void drm_plane_force_disable(struct drm_plane *plane); extern int drm_crtc_check_viewport(const struct drm_crtc *crtc, int x, int y, -- GitLab From a6a8bb848d5ca40bc0eb708ddeb23df2b0eca1fb Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 25 Jul 2014 17:47:18 +0200 Subject: [PATCH 0157/9167] drm: Move modeset_lock_all helpers to drm_modeset_lock.[hc] Somehow we've forgotten about this little bit of OCD. Reviewed-by: Dave Airlie Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 95 ------------------------------ drivers/gpu/drm/drm_modeset_lock.c | 95 ++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 4 -- include/drm/drm_modeset_lock.h | 5 ++ 4 files changed, 100 insertions(+), 99 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index f3ef461deeb8..caaa01f3b353 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -45,101 +45,6 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, struct drm_mode_fb_cmd2 *r, struct drm_file *file_priv); -/** - * drm_modeset_lock_all - take all modeset locks - * @dev: drm device - * - * This function takes all modeset locks, suitable where a more fine-grained - * scheme isn't (yet) implemented. Locks must be dropped with - * drm_modeset_unlock_all. - */ -void drm_modeset_lock_all(struct drm_device *dev) -{ - struct drm_mode_config *config = &dev->mode_config; - struct drm_modeset_acquire_ctx *ctx; - int ret; - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (WARN_ON(!ctx)) - return; - - mutex_lock(&config->mutex); - - drm_modeset_acquire_init(ctx, 0); - -retry: - ret = drm_modeset_lock(&config->connection_mutex, ctx); - if (ret) - goto fail; - ret = drm_modeset_lock_all_crtcs(dev, ctx); - if (ret) - goto fail; - - WARN_ON(config->acquire_ctx); - - /* now we hold the locks, so now that it is safe, stash the - * ctx for drm_modeset_unlock_all(): - */ - config->acquire_ctx = ctx; - - drm_warn_on_modeset_not_all_locked(dev); - - return; - -fail: - if (ret == -EDEADLK) { - drm_modeset_backoff(ctx); - goto retry; - } -} -EXPORT_SYMBOL(drm_modeset_lock_all); - -/** - * drm_modeset_unlock_all - drop all modeset locks - * @dev: device - * - * This function drop all modeset locks taken by drm_modeset_lock_all. - */ -void drm_modeset_unlock_all(struct drm_device *dev) -{ - struct drm_mode_config *config = &dev->mode_config; - struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx; - - if (WARN_ON(!ctx)) - return; - - config->acquire_ctx = NULL; - drm_modeset_drop_locks(ctx); - drm_modeset_acquire_fini(ctx); - - kfree(ctx); - - mutex_unlock(&dev->mode_config.mutex); -} -EXPORT_SYMBOL(drm_modeset_unlock_all); - -/** - * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked - * @dev: device - * - * Useful as a debug assert. - */ -void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) -{ - struct drm_crtc *crtc; - - /* Locking is currently fubar in the panic handler. */ - if (oops_in_progress) - return; - - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) - WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); - - WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); - WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); -} -EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); - /* Avoid boilerplate. I'm tired of typing. */ #define DRM_ENUM_NAME_FN(fnname, list) \ const char *fnname(int val) \ diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 0dc57d5ecd10..73e6534fd0aa 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -56,6 +56,101 @@ */ +/** + * drm_modeset_lock_all - take all modeset locks + * @dev: drm device + * + * This function takes all modeset locks, suitable where a more fine-grained + * scheme isn't (yet) implemented. Locks must be dropped with + * drm_modeset_unlock_all. + */ +void drm_modeset_lock_all(struct drm_device *dev) +{ + struct drm_mode_config *config = &dev->mode_config; + struct drm_modeset_acquire_ctx *ctx; + int ret; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (WARN_ON(!ctx)) + return; + + mutex_lock(&config->mutex); + + drm_modeset_acquire_init(ctx, 0); + +retry: + ret = drm_modeset_lock(&config->connection_mutex, ctx); + if (ret) + goto fail; + ret = drm_modeset_lock_all_crtcs(dev, ctx); + if (ret) + goto fail; + + WARN_ON(config->acquire_ctx); + + /* now we hold the locks, so now that it is safe, stash the + * ctx for drm_modeset_unlock_all(): + */ + config->acquire_ctx = ctx; + + drm_warn_on_modeset_not_all_locked(dev); + + return; + +fail: + if (ret == -EDEADLK) { + drm_modeset_backoff(ctx); + goto retry; + } +} +EXPORT_SYMBOL(drm_modeset_lock_all); + +/** + * drm_modeset_unlock_all - drop all modeset locks + * @dev: device + * + * This function drop all modeset locks taken by drm_modeset_lock_all. + */ +void drm_modeset_unlock_all(struct drm_device *dev) +{ + struct drm_mode_config *config = &dev->mode_config; + struct drm_modeset_acquire_ctx *ctx = config->acquire_ctx; + + if (WARN_ON(!ctx)) + return; + + config->acquire_ctx = NULL; + drm_modeset_drop_locks(ctx); + drm_modeset_acquire_fini(ctx); + + kfree(ctx); + + mutex_unlock(&dev->mode_config.mutex); +} +EXPORT_SYMBOL(drm_modeset_unlock_all); + +/** + * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked + * @dev: device + * + * Useful as a debug assert. + */ +void drm_warn_on_modeset_not_all_locked(struct drm_device *dev) +{ + struct drm_crtc *crtc; + + /* Locking is currently fubar in the panic handler. */ + if (oops_in_progress) + return; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) + WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); + + WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex)); + WARN_ON(!mutex_is_locked(&dev->mode_config.mutex)); +} +EXPORT_SYMBOL(drm_warn_on_modeset_not_all_locked); + /** * drm_modeset_acquire_init - initialize acquire context * @ctx: the acquire context diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 9f18e7022ab3..a11d73422e7f 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -218,10 +218,6 @@ struct drm_property { struct list_head enum_blob_list; }; -void drm_modeset_lock_all(struct drm_device *dev); -void drm_modeset_unlock_all(struct drm_device *dev); -void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); - struct drm_crtc; struct drm_connector; struct drm_encoder; diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index 402aa7a6a058..cf61e857bc06 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -120,6 +120,11 @@ int drm_modeset_lock_interruptible(struct drm_modeset_lock *lock, void drm_modeset_unlock(struct drm_modeset_lock *lock); struct drm_device; + +void drm_modeset_lock_all(struct drm_device *dev); +void drm_modeset_unlock_all(struct drm_device *dev); +void drm_warn_on_modeset_not_all_locked(struct drm_device *dev); + int drm_modeset_lock_all_crtcs(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); -- GitLab From d059f652e73c35678d28d4cd09ab2cec89696af9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 25 Jul 2014 18:07:40 +0200 Subject: [PATCH 0158/9167] drm: Handle legacy per-crtc locking with full acquire ctx So drivers using the atomic interfaces expect that they can acquire additional locks internal to the driver as-needed. Examples would be locks to protect shared state like shared display PLLs. Unfortunately the legacy ioctls assume that all locking is fully done by the drm core. Now for those paths which grab all locks we already have to keep around an acquire context in dev->mode_config. Helper functions that implement legacy interfaces in terms of atomic support can therefore grab this acquire contexts and reuse it. The only interfaces left are the cursor and pageflip ioctls. So add functions to grab the crtc lock these need using an acquire context and preserve it for atomic drivers to reuse. v2: - Fixup comments&kerneldoc. - Drop the WARNING from modeset_lock_all_crtcs since that can be used in legacy paths with crtc locking. v3: Fix a type on the kerneldoc Dave spotted. Cc: Dave Airlie Reviewed-by: Dave Airlie Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 8 +-- drivers/gpu/drm/drm_modeset_lock.c | 84 ++++++++++++++++++++++++++++++ include/drm/drm_crtc.h | 6 +++ include/drm/drm_modeset_lock.h | 5 ++ 4 files changed, 99 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index caaa01f3b353..ab121b6d980c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2801,7 +2801,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, if (crtc->cursor) return drm_mode_cursor_universal(crtc, req, file_priv); - drm_modeset_lock(&crtc->mutex, NULL); + drm_modeset_lock_crtc(crtc); if (req->flags & DRM_MODE_CURSOR_BO) { if (!crtc->funcs->cursor_set && !crtc->funcs->cursor_set2) { ret = -ENXIO; @@ -2825,7 +2825,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, } } out: - drm_modeset_unlock(&crtc->mutex); + drm_modeset_unlock_crtc(crtc); return ret; @@ -4561,7 +4561,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, if (!crtc) return -ENOENT; - drm_modeset_lock(&crtc->mutex, NULL); + drm_modeset_lock_crtc(crtc); if (crtc->primary->fb == NULL) { /* The framebuffer is currently unbound, presumably * due to a hotplug event, that userspace has not @@ -4645,7 +4645,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, drm_framebuffer_unreference(fb); if (old_fb) drm_framebuffer_unreference(old_fb); - drm_modeset_unlock(&crtc->mutex); + drm_modeset_unlock_crtc(crtc); return ret; } diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 73e6534fd0aa..4753c8bd5ab5 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -129,6 +129,90 @@ 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 + * + * 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. + */ +void drm_modeset_lock_crtc(struct drm_crtc *crtc) +{ + struct drm_modeset_acquire_ctx *ctx; + int ret; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (WARN_ON(!ctx)) + return; + + drm_modeset_acquire_init(ctx, 0); + +retry: + ret = drm_modeset_lock(&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 + * ctx for drm_modeset_unlock_crtc(): + */ + crtc->acquire_ctx = ctx; + + return; + +fail: + if (ret == -EDEADLK) { + drm_modeset_backoff(ctx); + goto retry; + } +} +EXPORT_SYMBOL(drm_modeset_lock_crtc); + +/** + * drm_modeset_legacy_acquire_ctx - find acquire ctx for legacy ioctls + * crtc: drm crtc + * + * Legacy ioctl operations like cursor updates or page flips only have per-crtc + * locking, and store the acquire ctx in the corresponding crtc. All other + * legacy operations take all locks and use a global acquire context. This + * function grabs the right one. + */ +struct drm_modeset_acquire_ctx * +drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc) +{ + if (crtc->acquire_ctx) + return crtc->acquire_ctx; + + WARN_ON(!crtc->dev->mode_config.acquire_ctx); + + return crtc->dev->mode_config.acquire_ctx; +} +EXPORT_SYMBOL(drm_modeset_legacy_acquire_ctx); + +/** + * drm_modeset_unlock_crtc - drop crtc lock + * @crtc: drm crtc + * + * This drops the crtc lock acquire with drm_modeset_lock_crtc() and all other + * locks acquired through the hidden context. + */ +void drm_modeset_unlock_crtc(struct drm_crtc *crtc) +{ + struct drm_modeset_acquire_ctx *ctx = crtc->acquire_ctx; + + if (WARN_ON(!ctx)) + return; + + crtc->acquire_ctx = NULL; + drm_modeset_drop_locks(ctx); + drm_modeset_acquire_fini(ctx); + + kfree(ctx); +} +EXPORT_SYMBOL(drm_modeset_unlock_crtc); + /** * drm_warn_on_modeset_not_all_locked - check that all modeset locks are locked * @dev: device diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index a11d73422e7f..508817bae538 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -371,6 +371,12 @@ struct drm_crtc { void *helper_private; struct drm_object_properties properties; + + /* + * For legacy crtc ioctls so that atomic drivers can get at the locking + * acquire context. + */ + struct drm_modeset_acquire_ctx *acquire_ctx; }; diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index cf61e857bc06..d38e1508f11a 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -120,10 +120,15 @@ int drm_modeset_lock_interruptible(struct drm_modeset_lock *lock, void drm_modeset_unlock(struct drm_modeset_lock *lock); struct drm_device; +struct drm_crtc; void drm_modeset_lock_all(struct drm_device *dev); void drm_modeset_unlock_all(struct drm_device *dev); +void drm_modeset_lock_crtc(struct drm_crtc *crtc); +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 * +drm_modeset_legacy_acquire_ctx(struct drm_crtc *crtc); int drm_modeset_lock_all_crtcs(struct drm_device *dev, struct drm_modeset_acquire_ctx *ctx); -- GitLab From 3d30a59bfcb7c96d4aacdb053c2ccc49394b2311 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 27 Jul 2014 13:42:42 +0200 Subject: [PATCH 0159/9167] drm: Move ->old_fb from crtc to plane Atomic implemenations for legacy ioctls must be able to drop locks. Which doesn't cause havoc since we only do that while constructing the new state, so no driver or hardware state change has happened. The only troubling bit is the fb refcounting the core does - if someone else has snuck in then it might potentially unref an outdated framebuffer. To fix that move the old_fb temporary storage into struct drm_plane for all ioctls, so that the atomic helpers can update it. v2: Fix up the error case handling as suggested by Matt Roper and just grab locks uncoditionally - there's no point in optimizing the locking for when userspace gets it wrong. Cc: Matt Roper Cc: Dave Airlie Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 46 ++++++++++++++++++++------------------ include/drm/drm_crtc.h | 8 +++---- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index ab121b6d980c..cacb460a7145 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1287,19 +1287,21 @@ EXPORT_SYMBOL(drm_plane_index); */ void drm_plane_force_disable(struct drm_plane *plane) { - struct drm_framebuffer *old_fb = plane->fb; int ret; - if (!old_fb) + if (!plane->fb) return; + plane->old_fb = plane->fb; ret = plane->funcs->disable_plane(plane); if (ret) { DRM_ERROR("failed to disable plane with busy fb\n"); + plane->old_fb = NULL; return; } /* disconnect the plane from the fb and crtc: */ - __drm_framebuffer_unreference(old_fb); + __drm_framebuffer_unreference(plane->old_fb); + plane->old_fb = NULL; plane->fb = NULL; plane->crtc = NULL; } @@ -2275,23 +2277,21 @@ static int setplane_internal(struct drm_plane *plane, uint32_t src_w, uint32_t src_h) { struct drm_device *dev = plane->dev; - struct drm_framebuffer *old_fb = NULL; int ret = 0; unsigned int fb_width, fb_height; int i; + drm_modeset_lock_all(dev); /* No fb means shut it down */ if (!fb) { - drm_modeset_lock_all(dev); - old_fb = plane->fb; + plane->old_fb = plane->fb; ret = plane->funcs->disable_plane(plane); if (!ret) { plane->crtc = NULL; plane->fb = NULL; } else { - old_fb = NULL; + plane->old_fb = NULL; } - drm_modeset_unlock_all(dev); goto out; } @@ -2331,8 +2331,7 @@ static int setplane_internal(struct drm_plane *plane, goto out; } - drm_modeset_lock_all(dev); - old_fb = plane->fb; + plane->old_fb = plane->fb; ret = plane->funcs->update_plane(plane, crtc, fb, crtc_x, crtc_y, crtc_w, crtc_h, src_x, src_y, src_w, src_h); @@ -2341,15 +2340,16 @@ static int setplane_internal(struct drm_plane *plane, plane->fb = fb; fb = NULL; } else { - old_fb = NULL; + plane->old_fb = NULL; } - drm_modeset_unlock_all(dev); out: if (fb) drm_framebuffer_unreference(fb); - if (old_fb) - drm_framebuffer_unreference(old_fb); + if (plane->old_fb) + drm_framebuffer_unreference(plane->old_fb); + plane->old_fb = NULL; + drm_modeset_unlock_all(dev); return ret; @@ -2456,7 +2456,7 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) * crtcs. Atomic modeset will have saner semantics ... */ list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) - tmp->old_fb = tmp->primary->fb; + tmp->primary->old_fb = tmp->primary->fb; fb = set->fb; @@ -2469,8 +2469,9 @@ int drm_mode_set_config_internal(struct drm_mode_set *set) list_for_each_entry(tmp, &crtc->dev->mode_config.crtc_list, head) { if (tmp->primary->fb) drm_framebuffer_reference(tmp->primary->fb); - if (tmp->old_fb) - drm_framebuffer_unreference(tmp->old_fb); + if (tmp->primary->old_fb) + drm_framebuffer_unreference(tmp->primary->old_fb); + tmp->primary->old_fb = NULL; } return ret; @@ -4545,7 +4546,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, { struct drm_mode_crtc_page_flip *page_flip = data; struct drm_crtc *crtc; - struct drm_framebuffer *fb = NULL, *old_fb = NULL; + struct drm_framebuffer *fb = NULL; struct drm_pending_vblank_event *e = NULL; unsigned long flags; int ret = -EINVAL; @@ -4617,7 +4618,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, (void (*) (struct drm_pending_event *)) kfree; } - old_fb = crtc->primary->fb; + crtc->primary->old_fb = crtc->primary->fb; ret = crtc->funcs->page_flip(crtc, fb, e, page_flip->flags); if (ret) { if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { @@ -4627,7 +4628,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, kfree(e); } /* Keep the old fb, don't unref it. */ - old_fb = NULL; + crtc->primary->old_fb = NULL; } else { /* * Warn if the driver hasn't properly updated the crtc->fb @@ -4643,8 +4644,9 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, out: if (fb) drm_framebuffer_unreference(fb); - if (old_fb) - drm_framebuffer_unreference(old_fb); + if (crtc->primary->old_fb) + drm_framebuffer_unreference(crtc->primary->old_fb); + crtc->primary->old_fb = NULL; drm_modeset_unlock_crtc(crtc); return ret; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 508817bae538..279565aa0c33 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -341,10 +341,6 @@ struct drm_crtc { int cursor_x; int cursor_y; - /* Temporary tracking of the old fb while a modeset is ongoing. Used - * by drm_mode_set_config_internal to implement correct refcounting. */ - struct drm_framebuffer *old_fb; - bool enabled; /* Requested mode from modesetting. */ @@ -623,6 +619,10 @@ struct drm_plane { struct drm_crtc *crtc; struct drm_framebuffer *fb; + /* Temporary tracking of the old fb while a modeset is ongoing. Used + * by drm_mode_set_config_internal to implement correct refcounting. */ + struct drm_framebuffer *old_fb; + const struct drm_plane_funcs *funcs; struct drm_object_properties properties; -- GitLab From cb597bb3a2fbfc871cc1c703fb330d247bd21394 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 27 Jul 2014 19:09:33 +0200 Subject: [PATCH 0160/9167] drm: trylock modest locking for fbdev panics In the fbdev code we want to do trylocks only to avoid deadlocks and other ugly issues. Thus far we've only grabbed the overall modeset lock, but that already failed to exclude a pile of potential concurrent operations. With proper atomic support this will be worse. So add a trylock mode to the modeset locking code which attempts all locks only with trylocks, if possible. We need to track this in the locking functions themselves and can't restrict this to drivers since driver-private w/w mutexes must be treated the same way. There's still the issue that other driver private locks aren't handled here at all, but well can't have everything. With this we will at least not regress, even once atomic allows lots of concurrent kms activity. Aside: We should move the acquire context to stack-based allocation in the callers to get rid of that awful WARN_ON(kmalloc_failed) control flow which just blows up when memory is short. But that's material for separate patches. v2: - Fix logic inversion fumble in the fb helper. - Add proper kerneldoc. Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c | 10 +++--- drivers/gpu/drm/drm_modeset_lock.c | 56 +++++++++++++++++++++++------- include/drm/drm_modeset_lock.h | 6 ++++ 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 3a6b6635e3f5..7b7b9565188f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -365,11 +365,11 @@ static bool drm_fb_helper_force_kernel_mode(void) if (dev->switch_power_state == DRM_SWITCH_POWER_OFF) continue; - /* NOTE: we use lockless flag below to avoid grabbing other - * modeset locks. So just trylock the underlying mutex - * directly: + /* + * NOTE: Use trylock mode to avoid deadlocks and sleeping in + * panic context. */ - if (!mutex_trylock(&dev->mode_config.mutex)) { + if (__drm_modeset_lock_all(dev, true) != 0) { error = true; continue; } @@ -378,7 +378,7 @@ static bool drm_fb_helper_force_kernel_mode(void) if (ret) error = true; - mutex_unlock(&dev->mode_config.mutex); + drm_modeset_unlock_all(dev); } return error; } diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 4753c8bd5ab5..5280b64a0230 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -57,26 +57,37 @@ /** - * drm_modeset_lock_all - take all modeset locks - * @dev: drm device + * __drm_modeset_lock_all - internal helper to grab all modeset locks + * @dev: DRM device + * @trylock: trylock mode for atomic contexts * - * This function takes all modeset locks, suitable where a more fine-grained - * scheme isn't (yet) implemented. Locks must be dropped with - * drm_modeset_unlock_all. + * This is a special version of drm_modeset_lock_all() which can also be used in + * atomic contexts. Then @trylock must be set to true. + * + * Returns: + * 0 on success or negative error code on failure. */ -void drm_modeset_lock_all(struct drm_device *dev) +int __drm_modeset_lock_all(struct drm_device *dev, + bool trylock) { struct drm_mode_config *config = &dev->mode_config; struct drm_modeset_acquire_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (WARN_ON(!ctx)) - return; + ctx = kzalloc(sizeof(*ctx), + trylock ? GFP_ATOMIC : GFP_KERNEL); + if (!ctx) + return -ENOMEM; - mutex_lock(&config->mutex); + if (trylock) { + if (!mutex_trylock(&config->mutex)) + return -EBUSY; + } else { + mutex_lock(&config->mutex); + } drm_modeset_acquire_init(ctx, 0); + ctx->trylock_only = trylock; retry: ret = drm_modeset_lock(&config->connection_mutex, ctx); @@ -95,13 +106,29 @@ void drm_modeset_lock_all(struct drm_device *dev) drm_warn_on_modeset_not_all_locked(dev); - return; + return 0; fail: if (ret == -EDEADLK) { drm_modeset_backoff(ctx); goto retry; } + + return ret; +} +EXPORT_SYMBOL(__drm_modeset_lock_all); + +/** + * drm_modeset_lock_all - take all modeset locks + * @dev: drm device + * + * This function takes all modeset locks, suitable where a more fine-grained + * scheme isn't (yet) implemented. Locks must be dropped with + * drm_modeset_unlock_all. + */ +void drm_modeset_lock_all(struct drm_device *dev) +{ + WARN_ON(__drm_modeset_lock_all(dev, false) != 0); } EXPORT_SYMBOL(drm_modeset_lock_all); @@ -287,7 +314,12 @@ static inline int modeset_lock(struct drm_modeset_lock *lock, WARN_ON(ctx->contended); - if (interruptible && slow) { + if (ctx->trylock_only) { + if (!ww_mutex_trylock(&lock->mutex)) + return -EBUSY; + else + return 0; + } else if (interruptible && slow) { ret = ww_mutex_lock_slow_interruptible(&lock->mutex, &ctx->ww_ctx); } else if (interruptible) { ret = ww_mutex_lock_interruptible(&lock->mutex, &ctx->ww_ctx); diff --git a/include/drm/drm_modeset_lock.h b/include/drm/drm_modeset_lock.h index d38e1508f11a..a3f736d24382 100644 --- a/include/drm/drm_modeset_lock.h +++ b/include/drm/drm_modeset_lock.h @@ -53,6 +53,11 @@ struct drm_modeset_acquire_ctx { * list of held locks (drm_modeset_lock) */ struct list_head locked; + + /** + * Trylock mode, use only for panic handlers! + */ + bool trylock_only; }; /** @@ -123,6 +128,7 @@ struct drm_device; struct drm_crtc; 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_unlock_crtc(struct drm_crtc *crtc); -- GitLab From 2c0827cffca8ac0c654b888c58a1989a5172f007 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 8 Aug 2014 20:44:59 +0200 Subject: [PATCH 0161/9167] drm/i915: Update DRIVER_DATE to 20140808 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 125a83c70768..fab97bc3215f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -53,7 +53,7 @@ #define DRIVER_NAME "i915" #define DRIVER_DESC "Intel Graphics" -#define DRIVER_DATE "20140725" +#define DRIVER_DATE "20140808" enum pipe { INVALID_PIPE = -1, -- GitLab From 4fa790421c10e5c9c62406655c06d97a94555d54 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 8 Aug 2014 19:25:57 +0100 Subject: [PATCH 0162/9167] drm/i915: Fix erroneous conversion to u8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit adj was defined as u8. The issue is last_adj can be negative and adj is initialized with: adj = dev_priv->rps.last_adj; and we were also happily doing things like: if (adj < 0) (thank static analysers!) v2: Make new_delay an int in case we overflow the u8 in the intermediate computations. new_delay will get clamped at the end anyway. (Ville) Cc: Deepak S Cc: Ville Syrjälä Signed-off-by: Damien Lespiau Reviewed-by: Ville Syrjälä 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 87abe8679495..f0d24db76e72 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1327,10 +1327,10 @@ static u32 vlv_c0_residency(struct drm_i915_private *dev_priv, * @dev_priv: DRM device private * */ -static u32 vlv_calc_delay_from_C0_counters(struct drm_i915_private *dev_priv) +static int vlv_calc_delay_from_C0_counters(struct drm_i915_private *dev_priv) { u32 residency_C0_up = 0, residency_C0_down = 0; - u8 new_delay, adj; + int new_delay, adj; dev_priv->rps.ei_interrupt_count++; -- GitLab From f45651bae2ee73ae551699d481f76aa6ad92138f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 8 Aug 2014 21:51:10 +0300 Subject: [PATCH 0163/9167] drm/i915: Eliminate rmw from .update_primary_plane() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the entire DSPCNTR register setup into the .update_primary_plane() functions. That's where it belongs anyway and it'll also help 830M which has the extra problem that plane registers reads will return the value latched at the last vblank, not the value that was last written. Also move DSPPOS and DSPSIZE setup there. v2: Don't move variable initialization to avoid churn later Reviewed-by: Matt Roper Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 100 +++++++++------------------ 1 file changed, 32 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 24295694e493..041fd76a2ded 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2388,12 +2388,26 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc, int plane = intel_crtc->plane; unsigned long linear_offset; u32 dspcntr; - u32 reg; + u32 reg = DSPCNTR(plane); + + dspcntr = DISPPLANE_GAMMA_ENABLE; + + if (intel_crtc->primary_enabled) + dspcntr |= DISPLAY_PLANE_ENABLE; + + if (INTEL_INFO(dev)->gen < 4) { + if (intel_crtc->pipe == PIPE_B) + dspcntr |= DISPPLANE_SEL_PIPE_B; + + /* pipesrc and dspsize control the size that is scaled from, + * which should always be the user's requested size. + */ + I915_WRITE(DSPSIZE(plane), + ((intel_crtc->config.pipe_src_h - 1) << 16) | + (intel_crtc->config.pipe_src_w - 1)); + I915_WRITE(DSPPOS(plane), 0); + } - reg = DSPCNTR(plane); - dspcntr = I915_READ(reg); - /* Mask out pixel format bits in case we change it */ - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; switch (fb->pixel_format) { case DRM_FORMAT_C8: dspcntr |= DISPPLANE_8BPP; @@ -2425,12 +2439,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc, BUG(); } - if (INTEL_INFO(dev)->gen >= 4) { - if (obj->tiling_mode != I915_TILING_NONE) - dspcntr |= DISPPLANE_TILED; - else - dspcntr &= ~DISPPLANE_TILED; - } + if (INTEL_INFO(dev)->gen >= 4 && + obj->tiling_mode != I915_TILING_NONE) + dspcntr |= DISPPLANE_TILED; if (IS_G4X(dev)) dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; @@ -2474,12 +2485,16 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc, int plane = intel_crtc->plane; unsigned long linear_offset; u32 dspcntr; - u32 reg; + u32 reg = DSPCNTR(plane); + + dspcntr = DISPPLANE_GAMMA_ENABLE; + + if (intel_crtc->primary_enabled) + dspcntr |= DISPLAY_PLANE_ENABLE; + + if (IS_HASWELL(dev) || IS_BROADWELL(dev)) + dspcntr |= DISPPLANE_PIPE_CSC_ENABLE; - reg = DSPCNTR(plane); - dspcntr = I915_READ(reg); - /* Mask out pixel format bits in case we change it */ - dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; switch (fb->pixel_format) { case DRM_FORMAT_C8: dspcntr |= DISPPLANE_8BPP; @@ -2509,12 +2524,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc, if (obj->tiling_mode != I915_TILING_NONE) dspcntr |= DISPPLANE_TILED; - else - dspcntr &= ~DISPPLANE_TILED; - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - dspcntr &= ~DISPPLANE_TRICKLE_FEED_DISABLE; - else + if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE; I915_WRITE(reg, dspcntr); @@ -3936,7 +3947,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; - enum plane plane = intel_crtc->plane; WARN_ON(!crtc->enabled); @@ -3958,10 +3968,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) ironlake_set_pipeconf(crtc); - /* Set up the display plane register */ - I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE); - POSTING_READ(DSPCNTR(plane)); - dev_priv->display.update_primary_plane(crtc, crtc->primary->fb, crtc->x, crtc->y); @@ -4049,7 +4055,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; - enum plane plane = intel_crtc->plane; WARN_ON(!crtc->enabled); @@ -4073,10 +4078,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_set_pipe_csc(crtc); - /* Set up the display plane register */ - I915_WRITE(DSPCNTR(plane), DISPPLANE_GAMMA_ENABLE | DISPPLANE_PIPE_CSC_ENABLE); - POSTING_READ(DSPCNTR(plane)); - dev_priv->display.update_primary_plane(crtc, crtc->primary->fb, crtc->x, crtc->y); @@ -4632,9 +4633,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; bool is_dsi; - u32 dspcntr; WARN_ON(!crtc->enabled); @@ -4650,27 +4649,13 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) vlv_prepare_pll(intel_crtc); } - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - if (intel_crtc->config.has_dp_encoder) intel_dp_set_m_n(intel_crtc); intel_set_pipe_timings(intel_crtc); - /* pipesrc and dspsize control the size that is scaled from, - * which should always be the user's requested size. - */ - I915_WRITE(DSPSIZE(plane), - ((intel_crtc->config.pipe_src_h - 1) << 16) | - (intel_crtc->config.pipe_src_w - 1)); - I915_WRITE(DSPPOS(plane), 0); - i9xx_set_pipeconf(intel_crtc); - I915_WRITE(DSPCNTR(plane), dspcntr); - POSTING_READ(DSPCNTR(plane)); - dev_priv->display.update_primary_plane(crtc, crtc->primary->fb, crtc->x, crtc->y); @@ -4725,8 +4710,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - u32 dspcntr; WARN_ON(!crtc->enabled); @@ -4735,32 +4718,13 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) i9xx_set_pll_dividers(intel_crtc); - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - - if (pipe == 0) - dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; - if (intel_crtc->config.has_dp_encoder) intel_dp_set_m_n(intel_crtc); intel_set_pipe_timings(intel_crtc); - /* pipesrc and dspsize control the size that is scaled from, - * which should always be the user's requested size. - */ - I915_WRITE(DSPSIZE(plane), - ((intel_crtc->config.pipe_src_h - 1) << 16) | - (intel_crtc->config.pipe_src_w - 1)); - I915_WRITE(DSPPOS(plane), 0); - i9xx_set_pipeconf(intel_crtc); - I915_WRITE(DSPCNTR(plane), dspcntr); - POSTING_READ(DSPCNTR(plane)); - dev_priv->display.update_primary_plane(crtc, crtc->primary->fb, crtc->x, crtc->y); -- GitLab From fdd508a6419217cce28213f3c9bd27c02a0d4c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 8 Aug 2014 21:51:11 +0300 Subject: [PATCH 0164/9167] drm/i915: Call .update_primary_plane in intel_{enable, disable}_primary_hw_plane() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the intel_{enable,disable}_primary_hw_plane() simply call .update_primary_plane(), thus eliminating the rmw from these functions which should help the poor old 830M. Now we can also remove the .update_primary_plane() from the .crtc_enable() hooks because we end up calling it via intel_crtc_enable_planes()->intel_enable_primary_hw_plane(). This also has the nice benefit of making primary planes a bit closer to the way we handle sprite planes during modesets. v2: Just write 0 to DSPCNTR and DSPSURF/DSPADDR if the plane is (to be) disabled. Quicker, and more importantly avoids an oops when fb==NULL due to BIOS fb takeover failure. Pimp the commit message a bit (Matt) v3: Drop useless primary_enabled checks when setting DISPLAY_PLANE_ENABLE Reviewed-by: Matt Roper Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 119 +++++++++++---------------- 1 file changed, 49 insertions(+), 70 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 041fd76a2ded..f306c91b74a5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2082,35 +2082,28 @@ void intel_flush_primary_plane(struct drm_i915_private *dev_priv, /** * intel_enable_primary_hw_plane - enable the primary plane on a given pipe - * @dev_priv: i915 private structure - * @plane: plane to enable - * @pipe: pipe being fed + * @plane: plane to be enabled + * @crtc: crtc for the plane * - * Enable @plane on @pipe, making sure that @pipe is running first. + * Enable @plane on @crtc, making sure that the pipe is running first. */ -static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv, - enum plane plane, enum pipe pipe) +static void intel_enable_primary_hw_plane(struct drm_plane *plane, + struct drm_crtc *crtc) { - struct drm_device *dev = dev_priv->dev; - struct intel_crtc *intel_crtc = - to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); - int reg; - u32 val; + struct drm_device *dev = plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); /* If the pipe isn't enabled, we can't pump pixels and may hang */ - assert_pipe_enabled(dev_priv, pipe); + assert_pipe_enabled(dev_priv, intel_crtc->pipe); if (intel_crtc->primary_enabled) return; intel_crtc->primary_enabled = true; - reg = DSPCNTR(plane); - val = I915_READ(reg); - WARN_ON(val & DISPLAY_PLANE_ENABLE); - - I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); - intel_flush_primary_plane(dev_priv, plane); + dev_priv->display.update_primary_plane(crtc, plane->fb, + crtc->x, crtc->y); /* * BDW signals flip done immediately if the plane @@ -2123,31 +2116,27 @@ static void intel_enable_primary_hw_plane(struct drm_i915_private *dev_priv, /** * intel_disable_primary_hw_plane - disable the primary hardware plane - * @dev_priv: i915 private structure - * @plane: plane to disable - * @pipe: pipe consuming the data + * @plane: plane to be disabled + * @crtc: crtc for the plane * - * Disable @plane; should be an independent operation. + * Disable @plane on @crtc, making sure that the pipe is running first. */ -static void intel_disable_primary_hw_plane(struct drm_i915_private *dev_priv, - enum plane plane, enum pipe pipe) +static void intel_disable_primary_hw_plane(struct drm_plane *plane, + struct drm_crtc *crtc) { - struct intel_crtc *intel_crtc = - to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); - int reg; - u32 val; + struct drm_device *dev = plane->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + + assert_pipe_enabled(dev_priv, intel_crtc->pipe); if (!intel_crtc->primary_enabled) return; intel_crtc->primary_enabled = false; - reg = DSPCNTR(plane); - val = I915_READ(reg); - WARN_ON((val & DISPLAY_PLANE_ENABLE) == 0); - - I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); - intel_flush_primary_plane(dev_priv, plane); + dev_priv->display.update_primary_plane(crtc, plane->fb, + crtc->x, crtc->y); } static bool need_vtd_wa(struct drm_device *dev) @@ -2390,10 +2379,19 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc, u32 dspcntr; u32 reg = DSPCNTR(plane); + if (!intel_crtc->primary_enabled) { + I915_WRITE(reg, 0); + if (INTEL_INFO(dev)->gen >= 4) + I915_WRITE(DSPSURF(plane), 0); + else + I915_WRITE(DSPADDR(plane), 0); + POSTING_READ(reg); + return; + } + dspcntr = DISPPLANE_GAMMA_ENABLE; - if (intel_crtc->primary_enabled) - dspcntr |= DISPLAY_PLANE_ENABLE; + dspcntr |= DISPLAY_PLANE_ENABLE; if (INTEL_INFO(dev)->gen < 4) { if (intel_crtc->pipe == PIPE_B) @@ -2487,10 +2485,16 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc, u32 dspcntr; u32 reg = DSPCNTR(plane); + if (!intel_crtc->primary_enabled) { + I915_WRITE(reg, 0); + I915_WRITE(DSPSURF(plane), 0); + POSTING_READ(reg); + return; + } + dspcntr = DISPPLANE_GAMMA_ENABLE; - if (intel_crtc->primary_enabled) - dspcntr |= DISPLAY_PLANE_ENABLE; + dspcntr |= DISPLAY_PLANE_ENABLE; if (IS_HASWELL(dev) || IS_BROADWELL(dev)) dspcntr |= DISPPLANE_PIPE_CSC_ENABLE; @@ -3884,14 +3888,12 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) static void intel_crtc_enable_planes(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 pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; drm_vblank_on(dev, pipe); - intel_enable_primary_hw_plane(dev_priv, plane, pipe); + intel_enable_primary_hw_plane(crtc->primary, crtc); intel_enable_planes(crtc); intel_crtc_update_cursor(crtc, true); intel_crtc_dpms_overlay(intel_crtc, true); @@ -3928,7 +3930,7 @@ static void intel_crtc_disable_planes(struct drm_crtc *crtc) intel_crtc_dpms_overlay(intel_crtc, false); intel_crtc_update_cursor(crtc, false); intel_disable_planes(crtc); - intel_disable_primary_hw_plane(dev_priv, plane, pipe); + intel_disable_primary_hw_plane(crtc->primary, crtc); /* * FIXME: Once we grow proper nuclear flip support out of this we need @@ -3968,9 +3970,6 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) ironlake_set_pipeconf(crtc); - dev_priv->display.update_primary_plane(crtc, crtc->primary->fb, - crtc->x, crtc->y); - intel_crtc->active = true; intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); @@ -4078,9 +4077,6 @@ static void haswell_crtc_enable(struct drm_crtc *crtc) intel_set_pipe_csc(crtc); - dev_priv->display.update_primary_plane(crtc, crtc->primary->fb, - crtc->x, crtc->y); - intel_crtc->active = true; intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); @@ -4629,7 +4625,6 @@ 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 = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; @@ -4656,9 +4651,6 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc) i9xx_set_pipeconf(intel_crtc); - dev_priv->display.update_primary_plane(crtc, crtc->primary->fb, - crtc->x, crtc->y); - intel_crtc->active = true; intel_set_cpu_fifo_underrun_reporting(dev, pipe, true); @@ -4706,7 +4698,6 @@ 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 = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; int pipe = intel_crtc->pipe; @@ -4725,9 +4716,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) i9xx_set_pipeconf(intel_crtc); - dev_priv->display.update_primary_plane(crtc, crtc->primary->fb, - crtc->x, crtc->y); - intel_crtc->active = true; if (!IS_GEN2(dev)) @@ -11351,7 +11339,6 @@ static int intel_crtc_set_config(struct drm_mode_set *set) ret = intel_set_mode(set->crtc, set->mode, set->x, set->y, set->fb); } else if (config->fb_changed) { - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(set->crtc); intel_crtc_wait_for_pending_flips(set->crtc); @@ -11365,8 +11352,7 @@ static int intel_crtc_set_config(struct drm_mode_set *set) */ if (!intel_crtc->primary_enabled && ret == 0) { WARN_ON(!intel_crtc->active); - intel_enable_primary_hw_plane(dev_priv, intel_crtc->plane, - intel_crtc->pipe); + intel_enable_primary_hw_plane(set->crtc->primary, set->crtc); } /* @@ -11519,8 +11505,6 @@ static int intel_primary_plane_disable(struct drm_plane *plane) { struct drm_device *dev = plane->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_plane *intel_plane = to_intel_plane(plane); struct intel_crtc *intel_crtc; if (!plane->fb) @@ -11543,8 +11527,8 @@ intel_primary_plane_disable(struct drm_plane *plane) goto disable_unpin; intel_crtc_wait_for_pending_flips(plane->crtc); - intel_disable_primary_hw_plane(dev_priv, intel_plane->plane, - intel_plane->pipe); + intel_disable_primary_hw_plane(plane, plane->crtc); + disable_unpin: mutex_lock(&dev->struct_mutex); i915_gem_track_fb(intel_fb_obj(plane->fb), NULL, @@ -11564,9 +11548,7 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, uint32_t src_w, uint32_t src_h) { 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_plane *intel_plane = to_intel_plane(plane); 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 = { @@ -11653,9 +11635,7 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, INTEL_FRONTBUFFER_PRIMARY(intel_crtc->pipe)); if (intel_crtc->primary_enabled) - intel_disable_primary_hw_plane(dev_priv, - intel_plane->plane, - intel_plane->pipe); + intel_disable_primary_hw_plane(plane, crtc); if (plane->fb != fb) @@ -11672,8 +11652,7 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc, return ret; if (!intel_crtc->primary_enabled) - intel_enable_primary_hw_plane(dev_priv, intel_crtc->plane, - intel_crtc->pipe); + intel_enable_primary_hw_plane(plane, crtc); return 0; } -- GitLab From fd5c9d230d2ac8a2594dfd15f0cca678fd7a64c7 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 7 Aug 2014 20:52:33 +0400 Subject: [PATCH 0165/9167] Smack: fix behavior of smack_inode_listsecurity Security operation ->inode_listsecurity is used for generating list of available extended attributes for syscall listxattr. Currently it's used only in nfs4 or if filesystem doesn't provide i_op->listxattr. The list is the set of NULL-terminated names, one after the other. This method must include zero byte at the and into result. Also this function must return length even if string does not fit into output buffer or it is NULL, see similar method in selinux and man listxattr. Signed-off-by: Konstantin Khlebnikov --- security/smack/smack_lsm.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index e6ab307ce86e..b11ab23b328b 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1122,13 +1122,12 @@ static int smack_inode_getsecurity(const struct inode *inode, static int smack_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer_size) { - int len = strlen(XATTR_NAME_SMACK); + int len = sizeof(XATTR_NAME_SMACK); - if (buffer != NULL && len <= buffer_size) { + if (buffer != NULL && len <= buffer_size) memcpy(buffer, XATTR_NAME_SMACK, len); - return len; - } - return -EINVAL; + + return len; } /** -- GitLab From b862e561bad6372872f5bf98d95f4131d265b110 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 7 Aug 2014 20:52:43 +0400 Subject: [PATCH 0166/9167] Smack: handle zero-length security labels without panic Zero-length security labels are invalid but kernel should handle them. This patch fixes kernel panic after setting zero-length security labels: # attr -S -s "SMACK64" -V "" file And after writing zero-length string into smackfs files syslog and onlycp: # python -c 'import os; os.write(1, "")' > /smack/syslog The problem is caused by brain-damaged logic in function smk_parse_smack() which takes pointer to buffer and its length but if length below or equal zero it thinks that the buffer is zero-terminated. Unfortunately callers of this function are widely used and proper fix requires serious refactoring. Signed-off-by: Konstantin Khlebnikov --- security/smack/smack_lsm.c | 2 +- security/smack/smackfs.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index b11ab23b328b..afa5ad0e7f72 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -923,7 +923,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name, rc = -EPERM; if (rc == 0 && check_import) { - skp = smk_import_entry(value, size); + skp = size ? smk_import_entry(value, size) : NULL; if (skp == NULL || (check_star && (skp == &smack_known_star || skp == &smack_known_web))) rc = -EINVAL; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 3c720ff10591..56a1439786a9 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -1677,7 +1677,7 @@ static ssize_t smk_write_onlycap(struct file *file, const char __user *buf, if (smack_onlycap != NULL && smack_onlycap != skp) return -EPERM; - data = kzalloc(count, GFP_KERNEL); + data = kzalloc(count + 1, GFP_KERNEL); if (data == NULL) return -ENOMEM; @@ -2228,7 +2228,7 @@ static ssize_t smk_write_syslog(struct file *file, const char __user *buf, if (!smack_privileged(CAP_MAC_ADMIN)) return -EPERM; - data = kzalloc(count, GFP_KERNEL); + data = kzalloc(count + 1, GFP_KERNEL); if (data == NULL) return -ENOMEM; -- GitLab From da1b63566c469bf3e2b24182114422e16b1aa34c Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 7 Aug 2014 20:52:49 +0400 Subject: [PATCH 0167/9167] Smack: remove unneeded NULL-termination from securtity label Values of extended attributes are stored as binary blobs. NULL-termination of them isn't required. It just wastes disk space and confuses command-line tools like getfattr because they have to print that zero byte at the end. This patch removes terminating zero byte from initial security label in smack_inode_init_security and cuts it out in function smack_inode_getsecurity which is used by syscall getxattr. This change seems completely safe, because function smk_parse_smack ignores everything after first zero byte. Signed-off-by: Konstantin Khlebnikov --- security/smack/smack_lsm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index afa5ad0e7f72..16ae8534b14c 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -672,7 +672,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, } if (len) - *len = strlen(isp) + 1; + *len = strlen(isp); return 0; } @@ -1076,7 +1076,7 @@ static int smack_inode_getsecurity(const struct inode *inode, if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { isp = smk_of_inode(inode); - ilen = strlen(isp) + 1; + ilen = strlen(isp); *buffer = isp; return ilen; } @@ -1101,7 +1101,7 @@ static int smack_inode_getsecurity(const struct inode *inode, else return -EOPNOTSUPP; - ilen = strlen(isp) + 1; + ilen = strlen(isp); if (rc == 0) { *buffer = isp; rc = ilen; -- GitLab From 3aaefce10351fecab348f5e06857f44cafc61a62 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 6 Aug 2014 15:21:00 -0700 Subject: [PATCH 0168/9167] x86, platform, kconfig: move kvmconfig functionality to a helper The new mergeconfig helper makes it easier to add other partial configurations similar to kvmconfig. Architecture-independent portions of those partial configurations should go in kernel/configs/${name}.config, and architecture-dependent portions should go in arch/${arch}/configs/${name}.config. Based on a patch by Luis R. Rodriguez . Originally-Signed-off-by: Luis R. Rodriguez Modified to make the helper name more general than just virtualization, support architecture-dependent and architecture-independent partial configurations, move the helper and kvmconfig to scripts/kconfig/Makefile, and factor out more of the common file path. Signed-off-by: Josh Triplett --- arch/x86/Makefile | 7 ------- scripts/kconfig/Makefile | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/arch/x86/Makefile b/arch/x86/Makefile index c65fd9650467..fcc74b7aabb0 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -247,12 +247,6 @@ archclean: $(Q)$(MAKE) $(clean)=$(boot) $(Q)$(MAKE) $(clean)=arch/x86/tools -PHONY += kvmconfig -kvmconfig: - $(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target)) - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(srctree)/arch/x86/configs/kvm_guest.config - $(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig - define archhelp echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)' echo ' install - Install kernel using' @@ -266,5 +260,4 @@ define archhelp echo ' bzdisk/fdimage*/isoimage also accept:' echo ' FDARGS="..." arguments for the booted kernel' echo ' FDINITRD=file initrd for the booted kernel' - echo ' kvmconfig - Enable additional options for guest kernel support' endef diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 9c4d2412fb72..8083b94b45ee 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -104,6 +104,19 @@ endif %_defconfig: $(obj)/conf $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig) +configfiles=$(wildcard $(srctree)/kernel/configs/$(1).config $(srctree)/arch/$(SRCARCH)/configs/$(1).config) + +define mergeconfig +$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target)) +$(if $(call configfiles,$(1)),, $(error No configuration exists for this target on this architecture)) +$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(call configfiles,$(1)) +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig +endef + +PHONY += kvmconfig +kvmconfig: + $(call mergeconfig,kvm_guest) + # Help text used by make help help: @echo ' config - Update current config utilising a line-oriented program' @@ -124,6 +137,7 @@ help: @echo ' randconfig - New config with random answer to all options' @echo ' listnewconfig - List new options' @echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their default value' + @echo ' kvmconfig - Enable additional options for guest kernel support' # lxdialog stuff check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh -- GitLab From 0da1d4a0b9516adb2acc4841e9f6da6618f47f4e Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Fri, 8 Aug 2014 16:25:47 -0700 Subject: [PATCH 0169/9167] x86: Add "make tinyconfig" to configure the tiniest possible kernel Since commit 5d2acfc7b974bbd3858b4dd3f2cdc6362dd8843a ("kconfig: make allnoconfig disable options behind EMBEDDED and EXPERT") in 3.15-rc1, "make allnoconfig" disables every possible config option. However, a few configuration options (CC_OPTIMIZE_FOR_SIZE, OPTIMIZE_INLINING) produce a smaller kernel when turned on, and a few choices exist (compression, highmem, allocator) for which a non-default option produces a smaller kernel. Add a "tinyconfig" option, which starts from allnoconfig and then sets these options to configure the tiniest possible kernel. This provides a better baseline for embedded systems or efforts to reduce kernel size. Signed-off-by: Josh Triplett --- arch/x86/configs/tiny.config | 1 + kernel/configs/tiny.config | 4 ++++ scripts/kconfig/Makefile | 5 +++++ 3 files changed, 10 insertions(+) create mode 100644 arch/x86/configs/tiny.config create mode 100644 kernel/configs/tiny.config diff --git a/arch/x86/configs/tiny.config b/arch/x86/configs/tiny.config new file mode 100644 index 000000000000..4e2ecfa23c15 --- /dev/null +++ b/arch/x86/configs/tiny.config @@ -0,0 +1 @@ +CONFIG_NOHIGHMEM=y diff --git a/kernel/configs/tiny.config b/kernel/configs/tiny.config new file mode 100644 index 000000000000..c2de56ab0fce --- /dev/null +++ b/kernel/configs/tiny.config @@ -0,0 +1,4 @@ +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_KERNEL_XZ=y +CONFIG_OPTIMIZE_INLINING=y +CONFIG_SLOB=y diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 8083b94b45ee..ebf40f6edb4d 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -117,6 +117,10 @@ PHONY += kvmconfig kvmconfig: $(call mergeconfig,kvm_guest) +PHONY += tinyconfig +tinyconfig: allnoconfig + $(call mergeconfig,tiny) + # Help text used by make help help: @echo ' config - Update current config utilising a line-oriented program' @@ -138,6 +142,7 @@ help: @echo ' listnewconfig - List new options' @echo ' olddefconfig - Same as silentoldconfig but sets new symbols to their default value' @echo ' kvmconfig - Enable additional options for guest kernel support' + @echo ' tinyconfig - Configure the tiniest possible kernel' # lxdialog stuff check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh -- GitLab From 22c59960d9fe72f3fbd28de69cc43c5522dd5fe6 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 8 Aug 2014 17:45:32 -0300 Subject: [PATCH 0170/9167] drm/i915: fix i915_interrupt_info on BDW Currently, if the machine is runtime suspended an you read the file, you will get an "Unclaimed register" error message. Testcase: igt/pm_rpm/debugfs-read Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 330caa1ab9f9..3b7decbeeed3 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -703,6 +703,12 @@ static int i915_interrupt_info(struct seq_file *m, void *data) } for_each_pipe(pipe) { + if (!intel_display_power_enabled(dev_priv, + POWER_DOMAIN_PIPE(pipe))) { + seq_printf(m, "Pipe %c power disabled\n", + pipe_name(pipe)); + continue; + } seq_printf(m, "Pipe %c IMR:\t%08x\n", pipe_name(pipe), I915_READ(GEN8_DE_PIPE_IMR(pipe))); -- GitLab From fd3cbdc0d1b5254a2e8793df58c409b469899a3f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 10 Aug 2014 08:53:39 +0200 Subject: [PATCH 0171/9167] jump_label: Fix small typos in the documentation Was reading through the documentation of this code and noticed a few typos, missing commas, etc. Cc: Jason Baron Cc: Peter Zijlstra Cc: Steven Rostedt Cc: Borislav Petkov Cc: Andrew Morton Cc: Linus Torvalds Cc: Thomas Gleixner Cc: Mel Gorman Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar --- include/linux/jump_label.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h index 784304b222b3..98f923b6a0ea 100644 --- a/include/linux/jump_label.h +++ b/include/linux/jump_label.h @@ -8,28 +8,28 @@ * Copyright (C) 2011-2012 Peter Zijlstra * * Jump labels provide an interface to generate dynamic branches using - * self-modifying code. Assuming toolchain and architecture support the result - * of a "if (static_key_false(&key))" statement is a unconditional branch (which + * self-modifying code. Assuming toolchain and architecture support, the result + * of a "if (static_key_false(&key))" statement is an unconditional branch (which * defaults to false - and the true block is placed out of line). * * However at runtime we can change the branch target using * static_key_slow_{inc,dec}(). These function as a 'reference' count on the key - * object and for as long as there are references all branches referring to + * object, and for as long as there are references all branches referring to * that particular key will point to the (out of line) true block. * - * Since this relies on modifying code the static_key_slow_{inc,dec}() functions + * Since this relies on modifying code, the static_key_slow_{inc,dec}() functions * must be considered absolute slow paths (machine wide synchronization etc.). - * OTOH, since the affected branches are unconditional their runtime overhead + * OTOH, since the affected branches are unconditional, their runtime overhead * will be absolutely minimal, esp. in the default (off) case where the total * effect is a single NOP of appropriate size. The on case will patch in a jump * to the out-of-line block. * - * When the control is directly exposed to userspace it is prudent to delay the + * When the control is directly exposed to userspace, it is prudent to delay the * decrement to avoid high frequency code modifications which can (and do) * cause significant performance degradation. Struct static_key_deferred and * static_key_slow_dec_deferred() provide for this. * - * Lacking toolchain and or architecture support, it falls back to a simple + * Lacking toolchain and or architecture support, jump labels fall back to a simple * conditional branch. * * struct static_key my_key = STATIC_KEY_INIT_TRUE; @@ -43,8 +43,7 @@ * * Not initializing the key (static data is initialized to 0s anyway) is the * same as using STATIC_KEY_INIT_FALSE. - * -*/ + */ #include #include -- GitLab From 3bb11b536c1037143765b4efc8056600438df7f6 Mon Sep 17 00:00:00 2001 From: Sonika Jindal Date: Mon, 11 Aug 2014 09:06:39 +0530 Subject: [PATCH 0172/9167] drm/i915: Continuation of future readiness series Removing the check for HAS_PCH_SPLIT, it looks redundant here. Anyways all the platforms are checked separately. v2: Reordering as per the gen (Ville) Signed-off-by: Sonika Jindal Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 42 +++++++++++++--------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f306c91b74a5..0746590ed4e3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12354,29 +12354,27 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.get_display_clock_speed = i830_get_display_clock_speed; - if (HAS_PCH_SPLIT(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_GEN8(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_G4X(dev)) { + if (IS_G4X(dev)) { dev_priv->display.write_eld = g4x_write_eld; + } else 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_GEN8(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; -- GitLab From d6699dd3a7f696a80a5f8e5bb6ecf6ff6dd7c998 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Sat, 9 Aug 2014 16:29:31 +0100 Subject: [PATCH 0173/9167] drm/i915: Fix wrong number of HDMI translation entries I keep telling myself that those tables aren't great because their size is the number of dwords we need to program and not the number of entries (number of dwords = number of entries * 2). And... I got it wrong when I refactored the code. Fortunately, it was only wrong when the VBT table (or the code parsing it) is itself erroneous. Long story short, it shouldn't matter, but still, there's a potential array overflow and random programming of the DDI translation tables. Cc: Paulo Zanoni Signed-off-by: Damien Lespiau Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index ca1f9a8a7d03..02d55843c78d 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -169,14 +169,14 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) ddi_translations_dp = bdw_ddi_translations_dp; ddi_translations_edp = bdw_ddi_translations_edp; ddi_translations_hdmi = bdw_ddi_translations_hdmi; - n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); + n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi) / 2; hdmi_800mV_0dB = 7; } else if (IS_HASWELL(dev)) { ddi_translations_fdi = hsw_ddi_translations_fdi; ddi_translations_dp = hsw_ddi_translations_dp; ddi_translations_edp = hsw_ddi_translations_dp; ddi_translations_hdmi = hsw_ddi_translations_hdmi; - n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); + n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi) / 2; hdmi_800mV_0dB = 6; } else { WARN(1, "ddi translation table missing\n"); @@ -184,7 +184,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port) ddi_translations_fdi = bdw_ddi_translations_fdi; ddi_translations_dp = bdw_ddi_translations_dp; ddi_translations_hdmi = bdw_ddi_translations_hdmi; - n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); + n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi) / 2; hdmi_800mV_0dB = 7; } -- GitLab From dc8cd1e790081a31ba4d86c3c0812c348eeec7fc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 Aug 2014 17:37:22 +0100 Subject: [PATCH 0174/9167] drm/i915: Only perform set-to-gtt domain for objects bound to the global gtt If an object is not bound into the global GTT, then it cannot be accessed via the GTT. This restores the original code that was muddled by ppGTT. In the process, we remove a WARN that had long outlived its usefulness and was simply being coded around instead. Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 20743bd421f9..1be7e541a7c7 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3592,11 +3592,12 @@ int i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) { struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + struct i915_vma *vma = i915_gem_obj_to_ggtt(obj); uint32_t old_write_domain, old_read_domains; int ret; /* Not valid to be called on unbound objects. */ - if (!i915_gem_obj_bound_any(obj)) + if (vma == NULL) return -EINVAL; if (obj->base.write_domain == I915_GEM_DOMAIN_GTT) @@ -3638,13 +3639,9 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) old_write_domain); /* And bump the LRU for this access */ - if (i915_gem_object_is_inactive(obj)) { - struct i915_vma *vma = i915_gem_obj_to_ggtt(obj); - if (vma) - list_move_tail(&vma->mm_list, - &dev_priv->gtt.base.inactive_list); - - } + if (i915_gem_object_is_inactive(obj)) + list_move_tail(&vma->mm_list, + &dev_priv->gtt.base.inactive_list); return 0; } @@ -3808,9 +3805,6 @@ static bool is_pin_display(struct drm_i915_gem_object *obj) { struct i915_vma *vma; - if (list_empty(&obj->vma_list)) - return false; - vma = i915_gem_obj_to_ggtt(obj); if (!vma) return false; @@ -5253,12 +5247,6 @@ struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj) { struct i915_vma *vma; - /* This WARN has probably outlived its usefulness (callers already - * WARN if they don't find the GGTT vma they expect). When removing, - * remember to remove the pre-check in is_pin_display() as well */ - if (WARN_ON(list_empty(&obj->vma_list))) - return NULL; - vma = list_first_entry(&obj->vma_list, typeof(*vma), vma_link); if (vma->vm != obj_to_ggtt(obj)) return NULL; -- GitLab From e6a844687cf929ec053c7578d5ecc794a8a6c5cf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 11 Aug 2014 12:00:12 +0200 Subject: [PATCH 0175/9167] drm/i915: Force CPU relocations if not GTT mapped Move the decision on whether we need to have a mappable object during execbuffer to the fore and then reuse that decision by propagating the flag through to reservation. As a corollary, before doing the actual relocation through the GTT, we can make sure that we do have a GTT mapping through which to operate. Note that the key to make this work is to ditch the obj->map_and_fenceable unbind optimization - with full ppgtt it doesn't make a lot of sense any more anyway. v2: Revamp and resend to ease future patches. v3: Refresh patch rationale References: https://bugs.freedesktop.org/show_bug.cgi?id=81094 Signed-off-by: Chris Wilson Cc: Ben Widawsky Cc: Daniel Vetter [danvet: Explain why obj->map_and_fenceable is key and split out the secure batch fix.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 8 +-- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 59 +++++++++++----------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1be7e541a7c7..1ca2231e3929 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2928,9 +2928,8 @@ int i915_vma_unbind(struct i915_vma *vma) vma->unbind_vma(vma); list_del_init(&vma->mm_list); - /* Avoid an unnecessary call to unbind on rebind. */ if (i915_is_ggtt(vma->vm)) - obj->map_and_fenceable = true; + obj->map_and_fenceable = false; drm_mm_remove_node(&vma->node); i915_gem_vma_destroy(vma); @@ -3282,6 +3281,9 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj) return 0; } } else if (enable) { + if (WARN_ON(!obj->map_and_fenceable)) + return -EINVAL; + reg = i915_find_fence_reg(dev); if (IS_ERR(reg)) return PTR_ERR(reg); @@ -4331,8 +4333,6 @@ void i915_gem_object_init(struct drm_i915_gem_object *obj, obj->fence_reg = I915_FENCE_REG_NONE; obj->madv = I915_MADV_WILLNEED; - /* Avoid an unnecessary call to unbind on the first bind. */ - obj->map_and_fenceable = true; i915_gem_info_add_obj(obj->base.dev->dev_private, obj->base.size); } diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 60998fc4e5b2..6320a385841b 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -35,6 +35,7 @@ #define __EXEC_OBJECT_HAS_PIN (1<<31) #define __EXEC_OBJECT_HAS_FENCE (1<<30) +#define __EXEC_OBJECT_NEEDS_MAP (1<<29) #define __EXEC_OBJECT_NEEDS_BIAS (1<<28) #define BATCH_OFFSET_BIAS (256*1024) @@ -534,14 +535,6 @@ i915_gem_execbuffer_relocate(struct eb_vmas *eb) return ret; } -static int -need_reloc_mappable(struct i915_vma *vma) -{ - struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; - return entry->relocation_count && !use_cpu_reloc(vma->obj) && - i915_is_ggtt(vma->vm); -} - static int i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, struct intel_engine_cs *ring, @@ -550,19 +543,12 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, struct drm_i915_gem_object *obj = vma->obj; struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; - bool need_fence; uint64_t flags; int ret; flags = 0; - - need_fence = - has_fenced_gpu_access && - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - if (need_fence || need_reloc_mappable(vma)) + if (entry->flags & __EXEC_OBJECT_NEEDS_MAP) flags |= PIN_MAPPABLE; - if (entry->flags & EXEC_OBJECT_NEEDS_GTT) flags |= PIN_GLOBAL; if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS) @@ -601,26 +587,40 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, } static bool -eb_vma_misplaced(struct i915_vma *vma, bool has_fenced_gpu_access) +need_reloc_mappable(struct i915_vma *vma) { struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; - struct drm_i915_gem_object *obj = vma->obj; - bool need_fence, need_mappable; - need_fence = - has_fenced_gpu_access && - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - need_mappable = need_fence || need_reloc_mappable(vma); + if (entry->relocation_count == 0) + return false; + + if (!i915_is_ggtt(vma->vm)) + return false; + + /* See also use_cpu_reloc() */ + if (HAS_LLC(vma->obj->base.dev)) + return false; + + if (vma->obj->base.write_domain == I915_GEM_DOMAIN_CPU) + return false; - WARN_ON((need_mappable || need_fence) && + return true; +} + +static bool +eb_vma_misplaced(struct i915_vma *vma) +{ + struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; + struct drm_i915_gem_object *obj = vma->obj; + + WARN_ON(entry->flags & __EXEC_OBJECT_NEEDS_MAP && !i915_is_ggtt(vma->vm)); if (entry->alignment && vma->node.start & (entry->alignment - 1)) return true; - if (need_mappable && !obj->map_and_fenceable) + if (entry->flags & __EXEC_OBJECT_NEEDS_MAP && !obj->map_and_fenceable) return true; if (entry->flags & __EXEC_OBJECT_NEEDS_BIAS && @@ -664,9 +664,10 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->tiling_mode != I915_TILING_NONE; need_mappable = need_fence || need_reloc_mappable(vma); - if (need_mappable) + if (need_mappable) { + entry->flags |= __EXEC_OBJECT_NEEDS_MAP; list_move(&vma->exec_list, &ordered_vmas); - else + } else list_move_tail(&vma->exec_list, &ordered_vmas); obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND; @@ -696,7 +697,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, if (!drm_mm_node_allocated(&vma->node)) continue; - if (eb_vma_misplaced(vma, has_fenced_gpu_access)) + if (eb_vma_misplaced(vma)) ret = i915_vma_unbind(vma); else ret = i915_gem_execbuffer_reserve_vma(vma, ring, need_relocs); -- GitLab From 82b6b6d786466e705e7244cc676189ce47a9199a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 Aug 2014 17:37:24 +0100 Subject: [PATCH 0176/9167] drm/i915: Remove fenced_gpu_access and pending_fenced_gpu_access This migrates the fence tracking onto the existing seqno infrastructure so that the later conversion to tracking via requests is simplified. Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 7 ----- drivers/gpu/drm/i915/i915_gem.c | 17 ----------- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 34 ++++++++++++---------- drivers/gpu/drm/i915/i915_gem_tiling.c | 2 +- 4 files changed, 20 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fab97bc3215f..5c3f033ff928 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1777,13 +1777,6 @@ struct drm_i915_gem_object { * Only honoured if hardware has relevant pte bit */ unsigned long gt_ro:1; - - /* - * Is the GPU currently using a fence to access this buffer, - */ - unsigned int pending_fenced_gpu_access:1; - unsigned int fenced_gpu_access:1; - unsigned int cache_level:3; unsigned int has_aliasing_ppgtt_mapping:1; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1ca2231e3929..3eec344bdac0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2161,8 +2161,6 @@ static void i915_gem_object_move_to_active(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; u32 seqno = intel_ring_get_seqno(ring); BUG_ON(ring == NULL); @@ -2181,19 +2179,6 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, list_move_tail(&obj->ring_list, &ring->active_list); obj->last_read_seqno = seqno; - - if (obj->fenced_gpu_access) { - obj->last_fenced_seqno = seqno; - - /* Bump MRU to take account of the delayed flush */ - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_fence_reg *reg; - - reg = &dev_priv->fence_regs[obj->fence_reg]; - list_move_tail(®->lru_list, - &dev_priv->mm.fence_list); - } - } } void i915_vma_move_to_active(struct i915_vma *vma, @@ -2229,7 +2214,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) obj->base.write_domain = 0; obj->last_fenced_seqno = 0; - obj->fenced_gpu_access = false; obj->active = 0; drm_gem_object_unreference(&obj->base); @@ -3174,7 +3158,6 @@ i915_gem_object_wait_fence(struct drm_i915_gem_object *obj) obj->last_fenced_seqno = 0; } - obj->fenced_gpu_access = false; return 0; } diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 6320a385841b..70946c551e5d 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -542,7 +542,6 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, { struct drm_i915_gem_object *obj = vma->obj; struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; - bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; uint64_t flags; int ret; @@ -560,17 +559,13 @@ i915_gem_execbuffer_reserve_vma(struct i915_vma *vma, entry->flags |= __EXEC_OBJECT_HAS_PIN; - if (has_fenced_gpu_access) { - if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { - ret = i915_gem_object_get_fence(obj); - if (ret) - return ret; - - if (i915_gem_object_pin_fence(obj)) - entry->flags |= __EXEC_OBJECT_HAS_FENCE; + if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { + ret = i915_gem_object_get_fence(obj); + if (ret) + return ret; - obj->pending_fenced_gpu_access = true; - } + if (i915_gem_object_pin_fence(obj)) + entry->flags |= __EXEC_OBJECT_HAS_FENCE; } if (entry->offset != vma->node.start) { @@ -658,8 +653,9 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj = vma->obj; entry = vma->exec_entry; + if (!has_fenced_gpu_access) + entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE; need_fence = - has_fenced_gpu_access && entry->flags & EXEC_OBJECT_NEEDS_FENCE && obj->tiling_mode != I915_TILING_NONE; need_mappable = need_fence || need_reloc_mappable(vma); @@ -672,7 +668,6 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, obj->base.pending_read_domains = I915_GEM_GPU_DOMAINS & ~I915_GEM_DOMAIN_COMMAND; obj->base.pending_write_domain = 0; - obj->pending_fenced_gpu_access = false; } list_splice(&ordered_vmas, vmas); @@ -959,9 +954,11 @@ static void i915_gem_execbuffer_move_to_active(struct list_head *vmas, struct intel_engine_cs *ring) { + u32 seqno = intel_ring_get_seqno(ring); struct i915_vma *vma; list_for_each_entry(vma, vmas, exec_list) { + struct drm_i915_gem_exec_object2 *entry = vma->exec_entry; struct drm_i915_gem_object *obj = vma->obj; u32 old_read = obj->base.read_domains; u32 old_write = obj->base.write_domain; @@ -970,18 +967,25 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas, if (obj->base.write_domain == 0) obj->base.pending_read_domains |= obj->base.read_domains; obj->base.read_domains = obj->base.pending_read_domains; - obj->fenced_gpu_access = obj->pending_fenced_gpu_access; i915_vma_move_to_active(vma, ring); if (obj->base.write_domain) { obj->dirty = 1; - obj->last_write_seqno = intel_ring_get_seqno(ring); + obj->last_write_seqno = seqno; intel_fb_obj_invalidate(obj, ring); /* update for the implicit flush after a batch */ obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; } + if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { + obj->last_fenced_seqno = seqno; + if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { + struct drm_i915_private *dev_priv = to_i915(ring->dev); + list_move_tail(&dev_priv->fence_regs[obj->fence_reg].lru_list, + &dev_priv->mm.fence_list); + } + } trace_i915_gem_object_change_domain(obj, old_read, old_write); } diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index cb150e8b4336..7e623bf097a1 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -376,7 +376,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, if (ret == 0) { obj->fence_dirty = - obj->fenced_gpu_access || + obj->last_fenced_seqno || obj->fence_reg != I915_FENCE_REG_NONE; obj->tiling_mode = args->tiling_mode; -- GitLab From 87f1f46514babd40fc3551ca2d6148cdedd9c7e3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 Aug 2014 19:18:42 +0100 Subject: [PATCH 0177/9167] drm/i915: Copy PCI device id into the device info block This is so that we can make the drm_i915_private->info always the preferred source for chipset type and feature queries. Signed-off-by: Chris Wilson Reviewed-by: Jani Nikula Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 5 ++-- drivers/gpu/drm/i915/i915_drv.h | 50 +++++++++++++++++---------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c965698a8bac..1867e2619e73 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1603,9 +1603,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev->dev_private = dev_priv; dev_priv->dev = dev; - /* copy initial configuration to dev_priv->info */ + /* Setup the write-once "constant" device info */ device_info = (struct intel_device_info *)&dev_priv->info; - *device_info = *info; + memcpy(device_info, info, sizeof(dev_priv->info)); + device_info->device_id = dev->pdev->device; spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->gpu_error.lock); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5c3f033ff928..8a55f07d80cb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -558,6 +558,7 @@ struct intel_uncore { struct intel_device_info { u32 display_mmio_offset; + u16 device_id; u8 num_pipes:3; u8 num_sprites[I915_MAX_PIPES]; u8 gen; @@ -1980,51 +1981,52 @@ struct drm_i915_cmd_table { int count; }; -#define INTEL_INFO(dev) (&to_i915(dev)->info) +#define INTEL_INFO(p) (&to_i915(p)->info) +#define INTEL_DEVID(p) (INTEL_INFO(p)->device_id) -#define IS_I830(dev) ((dev)->pdev->device == 0x3577) -#define IS_845G(dev) ((dev)->pdev->device == 0x2562) +#define IS_I830(dev) (INTEL_DEVID(dev) == 0x3577) +#define IS_845G(dev) (INTEL_DEVID(dev) == 0x2562) #define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) -#define IS_I865G(dev) ((dev)->pdev->device == 0x2572) +#define IS_I865G(dev) (INTEL_DEVID(dev) == 0x2572) #define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) -#define IS_I915GM(dev) ((dev)->pdev->device == 0x2592) -#define IS_I945G(dev) ((dev)->pdev->device == 0x2772) +#define IS_I915GM(dev) (INTEL_DEVID(dev) == 0x2592) +#define IS_I945G(dev) (INTEL_DEVID(dev) == 0x2772) #define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) #define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) #define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) -#define IS_GM45(dev) ((dev)->pdev->device == 0x2A42) +#define IS_GM45(dev) (INTEL_DEVID(dev) == 0x2A42) #define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) -#define IS_PINEVIEW_G(dev) ((dev)->pdev->device == 0xa001) -#define IS_PINEVIEW_M(dev) ((dev)->pdev->device == 0xa011) +#define IS_PINEVIEW_G(dev) (INTEL_DEVID(dev) == 0xa001) +#define IS_PINEVIEW_M(dev) (INTEL_DEVID(dev) == 0xa011) #define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) #define IS_G33(dev) (INTEL_INFO(dev)->is_g33) -#define IS_IRONLAKE_M(dev) ((dev)->pdev->device == 0x0046) +#define IS_IRONLAKE_M(dev) (INTEL_DEVID(dev) == 0x0046) #define IS_IVYBRIDGE(dev) (INTEL_INFO(dev)->is_ivybridge) -#define IS_IVB_GT1(dev) ((dev)->pdev->device == 0x0156 || \ - (dev)->pdev->device == 0x0152 || \ - (dev)->pdev->device == 0x015a) -#define IS_SNB_GT1(dev) ((dev)->pdev->device == 0x0102 || \ - (dev)->pdev->device == 0x0106 || \ - (dev)->pdev->device == 0x010A) +#define IS_IVB_GT1(dev) (INTEL_DEVID(dev) == 0x0156 || \ + INTEL_DEVID(dev) == 0x0152 || \ + INTEL_DEVID(dev) == 0x015a) +#define IS_SNB_GT1(dev) (INTEL_DEVID(dev) == 0x0102 || \ + INTEL_DEVID(dev) == 0x0106 || \ + INTEL_DEVID(dev) == 0x010A) #define IS_VALLEYVIEW(dev) (INTEL_INFO(dev)->is_valleyview) #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_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) #define IS_HSW_EARLY_SDV(dev) (IS_HASWELL(dev) && \ - ((dev)->pdev->device & 0xFF00) == 0x0C00) + (INTEL_DEVID(dev) & 0xFF00) == 0x0C00) #define IS_BDW_ULT(dev) (IS_BROADWELL(dev) && \ - (((dev)->pdev->device & 0xf) == 0x2 || \ - ((dev)->pdev->device & 0xf) == 0x6 || \ - ((dev)->pdev->device & 0xf) == 0xe)) + ((INTEL_DEVID(dev) & 0xf) == 0x2 || \ + (INTEL_DEVID(dev) & 0xf) == 0x6 || \ + (INTEL_DEVID(dev) & 0xf) == 0xe)) #define IS_HSW_ULT(dev) (IS_HASWELL(dev) && \ - ((dev)->pdev->device & 0xFF00) == 0x0A00) + (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) && \ - ((dev)->pdev->device & 0x00F0) == 0x0020) + (INTEL_DEVID(dev) & 0x00F0) == 0x0020) /* ULX machines are also considered ULT. */ -#define IS_HSW_ULX(dev) ((dev)->pdev->device == 0x0A0E || \ - (dev)->pdev->device == 0x0A1E) +#define IS_HSW_ULX(dev) (INTEL_DEVID(dev) == 0x0A0E || \ + INTEL_DEVID(dev) == 0x0A1E) #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary) /* -- GitLab From f6daaec29b2a201eb8db2ce26b4460b779ad8111 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Sat, 9 Aug 2014 23:00:56 +0100 Subject: [PATCH 0178/9167] drm/i915: Make intel_disable_shared_dpll() static Found with sparse. 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 0746590ed4e3..245cf4128314 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1797,7 +1797,7 @@ static void intel_enable_shared_dpll(struct intel_crtc *crtc) pll->on = true; } -void intel_disable_shared_dpll(struct intel_crtc *crtc) +static void intel_disable_shared_dpll(struct intel_crtc *crtc) { struct drm_device *dev = crtc->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; -- GitLab From 1bee20175f27b46427f10290fdd4a79334d41a60 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Sat, 9 Aug 2014 23:00:58 +0100 Subject: [PATCH 0179/9167] drm/i915: Remove set but unused 'gt_perf_status' Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 41de760bf1d4..12f4e143328c 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -3719,7 +3719,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 gt_perf_status; u32 rc6vids, pcu_mbox = 0, rc6_mask = 0; u32 gtfifodbg; int rc6_mode; @@ -3744,7 +3743,6 @@ 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); - gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); parse_rp_state_cap(dev_priv, rp_state_cap); -- GitLab From 9bec9b1334d687c0a9fcf3d3a1987a61b4826a45 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 11 Aug 2014 09:21:35 +0100 Subject: [PATCH 0180/9167] drm/i915: Double check ring is idle before declaring the GPU wedged During ring initialisation, sometimes we observe, though not in production hardware, that the idle flag is not set even though the ring is empty. Double check before giving up. Signed-off-by: Chris Wilson Cc: Damien Lespiau Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 117543e58d48..a059b64a0fb2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -478,7 +478,12 @@ static bool stop_ring(struct intel_engine_cs *ring) I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); if (wait_for((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { DRM_ERROR("%s : timed out trying to stop ring\n", ring->name); - return false; + /* Sometimes we observe that the idle flag is not + * set even though the ring is empty. So double + * check before giving up. + */ + if (I915_READ_HEAD(ring) != I915_READ_TAIL(ring)) + return false; } } -- GitLab From dbbe91279511d6a18a521b953a3c139e4787e660 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 9 Aug 2014 19:18:43 +0100 Subject: [PATCH 0181/9167] drm/i915: Agnostic INTEL_INFO Adapt the macro so that we can pass either the struct drm_device or the struct drm_i915_private pointers and get the answer we want. Over time, my plan is to convert all users over to using drm_i915_private and so trimming down the pointer dance. Having spent a few hours chasing that goal and achieved over 8k of object code saving, it appears to be a worthwhile target. This interim macro allows us to slowly convert over. Signed-off-by: Chris Wilson [danvet: Drop the (struct drm_device *) cast per the m-l discussion. Also explain the seemingly unecessary first cast.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 3 +++ drivers/gpu/drm/i915/i915_drv.h | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1867e2619e73..1763fbf34e1d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1596,6 +1596,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!drm_core_check_feature(dev, DRIVER_MODESET) && !dev->agp) return -EINVAL; + /* For the ugly agnostic INTEL_INFO macro */ + BUILD_BUG_ON(sizeof(*dev_priv) == sizeof(*dev)); + dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (dev_priv == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8a55f07d80cb..6959c1b2d648 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1981,7 +1981,10 @@ struct drm_i915_cmd_table { int count; }; -#define INTEL_INFO(p) (&to_i915(p)->info) +/* Note that the (struct drm_i915_private *) cast is just to shut up gcc. */ +#define __I915__(p) ((sizeof(*(p)) == sizeof(struct drm_i915_private)) ? \ + (struct drm_i915_private *)(p) : to_i915(p)) +#define INTEL_INFO(p) (&__I915__(p)->info) #define INTEL_DEVID(p) (INTEL_INFO(p)->device_id) #define IS_I830(dev) (INTEL_DEVID(dev) == 0x3577) -- GitLab From da51a1e7e398129d9fddd4b26b8469145dd4fd08 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Aug 2014 12:08:58 +0200 Subject: [PATCH 0182/9167] drm/i915: Fix secure dispatch with full ppgtt Based upon a hunk from a patch from Chris Wilson, but augmented to: - Process the batch in the full ppgtt vm so that self-relocations match again with userspace's expectations.. - Add a comment why plain pin for the global gtt binding is safe at that point. v2: Drop local bind_vm variable (Chris). v3: Explain why this works despite the lack of proper active tracking for the ggtt batch vma. Cc: Chris Wilson Cc: Ben Widawsky Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 48 +++++++++++----------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 70946c551e5d..e1eac15b2583 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -95,7 +95,6 @@ eb_lookup_vmas(struct eb_vmas *eb, struct i915_address_space *vm, struct drm_file *file) { - struct drm_i915_private *dev_priv = vm->dev->dev_private; struct drm_i915_gem_object *obj; struct list_head objects; int i, ret; @@ -130,7 +129,6 @@ eb_lookup_vmas(struct eb_vmas *eb, i = 0; while (!list_empty(&objects)) { struct i915_vma *vma; - struct i915_address_space *bind_vm = vm; if (exec[i].flags & EXEC_OBJECT_NEEDS_GTT && USES_FULL_PPGTT(vm->dev)) { @@ -138,13 +136,6 @@ eb_lookup_vmas(struct eb_vmas *eb, goto err; } - /* If we have secure dispatch, or the userspace assures us that - * they know what they're doing, use the GGTT VM. - */ - if (((args->flags & I915_EXEC_SECURE) && - (i == (args->buffer_count - 1)))) - bind_vm = &dev_priv->gtt.base; - obj = list_first_entry(&objects, struct drm_i915_gem_object, obj_exec_link); @@ -157,7 +148,7 @@ eb_lookup_vmas(struct eb_vmas *eb, * from the (obj, vm) we don't run the risk of creating * duplicated vmas for the same vm. */ - vma = i915_gem_obj_lookup_or_create_vma(obj, bind_vm); + vma = i915_gem_obj_lookup_or_create_vma(obj, vm); if (IS_ERR(vma)) { DRM_DEBUG("Failed to lookup VMA\n"); ret = PTR_ERR(vma); @@ -1391,25 +1382,36 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, /* snb/ivb/vlv conflate the "batch in ppgtt" bit with the "non-secure * batch" bit. Hence we need to pin secure batches into the global gtt. * hsw should have this fixed, but bdw mucks it up again. */ - if (flags & I915_DISPATCH_SECURE && - !batch_obj->has_global_gtt_mapping) { - /* When we have multiple VMs, we'll need to make sure that we - * allocate space first */ - struct i915_vma *vma = i915_gem_obj_to_ggtt(batch_obj); - BUG_ON(!vma); - vma->bind_vma(vma, batch_obj->cache_level, GLOBAL_BIND); - } + if (flags & I915_DISPATCH_SECURE) { + /* + * So on first glance it looks freaky that we pin the batch here + * outside of the reservation loop. But: + * - The batch is already pinned into the relevant ppgtt, so we + * already have the backing storage fully allocated. + * - No other BO uses the global gtt (well contexts, but meh), + * so we don't really have issues with mutliple objects not + * fitting due to fragmentation. + * So this is actually safe. + */ + ret = i915_gem_obj_ggtt_pin(batch_obj, 0, 0); + if (ret) + goto err; - if (flags & I915_DISPATCH_SECURE) exec_start += i915_gem_obj_ggtt_offset(batch_obj); - else + } else exec_start += i915_gem_obj_offset(batch_obj, vm); ret = legacy_ringbuffer_submission(dev, file, ring, ctx, - args, &eb->vmas, batch_obj, exec_start, flags); - if (ret) - goto err; + args, &eb->vmas, batch_obj, exec_start, flags); + /* + * FIXME: We crucially rely upon the active tracking for the (ppgtt) + * batch vma for correctness. For less ugly and less fragility this + * needs to be adjusted to also track the ggtt batch vma properly as + * active. + */ + if (flags & I915_DISPATCH_SECURE) + i915_gem_object_ggtt_unpin(batch_obj); err: /* the request owns the ref now */ i915_gem_context_unreference(ctx); -- GitLab From ad19f10bc2a5964f1564639e60953de76b7e50f6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 10 Aug 2014 06:29:08 +0100 Subject: [PATCH 0183/9167] drm/i915: Pre-validate the NEED_GTTS flag for execbuffer We have an implementation requirement that precludes the user from requesting a ggtt entry when the device is operating in ppgtt mode. Move the current check from inside the execbuffer object collation to the prevalidation phase. v2: Roll both invalid flags checks into one Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index e1eac15b2583..446f4b6fbefe 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -130,12 +130,6 @@ eb_lookup_vmas(struct eb_vmas *eb, while (!list_empty(&objects)) { struct i915_vma *vma; - if (exec[i].flags & EXEC_OBJECT_NEEDS_GTT && - USES_FULL_PPGTT(vm->dev)) { - ret = -EINVAL; - goto err; - } - obj = list_first_entry(&objects, struct drm_i915_gem_object, obj_exec_link); @@ -877,18 +871,24 @@ i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) } static int -validate_exec_list(struct drm_i915_gem_exec_object2 *exec, +validate_exec_list(struct drm_device *dev, + struct drm_i915_gem_exec_object2 *exec, int count) { - int i; unsigned relocs_total = 0; unsigned relocs_max = UINT_MAX / sizeof(struct drm_i915_gem_relocation_entry); + unsigned invalid_flags; + int i; + + invalid_flags = __EXEC_OBJECT_UNKNOWN_FLAGS; + if (USES_FULL_PPGTT(dev)) + invalid_flags |= EXEC_OBJECT_NEEDS_GTT; for (i = 0; i < count; i++) { char __user *ptr = to_user_ptr(exec[i].relocs_ptr); int length; /* limited by fault_in_pages_readable() */ - if (exec[i].flags & __EXEC_OBJECT_UNKNOWN_FLAGS) + if (exec[i].flags & invalid_flags) return -EINVAL; /* First check for malicious input causing overflow in @@ -1250,7 +1250,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (!i915_gem_check_execbuffer(args)) return -EINVAL; - ret = validate_exec_list(exec, args->buffer_count); + ret = validate_exec_list(dev, exec, args->buffer_count); if (ret) return ret; -- GitLab From 060e82c6f4ccf678decffb28ba8301ca9220a995 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 10 Aug 2014 06:29:10 +0100 Subject: [PATCH 0184/9167] drm/i915: Remove redundant list_empty(eb->vmas) tests in execbuffer Part of the pre-validation for an execbuffer call is that there is at least one object in the execlist. As we bail if we fail to lookup any object, we can be sure that after the eb_lookup_vma() there is at least one object in the vma list and so we do not need to assert. Signed-off-by: Chris Wilson Cc: Ben Widawsky Cc: Daniel Vetter Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 446f4b6fbefe..6c07940b468c 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -622,9 +622,6 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *ring, bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; int retry; - if (list_empty(vmas)) - return 0; - i915_gem_retire_requests_ring(ring); vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm; @@ -725,9 +722,6 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, int i, total, ret; unsigned count = args->buffer_count; - if (WARN_ON(list_empty(&eb->vmas))) - return 0; - vm = list_first_entry(&eb->vmas, struct i915_vma, exec_list)->vm; /* We may process another execbuffer during the unlock... */ -- GitLab From 906843c3a1acc36407e500a073679c4207d307cd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 10 Aug 2014 06:29:11 +0100 Subject: [PATCH 0185/9167] drm/i915: Simplify relocate_entry_gtt() and make 64-bit safe Even though we should not try to use 4+GiB GTTs on 32-bit systems, by using a local variable we can future proof the code whilst making it easier to read. Signed-off-by: Chris Wilson [danvet: Appease checkpatch a bit.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 25 +++++++++++----------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 6c07940b468c..dec2cc2fbd42 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -293,7 +293,7 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; uint64_t delta = reloc->delta + target_offset; - uint32_t __iomem *reloc_entry; + uint64_t offset; void __iomem *reloc_page; int ret; @@ -306,25 +306,24 @@ relocate_entry_gtt(struct drm_i915_gem_object *obj, return ret; /* Map the page containing the relocation we're going to perform. */ - reloc->offset += i915_gem_obj_ggtt_offset(obj); + offset = i915_gem_obj_ggtt_offset(obj); + offset += reloc->offset; reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, - reloc->offset & PAGE_MASK); - reloc_entry = (uint32_t __iomem *) - (reloc_page + offset_in_page(reloc->offset)); - iowrite32(lower_32_bits(delta), reloc_entry); + offset & PAGE_MASK); + iowrite32(lower_32_bits(delta), reloc_page + offset_in_page(offset)); if (INTEL_INFO(dev)->gen >= 8) { - reloc_entry += 1; + offset += sizeof(uint32_t); - if (offset_in_page(reloc->offset + sizeof(uint32_t)) == 0) { + if (offset_in_page(offset) == 0) { io_mapping_unmap_atomic(reloc_page); - reloc_page = io_mapping_map_atomic_wc( - dev_priv->gtt.mappable, - reloc->offset + sizeof(uint32_t)); - reloc_entry = reloc_page; + reloc_page = + io_mapping_map_atomic_wc(dev_priv->gtt.mappable, + offset); } - iowrite32(upper_32_bits(delta), reloc_entry); + iowrite32(upper_32_bits(delta), + reloc_page + offset_in_page(offset)); } io_mapping_unmap_atomic(reloc_page); -- GitLab From 2a0d7cfd9482ca4c10a4d8794791760a6a7ce40c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 29 Jul 2014 15:32:37 +0200 Subject: [PATCH 0186/9167] drm: Add a plane->reset hook In general having this can't hurt, and the atomic helpers will need it to be able to reset the state objects properly. The overall idea is to reset in the order pixels flow, so planes -> crtcs -> encoders -> connectors. v2: Squash in fixup from Ville to correctly deference struct drm_plane instead of drm_crtc when walking the plane list. Fixes an oops in driver init and resume. Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 5 +++++ include/drm/drm_crtc.h | 1 + 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index cacb460a7145..285e62a134b2 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4663,9 +4663,14 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, void drm_mode_config_reset(struct drm_device *dev) { struct drm_crtc *crtc; + struct drm_plane *plane; struct drm_encoder *encoder; struct drm_connector *connector; + list_for_each_entry(plane, &dev->mode_config.plane_list, head) + if (plane->funcs->reset) + plane->funcs->reset(plane); + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) if (crtc->funcs->reset) crtc->funcs->reset(crtc); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 279565aa0c33..2c1f58d6957a 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -581,6 +581,7 @@ struct drm_plane_funcs { uint32_t src_w, uint32_t src_h); int (*disable_plane)(struct drm_plane *plane); void (*destroy)(struct drm_plane *plane); + void (*reset)(struct drm_plane *plane); int (*set_property)(struct drm_plane *plane, struct drm_property *property, uint64_t val); -- GitLab From e8450f51a4b39cfe0878b4aee339820b2bfff240 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 25 Jul 2014 23:34:03 +0200 Subject: [PATCH 0187/9167] drm/irq: Implement a generic vblank_wait function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As usual in both a crtc index and a struct drm_crtc * version. The function assumes that no one drivers their display below 10Hz, and it will complain if the vblank wait takes longer than that. v2: Also check dev->max_vblank_counter since some drivers register a fake get_vblank_counter function. v3: Use drm_vblank_count instead of calling the low-level ->get_vblank_counter callback. That way we'll get the sw-cooked counter for platforms without proper vblank support and so can ditch the max_vblank_counter check again. v4: Review from Michel Dänzer: - Restore lost notes about v3: - Spelling in kerneldoc. - Inline wait_event condition. - s/vblank_wait/wait_one_vblank/ Cc: Michel Dänzer Cc: Ville Syrjälä Reviewed-by: Michel Dänzer Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_irq.c | 44 +++++++++++++++++++++++++++++++++++++++ include/drm/drmP.h | 2 ++ 2 files changed, 46 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 6f16a104d6d0..e64d24951fc2 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1009,6 +1009,50 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc) } EXPORT_SYMBOL(drm_crtc_vblank_put); +/** + * drm_wait_one_vblank - wait for one vblank + * @dev: DRM device + * @crtc: crtc index + * + * This waits for one vblank to pass on @crtc, using the irq driver interfaces. + * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. + * due to lack of driver support or because the crtc is off. + */ +void drm_wait_one_vblank(struct drm_device *dev, int crtc) +{ + int ret; + u32 last; + + ret = drm_vblank_get(dev, crtc); + if (WARN_ON(ret)) + return; + + last = drm_vblank_count(dev, crtc); + + ret = wait_event_timeout(dev->vblank[crtc].queue, + last != drm_vblank_count(dev, crtc), + msecs_to_jiffies(100)); + + WARN_ON(ret == 0); + + drm_vblank_put(dev, crtc); +} +EXPORT_SYMBOL(drm_wait_one_vblank); + +/** + * drm_crtc_wait_one_vblank - wait for one vblank + * @crtc: DRM crtc + * + * This waits for one vblank to pass on @crtc, using the irq driver interfaces. + * It is a failure to call this when the vblank irq for @crtc is disabled, e.g. + * due to lack of driver support or because the crtc is off. + */ +void drm_crtc_wait_one_vblank(struct drm_crtc *crtc) +{ + drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc)); +} +EXPORT_SYMBOL(drm_crtc_wait_one_vblank); + /** * drm_vblank_off - disable vblank events on a CRTC * @dev: DRM device diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d3d9be6b83ef..c2209178981f 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1327,6 +1327,8 @@ extern int drm_vblank_get(struct drm_device *dev, int crtc); extern void drm_vblank_put(struct drm_device *dev, int crtc); extern int drm_crtc_vblank_get(struct drm_crtc *crtc); extern void drm_crtc_vblank_put(struct drm_crtc *crtc); +extern void drm_wait_one_vblank(struct drm_device *dev, int crtc); +extern void drm_crtc_wait_one_vblank(struct drm_crtc *crtc); extern void drm_vblank_off(struct drm_device *dev, int crtc); extern void drm_vblank_on(struct drm_device *dev, int crtc); extern void drm_crtc_vblank_off(struct drm_crtc *crtc); -- GitLab From b20385f1f8434ec32d73414ffcadb7dcbd3a2a61 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:10 +0100 Subject: [PATCH 0188/9167] drm/i915/bdw: New source and header file for LRs, LRCs and Execlists Some legacy HW context code assumptions don't make sense for this new submission method, so we will place this stuff in a separate file. Note for reviewers: I've carefully considered the best name for this file and this was my best option (other possibilities were intel_lr_context.c or intel_execlist.c). I am open to a certain bikeshedding on this matter, anyway. And some point in time, it would be a good idea to split intel_lrc.c/.h even further, but for the moment just shove everything together. v2: Change to intel_lrc.c v3: Squash together with the header file addition Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 42 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.h | 27 ++++++++++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 drivers/gpu/drm/i915/intel_lrc.c create mode 100644 drivers/gpu/drm/i915/intel_lrc.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 91bd167e1cb7..c1dd485aeb6c 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -31,6 +31,7 @@ i915-y += i915_cmd_parser.o \ i915_gpu_error.o \ i915_irq.o \ i915_trace_points.o \ + intel_lrc.o \ intel_ringbuffer.o \ intel_uncore.o diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6959c1b2d648..ec2a094f3622 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -35,6 +35,7 @@ #include "i915_reg.h" #include "intel_bios.h" #include "intel_ringbuffer.h" +#include "intel_lrc.h" #include "i915_gem_gtt.h" #include #include diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c new file mode 100644 index 000000000000..49bb6fcdface --- /dev/null +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -0,0 +1,42 @@ +/* + * 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: + * Ben Widawsky + * Michel Thierry + * Thomas Daniel + * Oscar Mateo + * + */ + +/* + * GEN8 brings an expansion of the HW contexts: "Logical Ring Contexts". + * These expanded contexts enable a number of new abilities, especially + * "Execlists" (also implemented in this file). + * + * Execlists are the new method by which, on gen8+ hardware, workloads are + * submitted for execution (as opposed to the legacy, ringbuffer-based, method). + */ + +#include +#include +#include "i915_drv.h" diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h new file mode 100644 index 000000000000..f6830a4ec773 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -0,0 +1,27 @@ +/* + * 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. + */ + +#ifndef _INTEL_LRC_H_ +#define _INTEL_LRC_H_ + +#endif /* _INTEL_LRC_H_ */ -- GitLab From 127f100369a1f302904335950387d566680eb275 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:11 +0100 Subject: [PATCH 0189/9167] drm/i915/bdw: Macro for LRCs and module option for Execlists GEN8 brings an expansion of the HW contexts: "Logical Ring Contexts". These expanded contexts enable a number of new abilities, especially "Execlists". The macro is defined to off until we have things in place to hope to work. v2: Rename "advanced contexts" to the more correct "logical ring contexts". v3: Add a module parameter to enable execlists. Execlist are relatively new, and so it'd be wise to be able to switch back to ring submission to debug subtle problems that will inevitably arise. v4: Add an intel_enable_execlists function. v5: Sanitize early, as suggested by Daniel. Remove lrc_enabled. Signed-off-by: Ben Widawsky (v1) Signed-off-by: Damien Lespiau (v3) Signed-off-by: Oscar Mateo (v2, v4 & v5) Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 3 +++ drivers/gpu/drm/i915/i915_params.c | 6 ++++++ drivers/gpu/drm/i915/intel_lrc.c | 11 +++++++++++ drivers/gpu/drm/i915/intel_lrc.h | 3 +++ 5 files changed, 25 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ec2a094f3622..fd2aa15ce02b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2062,6 +2062,7 @@ struct drm_i915_cmd_table { #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) +#define HAS_LOGICAL_RING_CONTEXTS(dev) 0 #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) @@ -2149,6 +2150,7 @@ struct i915_params { int enable_rc6; int enable_fbc; int enable_ppgtt; + int enable_execlists; int enable_psr; unsigned int preliminary_hw_support; int disable_power_well; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3eec344bdac0..5646e9ba6383 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4723,6 +4723,9 @@ int i915_gem_init(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int ret; + i915.enable_execlists = intel_sanitize_enable_execlists(dev, + i915.enable_execlists); + mutex_lock(&dev->struct_mutex); if (IS_VALLEYVIEW(dev)) { diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index 62ee8308d682..f7f8350c3793 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -35,6 +35,7 @@ struct i915_params i915 __read_mostly = { .vbt_sdvo_panel_type = -1, .enable_rc6 = -1, .enable_fbc = -1, + .enable_execlists = -1, .enable_hangcheck = true, .enable_ppgtt = -1, .enable_psr = 1, @@ -118,6 +119,11 @@ MODULE_PARM_DESC(enable_ppgtt, "Override PPGTT usage. " "(-1=auto [default], 0=disabled, 1=aliasing, 2=full)"); +module_param_named(enable_execlists, i915.enable_execlists, int, 0400); +MODULE_PARM_DESC(enable_execlists, + "Override execlists usage. " + "(-1=auto [default], 0=disabled, 1=enabled)"); + module_param_named(enable_psr, i915.enable_psr, int, 0600); MODULE_PARM_DESC(enable_psr, "Enable PSR (default: true)"); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 49bb6fcdface..21f7f1cce86e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -40,3 +40,14 @@ #include #include #include "i915_drv.h" + +int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) +{ + if (enable_execlists == 0) + return 0; + + if (HAS_LOGICAL_RING_CONTEXTS(dev) && USES_PPGTT(dev)) + return 1; + + return 0; +} diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index f6830a4ec773..75ee9c3cb7dc 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -24,4 +24,7 @@ #ifndef _INTEL_LRC_H_ #define _INTEL_LRC_H_ +/* Execlists */ +int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists); + #endif /* _INTEL_LRC_H_ */ -- GitLab From bd84b1e995918ad83bdba5d5be1bef901e169f19 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Aug 2014 15:57:57 +0200 Subject: [PATCH 0190/9167] drm/i915: WARN if module opt sanitization goes out of order Depending upon one module option to be sanitized (through USES_PPGTT) for the other is a bit too fragile for my taste. At least WARN about this. Cc: Ben Widawsky Cc: Damien Lespiau Cc: Oscar Mateo Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 21f7f1cce86e..44721292eb77 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -43,6 +43,8 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) { + WARN_ON(i915.enable_ppgtt == -1); + if (enable_execlists == 0) return 0; -- GitLab From ede7d42baeece583c864badb6f9081f4cded6c32 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:12 +0100 Subject: [PATCH 0191/9167] drm/i915/bdw: Initialization for Logical Ring Contexts For the moment this is just a placeholder, but it shows one of the main differences between the good ol' HW contexts and the shiny new Logical Ring Contexts: LR contexts allocate and free their own backing objects. Another difference is that the allocation is deferred (as the create function name suggests), but that does not happen in this patch yet, because for the moment we are only dealing with the default context. Early in the series we had our own gen8_gem_context_init/fini functions, but the truth is they now look almost the same as the legacy hw context init/fini functions. We can always split them later if this ceases to be the case. Also, we do not fall back to legacy ringbuffers when logical ring context initialization fails (not very likely to happen and, even if it does, hw contexts would probably fail as well). v2: Daniel says "explain, do not showcase". Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: s/BUG_ON/WARN_ON/.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_context.c | 29 ++++++++++++++++++++----- drivers/gpu/drm/i915/intel_lrc.c | 15 +++++++++++++ drivers/gpu/drm/i915/intel_lrc.h | 5 +++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 3b99390e467a..3552a351ccf7 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -182,7 +182,10 @@ void i915_gem_context_free(struct kref *ctx_ref) typeof(*ctx), ref); struct i915_hw_ppgtt *ppgtt = NULL; - if (ctx->legacy_hw_ctx.rcs_state) { + if (i915.enable_execlists) { + ppgtt = ctx_to_ppgtt(ctx); + intel_lr_context_free(ctx); + } else if (ctx->legacy_hw_ctx.rcs_state) { /* We refcount even the aliasing PPGTT to keep the code symmetric */ if (USES_PPGTT(ctx->legacy_hw_ctx.rcs_state->base.dev)) ppgtt = ctx_to_ppgtt(ctx); @@ -417,7 +420,11 @@ int i915_gem_context_init(struct drm_device *dev) if (WARN_ON(dev_priv->ring[RCS].default_context)) return 0; - if (HAS_HW_CONTEXTS(dev)) { + if (i915.enable_execlists) { + /* NB: intentionally left blank. We will allocate our own + * backing objects as we need them, thank you very much */ + dev_priv->hw_context_size = 0; + } else if (HAS_HW_CONTEXTS(dev)) { dev_priv->hw_context_size = round_up(get_context_size(dev), 4096); if (dev_priv->hw_context_size > (1<<20)) { DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n", @@ -433,11 +440,20 @@ int i915_gem_context_init(struct drm_device *dev) return PTR_ERR(ctx); } - /* NB: RCS will hold a ref for all rings */ - for (i = 0; i < I915_NUM_RINGS; i++) - dev_priv->ring[i].default_context = ctx; + for (i = 0; i < I915_NUM_RINGS; i++) { + struct intel_engine_cs *ring = &dev_priv->ring[i]; + + /* NB: RCS will hold a ref for all rings */ + ring->default_context = ctx; + + /* FIXME: we really only want to do this for initialized rings */ + if (i915.enable_execlists) + intel_lr_context_deferred_create(ctx, ring); + } - DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->hw_context_size ? "HW" : "fake"); + DRM_DEBUG_DRIVER("%s context support initialized\n", + i915.enable_execlists ? "LR" : + dev_priv->hw_context_size ? "HW" : "fake"); return 0; } @@ -779,6 +795,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct intel_context *ctx; int ret; + /* FIXME: allow user-created LR contexts as well */ if (!hw_context_enabled(dev)) return -ENODEV; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 44721292eb77..2d82d52d18bb 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -53,3 +53,18 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } + +void intel_lr_context_free(struct intel_context *ctx) +{ + /* TODO */ +} + +int intel_lr_context_deferred_create(struct intel_context *ctx, + struct intel_engine_cs *ring) +{ + WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL); + + /* TODO */ + + return 0; +} diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 75ee9c3cb7dc..3b93572431e3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -24,6 +24,11 @@ #ifndef _INTEL_LRC_H_ #define _INTEL_LRC_H_ +/* Logical Ring Contexts */ +void intel_lr_context_free(struct intel_context *ctx); +int intel_lr_context_deferred_create(struct intel_context *ctx, + struct intel_engine_cs *ring); + /* Execlists */ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists); -- GitLab From c9e003af2d44d9f6eafe855448c41c9ac08ae895 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:13 +0100 Subject: [PATCH 0192/9167] drm/i915/bdw: Introduce one context backing object per engine A context backing object only makes sense for a given engine (because it holds state data specific to that engine). In legacy ringbuffer sumission mode, the only MI_SET_CONTEXT we really perform is for the render engine, so one backing object is all we nee. With Execlists, however, we need backing objects for every engine, as contexts become the only way to submit workloads to the GPU. To tackle this problem, we multiplex the context struct to contain objects. Originally, I colored this code by instantiating one new context for every engine I wanted to use, but this change suggested by Brad Volkin makes it more elegant. v2: Leave the old backing object pointer behind. Daniel Vetter suggested using a union, but it makes more sense to keep rcs_state as a NULL pointer behind, to make sure no one uses it incorrectly when Execlists are enabled, similar to what he suggested for ring->buffer (Rusty's API level 5). v3: Use the name "state" instead of the too-generic "obj", so that it mirrors the name choice for the legacy rcs_state. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index fd2aa15ce02b..ad70e8ec18bc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -626,11 +626,17 @@ struct intel_context { struct i915_ctx_hang_stats hang_stats; struct i915_address_space *vm; + /* Legacy ring buffer submission */ struct { struct drm_i915_gem_object *rcs_state; bool initialized; } legacy_hw_ctx; + /* Execlists */ + struct { + struct drm_i915_gem_object *state; + } engine[I915_NUM_RINGS]; + struct list_head link; }; -- GitLab From 8c8579176a144b1dca1d99ebb92510924168d508 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:14 +0100 Subject: [PATCH 0193/9167] drm/i915/bdw: A bit more advanced LR context alloc/free Now that we have the ability to allocate our own context backing objects and we have multiplexed one of them per engine inside the context structs, we can finally allocate and free them correctly. Regarding the context size, reading the register to calculate the sizes can work, I think, however the docs are very clear about the actual context sizes on GEN8, so just hardcode that and use it. v2: Rebased on top of the Full PPGTT series. It is important to notice that at this point we have one global default context per engine, all of them using the aliasing PPGTT (as opposed to the single global default context we have with legacy HW contexts). v3: - Go back to one single global default context, this time with multiple backing objects inside. - Use different context sizes for non-render engines, as suggested by Damien (still hardcoded, since the information about the context size registers in the BSpec is, well, *lacking*). - Render ctx size is 20 (or 19) pages, but not 21 (caught by Damien). - Move default context backing object creation to intel_init_ring (so that we don't waste memory in rings that might not get initialized). v4: - Reuse the HW legacy context init/fini. - Create a separate free function. - Rename the functions with an intel_ preffix. v5: Several rebases to account for the changes in the previous patches. Signed-off-by: Ben Widawsky (v1) Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gem_context.c | 2 +- drivers/gpu/drm/i915/intel_lrc.c | 59 ++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ad70e8ec18bc..cbae19bab4bf 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2528,6 +2528,8 @@ int i915_switch_context(struct intel_engine_cs *ring, struct intel_context * i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id); void i915_gem_context_free(struct kref *ctx_ref); +struct drm_i915_gem_object * +i915_gem_alloc_context_obj(struct drm_device *dev, size_t size); static inline void i915_gem_context_reference(struct intel_context *ctx) { kref_get(&ctx->ref); diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 3552a351ccf7..9f8fbbacf6c0 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -199,7 +199,7 @@ void i915_gem_context_free(struct kref *ctx_ref) kfree(ctx); } -static struct drm_i915_gem_object * +struct drm_i915_gem_object * i915_gem_alloc_context_obj(struct drm_device *dev, size_t size) { struct drm_i915_gem_object *obj; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 2d82d52d18bb..9f30ee80e487 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -41,6 +41,11 @@ #include #include "i915_drv.h" +#define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE) +#define GEN8_LR_CONTEXT_OTHER_SIZE (2 * PAGE_SIZE) + +#define GEN8_LR_CONTEXT_ALIGN 4096 + int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) { WARN_ON(i915.enable_ppgtt == -1); @@ -56,15 +61,65 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists void intel_lr_context_free(struct intel_context *ctx) { - /* TODO */ + int i; + + for (i = 0; i < I915_NUM_RINGS; i++) { + struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state; + if (ctx_obj) { + i915_gem_object_ggtt_unpin(ctx_obj); + drm_gem_object_unreference(&ctx_obj->base); + } + } +} + +static uint32_t get_lr_context_size(struct intel_engine_cs *ring) +{ + int ret = 0; + + WARN_ON(INTEL_INFO(ring->dev)->gen != 8); + + switch (ring->id) { + case RCS: + ret = GEN8_LR_CONTEXT_RENDER_SIZE; + break; + case VCS: + case BCS: + case VECS: + case VCS2: + ret = GEN8_LR_CONTEXT_OTHER_SIZE; + break; + } + + return ret; } int intel_lr_context_deferred_create(struct intel_context *ctx, struct intel_engine_cs *ring) { + struct drm_device *dev = ring->dev; + struct drm_i915_gem_object *ctx_obj; + uint32_t context_size; + int ret; + WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL); - /* TODO */ + context_size = round_up(get_lr_context_size(ring), 4096); + + ctx_obj = i915_gem_alloc_context_obj(dev, context_size); + if (IS_ERR(ctx_obj)) { + ret = PTR_ERR(ctx_obj); + DRM_DEBUG_DRIVER("Alloc LRC backing obj failed: %d\n", ret); + 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; + } + + ctx->engine[ring->id].state = ctx_obj; return 0; } -- GitLab From 84c2377fcee7a43cd964b62143e9a3714130bb0c Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:15 +0100 Subject: [PATCH 0194/9167] drm/i915/bdw: Allocate ringbuffers for Logical Ring Contexts As we have said a couple of times by now, logical ring contexts have their own ringbuffers: not only the backing pages, but the whole management struct. In a previous version of the series, this was achieved with two separate patches: drm/i915/bdw: Allocate ringbuffer backing objects for default global LRC drm/i915/bdw: Allocate ringbuffer for user-created LRCs Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 38 +++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 6 ++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cbae19bab4bf..eccb8e406e9c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -635,6 +635,7 @@ struct intel_context { /* Execlists */ struct { struct drm_i915_gem_object *state; + struct intel_ringbuffer *ringbuf; } engine[I915_NUM_RINGS]; struct list_head link; diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 9f30ee80e487..0c80bb1f5420 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -65,7 +65,11 @@ 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) { + intel_destroy_ringbuffer_obj(ringbuf); + kfree(ringbuf); i915_gem_object_ggtt_unpin(ctx_obj); drm_gem_object_unreference(&ctx_obj->base); } @@ -99,6 +103,7 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, struct drm_device *dev = ring->dev; struct drm_i915_gem_object *ctx_obj; uint32_t context_size; + struct intel_ringbuffer *ringbuf; int ret; WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL); @@ -119,6 +124,39 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, 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); + drm_gem_object_unreference(&ctx_obj->base); + ret = -ENOMEM; + return ret; + } + + ringbuf->size = 32 * PAGE_SIZE; + ringbuf->effective_size = ringbuf->size; + ringbuf->head = 0; + ringbuf->tail = 0; + 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", + ring->name, ret); + kfree(ringbuf); + i915_gem_object_ggtt_unpin(ctx_obj); + drm_gem_object_unreference(&ctx_obj->base); + return ret; + } + + ctx->engine[ring->id].ringbuf = ringbuf; ctx->engine[ring->id].state = ctx_obj; return 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a059b64a0fb2..064652034d7e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1519,7 +1519,7 @@ static int init_phys_status_page(struct intel_engine_cs *ring) return 0; } -static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) +void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) { if (!ringbuf->obj) return; @@ -1530,8 +1530,8 @@ static void intel_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf) ringbuf->obj = NULL; } -static int intel_alloc_ringbuffer_obj(struct drm_device *dev, - 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; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 70525d0c2c74..669cc7527f9a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -355,6 +355,10 @@ 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_destroy_ringbuffer_obj(struct intel_ringbuffer *ringbuf); +int intel_alloc_ringbuffer_obj(struct drm_device *dev, + struct intel_ringbuffer *ringbuf); + void intel_stop_ring_buffer(struct intel_engine_cs *ring); void intel_cleanup_ring_buffer(struct intel_engine_cs *ring); -- GitLab From 0c7dd53b84def4fbbba907bef3d32a5171b617a5 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Mon, 11 Aug 2014 16:17:44 +0200 Subject: [PATCH 0195/9167] drm/i915/bdw: Add a context and an engine pointers to the ringbuffer Any given ringbuffer is unequivocally tied to one context and one engine. By setting the appropriate pointers to them, the ringbuffer struct holds all the infromation you might need to submit a workload for processing, Execlists style. v2: Drop ring->ctx since that looks terribly ill-defined for legacy ringbuffer submission. Signed-off-by: Oscar Mateo (v1) Acked-by: Damien Lespiau (v2) Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 1 + drivers/gpu/drm/i915/intel_ringbuffer.h | 2 ++ 3 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 0c80bb1f5420..8f2d14da6228 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -134,6 +134,7 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, return ret; } + ringbuf->ring = ring; ringbuf->size = 32 * PAGE_SIZE; ringbuf->effective_size = ringbuf->size; ringbuf->head = 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 064652034d7e..c35f956ed6a0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1594,6 +1594,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, INIT_LIST_HEAD(&ring->active_list); INIT_LIST_HEAD(&ring->request_list); ringbuf->size = 32 * PAGE_SIZE; + ringbuf->ring = ring; memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno)); init_waitqueue_head(&ring->irq_queue); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 669cc7527f9a..fe9d9d9d3598 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -90,6 +90,8 @@ struct intel_ringbuffer { struct drm_i915_gem_object *obj; void __iomem *virtual_start; + struct intel_engine_cs *ring; + u32 head; u32 tail; int space; -- GitLab From 8670d6f97d8c19595950af1838f8458d7529825f Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:17 +0100 Subject: [PATCH 0196/9167] drm/i915/bdw: Populate LR contexts (somewhat) For the most part, logical ring context objects are similar to hardware contexts in that the backing object is meant to be opaque. There are some exceptions where we need to poke certain offsets of the object for initialization, updating the tail pointer or updating the PDPs. For our basic execlist implementation we'll only need our PPGTT PDs, and ringbuffer addresses in order to set up the context. With previous patches, we have both, so start prepping the context to be load. Before running a context for the first time you must populate some fields in the context object. These fields begin 1 PAGE + LRCA, ie. the first page (in 0 based counting) of the context image. These same fields will be read and written to as contexts are saved and restored once the system is up and running. Many of these fields are completely reused from previous global registers: ringbuffer head/tail/control, context control matches some previous MI_SET_CONTEXT flags, and page directories. There are other fields which we don't touch which we may want in the future. v2: CTX_LRI_HEADER_0 is MI_LOAD_REGISTER_IMM(14) for render and (11) for other engines. v3: Several rebases and general changes to the code. v4: Squash with "Extract LR context object populating" Also, Damien's review comments: - Set the Force Posted bit on the LRI header, as the BSpec suggest we do. - Prevent warning when compiling a 32-bits kernel without HIGHMEM64. - Add a clarifying comment to the context population code. v5: Damien's review comments: - The third MI_LOAD_REGISTER_IMM in the context does not set Force Posted. - Remove dead code. v6: Add a note about the (presumed) differences between BDW and CHV state contexts. Also, Brad's review comments: - Use the _MASKED_BIT_ENABLE, upper_32_bits and lower_32_bits macros. - Be less magical about how we set the ring size in the context. Signed-off-by: Ben Widawsky (v1) Signed-off-by: Rafael Barbalho (v2) Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 159 ++++++++++++++++++++++++++++++- 2 files changed, 156 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 7a6cc69cdc2b..c1d24242a02d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -282,6 +282,7 @@ * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! */ #define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*(x)-1) +#define MI_LRI_FORCE_POSTED (1<<12) #define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*(x)-1) #define MI_STORE_REGISTER_MEM_GEN8(x) MI_INSTR(0x24, 3*(x)-1) #define MI_SRM_LRM_GLOBAL_GTT (1<<22) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8f2d14da6228..a7a08a85edb3 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -46,6 +46,38 @@ #define GEN8_LR_CONTEXT_ALIGN 4096 +#define RING_ELSP(ring) ((ring)->mmio_base+0x230) +#define RING_CONTEXT_CONTROL(ring) ((ring)->mmio_base+0x244) + +#define CTX_LRI_HEADER_0 0x01 +#define CTX_CONTEXT_CONTROL 0x02 +#define CTX_RING_HEAD 0x04 +#define CTX_RING_TAIL 0x06 +#define CTX_RING_BUFFER_START 0x08 +#define CTX_RING_BUFFER_CONTROL 0x0a +#define CTX_BB_HEAD_U 0x0c +#define CTX_BB_HEAD_L 0x0e +#define CTX_BB_STATE 0x10 +#define CTX_SECOND_BB_HEAD_U 0x12 +#define CTX_SECOND_BB_HEAD_L 0x14 +#define CTX_SECOND_BB_STATE 0x16 +#define CTX_BB_PER_CTX_PTR 0x18 +#define CTX_RCS_INDIRECT_CTX 0x1a +#define CTX_RCS_INDIRECT_CTX_OFFSET 0x1c +#define CTX_LRI_HEADER_1 0x21 +#define CTX_CTX_TIMESTAMP 0x22 +#define CTX_PDP3_UDW 0x24 +#define CTX_PDP3_LDW 0x26 +#define CTX_PDP2_UDW 0x28 +#define CTX_PDP2_LDW 0x2a +#define CTX_PDP1_UDW 0x2c +#define CTX_PDP1_LDW 0x2e +#define CTX_PDP0_UDW 0x30 +#define CTX_PDP0_LDW 0x32 +#define CTX_LRI_HEADER_2 0x41 +#define CTX_R_PWR_CLK_STATE 0x42 +#define CTX_GPGPU_CSR_BASE_ADDRESS 0x44 + int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) { WARN_ON(i915.enable_ppgtt == -1); @@ -59,6 +91,115 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +static int +populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_obj, + struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf) +{ + struct drm_i915_gem_object *ring_obj = ringbuf->obj; + struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(ctx); + struct page *page; + uint32_t *reg_state; + int ret; + + ret = i915_gem_object_set_to_cpu_domain(ctx_obj, true); + if (ret) { + DRM_DEBUG_DRIVER("Could not set to CPU domain\n"); + return ret; + } + + ret = i915_gem_object_get_pages(ctx_obj); + if (ret) { + DRM_DEBUG_DRIVER("Could not get object pages\n"); + return ret; + } + + i915_gem_object_pin_pages(ctx_obj); + + /* The second page of the context object contains some fields which must + * be set up prior to the first execution. */ + page = i915_gem_object_get_page(ctx_obj, 1); + reg_state = kmap_atomic(page); + + /* A context is actually a big batch buffer with several MI_LOAD_REGISTER_IMM + * commands followed by (reg, value) pairs. The values we are setting here are + * only for the first context restore: on a subsequent save, the GPU will + * recreate this batchbuffer with new values (including all the missing + * MI_LOAD_REGISTER_IMM commands that we are not initializing here). */ + if (ring->id == RCS) + reg_state[CTX_LRI_HEADER_0] = MI_LOAD_REGISTER_IMM(14); + else + reg_state[CTX_LRI_HEADER_0] = MI_LOAD_REGISTER_IMM(11); + reg_state[CTX_LRI_HEADER_0] |= MI_LRI_FORCE_POSTED; + reg_state[CTX_CONTEXT_CONTROL] = RING_CONTEXT_CONTROL(ring); + reg_state[CTX_CONTEXT_CONTROL+1] = + _MASKED_BIT_ENABLE((1<<3) | MI_RESTORE_INHIBIT); + reg_state[CTX_RING_HEAD] = RING_HEAD(ring->mmio_base); + reg_state[CTX_RING_HEAD+1] = 0; + 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); + 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; + reg_state[CTX_BB_HEAD_U] = ring->mmio_base + 0x168; + reg_state[CTX_BB_HEAD_U+1] = 0; + reg_state[CTX_BB_HEAD_L] = ring->mmio_base + 0x140; + reg_state[CTX_BB_HEAD_L+1] = 0; + reg_state[CTX_BB_STATE] = ring->mmio_base + 0x110; + reg_state[CTX_BB_STATE+1] = (1<<5); + reg_state[CTX_SECOND_BB_HEAD_U] = ring->mmio_base + 0x11c; + reg_state[CTX_SECOND_BB_HEAD_U+1] = 0; + reg_state[CTX_SECOND_BB_HEAD_L] = ring->mmio_base + 0x114; + reg_state[CTX_SECOND_BB_HEAD_L+1] = 0; + reg_state[CTX_SECOND_BB_STATE] = ring->mmio_base + 0x118; + reg_state[CTX_SECOND_BB_STATE+1] = 0; + if (ring->id == RCS) { + /* TODO: according to BSpec, the register state context + * for CHV does not have these. OTOH, these registers do + * exist in CHV. I'm waiting for a clarification */ + reg_state[CTX_BB_PER_CTX_PTR] = ring->mmio_base + 0x1c0; + reg_state[CTX_BB_PER_CTX_PTR+1] = 0; + reg_state[CTX_RCS_INDIRECT_CTX] = ring->mmio_base + 0x1c4; + reg_state[CTX_RCS_INDIRECT_CTX+1] = 0; + reg_state[CTX_RCS_INDIRECT_CTX_OFFSET] = ring->mmio_base + 0x1c8; + reg_state[CTX_RCS_INDIRECT_CTX_OFFSET+1] = 0; + } + reg_state[CTX_LRI_HEADER_1] = MI_LOAD_REGISTER_IMM(9); + reg_state[CTX_LRI_HEADER_1] |= MI_LRI_FORCE_POSTED; + reg_state[CTX_CTX_TIMESTAMP] = ring->mmio_base + 0x3a8; + reg_state[CTX_CTX_TIMESTAMP+1] = 0; + reg_state[CTX_PDP3_UDW] = GEN8_RING_PDP_UDW(ring, 3); + reg_state[CTX_PDP3_LDW] = GEN8_RING_PDP_LDW(ring, 3); + reg_state[CTX_PDP2_UDW] = GEN8_RING_PDP_UDW(ring, 2); + reg_state[CTX_PDP2_LDW] = GEN8_RING_PDP_LDW(ring, 2); + reg_state[CTX_PDP1_UDW] = GEN8_RING_PDP_UDW(ring, 1); + reg_state[CTX_PDP1_LDW] = GEN8_RING_PDP_LDW(ring, 1); + reg_state[CTX_PDP0_UDW] = GEN8_RING_PDP_UDW(ring, 0); + reg_state[CTX_PDP0_LDW] = GEN8_RING_PDP_LDW(ring, 0); + reg_state[CTX_PDP3_UDW+1] = upper_32_bits(ppgtt->pd_dma_addr[3]); + reg_state[CTX_PDP3_LDW+1] = lower_32_bits(ppgtt->pd_dma_addr[3]); + reg_state[CTX_PDP2_UDW+1] = upper_32_bits(ppgtt->pd_dma_addr[2]); + reg_state[CTX_PDP2_LDW+1] = lower_32_bits(ppgtt->pd_dma_addr[2]); + reg_state[CTX_PDP1_UDW+1] = upper_32_bits(ppgtt->pd_dma_addr[1]); + reg_state[CTX_PDP1_LDW+1] = lower_32_bits(ppgtt->pd_dma_addr[1]); + reg_state[CTX_PDP0_UDW+1] = upper_32_bits(ppgtt->pd_dma_addr[0]); + reg_state[CTX_PDP0_LDW+1] = lower_32_bits(ppgtt->pd_dma_addr[0]); + if (ring->id == RCS) { + reg_state[CTX_LRI_HEADER_2] = MI_LOAD_REGISTER_IMM(1); + reg_state[CTX_R_PWR_CLK_STATE] = 0x20c8; + reg_state[CTX_R_PWR_CLK_STATE+1] = 0; + } + + kunmap_atomic(reg_state); + + ctx_obj->dirty = 1; + set_page_dirty(page); + i915_gem_object_unpin_pages(ctx_obj); + + return 0; +} + void intel_lr_context_free(struct intel_context *ctx) { int i; @@ -151,14 +292,24 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, if (ret) { DRM_DEBUG_DRIVER("Failed to allocate ringbuffer obj %s: %d\n", ring->name, ret); - kfree(ringbuf); - i915_gem_object_ggtt_unpin(ctx_obj); - drm_gem_object_unreference(&ctx_obj->base); - return ret; + goto error; + } + + 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; } ctx->engine[ring->id].ringbuf = ringbuf; ctx->engine[ring->id].state = ctx_obj; return 0; + +error: + kfree(ringbuf); + i915_gem_object_ggtt_unpin(ctx_obj); + drm_gem_object_unreference(&ctx_obj->base); + return ret; } -- GitLab From ec3e9963a681789860e5c0120a745b717d942392 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:18 +0100 Subject: [PATCH 0197/9167] drm/i915/bdw: Deferred creation of user-created LRCs The backing objects and ringbuffers for contexts created via open fd are actually empty until the user starts sending execbuffers to them. At that point, we allocate & populate them. We do this because, at create time, we really don't know which engine is going to be used with the context later on (and we don't want to waste memory on objects that we might never use). v2: As contexts created via ioctl can only be used with the render ring, we have enough information to allocate & populate them right away. v3: Defer the creation always, even with ioctl-created contexts, as requested by Daniel Vetter. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_context.c | 7 +++---- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 8 ++++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 9f8fbbacf6c0..bcb41002aa13 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -782,9 +782,9 @@ int i915_switch_context(struct intel_engine_cs *ring, return do_switch(ring, to); } -static bool hw_context_enabled(struct drm_device *dev) +static bool contexts_enabled(struct drm_device *dev) { - return to_i915(dev)->hw_context_size; + return i915.enable_execlists || to_i915(dev)->hw_context_size; } int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, @@ -795,8 +795,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, struct intel_context *ctx; int ret; - /* FIXME: allow user-created LR contexts as well */ - if (!hw_context_enabled(dev)) + if (!contexts_enabled(dev)) return -ENODEV; ret = i915_mutex_lock_interruptible(dev); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index dec2cc2fbd42..29cb2156d32b 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -931,6 +931,14 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, return ERR_PTR(-EIO); } + if (i915.enable_execlists && !ctx->engine[ring->id].state) { + int ret = intel_lr_context_deferred_create(ctx, ring); + if (ret) { + DRM_DEBUG("Could not create LRC %u: %d\n", ctx_id, ret); + return ERR_PTR(ret); + } + } + return ctx; } -- GitLab From a83014d3f8b936778a9bc9b3d4137769bb26d9eb Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:21 +0100 Subject: [PATCH 0198/9167] drm/i915: Abstract the legacy workload submission mechanism away As suggested by Daniel Vetter. The idea, in subsequent patches, is to provide an alternative to these vfuncs for the Execlists submission mechanism. v2: Splitted into two and reordered to illustrate our intentions, instead of showing it off. Also, remove the add_request vfunc and added the stop_ring one. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: - Make checkpatch happy. - Be grumpy about the excessive vtable. - Ditch gt->is_ring_initialized.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 23 ++++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem.c | 15 ++++++++++---- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 20 +++++++++---------- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index eccb8e406e9c..9198f1c96470 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1645,6 +1645,20 @@ struct drm_i915_private { /* 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, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags); + int (*init_rings)(struct drm_device *dev); + void (*cleanup_ring)(struct intel_engine_cs *ring); + void (*stop_ring)(struct intel_engine_cs *ring); + } gt; + /* * NOTE: This is the dri1/ums dungeon, don't add stuff here. Your patch * will be rejected. Instead look for a better place. @@ -2252,6 +2266,14 @@ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +int i915_gem_ringbuffer_submission(struct drm_device *dev, + struct drm_file *file, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags); int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_execbuffer2(struct drm_device *dev, void *data, @@ -2404,6 +2426,7 @@ void i915_gem_reset(struct drm_device *dev); bool i915_gem_clflush_object(struct drm_i915_gem_object *obj, bool force); int __must_check i915_gem_object_finish_gpu(struct drm_i915_gem_object *obj); int __must_check i915_gem_init(struct drm_device *dev); +int i915_gem_init_rings(struct drm_device *dev); int __must_check i915_gem_init_hw(struct drm_device *dev); int i915_gem_l3_remap(struct intel_engine_cs *ring, int slice); void i915_gem_init_swizzling(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5646e9ba6383..33a54cbf9a2e 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4495,7 +4495,7 @@ i915_gem_stop_ringbuffers(struct drm_device *dev) int i; for_each_ring(ring, dev_priv, i) - intel_stop_ring_buffer(ring); + dev_priv->gt.stop_ring(ring); } int @@ -4612,7 +4612,7 @@ intel_enable_blt(struct drm_device *dev) return true; } -static int i915_gem_init_rings(struct drm_device *dev) +int i915_gem_init_rings(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -4695,7 +4695,7 @@ i915_gem_init_hw(struct drm_device *dev) i915_gem_init_swizzling(dev); - ret = i915_gem_init_rings(dev); + ret = dev_priv->gt.init_rings(dev); if (ret) return ret; @@ -4736,6 +4736,13 @@ int i915_gem_init(struct drm_device *dev) DRM_DEBUG_DRIVER("allow wake ack timed out\n"); } + if (!i915.enable_execlists) { + dev_priv->gt.do_execbuf = i915_gem_ringbuffer_submission; + dev_priv->gt.init_rings = i915_gem_init_rings; + dev_priv->gt.cleanup_ring = intel_cleanup_ring_buffer; + dev_priv->gt.stop_ring = intel_stop_ring_buffer; + } + i915_gem_init_userptr(dev); i915_gem_init_global_gtt(dev); @@ -4771,7 +4778,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) int i; for_each_ring(ring, dev_priv, i) - intel_cleanup_ring_buffer(ring); + dev_priv->gt.cleanup_ring(ring); } int diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 29cb2156d32b..26b38b3ae4f3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1023,14 +1023,14 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev, return 0; } -static int -legacy_ringbuffer_submission(struct drm_device *dev, struct drm_file *file, - struct intel_engine_cs *ring, - struct intel_context *ctx, - struct drm_i915_gem_execbuffer2 *args, - struct list_head *vmas, - struct drm_i915_gem_object *batch_obj, - u64 exec_start, u32 flags) +int +i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags) { struct drm_clip_rect *cliprects = NULL; struct drm_i915_private *dev_priv = dev->dev_private; @@ -1402,8 +1402,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } else exec_start += i915_gem_obj_offset(batch_obj, vm); - ret = legacy_ringbuffer_submission(dev, file, ring, ctx, - args, &eb->vmas, batch_obj, exec_start, flags); + ret = dev_priv->gt.do_execbuf(dev, file, ring, ctx, args, + &eb->vmas, batch_obj, exec_start, flags); /* * FIXME: We crucially rely upon the active tracking for the (ppgtt) -- GitLab From 454afebde873874b939465bfc1a294ac3697c96e Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:22 +0100 Subject: [PATCH 0199/9167] drm/i915/bdw: Skeleton for the new logical rings submission path Execlists are indeed a brave new world with respect to workload submission to the GPU. In previous version of these series, I have tried to impact the legacy ringbuffer submission path as little as possible (mostly, passing the context around and using the correct ringbuffer when I needed one) but Daniel is afraid (probably with a reason) that these changes and, especially, future ones, will end up breaking older gens. This commit and some others coming next will try to limit the damage by creating an alternative path for workload submission. The first step is here: laying out a new ring init/fini. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 5 + drivers/gpu/drm/i915/intel_lrc.c | 151 +++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.h | 12 +++ 3 files changed, 168 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 33a54cbf9a2e..9acb2469116a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4741,6 +4741,11 @@ int i915_gem_init(struct drm_device *dev) dev_priv->gt.init_rings = i915_gem_init_rings; dev_priv->gt.cleanup_ring = intel_cleanup_ring_buffer; dev_priv->gt.stop_ring = intel_stop_ring_buffer; + } else { + dev_priv->gt.do_execbuf = intel_execlists_submission; + dev_priv->gt.init_rings = intel_logical_rings_init; + dev_priv->gt.cleanup_ring = intel_logical_ring_cleanup; + dev_priv->gt.stop_ring = intel_logical_ring_stop; } i915_gem_init_userptr(dev); diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index a7a08a85edb3..9c2ff8f11c90 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -91,6 +91,157 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags) +{ + /* TODO */ + return 0; +} + +void intel_logical_ring_stop(struct intel_engine_cs *ring) +{ + /* TODO */ +} + +void intel_logical_ring_cleanup(struct intel_engine_cs *ring) +{ + /* TODO */ +} + +static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) +{ + /* TODO */ + return 0; +} + +static int logical_render_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring = &dev_priv->ring[RCS]; + + ring->name = "render ring"; + ring->id = RCS; + ring->mmio_base = RENDER_RING_BASE; + ring->irq_enable_mask = + GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +static int logical_bsd_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring = &dev_priv->ring[VCS]; + + ring->name = "bsd ring"; + ring->id = VCS; + ring->mmio_base = GEN6_BSD_RING_BASE; + ring->irq_enable_mask = + GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +static int logical_bsd2_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring = &dev_priv->ring[VCS2]; + + ring->name = "bds2 ring"; + ring->id = VCS2; + ring->mmio_base = GEN8_BSD2_RING_BASE; + ring->irq_enable_mask = + GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +static int logical_blt_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring = &dev_priv->ring[BCS]; + + ring->name = "blitter ring"; + ring->id = BCS; + ring->mmio_base = BLT_RING_BASE; + ring->irq_enable_mask = + GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +static int logical_vebox_ring_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring = &dev_priv->ring[VECS]; + + ring->name = "video enhancement ring"; + ring->id = VECS; + ring->mmio_base = VEBOX_RING_BASE; + ring->irq_enable_mask = + GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; + + return logical_ring_init(dev, ring); +} + +int intel_logical_rings_init(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + ret = logical_render_ring_init(dev); + if (ret) + return ret; + + if (HAS_BSD(dev)) { + ret = logical_bsd_ring_init(dev); + if (ret) + goto cleanup_render_ring; + } + + if (HAS_BLT(dev)) { + ret = logical_blt_ring_init(dev); + if (ret) + goto cleanup_bsd_ring; + } + + if (HAS_VEBOX(dev)) { + ret = logical_vebox_ring_init(dev); + if (ret) + goto cleanup_blt_ring; + } + + if (HAS_BSD2(dev)) { + ret = logical_bsd2_ring_init(dev); + if (ret) + goto cleanup_vebox_ring; + } + + ret = i915_gem_set_seqno(dev, ((u32)~0 - 0x1000)); + if (ret) + goto cleanup_bsd2_ring; + + return 0; + +cleanup_bsd2_ring: + intel_logical_ring_cleanup(&dev_priv->ring[VCS2]); +cleanup_vebox_ring: + intel_logical_ring_cleanup(&dev_priv->ring[VECS]); +cleanup_blt_ring: + intel_logical_ring_cleanup(&dev_priv->ring[BCS]); +cleanup_bsd_ring: + intel_logical_ring_cleanup(&dev_priv->ring[VCS]); +cleanup_render_ring: + intel_logical_ring_cleanup(&dev_priv->ring[RCS]); + + return ret; +} + static int populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_obj, struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf) diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 3b93572431e3..bf0eff4e9f08 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -24,6 +24,11 @@ #ifndef _INTEL_LRC_H_ #define _INTEL_LRC_H_ +/* Logical Rings */ +void intel_logical_ring_stop(struct intel_engine_cs *ring); +void intel_logical_ring_cleanup(struct intel_engine_cs *ring); +int intel_logical_rings_init(struct drm_device *dev); + /* Logical Ring Contexts */ void intel_lr_context_free(struct intel_context *ctx); int intel_lr_context_deferred_create(struct intel_context *ctx, @@ -31,5 +36,12 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, /* Execlists */ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists); +int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags); #endif /* _INTEL_LRC_H_ */ -- GitLab From 48d823878d64f93163f5a949623346748bbce1b4 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:23 +0100 Subject: [PATCH 0200/9167] drm/i915/bdw: Generic logical ring init and cleanup Allocate and populate the default LRC for every ring, call gen-specific init/cleanup, init/fini the command parser and set the status page (now inside the LRC object). These are things all engines/rings have in common. Stopping the ring before cleanup and initializing the seqnos is left as a TODO task (we need more infrastructure in place before we can achieve this). v2: Check the ringbuffer backing obj for ring_is_initialized, instead of the context backing obj (similar, but not exactly the same). Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_context.c | 4 -- drivers/gpu/drm/i915/intel_lrc.c | 54 ++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_ringbuffer.c | 17 ++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 6 +-- 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index bcb41002aa13..7a08f3e9e1ae 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -445,10 +445,6 @@ int i915_gem_context_init(struct drm_device *dev) /* NB: RCS will hold a ref for all rings */ ring->default_context = ctx; - - /* FIXME: we really only want to do this for initialized rings */ - if (i915.enable_execlists) - intel_lr_context_deferred_create(ctx, ring); } DRM_DEBUG_DRIVER("%s context support initialized\n", diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 9c2ff8f11c90..ed7a4ff3bbd2 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -110,12 +110,60 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring) void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { - /* TODO */ + if (!intel_ring_initialized(ring)) + return; + + /* TODO: make sure the ring is stopped */ + ring->preallocated_lazy_request = NULL; + ring->outstanding_lazy_seqno = 0; + + if (ring->cleanup) + ring->cleanup(ring); + + i915_cmd_parser_fini_ring(ring); + + if (ring->status_page.obj) { + kunmap(sg_page(ring->status_page.obj->pages->sgl)); + ring->status_page.obj = NULL; + } } static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *ring) { - /* TODO */ + int ret; + struct intel_context *dctx = ring->default_context; + struct drm_i915_gem_object *dctx_obj; + + /* Intentionally left blank. */ + ring->buffer = NULL; + + ring->dev = dev; + INIT_LIST_HEAD(&ring->active_list); + INIT_LIST_HEAD(&ring->request_list); + init_waitqueue_head(&ring->irq_queue); + + ret = intel_lr_context_deferred_create(dctx, ring); + if (ret) + return ret; + + /* The status page is offset 0 from the context object in LRCs. */ + dctx_obj = dctx->engine[ring->id].state; + ring->status_page.gfx_addr = i915_gem_obj_ggtt_offset(dctx_obj); + ring->status_page.page_addr = kmap(sg_page(dctx_obj->pages->sgl)); + if (ring->status_page.page_addr == NULL) + return -ENOMEM; + ring->status_page.obj = dctx_obj; + + ret = i915_cmd_parser_init_ring(ring); + if (ret) + return ret; + + if (ring->init) { + ret = ring->init(ring); + if (ret) + return ret; + } + return 0; } @@ -399,6 +447,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, int ret; WARN_ON(ctx->legacy_hw_ctx.rcs_state != NULL); + if (ctx->engine[ring->id].state) + return 0; context_size = round_up(get_lr_context_size(ring), 4096); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index c35f956ed6a0..e4b97f5c5797 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -40,6 +40,23 @@ */ #define CACHELINE_BYTES 64 +bool +intel_ring_initialized(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + + if (!dev) + return false; + + if (i915.enable_execlists) { + struct intel_context *dctx = ring->default_context; + struct intel_ringbuffer *ringbuf = dctx->engine[ring->id].ringbuf; + + return ringbuf->obj; + } else + return ring->buffer && ring->buffer->obj; +} + static inline int __ring_space(int head, int tail, int size) { int space = head - (tail + I915_RING_FREE_SPACE); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index fe9d9d9d3598..fbe54ef6a9a1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -289,11 +289,7 @@ struct intel_engine_cs { u32 (*get_cmd_length_mask)(u32 cmd_header); }; -static inline bool -intel_ring_initialized(struct intel_engine_cs *ring) -{ - return ring->buffer && ring->buffer->obj; -} +bool intel_ring_initialized(struct intel_engine_cs *ring); static inline unsigned intel_ring_flag(struct intel_engine_cs *ring) -- GitLab From 9b1136d505b1de5478e11b59ca59cf8ce2a33217 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:24 +0100 Subject: [PATCH 0201/9167] drm/i915/bdw: GEN-specific logical ring init Logical rings do not need most of the initialization their legacy ringbuffer counterparts do: we just need the pipe control object for the render ring, enable Execlists on the hardware and a few workarounds. v2: Squash with: "drm/i915: Extract pipe control fini & make init outside accesible". Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Make checkpatch happy.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 54 +++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 34 ++++++++++------ drivers/gpu/drm/i915/intel_ringbuffer.h | 3 ++ 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index ed7a4ff3bbd2..1a1f5f98f05b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -108,6 +108,49 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring) /* TODO */ } +static int gen8_init_common_ring(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(RING_MODE_GEN7(ring), + _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) | + _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)); + POSTING_READ(RING_MODE_GEN7(ring)); + DRM_DEBUG_DRIVER("Execlists enabled for %s\n", ring->name); + + memset(&ring->hangcheck, 0, sizeof(ring->hangcheck)); + + return 0; +} + +static int gen8_init_render_ring(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + ret = gen8_init_common_ring(ring); + if (ret) + return ret; + + /* We need to disable the AsyncFlip performance optimisations in order + * to use MI_WAIT_FOR_EVENT within the CS. It should already be + * programmed to '1' on all products. + * + * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv,bdw,chv + */ + I915_WRITE(MI_MODE, _MASKED_BIT_ENABLE(ASYNC_FLIP_PERF_DISABLE)); + + ret = intel_init_pipe_control(ring); + if (ret) + return ret; + + I915_WRITE(INSTPM, _MASKED_BIT_ENABLE(INSTPM_FORCE_ORDERING)); + + return ret; +} + void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { if (!intel_ring_initialized(ring)) @@ -178,6 +221,9 @@ static int logical_render_ring_init(struct drm_device *dev) ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT; + ring->init = gen8_init_render_ring; + ring->cleanup = intel_fini_pipe_control; + return logical_ring_init(dev, ring); } @@ -192,6 +238,8 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; + ring->init = gen8_init_common_ring; + return logical_ring_init(dev, ring); } @@ -206,6 +254,8 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; + ring->init = gen8_init_common_ring; + return logical_ring_init(dev, ring); } @@ -220,6 +270,8 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; + ring->init = gen8_init_common_ring; + return logical_ring_init(dev, ring); } @@ -234,6 +286,8 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; + ring->init = gen8_init_common_ring; + return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e4b97f5c5797..dab5e7c79036 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -597,8 +597,25 @@ static int init_ring_common(struct intel_engine_cs *ring) return ret; } -static int -init_pipe_control(struct intel_engine_cs *ring) +void +intel_fini_pipe_control(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + + if (ring->scratch.obj == NULL) + return; + + if (INTEL_INFO(dev)->gen >= 5) { + kunmap(sg_page(ring->scratch.obj->pages->sgl)); + i915_gem_object_ggtt_unpin(ring->scratch.obj); + } + + drm_gem_object_unreference(&ring->scratch.obj->base); + ring->scratch.obj = NULL; +} + +int +intel_init_pipe_control(struct intel_engine_cs *ring) { int ret; @@ -673,7 +690,7 @@ static int init_render_ring(struct intel_engine_cs *ring) _MASKED_BIT_ENABLE(GFX_REPLAY_MODE)); if (INTEL_INFO(dev)->gen >= 5) { - ret = init_pipe_control(ring); + ret = intel_init_pipe_control(ring); if (ret) return ret; } @@ -708,16 +725,7 @@ static void render_ring_cleanup(struct intel_engine_cs *ring) dev_priv->semaphore_obj = NULL; } - if (ring->scratch.obj == NULL) - return; - - if (INTEL_INFO(dev)->gen >= 5) { - kunmap(sg_page(ring->scratch.obj->pages->sgl)); - i915_gem_object_ggtt_unpin(ring->scratch.obj); - } - - drm_gem_object_unreference(&ring->scratch.obj->base); - ring->scratch.obj = NULL; + intel_fini_pipe_control(ring); } static int gen8_rcs_signal(struct intel_engine_cs *signaller, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index fbe54ef6a9a1..677df0d7be48 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -381,6 +381,9 @@ void intel_ring_init_seqno(struct intel_engine_cs *ring, u32 seqno); int intel_ring_flush_all_caches(struct intel_engine_cs *ring); int intel_ring_invalidate_all_caches(struct intel_engine_cs *ring); +void intel_fini_pipe_control(struct intel_engine_cs *ring); +int intel_init_pipe_control(struct intel_engine_cs *ring); + int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev); int intel_init_bsd2_ring_buffer(struct drm_device *dev); -- GitLab From f72a113a71ab08c4df8a5f80ab2f8a140feb81f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 7 Aug 2014 09:36:00 +0200 Subject: [PATCH 0202/9167] drm/radeon: add userptr support v8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds an IOCTL for turning a pointer supplied by userspace into a buffer object. It imposes several restrictions upon the memory being mapped: 1. It must be page aligned (both start/end addresses, i.e ptr and size). 2. It must be normal system memory, not a pointer into another map of IO space (e.g. it must not be a GTT mmapping of another object). 3. The BO is mapped into GTT, so the maximum amount of memory mapped at all times is still the GTT limit. 4. The BO is only mapped readonly for now, so no write support. 5. List of backing pages is only acquired once, so they represent a snapshot of the first use. Exporting and sharing as well as mapping of buffer objects created by this function is forbidden and results in an -EPERM. v2: squash all previous changes into first public version v3: fix tabs, map readonly, don't use MM callback any more v4: set TTM_PAGE_FLAG_SG so that TTM never messes with the pages, pin/unpin pages on bind/unbind instead of populate/unpopulate v5: rebased on 3.17-wip, IOCTL renamed to userptr, reject any unknown flags, better handle READONLY flag, improve permission check v6: fix ptr cast warning, use set_page_dirty/mark_page_accessed on unpin v7: add warning about it's availability in the API definition v8: drop access_ok check, fix VM mapping bits Signed-off-by: Christian König Reviewed-by: Alex Deucher (v4) Reviewed-by: Jérôme Glisse (v4) Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon.h | 6 + drivers/gpu/drm/radeon/radeon_cs.c | 25 ++++- drivers/gpu/drm/radeon/radeon_drv.c | 5 +- drivers/gpu/drm/radeon/radeon_gem.c | 68 ++++++++++++ drivers/gpu/drm/radeon/radeon_kms.c | 1 + drivers/gpu/drm/radeon/radeon_object.c | 3 + drivers/gpu/drm/radeon/radeon_prime.c | 10 ++ drivers/gpu/drm/radeon/radeon_ttm.c | 145 +++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_vm.c | 3 + include/uapi/drm/radeon_drm.h | 16 +++ 10 files changed, 279 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 9e1732eb402c..6f38a23a5810 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -2138,6 +2138,8 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int radeon_gem_create_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); +int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp); int radeon_gem_pin_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int radeon_gem_unpin_ioctl(struct drm_device *dev, void *data, @@ -2871,6 +2873,10 @@ extern void radeon_legacy_set_clock_gating(struct radeon_device *rdev, int enabl extern void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); extern void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain); extern bool radeon_ttm_bo_is_radeon_bo(struct ttm_buffer_object *bo); +extern int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, + uint32_t flags); +extern bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm); +extern bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm); extern void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 base); extern void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); extern int radeon_resume_kms(struct drm_device *dev, bool resume, bool fbcon); diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index ee712c199b25..1321491cf499 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -78,7 +78,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) struct radeon_cs_chunk *chunk; struct radeon_cs_buckets buckets; unsigned i, j; - bool duplicate; + bool duplicate, need_mmap_lock = false; + int r; if (p->chunk_relocs_idx == -1) { return 0; @@ -164,6 +165,19 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) p->relocs[i].allowed_domains = domain; } + if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) { + uint32_t domain = p->relocs[i].prefered_domains; + if (!(domain & RADEON_GEM_DOMAIN_GTT)) { + DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is " + "allowed for userptr BOs\n"); + return -EINVAL; + } + need_mmap_lock = true; + domain = RADEON_GEM_DOMAIN_GTT; + p->relocs[i].prefered_domains = domain; + p->relocs[i].allowed_domains = domain; + } + p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; p->relocs[i].handle = r->handle; @@ -176,8 +190,15 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) if (p->cs_flags & RADEON_CS_USE_VM) p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm, &p->validated); + if (need_mmap_lock) + down_read(¤t->mm->mmap_sem); + + r = radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring); - return radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring); + if (need_mmap_lock) + up_read(¤t->mm->mmap_sem); + + return r; } static int radeon_cs_get_ring(struct radeon_cs_parser *p, u32 ring, s32 priority) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a773830c6c40..5b18af926527 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -114,6 +114,9 @@ int radeon_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv); void radeon_gem_object_close(struct drm_gem_object *obj, struct drm_file *file_priv); +struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *gobj, + int flags); extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, unsigned int flags, int *vpos, int *hpos, ktime_t *stime, @@ -568,7 +571,7 @@ static struct drm_driver kms_driver = { .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - .gem_prime_export = drm_gem_prime_export, + .gem_prime_export = radeon_gem_prime_export, .gem_prime_import = drm_gem_prime_import, .gem_prime_pin = radeon_gem_prime_pin, .gem_prime_unpin = radeon_gem_prime_unpin, diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index bfd7e1b0ff3f..993ab223b503 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -272,6 +272,65 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data, return 0; } +int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data, + struct drm_file *filp) +{ + struct radeon_device *rdev = dev->dev_private; + struct drm_radeon_gem_userptr *args = data; + struct drm_gem_object *gobj; + struct radeon_bo *bo; + uint32_t handle; + int r; + + if (offset_in_page(args->addr | args->size)) + return -EINVAL; + + /* we only support read only mappings for now */ + if (!(args->flags & RADEON_GEM_USERPTR_READONLY)) + return -EACCES; + + /* reject unknown flag values */ + if (args->flags & ~RADEON_GEM_USERPTR_READONLY) + return -EINVAL; + + /* readonly pages not tested on older hardware */ + if (rdev->family < CHIP_R600) + return -EINVAL; + + down_read(&rdev->exclusive_lock); + + /* create a gem object to contain this object in */ + r = radeon_gem_object_create(rdev, args->size, 0, + RADEON_GEM_DOMAIN_CPU, 0, + false, &gobj); + if (r) + goto handle_lockup; + + bo = gem_to_radeon_bo(gobj); + r = radeon_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags); + if (r) + goto release_object; + + r = drm_gem_handle_create(filp, gobj, &handle); + /* drop reference from allocate - handle holds it now */ + drm_gem_object_unreference_unlocked(gobj); + if (r) + goto handle_lockup; + + args->handle = handle; + up_read(&rdev->exclusive_lock); + return 0; + +release_object: + drm_gem_object_unreference_unlocked(gobj); + +handle_lockup: + up_read(&rdev->exclusive_lock); + r = radeon_gem_handle_lockup(rdev, r); + + return r; +} + int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { @@ -315,6 +374,10 @@ int radeon_mode_dumb_mmap(struct drm_file *filp, return -ENOENT; } robj = gem_to_radeon_bo(gobj); + if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) { + drm_gem_object_unreference_unlocked(gobj); + return -EPERM; + } *offset_p = radeon_bo_mmap_offset(robj); drm_gem_object_unreference_unlocked(gobj); return 0; @@ -532,6 +595,11 @@ int radeon_gem_op_ioctl(struct drm_device *dev, void *data, return -ENOENT; } robj = gem_to_radeon_bo(gobj); + + r = -EPERM; + if (radeon_ttm_tt_has_userptr(robj->tbo.ttm)) + goto out; + r = radeon_bo_reserve(robj, false); if (unlikely(r)) goto out; diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index eb7164d07985..8309b11e674d 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -885,5 +885,6 @@ const struct drm_ioctl_desc radeon_ioctls_kms[] = { DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(RADEON_GEM_VA, radeon_gem_va_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(RADEON_GEM_OP, radeon_gem_op_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(RADEON_GEM_USERPTR, radeon_gem_userptr_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), }; int radeon_max_kms_ioctl = ARRAY_SIZE(radeon_ioctls_kms); diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 480c87d8edc5..c73c1e320585 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -264,6 +264,9 @@ int radeon_bo_pin_restricted(struct radeon_bo *bo, u32 domain, u64 max_offset, { int r, i; + if (radeon_ttm_tt_has_userptr(bo->tbo.ttm)) + return -EPERM; + if (bo->pin_count) { bo->pin_count++; if (gpu_addr) diff --git a/drivers/gpu/drm/radeon/radeon_prime.c b/drivers/gpu/drm/radeon/radeon_prime.c index f7e48d329db3..bb18bc74b7d7 100644 --- a/drivers/gpu/drm/radeon/radeon_prime.c +++ b/drivers/gpu/drm/radeon/radeon_prime.c @@ -103,3 +103,13 @@ void radeon_gem_prime_unpin(struct drm_gem_object *obj) radeon_bo_unpin(bo); radeon_bo_unreserve(bo); } + +struct dma_buf *radeon_gem_prime_export(struct drm_device *dev, + struct drm_gem_object *gobj, + int flags) +{ + struct radeon_bo *bo = gem_to_radeon_bo(gobj); + if (radeon_ttm_tt_has_userptr(bo->tbo.ttm)) + return ERR_PTR(-EPERM); + return drm_gem_prime_export(dev, gobj, flags); +} diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 72afe82a95c9..b20933fa35c6 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include #include "radeon_reg.h" #include "radeon.h" @@ -515,8 +517,92 @@ struct radeon_ttm_tt { struct ttm_dma_tt ttm; struct radeon_device *rdev; u64 offset; + + uint64_t userptr; + struct mm_struct *usermm; + uint32_t userflags; }; +/* prepare the sg table with the user pages */ +static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm) +{ + struct radeon_device *rdev = radeon_get_rdev(ttm->bdev); + struct radeon_ttm_tt *gtt = (void *)ttm; + unsigned pinned = 0, nents; + int r; + + int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY); + enum dma_data_direction direction = write ? + DMA_BIDIRECTIONAL : DMA_TO_DEVICE; + + if (current->mm != gtt->usermm) + return -EPERM; + + do { + unsigned num_pages = ttm->num_pages - pinned; + uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE; + struct page **pages = ttm->pages + pinned; + + r = get_user_pages(current, current->mm, userptr, num_pages, + write, 0, pages, NULL); + if (r < 0) + goto release_pages; + + pinned += r; + + } while (pinned < ttm->num_pages); + + r = sg_alloc_table_from_pages(ttm->sg, ttm->pages, ttm->num_pages, 0, + ttm->num_pages << PAGE_SHIFT, + GFP_KERNEL); + if (r) + goto release_sg; + + r = -ENOMEM; + nents = dma_map_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); + if (nents != ttm->sg->nents) + goto release_sg; + + drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, + gtt->ttm.dma_address, ttm->num_pages); + + return 0; + +release_sg: + kfree(ttm->sg); + +release_pages: + release_pages(ttm->pages, pinned, 0); + return r; +} + +static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) +{ + struct radeon_device *rdev = radeon_get_rdev(ttm->bdev); + struct radeon_ttm_tt *gtt = (void *)ttm; + struct scatterlist *sg; + int i; + + int write = !(gtt->userflags & RADEON_GEM_USERPTR_READONLY); + enum dma_data_direction direction = write ? + DMA_BIDIRECTIONAL : DMA_TO_DEVICE; + + /* free the sg table and pages again */ + dma_unmap_sg(rdev->dev, ttm->sg->sgl, ttm->sg->nents, direction); + + for_each_sg(ttm->sg->sgl, sg, ttm->sg->nents, i) { + struct page *page = sg_page(sg); + + if (!(gtt->userflags & RADEON_GEM_USERPTR_READONLY)) + set_page_dirty(page); + + mark_page_accessed(page); + page_cache_release(page); + } + + sg_free_table(ttm->sg); +} + static int radeon_ttm_backend_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem) { @@ -525,6 +611,11 @@ static int radeon_ttm_backend_bind(struct ttm_tt *ttm, RADEON_GART_PAGE_WRITE; int r; + if (gtt->userptr) { + radeon_ttm_tt_pin_userptr(ttm); + flags &= ~RADEON_GART_PAGE_WRITE; + } + gtt->offset = (unsigned long)(bo_mem->start << PAGE_SHIFT); if (!ttm->num_pages) { WARN(1, "nothing to bind %lu pages for mreg %p back %p!\n", @@ -547,6 +638,10 @@ static int radeon_ttm_backend_unbind(struct ttm_tt *ttm) struct radeon_ttm_tt *gtt = (void *)ttm; radeon_gart_unbind(gtt->rdev, gtt->offset, ttm->num_pages); + + if (gtt->userptr) + radeon_ttm_tt_unpin_userptr(ttm); + return 0; } @@ -603,6 +698,16 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm) if (ttm->state != tt_unpopulated) return 0; + if (gtt->userptr) { + ttm->sg = kcalloc(1, sizeof(struct sg_table), GFP_KERNEL); + if (!ttm->sg) + return -ENOMEM; + + ttm->page_flags |= TTM_PAGE_FLAG_SG; + ttm->state = tt_unbound; + return 0; + } + if (slave && ttm->sg) { drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages, gtt->ttm.dma_address, ttm->num_pages); @@ -652,6 +757,12 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm) unsigned i; bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG); + if (gtt->userptr) { + kfree(ttm->sg); + ttm->page_flags &= ~TTM_PAGE_FLAG_SG; + return; + } + if (slave) return; @@ -680,6 +791,40 @@ static void radeon_ttm_tt_unpopulate(struct ttm_tt *ttm) ttm_pool_unpopulate(ttm); } +int radeon_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr, + uint32_t flags) +{ + struct radeon_ttm_tt *gtt = (void *)ttm; + + if (gtt == NULL) + return -EINVAL; + + gtt->userptr = addr; + gtt->usermm = current->mm; + gtt->userflags = flags; + return 0; +} + +bool radeon_ttm_tt_has_userptr(struct ttm_tt *ttm) +{ + struct radeon_ttm_tt *gtt = (void *)ttm; + + if (gtt == NULL) + return false; + + return !!gtt->userptr; +} + +bool radeon_ttm_tt_is_readonly(struct ttm_tt *ttm) +{ + struct radeon_ttm_tt *gtt = (void *)ttm; + + if (gtt == NULL) + return false; + + return !!(gtt->userflags & RADEON_GEM_USERPTR_READONLY); +} + static struct ttm_bo_driver radeon_bo_driver = { .ttm_tt_create = &radeon_ttm_tt_create, .ttm_tt_populate = &radeon_ttm_tt_populate, diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index ccae4d9dc3de..0e107c5650bf 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -888,6 +888,9 @@ int radeon_vm_bo_update(struct radeon_device *rdev, bo_va->flags &= ~RADEON_VM_PAGE_VALID; bo_va->flags &= ~RADEON_VM_PAGE_SYSTEM; bo_va->flags &= ~RADEON_VM_PAGE_SNOOPED; + if (bo_va->bo && radeon_ttm_tt_is_readonly(bo_va->bo->tbo.ttm)) + bo_va->flags &= ~RADEON_VM_PAGE_WRITEABLE; + if (mem) { addr = mem->start << PAGE_SHIFT; if (mem->mem_type != TTM_PL_SYSTEM) { diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h index 509b2d7a41b7..3a9f20930372 100644 --- a/include/uapi/drm/radeon_drm.h +++ b/include/uapi/drm/radeon_drm.h @@ -511,6 +511,7 @@ typedef struct { #define DRM_RADEON_GEM_BUSY 0x2a #define DRM_RADEON_GEM_VA 0x2b #define DRM_RADEON_GEM_OP 0x2c +#define DRM_RADEON_GEM_USERPTR 0x2d #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t) #define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START) @@ -554,6 +555,7 @@ typedef struct { #define DRM_IOCTL_RADEON_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_BUSY, struct drm_radeon_gem_busy) #define DRM_IOCTL_RADEON_GEM_VA DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_VA, struct drm_radeon_gem_va) #define DRM_IOCTL_RADEON_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_OP, struct drm_radeon_gem_op) +#define DRM_IOCTL_RADEON_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GEM_USERPTR, struct drm_radeon_gem_userptr) typedef struct drm_radeon_init { enum { @@ -808,6 +810,20 @@ struct drm_radeon_gem_create { uint32_t flags; }; +/* + * This is not a reliable API and you should expect it to fail for any + * number of reasons and have fallback path that do not use userptr to + * perform any operation. + */ +#define RADEON_GEM_USERPTR_READONLY (1 << 0) + +struct drm_radeon_gem_userptr { + uint64_t addr; + uint64_t size; + uint32_t flags; + uint32_t handle; +}; + #define RADEON_TILING_MACRO 0x1 #define RADEON_TILING_MICRO 0x2 #define RADEON_TILING_SWAP_16BIT 0x4 -- GitLab From ddd00e33e17a62c5f44377ab42e7562ccfae7bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 7 Aug 2014 09:36:01 +0200 Subject: [PATCH 0203/9167] drm/radeon: add userptr flag to limit it to anonymous memory v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid problems with writeback by limiting userptr to anonymous memory. v2: add commit and code comments Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_gem.c | 3 ++- drivers/gpu/drm/radeon/radeon_ttm.c | 10 ++++++++++ include/uapi/drm/radeon_drm.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 993ab223b503..032736b429bf 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -290,7 +290,8 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data, return -EACCES; /* reject unknown flag values */ - if (args->flags & ~RADEON_GEM_USERPTR_READONLY) + if (args->flags & ~(RADEON_GEM_USERPTR_READONLY | + RADEON_GEM_USERPTR_ANONONLY)) return -EINVAL; /* readonly pages not tested on older hardware */ diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index b20933fa35c6..12e37b1ddc40 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -538,6 +538,16 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm) if (current->mm != gtt->usermm) return -EPERM; + if (gtt->userflags & RADEON_GEM_USERPTR_ANONONLY) { + /* check that we only pin down anonymous memory + to prevent problems with writeback */ + unsigned long end = gtt->userptr + ttm->num_pages * PAGE_SIZE; + struct vm_area_struct *vma; + vma = find_vma(gtt->usermm, gtt->userptr); + if (!vma || vma->vm_file || vma->vm_end < end) + return -EPERM; + } + do { unsigned num_pages = ttm->num_pages - pinned; uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE; diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h index 3a9f20930372..9720e1a36848 100644 --- a/include/uapi/drm/radeon_drm.h +++ b/include/uapi/drm/radeon_drm.h @@ -816,6 +816,7 @@ struct drm_radeon_gem_create { * perform any operation. */ #define RADEON_GEM_USERPTR_READONLY (1 << 0) +#define RADEON_GEM_USERPTR_ANONONLY (1 << 1) struct drm_radeon_gem_userptr { uint64_t addr; -- GitLab From 2a84a4476d6e13de72472f6ca4338aed0a8269b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 7 Aug 2014 09:36:02 +0200 Subject: [PATCH 0204/9167] drm/radeon: add userptr flag to directly validate the BO to GTT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way we test userptr availability at BO creation time instead of first use. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_gem.c | 18 +++++++++++++++++- include/uapi/drm/radeon_drm.h | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 032736b429bf..450656027aba 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -291,7 +291,7 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data, /* reject unknown flag values */ if (args->flags & ~(RADEON_GEM_USERPTR_READONLY | - RADEON_GEM_USERPTR_ANONONLY)) + RADEON_GEM_USERPTR_ANONONLY | RADEON_GEM_USERPTR_VALIDATE)) return -EINVAL; /* readonly pages not tested on older hardware */ @@ -312,6 +312,22 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data, if (r) goto release_object; + if (args->flags & RADEON_GEM_USERPTR_VALIDATE) { + down_read(¤t->mm->mmap_sem); + r = radeon_bo_reserve(bo, true); + if (r) { + up_read(¤t->mm->mmap_sem); + goto release_object; + } + + radeon_ttm_placement_from_domain(bo, RADEON_GEM_DOMAIN_GTT); + r = ttm_bo_validate(&bo->tbo, &bo->placement, true, false); + radeon_bo_unreserve(bo); + up_read(¤t->mm->mmap_sem); + if (r) + goto release_object; + } + r = drm_gem_handle_create(filp, gobj, &handle); /* drop reference from allocate - handle holds it now */ drm_gem_object_unreference_unlocked(gobj); diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h index 9720e1a36848..5dc61c2d4c73 100644 --- a/include/uapi/drm/radeon_drm.h +++ b/include/uapi/drm/radeon_drm.h @@ -817,6 +817,7 @@ struct drm_radeon_gem_create { */ #define RADEON_GEM_USERPTR_READONLY (1 << 0) #define RADEON_GEM_USERPTR_ANONONLY (1 << 1) +#define RADEON_GEM_USERPTR_VALIDATE (1 << 2) struct drm_radeon_gem_userptr { uint64_t addr; -- GitLab From 341cb9e426fac32523427c80c67543a16be46605 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 7 Aug 2014 09:36:03 +0200 Subject: [PATCH 0205/9167] drm/radeon: add userptr flag to register MMU notifier v3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Whenever userspace mapping related to our userptr change we wait for it to become idle and unmap it from GTT. v2: rebased, fix mutex unlock in error path v3: improve commit message Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/radeon/Makefile | 2 +- drivers/gpu/drm/radeon/radeon.h | 12 ++ drivers/gpu/drm/radeon/radeon_device.c | 2 + drivers/gpu/drm/radeon/radeon_gem.c | 9 +- drivers/gpu/drm/radeon/radeon_mn.c | 272 +++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_object.c | 1 + include/uapi/drm/radeon_drm.h | 1 + 8 files changed, 298 insertions(+), 2 deletions(-) create mode 100644 drivers/gpu/drm/radeon/radeon_mn.c diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index b066bb3ca01a..358b6e8697e9 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -115,6 +115,7 @@ config DRM_RADEON select HWMON select BACKLIGHT_CLASS_DEVICE select INTERVAL_TREE + select MMU_NOTIFIER help Choose this option if you have an ATI Radeon graphics card. There are both PCI and AGP versions. You don't need to choose this to diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 0013ad0db9ef..c7fa1aeb8c3f 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -80,7 +80,7 @@ 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 + ci_dpm.o dce6_afmt.o radeon_vm.o radeon_ucode.o radeon_ib.o radeon_mn.o # add async DMA block radeon-y += \ diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 6f38a23a5810..542da8208674 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -65,6 +65,7 @@ #include #include #include +#include #include #include @@ -487,6 +488,9 @@ struct radeon_bo { struct ttm_bo_kmap_obj dma_buf_vmap; pid_t pid; + + struct radeon_mn *mn; + struct interval_tree_node mn_it; }; #define gem_to_radeon_bo(gobj) container_of((gobj), struct radeon_bo, gem_base) @@ -1725,6 +1729,11 @@ void radeon_test_ring_sync(struct radeon_device *rdev, struct radeon_ring *cpB); void radeon_test_syncing(struct radeon_device *rdev); +/* + * MMU Notifier + */ +int radeon_mn_register(struct radeon_bo *bo, unsigned long addr); +void radeon_mn_unregister(struct radeon_bo *bo); /* * Debugfs @@ -2372,6 +2381,9 @@ struct radeon_device { /* tracking pinned memory */ u64 vram_pin_size; u64 gart_pin_size; + + struct mutex mn_lock; + DECLARE_HASHTABLE(mn_hash, 7); }; bool radeon_is_px(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index c8ea050c8fa4..c58f84f3c6a5 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -1270,6 +1270,8 @@ int radeon_device_init(struct radeon_device *rdev, init_rwsem(&rdev->pm.mclk_lock); init_rwsem(&rdev->exclusive_lock); init_waitqueue_head(&rdev->irq.vblank_queue); + mutex_init(&rdev->mn_lock); + hash_init(rdev->mn_hash); r = radeon_gem_init(rdev); if (r) return r; diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 450656027aba..2a6fbf101cf0 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -291,7 +291,8 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data, /* reject unknown flag values */ if (args->flags & ~(RADEON_GEM_USERPTR_READONLY | - RADEON_GEM_USERPTR_ANONONLY | RADEON_GEM_USERPTR_VALIDATE)) + RADEON_GEM_USERPTR_ANONONLY | RADEON_GEM_USERPTR_VALIDATE | + RADEON_GEM_USERPTR_REGISTER)) return -EINVAL; /* readonly pages not tested on older hardware */ @@ -312,6 +313,12 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data, if (r) goto release_object; + if (args->flags & RADEON_GEM_USERPTR_REGISTER) { + r = radeon_mn_register(bo, args->addr); + if (r) + goto release_object; + } + if (args->flags & RADEON_GEM_USERPTR_VALIDATE) { down_read(¤t->mm->mmap_sem); r = radeon_bo_reserve(bo, true); diff --git a/drivers/gpu/drm/radeon/radeon_mn.c b/drivers/gpu/drm/radeon/radeon_mn.c new file mode 100644 index 000000000000..0157bc2f11f8 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_mn.c @@ -0,0 +1,272 @@ +/* + * 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 +#include +#include +#include + +#include "radeon.h" + +struct radeon_mn { + /* constant after initialisation */ + struct radeon_device *rdev; + struct mm_struct *mm; + struct mmu_notifier mn; + + /* only used on destruction */ + struct work_struct work; + + /* protected by rdev->mn_lock */ + struct hlist_node node; + + /* objects protected by lock */ + struct mutex lock; + struct rb_root objects; +}; + +/** + * radeon_mn_destroy - destroy the rmn + * + * @work: previously sheduled work item + * + * Lazy destroys the notifier from a work item + */ +static void radeon_mn_destroy(struct work_struct *work) +{ + struct radeon_mn *rmn = container_of(work, struct radeon_mn, work); + struct radeon_device *rdev = rmn->rdev; + struct radeon_bo *bo, *next; + + mutex_lock(&rdev->mn_lock); + mutex_lock(&rmn->lock); + hash_del(&rmn->node); + rbtree_postorder_for_each_entry_safe(bo, next, &rmn->objects, mn_it.rb) { + interval_tree_remove(&bo->mn_it, &rmn->objects); + bo->mn = NULL; + } + mutex_unlock(&rmn->lock); + mutex_unlock(&rdev->mn_lock); + mmu_notifier_unregister(&rmn->mn, rmn->mm); + kfree(rmn); +} + +/** + * radeon_mn_release - callback to notify about mm destruction + * + * @mn: our notifier + * @mn: the mm this callback is about + * + * Shedule a work item to lazy destroy our notifier. + */ +static void radeon_mn_release(struct mmu_notifier *mn, + struct mm_struct *mm) +{ + struct radeon_mn *rmn = container_of(mn, struct radeon_mn, mn); + INIT_WORK(&rmn->work, radeon_mn_destroy); + schedule_work(&rmn->work); +} + +/** + * radeon_mn_invalidate_range_start - callback to notify about mm change + * + * @mn: our notifier + * @mn: the mm this callback is about + * @start: start of updated range + * @end: end of updated range + * + * We block for all BOs between start and end to be idle and + * unmap them by move them into system domain again. + */ +static void radeon_mn_invalidate_range_start(struct mmu_notifier *mn, + struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + struct radeon_mn *rmn = container_of(mn, struct radeon_mn, mn); + struct interval_tree_node *it; + + /* notification is exclusive, but interval is inclusive */ + end -= 1; + + mutex_lock(&rmn->lock); + + it = interval_tree_iter_first(&rmn->objects, start, end); + while (it) { + struct radeon_bo *bo; + int r; + + bo = container_of(it, struct radeon_bo, mn_it); + it = interval_tree_iter_next(it, start, end); + + r = radeon_bo_reserve(bo, true); + if (r) { + DRM_ERROR("(%d) failed to reserve user bo\n", r); + continue; + } + + if (bo->tbo.sync_obj) { + r = radeon_fence_wait(bo->tbo.sync_obj, false); + if (r) + DRM_ERROR("(%d) failed to wait for user bo\n", r); + } + + radeon_ttm_placement_from_domain(bo, RADEON_GEM_DOMAIN_CPU); + r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false); + if (r) + DRM_ERROR("(%d) failed to validate user bo\n", r); + + radeon_bo_unreserve(bo); + } + + mutex_unlock(&rmn->lock); +} + +static const struct mmu_notifier_ops radeon_mn_ops = { + .release = radeon_mn_release, + .invalidate_range_start = radeon_mn_invalidate_range_start, +}; + +/** + * radeon_mn_get - create notifier context + * + * @rdev: radeon device pointer + * + * Creates a notifier context for current->mm. + */ +static struct radeon_mn *radeon_mn_get(struct radeon_device *rdev) +{ + struct mm_struct *mm = current->mm; + struct radeon_mn *rmn; + int r; + + down_write(&mm->mmap_sem); + mutex_lock(&rdev->mn_lock); + + hash_for_each_possible(rdev->mn_hash, rmn, node, (unsigned long)mm) + if (rmn->mm == mm) + goto release_locks; + + rmn = kzalloc(sizeof(*rmn), GFP_KERNEL); + if (!rmn) { + rmn = ERR_PTR(-ENOMEM); + goto release_locks; + } + + rmn->rdev = rdev; + rmn->mm = mm; + rmn->mn.ops = &radeon_mn_ops; + mutex_init(&rmn->lock); + rmn->objects = RB_ROOT; + + r = __mmu_notifier_register(&rmn->mn, mm); + if (r) + goto free_rmn; + + hash_add(rdev->mn_hash, &rmn->node, (unsigned long)mm); + +release_locks: + mutex_unlock(&rdev->mn_lock); + up_write(&mm->mmap_sem); + + return rmn; + +free_rmn: + mutex_unlock(&rdev->mn_lock); + up_write(&mm->mmap_sem); + kfree(rmn); + + return ERR_PTR(r); +} + +/** + * radeon_mn_register - register a BO for notifier updates + * + * @bo: radeon buffer object + * @addr: userptr addr we should monitor + * + * Registers an MMU notifier for the given BO at the specified address. + * Returns 0 on success, -ERRNO if anything goes wrong. + */ +int radeon_mn_register(struct radeon_bo *bo, unsigned long addr) +{ + unsigned long end = addr + radeon_bo_size(bo) - 1; + struct radeon_device *rdev = bo->rdev; + struct radeon_mn *rmn; + struct interval_tree_node *it; + + rmn = radeon_mn_get(rdev); + if (IS_ERR(rmn)) + return PTR_ERR(rmn); + + mutex_lock(&rmn->lock); + + it = interval_tree_iter_first(&rmn->objects, addr, end); + if (it) { + mutex_unlock(&rmn->lock); + return -EEXIST; + } + + bo->mn = rmn; + bo->mn_it.start = addr; + bo->mn_it.last = end; + interval_tree_insert(&bo->mn_it, &rmn->objects); + + mutex_unlock(&rmn->lock); + + return 0; +} + +/** + * radeon_mn_unregister - unregister a BO for notifier updates + * + * @bo: radeon buffer object + * + * Remove any registration of MMU notifier updates from the buffer object. + */ +void radeon_mn_unregister(struct radeon_bo *bo) +{ + struct radeon_device *rdev = bo->rdev; + struct radeon_mn *rmn; + + mutex_lock(&rdev->mn_lock); + rmn = bo->mn; + if (rmn == NULL) { + mutex_unlock(&rdev->mn_lock); + return; + } + + mutex_lock(&rmn->lock); + interval_tree_remove(&bo->mn_it, &rmn->objects); + bo->mn = NULL; + mutex_unlock(&rmn->lock); + mutex_unlock(&rdev->mn_lock); +} diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index c73c1e320585..287523807989 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -75,6 +75,7 @@ static void radeon_ttm_bo_destroy(struct ttm_buffer_object *tbo) bo = container_of(tbo, struct radeon_bo, tbo); radeon_update_memory_usage(bo, bo->tbo.mem.mem_type, -1); + radeon_mn_unregister(bo); mutex_lock(&bo->rdev->gem.mutex); list_del_init(&bo->list); diff --git a/include/uapi/drm/radeon_drm.h b/include/uapi/drm/radeon_drm.h index 5dc61c2d4c73..c77495ffc44f 100644 --- a/include/uapi/drm/radeon_drm.h +++ b/include/uapi/drm/radeon_drm.h @@ -818,6 +818,7 @@ struct drm_radeon_gem_create { #define RADEON_GEM_USERPTR_READONLY (1 << 0) #define RADEON_GEM_USERPTR_ANONONLY (1 << 1) #define RADEON_GEM_USERPTR_VALIDATE (1 << 2) +#define RADEON_GEM_USERPTR_REGISTER (1 << 3) struct drm_radeon_gem_userptr { uint64_t addr; -- GitLab From bd645e4314b95b21146aa6ff893d783de20c4e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 7 Aug 2014 09:36:04 +0200 Subject: [PATCH 0206/9167] drm/radeon: allow userptr write access under certain conditions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It needs to be anonymous memory (no file mappings) and we are requried to install an MMU notifier. Signed-off-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_gem.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 2a6fbf101cf0..01b58941acd4 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -285,19 +285,24 @@ int radeon_gem_userptr_ioctl(struct drm_device *dev, void *data, if (offset_in_page(args->addr | args->size)) return -EINVAL; - /* we only support read only mappings for now */ - if (!(args->flags & RADEON_GEM_USERPTR_READONLY)) - return -EACCES; - /* reject unknown flag values */ if (args->flags & ~(RADEON_GEM_USERPTR_READONLY | RADEON_GEM_USERPTR_ANONONLY | RADEON_GEM_USERPTR_VALIDATE | RADEON_GEM_USERPTR_REGISTER)) return -EINVAL; - /* readonly pages not tested on older hardware */ - if (rdev->family < CHIP_R600) - return -EINVAL; + if (args->flags & RADEON_GEM_USERPTR_READONLY) { + /* readonly pages not tested on older hardware */ + if (rdev->family < CHIP_R600) + return -EINVAL; + + } else if (!(args->flags & RADEON_GEM_USERPTR_ANONONLY) || + !(args->flags & RADEON_GEM_USERPTR_REGISTER)) { + + /* if we want to write to it we must require anonymous + memory and install a MMU notifier */ + return -EACCES; + } down_read(&rdev->exclusive_lock); -- GitLab From e94e37ad19c74b4c2569d556cda9da4a03d4e3f8 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:25 +0100 Subject: [PATCH 0207/9167] drm/i915/bdw: GEN-specific logical ring set/get seqno No mistery here: the seqno is still retrieved from the engine's HW status page (the one in the default context. For the moment, I see no reason to worry about other context's HWS page). Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 1a1f5f98f05b..c9518c6261de 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -151,6 +151,16 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) return ret; } +static u32 gen8_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) +{ + return intel_read_status_page(ring, I915_GEM_HWS_INDEX); +} + +static void gen8_set_seqno(struct intel_engine_cs *ring, u32 seqno) +{ + intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); +} + void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { if (!intel_ring_initialized(ring)) @@ -223,6 +233,8 @@ static int logical_render_ring_init(struct drm_device *dev) ring->init = gen8_init_render_ring; ring->cleanup = intel_fini_pipe_control; + ring->get_seqno = gen8_get_seqno; + ring->set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } @@ -239,6 +251,8 @@ static int logical_bsd_ring_init(struct drm_device *dev) GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; ring->init = gen8_init_common_ring; + ring->get_seqno = gen8_get_seqno; + ring->set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } @@ -255,6 +269,8 @@ static int logical_bsd2_ring_init(struct drm_device *dev) GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; ring->init = gen8_init_common_ring; + ring->get_seqno = gen8_get_seqno; + ring->set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } @@ -271,6 +287,8 @@ static int logical_blt_ring_init(struct drm_device *dev) GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; ring->init = gen8_init_common_ring; + ring->get_seqno = gen8_get_seqno; + ring->set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } @@ -287,6 +305,8 @@ static int logical_vebox_ring_init(struct drm_device *dev) GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; ring->init = gen8_init_common_ring; + ring->get_seqno = gen8_get_seqno; + ring->set_seqno = gen8_set_seqno; return logical_ring_init(dev, ring); } -- GitLab From 26fbb77445bd402417f42936f68c0da26d33855d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 11 Aug 2014 18:37:37 +0300 Subject: [PATCH 0208/9167] drm/i915: Make hpd debug messages less cryptic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Don't print raw numbers, use port_name() and tell the user whether it's long or short without having to figure out what the other magic number means. Signed-off-by: Ville Syrjälä Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 4 +++- drivers/gpu/drm/i915/intel_dp.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index f0d24db76e72..36eb1f234608 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1777,7 +1777,9 @@ static inline void intel_hpd_irq_handler(struct drm_device *dev, long_hpd = (dig_hotplug_reg >> dig_shift) & PORTB_HOTPLUG_LONG_DETECT; } - DRM_DEBUG_DRIVER("digital hpd port %d %d\n", port, long_hpd); + DRM_DEBUG_DRIVER("digital hpd port %c - %s\n", + port_name(port), + long_hpd ? "long" : "short"); /* for long HPD pulses we want to have the digital queue happen, but we still want HPD storm detection to function. */ if (long_hpd) { diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 3b88255d87dc..def55cdfef25 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -4041,7 +4041,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; - DRM_DEBUG_KMS("got hpd irq on port %d - %s\n", intel_dig_port->port, + DRM_DEBUG_KMS("got hpd irq on port %c - %s\n", + port_name(intel_dig_port->port), long_hpd ? "long" : "short"); if (long_hpd) { -- GitLab From 82e104cc266c6da30a30fc5028b2f0236c669cd7 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:26 +0100 Subject: [PATCH 0209/9167] drm/i915/bdw: New logical ring submission mechanism Well, new-ish: if all this code looks familiar, that's because it's a clone of the existing submission mechanism (with some modifications here and there to adapt it to LRCs and Execlists). And why did we do this instead of reusing code, one might wonder? Well, there are some fears that the differences are big enough that they will end up breaking all platforms. Also, Execlists offer several advantages, like control over when the GPU is done with a given workload, that can help simplify the submission mechanism, no doubt. I am interested in getting Execlists to work first and foremost, but in the future this parallel submission mechanism will help us to fine tune the mechanism without affecting old gens. v2: Pass the ringbuffer only (whenever possible). Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Appease checkpatch. Again. And drop the legacy sarea gunk that somehow crept in.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 189 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.h | 13 ++ drivers/gpu/drm/i915/intel_ringbuffer.c | 22 +-- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 + 4 files changed, 217 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index c9518c6261de..31025847d680 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -108,6 +108,195 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring) /* TODO */ } +void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) +{ + intel_logical_ring_advance(ringbuf); + + if (intel_ring_stopped(ringbuf->ring)) + return; + + /* TODO: how to submit a context to the ELSP is not here yet */ +} + +static int logical_ring_alloc_seqno(struct intel_engine_cs *ring) +{ + if (ring->outstanding_lazy_seqno) + return 0; + + if (ring->preallocated_lazy_request == NULL) { + struct drm_i915_gem_request *request; + + request = kmalloc(sizeof(*request), GFP_KERNEL); + if (request == NULL) + return -ENOMEM; + + ring->preallocated_lazy_request = request; + } + + return i915_gem_get_seqno(ring->dev, &ring->outstanding_lazy_seqno); +} + +static int logical_ring_wait_request(struct intel_ringbuffer *ringbuf, + int bytes) +{ + struct intel_engine_cs *ring = ringbuf->ring; + struct drm_i915_gem_request *request; + u32 seqno = 0; + int ret; + + if (ringbuf->last_retired_head != -1) { + ringbuf->head = ringbuf->last_retired_head; + ringbuf->last_retired_head = -1; + + ringbuf->space = intel_ring_space(ringbuf); + if (ringbuf->space >= bytes) + return 0; + } + + list_for_each_entry(request, &ring->request_list, list) { + if (__intel_ring_space(request->tail, ringbuf->tail, + ringbuf->size) >= bytes) { + seqno = request->seqno; + break; + } + } + + if (seqno == 0) + return -ENOSPC; + + ret = i915_wait_seqno(ring, seqno); + if (ret) + return ret; + + /* TODO: make sure we update the right ringbuffer's last_retired_head + * when retiring requests */ + i915_gem_retire_requests_ring(ring); + ringbuf->head = ringbuf->last_retired_head; + ringbuf->last_retired_head = -1; + + ringbuf->space = intel_ring_space(ringbuf); + return 0; +} + +static int logical_ring_wait_for_space(struct intel_ringbuffer *ringbuf, + int bytes) +{ + struct intel_engine_cs *ring = ringbuf->ring; + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long end; + int ret; + + ret = logical_ring_wait_request(ringbuf, bytes); + if (ret != -ENOSPC) + return ret; + + /* Force the context submission in case we have been skipping it */ + intel_logical_ring_advance_and_submit(ringbuf); + + /* With GEM the hangcheck timer should kick us out of the loop, + * leaving it early runs the risk of corrupting GEM state (due + * to running on almost untested codepaths). But on resume + * timers don't work yet, so prevent a complete hang in that + * case by choosing an insanely large timeout. */ + end = jiffies + 60 * HZ; + + do { + ringbuf->head = I915_READ_HEAD(ring); + ringbuf->space = intel_ring_space(ringbuf); + if (ringbuf->space >= bytes) { + ret = 0; + break; + } + + msleep(1); + + if (dev_priv->mm.interruptible && signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + + ret = i915_gem_check_wedge(&dev_priv->gpu_error, + dev_priv->mm.interruptible); + if (ret) + break; + + if (time_after(jiffies, end)) { + ret = -EBUSY; + break; + } + } while (1); + + return ret; +} + +static int logical_ring_wrap_buffer(struct intel_ringbuffer *ringbuf) +{ + uint32_t __iomem *virt; + int rem = ringbuf->size - ringbuf->tail; + + if (ringbuf->space < rem) { + int ret = logical_ring_wait_for_space(ringbuf, rem); + + if (ret) + return ret; + } + + virt = ringbuf->virtual_start + ringbuf->tail; + rem /= 4; + while (rem--) + iowrite32(MI_NOOP, virt++); + + ringbuf->tail = 0; + ringbuf->space = intel_ring_space(ringbuf); + + return 0; +} + +static int logical_ring_prepare(struct intel_ringbuffer *ringbuf, int bytes) +{ + int ret; + + if (unlikely(ringbuf->tail + bytes > ringbuf->effective_size)) { + ret = logical_ring_wrap_buffer(ringbuf); + if (unlikely(ret)) + return ret; + } + + if (unlikely(ringbuf->space < bytes)) { + ret = logical_ring_wait_for_space(ringbuf, bytes); + if (unlikely(ret)) + return ret; + } + + return 0; +} + +int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords) +{ + struct intel_engine_cs *ring = ringbuf->ring; + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int ret; + + ret = i915_gem_check_wedge(&dev_priv->gpu_error, + dev_priv->mm.interruptible); + if (ret) + return ret; + + ret = logical_ring_prepare(ringbuf, num_dwords * sizeof(uint32_t)); + if (ret) + return ret; + + /* Preallocate the olr before touching the ring */ + ret = logical_ring_alloc_seqno(ring); + if (ret) + return ret; + + ringbuf->space -= num_dwords * sizeof(uint32_t); + return 0; +} + static int gen8_init_common_ring(struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index bf0eff4e9f08..4e032875c1fd 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -29,6 +29,19 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring); void intel_logical_ring_cleanup(struct intel_engine_cs *ring); int intel_logical_rings_init(struct drm_device *dev); +void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf); +static inline void intel_logical_ring_advance(struct intel_ringbuffer *ringbuf) +{ + ringbuf->tail &= ringbuf->size - 1; +} +static inline void intel_logical_ring_emit(struct intel_ringbuffer *ringbuf, + u32 data) +{ + iowrite32(data, ringbuf->virtual_start + ringbuf->tail); + ringbuf->tail += 4; +} +int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords); + /* Logical Ring Contexts */ void intel_lr_context_free(struct intel_context *ctx); int intel_lr_context_deferred_create(struct intel_context *ctx, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index dab5e7c79036..0bfa018fab20 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -57,7 +57,7 @@ intel_ring_initialized(struct intel_engine_cs *ring) return ring->buffer && ring->buffer->obj; } -static inline int __ring_space(int head, int tail, int size) +int __intel_ring_space(int head, int tail, int size) { int space = head - (tail + I915_RING_FREE_SPACE); if (space < 0) @@ -65,12 +65,13 @@ static inline int __ring_space(int head, int tail, int size) return space; } -static inline int ring_space(struct intel_ringbuffer *ringbuf) +int intel_ring_space(struct intel_ringbuffer *ringbuf) { - return __ring_space(ringbuf->head & HEAD_ADDR, ringbuf->tail, ringbuf->size); + return __intel_ring_space(ringbuf->head & HEAD_ADDR, + ringbuf->tail, ringbuf->size); } -static bool intel_ring_stopped(struct intel_engine_cs *ring) +bool intel_ring_stopped(struct intel_engine_cs *ring) { struct drm_i915_private *dev_priv = ring->dev->dev_private; return dev_priv->gpu_error.stop_rings & intel_ring_flag(ring); @@ -585,7 +586,7 @@ static int init_ring_common(struct intel_engine_cs *ring) else { ringbuf->head = I915_READ_HEAD(ring); ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR; - ringbuf->space = ring_space(ringbuf); + ringbuf->space = intel_ring_space(ringbuf); ringbuf->last_retired_head = -1; } @@ -1702,13 +1703,14 @@ static int intel_ring_wait_request(struct intel_engine_cs *ring, int n) ringbuf->head = ringbuf->last_retired_head; ringbuf->last_retired_head = -1; - ringbuf->space = ring_space(ringbuf); + ringbuf->space = intel_ring_space(ringbuf); if (ringbuf->space >= n) return 0; } list_for_each_entry(request, &ring->request_list, list) { - if (__ring_space(request->tail, ringbuf->tail, ringbuf->size) >= n) { + if (__intel_ring_space(request->tail, ringbuf->tail, + ringbuf->size) >= n) { seqno = request->seqno; break; } @@ -1725,7 +1727,7 @@ static int intel_ring_wait_request(struct intel_engine_cs *ring, int n) ringbuf->head = ringbuf->last_retired_head; ringbuf->last_retired_head = -1; - ringbuf->space = ring_space(ringbuf); + ringbuf->space = intel_ring_space(ringbuf); return 0; } @@ -1754,7 +1756,7 @@ static int ring_wait_for_space(struct intel_engine_cs *ring, int n) trace_i915_ring_wait_begin(ring); do { ringbuf->head = I915_READ_HEAD(ring); - ringbuf->space = ring_space(ringbuf); + ringbuf->space = intel_ring_space(ringbuf); if (ringbuf->space >= n) { ret = 0; break; @@ -1806,7 +1808,7 @@ static int intel_wrap_ring_buffer(struct intel_engine_cs *ring) iowrite32(MI_NOOP, virt++); ringbuf->tail = 0; - ringbuf->space = ring_space(ringbuf); + ringbuf->space = intel_ring_space(ringbuf); return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 677df0d7be48..81bad364e36d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -374,6 +374,9 @@ static inline void intel_ring_advance(struct intel_engine_cs *ring) struct intel_ringbuffer *ringbuf = ring->buffer; ringbuf->tail &= ringbuf->size - 1; } +int __intel_ring_space(int head, int tail, int size); +int intel_ring_space(struct intel_ringbuffer *ringbuf); +bool intel_ring_stopped(struct intel_engine_cs *ring); void __intel_ring_advance(struct intel_engine_cs *ring); int __must_check intel_ring_idle(struct intel_engine_cs *ring); -- GitLab From 4da46e1e5bb7e7396fad172cdaffbe496562f3d8 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:27 +0100 Subject: [PATCH 0210/9167] drm/i915/bdw: GEN-specific logical ring emit request Very similar to the legacy add_request, only modified to account for logical ringbuffer. v2: Use MI_GLOBAL_GTT, as suggested by Brad Volkin. v3: Unify render and non-render in the same function, as noticed by Brad Volkin. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_lrc.c | 31 +++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +++ 3 files changed, 35 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c1d24242a02d..3388afb90a93 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -272,6 +272,7 @@ #define MI_SEMAPHORE_POLL (1<<15) #define MI_SEMAPHORE_SAD_GTE_SDD (1<<12) #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) +#define MI_STORE_DWORD_IMM_GEN8 MI_INSTR(0x20, 2) #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) #define MI_STORE_DWORD_INDEX_SHIFT 2 diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 31025847d680..94f8b4087642 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -350,6 +350,32 @@ static void gen8_set_seqno(struct intel_engine_cs *ring, u32 seqno) intel_write_status_page(ring, I915_GEM_HWS_INDEX, seqno); } +static int gen8_emit_request(struct intel_ringbuffer *ringbuf) +{ + struct intel_engine_cs *ring = ringbuf->ring; + u32 cmd; + int ret; + + ret = intel_logical_ring_begin(ringbuf, 6); + if (ret) + return ret; + + cmd = MI_STORE_DWORD_IMM_GEN8; + cmd |= MI_GLOBAL_GTT; + + intel_logical_ring_emit(ringbuf, cmd); + intel_logical_ring_emit(ringbuf, + (ring->status_page.gfx_addr + + (I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT))); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_emit(ringbuf, ring->outstanding_lazy_seqno); + intel_logical_ring_emit(ringbuf, MI_USER_INTERRUPT); + intel_logical_ring_emit(ringbuf, MI_NOOP); + intel_logical_ring_advance_and_submit(ringbuf); + + return 0; +} + void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { if (!intel_ring_initialized(ring)) @@ -424,6 +450,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring->cleanup = intel_fini_pipe_control; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; + ring->emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } @@ -442,6 +469,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->init = gen8_init_common_ring; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; + ring->emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } @@ -460,6 +488,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->init = gen8_init_common_ring; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; + ring->emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } @@ -478,6 +507,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->init = gen8_init_common_ring; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; + ring->emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } @@ -496,6 +526,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->init = gen8_init_common_ring; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; + ring->emit_request = gen8_emit_request; return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 81bad364e36d..467885159a80 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -216,6 +216,9 @@ struct intel_engine_cs { unsigned int num_dwords); } semaphore; + /* Execlists */ + int (*emit_request)(struct intel_ringbuffer *ringbuf); + /** * List of objects currently involved in rendering from the * ringbuffer. -- GitLab From 4712274c362b7730a1c6e01c9a51a6d46f5b7f43 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:28 +0100 Subject: [PATCH 0211/9167] drm/i915/bdw: GEN-specific logical ring emit flush Same as the legacy-style ring->flush. v2: The BSD invalidate bit still exists in GEN8! Add it for the VCS rings (but still consolidate the blt and bsd ring flushes into one). This was noticed by Brad Volkin. v3: The command for BSD and for other rings is slightly different: get it exactly the same as in gen6_ring_flush + gen6_bsd_ring_flush Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Checkpatch.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 85 +++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 7 -- drivers/gpu/drm/i915/intel_ringbuffer.h | 10 +++ 3 files changed, 95 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 94f8b4087642..a88fa6e9360b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -340,6 +340,86 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) return ret; } +static int gen8_emit_flush(struct intel_ringbuffer *ringbuf, + u32 invalidate_domains, + u32 unused) +{ + struct intel_engine_cs *ring = ringbuf->ring; + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t cmd; + int ret; + + ret = intel_logical_ring_begin(ringbuf, 4); + if (ret) + return ret; + + cmd = MI_FLUSH_DW + 1; + + if (ring == &dev_priv->ring[VCS]) { + if (invalidate_domains & I915_GEM_GPU_DOMAINS) + cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD | + MI_FLUSH_DW_STORE_INDEX | + MI_FLUSH_DW_OP_STOREDW; + } else { + if (invalidate_domains & I915_GEM_DOMAIN_RENDER) + cmd |= MI_INVALIDATE_TLB | MI_FLUSH_DW_STORE_INDEX | + MI_FLUSH_DW_OP_STOREDW; + } + + intel_logical_ring_emit(ringbuf, cmd); + intel_logical_ring_emit(ringbuf, + I915_GEM_HWS_SCRATCH_ADDR | + MI_FLUSH_DW_USE_GTT); + intel_logical_ring_emit(ringbuf, 0); /* upper addr */ + intel_logical_ring_emit(ringbuf, 0); /* value */ + intel_logical_ring_advance(ringbuf); + + return 0; +} + +static int gen8_emit_flush_render(struct intel_ringbuffer *ringbuf, + u32 invalidate_domains, + u32 flush_domains) +{ + struct intel_engine_cs *ring = ringbuf->ring; + u32 scratch_addr = ring->scratch.gtt_offset + 2 * CACHELINE_BYTES; + u32 flags = 0; + int ret; + + flags |= PIPE_CONTROL_CS_STALL; + + if (flush_domains) { + flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; + flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; + } + + if (invalidate_domains) { + flags |= PIPE_CONTROL_TLB_INVALIDATE; + flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; + flags |= PIPE_CONTROL_QW_WRITE; + flags |= PIPE_CONTROL_GLOBAL_GTT_IVB; + } + + ret = intel_logical_ring_begin(ringbuf, 6); + if (ret) + return ret; + + intel_logical_ring_emit(ringbuf, GFX_OP_PIPE_CONTROL(6)); + intel_logical_ring_emit(ringbuf, flags); + intel_logical_ring_emit(ringbuf, scratch_addr); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_emit(ringbuf, 0); + intel_logical_ring_advance(ringbuf); + + return 0; +} + static u32 gen8_get_seqno(struct intel_engine_cs *ring, bool lazy_coherency) { return intel_read_status_page(ring, I915_GEM_HWS_INDEX); @@ -451,6 +531,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; + ring->emit_flush = gen8_emit_flush_render; return logical_ring_init(dev, ring); } @@ -470,6 +551,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; + ring->emit_flush = gen8_emit_flush; return logical_ring_init(dev, ring); } @@ -489,6 +571,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; + ring->emit_flush = gen8_emit_flush; return logical_ring_init(dev, ring); } @@ -508,6 +591,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; + ring->emit_flush = gen8_emit_flush; return logical_ring_init(dev, ring); } @@ -527,6 +611,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; + ring->emit_flush = gen8_emit_flush; return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 0bfa018fab20..4236014c1cda 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -33,13 +33,6 @@ #include "i915_trace.h" #include "intel_drv.h" -/* Early gen2 devices have a cacheline of just 32 bytes, using 64 is overkill, - * but keeps the logic simple. Indeed, the whole purpose of this macro is just - * to give some inclination as to some of the magic values used in the various - * workarounds! - */ -#define CACHELINE_BYTES 64 - bool intel_ring_initialized(struct intel_engine_cs *ring) { diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 467885159a80..e497837c7724 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -5,6 +5,13 @@ #define I915_CMD_HASH_ORDER 9 +/* Early gen2 devices have a cacheline of just 32 bytes, using 64 is overkill, + * but keeps the logic simple. Indeed, the whole purpose of this macro is just + * to give some inclination as to some of the magic values used in the various + * workarounds! + */ +#define CACHELINE_BYTES 64 + /* * Gen2 BSpec "1. Programming Environment" / 1.4.4.6 "Ring Buffer Use" * Gen3 BSpec "vol1c Memory Interface Functions" / 2.3.4.5 "Ring Buffer Use" @@ -218,6 +225,9 @@ struct intel_engine_cs { /* Execlists */ int (*emit_request)(struct intel_ringbuffer *ringbuf); + int (*emit_flush)(struct intel_ringbuffer *ringbuf, + u32 invalidate_domains, + u32 flush_domains); /** * List of objects currently involved in rendering from the -- GitLab From 9832b9dae8f9f505c7ed898a043b4f54b54597ed Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:30 +0100 Subject: [PATCH 0212/9167] drm/i915/bdw: Ring idle and stop with logical rings This is a hard one, since there is no direct hardware ring to control when in Execlists. We reuse intel_ring_idle here, but it should be fine as long as i915_add_request does the ring thing. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index a88fa6e9360b..8a524baa8a6b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -105,7 +105,24 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, void intel_logical_ring_stop(struct intel_engine_cs *ring) { - /* TODO */ + struct drm_i915_private *dev_priv = ring->dev->dev_private; + int ret; + + if (!intel_ring_initialized(ring)) + return; + + ret = intel_ring_idle(ring); + if (ret && !i915_reset_in_progress(&to_i915(ring->dev)->gpu_error)) + DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n", + ring->name, ret); + + /* TODO: Is this correct with Execlists enabled? */ + I915_WRITE_MODE(ring, _MASKED_BIT_ENABLE(STOP_RING)); + if (wait_for_atomic((I915_READ_MODE(ring) & MODE_IDLE) != 0, 1000)) { + DRM_ERROR("%s :timed out trying to stop ring\n", ring->name); + return; + } + I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); } void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) @@ -458,10 +475,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; + if (!intel_ring_initialized(ring)) return; - /* TODO: make sure the ring is stopped */ + intel_logical_ring_stop(ring); + WARN_ON((I915_READ_MODE(ring) & MODE_IDLE) == 0); ring->preallocated_lazy_request = NULL; ring->outstanding_lazy_seqno = 0; -- GitLab From 73d477f6bb17a1f14c4897a4b4a6597fe9a38ad2 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:31 +0100 Subject: [PATCH 0213/9167] drm/i915/bdw: Interrupts with logical rings We need to attend context switch interrupts from all rings. Also, fixed writing IMR/IER and added HWSTAM at ring init time. Notice that, if added to irq_enable_mask, the context switch interrupts would be incorrectly masked out when the user interrupts are due to no users waiting on a sequence number. Therefore, this commit adds a bitmask of interrupts to be kept unmasked at all times. v2: Disable HWSTAM, as suggested by Damien (nobody listens to these interrupts, anyway). v3: Add new get/put_irq functions. Signed-off-by: Thomas Daniel (v1) Signed-off-by: Oscar Mateo (v2 & v3) Reviewed-by: Damien Lespiau [danvet: Drop the GEN8_ prefix from the context switch interrupt define and move it to its brethren.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 19 ++++++-- drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_lrc.c | 58 +++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 36eb1f234608..00957fa0b877 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1647,6 +1647,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, notify_ring(dev, &dev_priv->ring[RCS]); if (bcs & GT_RENDER_USER_INTERRUPT) notify_ring(dev, &dev_priv->ring[BCS]); + if ((rcs | bcs) & GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER("TODO: Context switch\n"); } else DRM_ERROR("The master control interrupt lied (GT0)!\n"); } @@ -1659,9 +1661,13 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp >> GEN8_VCS1_IRQ_SHIFT; if (vcs & GT_RENDER_USER_INTERRUPT) notify_ring(dev, &dev_priv->ring[VCS]); + if (vcs & GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER("TODO: Context switch\n"); vcs = tmp >> GEN8_VCS2_IRQ_SHIFT; if (vcs & GT_RENDER_USER_INTERRUPT) notify_ring(dev, &dev_priv->ring[VCS2]); + if (vcs & GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER("TODO: Context switch\n"); } else DRM_ERROR("The master control interrupt lied (GT1)!\n"); } @@ -1685,6 +1691,8 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, vcs = tmp >> GEN8_VECS_IRQ_SHIFT; if (vcs & GT_RENDER_USER_INTERRUPT) notify_ring(dev, &dev_priv->ring[VECS]); + if (vcs & GT_CONTEXT_SWITCH_INTERRUPT) + DRM_DEBUG_DRIVER("TODO: Context switch\n"); } else DRM_ERROR("The master control interrupt lied (GT3)!\n"); } @@ -3788,12 +3796,17 @@ static void gen8_gt_irq_postinstall(struct drm_i915_private *dev_priv) /* These are interrupts we'll toggle with the ring mask register */ uint32_t gt_interrupts[] = { GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT | + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT | GT_RENDER_L3_PARITY_ERROR_INTERRUPT | - GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT, + GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT | + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT, GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT | - GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT, + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT | + GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT | + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT, 0, - GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT + GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT | + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT }; for (i = 0; i < ARRAY_SIZE(gt_interrupts); i++) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3388afb90a93..f79c20d49d99 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1087,6 +1087,7 @@ enum punit_power_well { #define RING_ACTHD_UDW(base) ((base)+0x5c) #define RING_NOPID(base) ((base)+0x94) #define RING_IMR(base) ((base)+0xa8) +#define RING_HWSTAM(base) ((base)+0x98) #define RING_TIMESTAMP(base) ((base)+0x358) #define TAIL_ADDR 0x001FFFF8 #define HEAD_WRAP_COUNT 0xFFE00000 @@ -1403,6 +1404,7 @@ enum punit_power_well { #define GT_BSD_CS_ERROR_INTERRUPT (1 << 15) #define GT_BSD_USER_INTERRUPT (1 << 12) #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT_S1 (1 << 11) /* hsw+; rsvd on snb, ivb, vlv */ +#define GT_CONTEXT_SWITCH_INTERRUPT (1 << 8) #define GT_RENDER_L3_PARITY_ERROR_INTERRUPT (1 << 5) /* !snb */ #define GT_RENDER_PIPECTL_NOTIFY_INTERRUPT (1 << 4) #define GT_RENDER_CS_MASTER_ERROR_INTERRUPT (1 << 3) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 8a524baa8a6b..009a8b5c088e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -319,6 +319,9 @@ static int gen8_init_common_ring(struct intel_engine_cs *ring) struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; + I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); + I915_WRITE(RING_HWSTAM(ring->mmio_base), 0xffffffff); + I915_WRITE(RING_MODE_GEN7(ring), _MASKED_BIT_DISABLE(GFX_REPLAY_MODE) | _MASKED_BIT_ENABLE(GFX_RUN_LIST_ENABLE)); @@ -357,6 +360,39 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) return ret; } +static bool gen8_logical_ring_get_irq(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long flags; + + if (!dev->irq_enabled) + return false; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (ring->irq_refcount++ == 0) { + I915_WRITE_IMR(ring, ~(ring->irq_enable_mask | ring->irq_keep_mask)); + POSTING_READ(RING_IMR(ring->mmio_base)); + } + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); + + return true; +} + +static void gen8_logical_ring_put_irq(struct intel_engine_cs *ring) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); + if (--ring->irq_refcount == 0) { + I915_WRITE_IMR(ring, ~ring->irq_keep_mask); + POSTING_READ(RING_IMR(ring->mmio_base)); + } + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); +} + static int gen8_emit_flush(struct intel_ringbuffer *ringbuf, u32 invalidate_domains, u32 unused) @@ -545,6 +581,10 @@ static int logical_render_ring_init(struct drm_device *dev) ring->mmio_base = RENDER_RING_BASE; ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_RCS_IRQ_SHIFT; + ring->irq_keep_mask = + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_RCS_IRQ_SHIFT; + if (HAS_L3_DPF(dev)) + ring->irq_keep_mask |= GT_RENDER_L3_PARITY_ERROR_INTERRUPT; ring->init = gen8_init_render_ring; ring->cleanup = intel_fini_pipe_control; @@ -552,6 +592,8 @@ static int logical_render_ring_init(struct drm_device *dev) ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; ring->emit_flush = gen8_emit_flush_render; + ring->irq_get = gen8_logical_ring_get_irq; + ring->irq_put = gen8_logical_ring_put_irq; return logical_ring_init(dev, ring); } @@ -566,12 +608,16 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->mmio_base = GEN6_BSD_RING_BASE; ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; + ring->irq_keep_mask = + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS1_IRQ_SHIFT; ring->init = gen8_init_common_ring; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; ring->emit_flush = gen8_emit_flush; + ring->irq_get = gen8_logical_ring_get_irq; + ring->irq_put = gen8_logical_ring_put_irq; return logical_ring_init(dev, ring); } @@ -586,12 +632,16 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->mmio_base = GEN8_BSD2_RING_BASE; ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; + ring->irq_keep_mask = + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VCS2_IRQ_SHIFT; ring->init = gen8_init_common_ring; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; ring->emit_flush = gen8_emit_flush; + ring->irq_get = gen8_logical_ring_get_irq; + ring->irq_put = gen8_logical_ring_put_irq; return logical_ring_init(dev, ring); } @@ -606,12 +656,16 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->mmio_base = BLT_RING_BASE; ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_BCS_IRQ_SHIFT; + ring->irq_keep_mask = + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_BCS_IRQ_SHIFT; ring->init = gen8_init_common_ring; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; ring->emit_flush = gen8_emit_flush; + ring->irq_get = gen8_logical_ring_get_irq; + ring->irq_put = gen8_logical_ring_put_irq; return logical_ring_init(dev, ring); } @@ -626,12 +680,16 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->mmio_base = VEBOX_RING_BASE; ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT << GEN8_VECS_IRQ_SHIFT; + ring->irq_keep_mask = + GT_CONTEXT_SWITCH_INTERRUPT << GEN8_VECS_IRQ_SHIFT; ring->init = gen8_init_common_ring; ring->get_seqno = gen8_get_seqno; ring->set_seqno = gen8_set_seqno; ring->emit_request = gen8_emit_request; ring->emit_flush = gen8_emit_flush; + ring->irq_get = gen8_logical_ring_get_irq; + ring->irq_put = gen8_logical_ring_put_irq; return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index e497837c7724..cb529ee10c8f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -224,6 +224,7 @@ struct intel_engine_cs { } semaphore; /* Execlists */ + u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */ int (*emit_request)(struct intel_ringbuffer *ringbuf); int (*emit_flush)(struct intel_ringbuffer *ringbuf, u32 invalidate_domains, -- GitLab From 156485852684b511be28a83c78fece8b27ef7c26 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:32 +0100 Subject: [PATCH 0214/9167] drm/i915/bdw: GEN-specific logical ring emit batchbuffer start Dispatch_execbuffer's evil twin. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Ditch the check for aliasing ppgtt. It'll break soon and execlists requires full ppgtt anyway.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 27 +++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 2 ++ 2 files changed, 29 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 009a8b5c088e..e0d4ef2a5c30 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -360,6 +360,28 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) return ret; } +static int gen8_emit_bb_start(struct intel_ringbuffer *ringbuf, + u64 offset, unsigned flags) +{ + struct intel_engine_cs *ring = ringbuf->ring; + struct drm_i915_private *dev_priv = ring->dev->dev_private; + bool ppgtt = !(flags & I915_DISPATCH_SECURE); + int ret; + + ret = intel_logical_ring_begin(ringbuf, 4); + if (ret) + return ret; + + /* FIXME(BDW): Address space and security selectors. */ + intel_logical_ring_emit(ringbuf, MI_BATCH_BUFFER_START_GEN8 | (ppgtt<<8)); + intel_logical_ring_emit(ringbuf, lower_32_bits(offset)); + intel_logical_ring_emit(ringbuf, upper_32_bits(offset)); + intel_logical_ring_emit(ringbuf, MI_NOOP); + intel_logical_ring_advance(ringbuf); + + return 0; +} + static bool gen8_logical_ring_get_irq(struct intel_engine_cs *ring) { struct drm_device *dev = ring->dev; @@ -594,6 +616,7 @@ static int logical_render_ring_init(struct drm_device *dev) ring->emit_flush = gen8_emit_flush_render; ring->irq_get = gen8_logical_ring_get_irq; ring->irq_put = gen8_logical_ring_put_irq; + ring->emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } @@ -618,6 +641,7 @@ static int logical_bsd_ring_init(struct drm_device *dev) ring->emit_flush = gen8_emit_flush; ring->irq_get = gen8_logical_ring_get_irq; ring->irq_put = gen8_logical_ring_put_irq; + ring->emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } @@ -642,6 +666,7 @@ static int logical_bsd2_ring_init(struct drm_device *dev) ring->emit_flush = gen8_emit_flush; ring->irq_get = gen8_logical_ring_get_irq; ring->irq_put = gen8_logical_ring_put_irq; + ring->emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } @@ -666,6 +691,7 @@ static int logical_blt_ring_init(struct drm_device *dev) ring->emit_flush = gen8_emit_flush; ring->irq_get = gen8_logical_ring_get_irq; ring->irq_put = gen8_logical_ring_put_irq; + ring->emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } @@ -690,6 +716,7 @@ static int logical_vebox_ring_init(struct drm_device *dev) ring->emit_flush = gen8_emit_flush; ring->irq_get = gen8_logical_ring_get_irq; ring->irq_put = gen8_logical_ring_put_irq; + ring->emit_bb_start = gen8_emit_bb_start; return logical_ring_init(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index cb529ee10c8f..24437da91f77 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -229,6 +229,8 @@ struct intel_engine_cs { int (*emit_flush)(struct intel_ringbuffer *ringbuf, u32 invalidate_domains, u32 flush_domains); + int (*emit_bb_start)(struct intel_ringbuffer *ringbuf, + u64 offset, unsigned flags); /** * List of objects currently involved in rendering from the -- GitLab From ba8b7ccb196b07c1c553450e8e7b44a7a938e58a Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:33 +0100 Subject: [PATCH 0215/9167] drm/i915/bdw: Workload submission mechanism for Execlists This is what i915_gem_do_execbuffer calls when it wants to execute some worload in an Execlists world. v2: Check arguments before doing stuff in intel_execlists_submission. Also, get rel_constants parsing right. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Drop the chipset flush, that's pre-gen6. And appease checkpatch a bit .... again!] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 6 + drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 +- drivers/gpu/drm/i915/intel_lrc.c | 130 ++++++++++++++++++++- 3 files changed, 135 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9198f1c96470..53cc4c083d0d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2266,6 +2266,12 @@ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +void i915_gem_execbuffer_move_to_active(struct list_head *vmas, + struct intel_engine_cs *ring); +void i915_gem_execbuffer_retire_commands(struct drm_device *dev, + struct drm_file *file, + struct intel_engine_cs *ring, + struct drm_i915_gem_object *obj); int i915_gem_ringbuffer_submission(struct drm_device *dev, struct drm_file *file, struct intel_engine_cs *ring, diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 26b38b3ae4f3..7e04a4825ed0 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -942,7 +942,7 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, return ctx; } -static void +void i915_gem_execbuffer_move_to_active(struct list_head *vmas, struct intel_engine_cs *ring) { @@ -983,7 +983,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas, } } -static void +void i915_gem_execbuffer_retire_commands(struct drm_device *dev, struct drm_file *file, struct intel_engine_cs *ring, diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e0d4ef2a5c30..e1a298f23f50 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -91,6 +91,55 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf) +{ + struct intel_engine_cs *ring = ringbuf->ring; + uint32_t flush_domains; + int ret; + + flush_domains = 0; + if (ring->gpu_caches_dirty) + flush_domains = I915_GEM_GPU_DOMAINS; + + ret = ring->emit_flush(ringbuf, I915_GEM_GPU_DOMAINS, flush_domains); + if (ret) + return ret; + + ring->gpu_caches_dirty = false; + return 0; +} + +static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf, + struct list_head *vmas) +{ + struct intel_engine_cs *ring = ringbuf->ring; + struct i915_vma *vma; + uint32_t flush_domains = 0; + bool flush_chipset = false; + int ret; + + list_for_each_entry(vma, vmas, exec_list) { + struct drm_i915_gem_object *obj = vma->obj; + + ret = i915_gem_object_sync(obj, ring); + if (ret) + return ret; + + if (obj->base.write_domain & I915_GEM_DOMAIN_CPU) + flush_chipset |= i915_gem_clflush_object(obj, false); + + flush_domains |= obj->base.write_domain; + } + + if (flush_domains & I915_GEM_DOMAIN_GTT) + wmb(); + + /* Unconditionally invalidate gpu caches and ensure that we do flush + * any residual writes from the previous batch. + */ + return logical_ring_invalidate_all_caches(ringbuf); +} + int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, struct intel_engine_cs *ring, struct intel_context *ctx, @@ -99,7 +148,84 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, struct drm_i915_gem_object *batch_obj, u64 exec_start, u32 flags) { - /* TODO */ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_ringbuffer *ringbuf = ctx->engine[ring->id].ringbuf; + int instp_mode; + u32 instp_mask; + int ret; + + instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK; + instp_mask = I915_EXEC_CONSTANTS_MASK; + switch (instp_mode) { + case I915_EXEC_CONSTANTS_REL_GENERAL: + case I915_EXEC_CONSTANTS_ABSOLUTE: + case I915_EXEC_CONSTANTS_REL_SURFACE: + if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) { + DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); + return -EINVAL; + } + + if (instp_mode != dev_priv->relative_constants_mode) { + if (instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) { + DRM_DEBUG("rel surface constants mode invalid on gen5+\n"); + return -EINVAL; + } + + /* The HW changed the meaning on this bit on gen6 */ + instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE; + } + break; + default: + DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode); + return -EINVAL; + } + + if (args->num_cliprects != 0) { + DRM_DEBUG("clip rectangles are only valid on pre-gen5\n"); + return -EINVAL; + } else { + if (args->DR4 == 0xffffffff) { + DRM_DEBUG("UXA submitting garbage DR4, fixing up\n"); + args->DR4 = 0; + } + + if (args->DR1 || args->DR4 || args->cliprects_ptr) { + DRM_DEBUG("0 cliprects but dirt in cliprects fields\n"); + return -EINVAL; + } + } + + if (args->flags & I915_EXEC_GEN7_SOL_RESET) { + DRM_DEBUG("sol reset is gen7 only\n"); + return -EINVAL; + } + + ret = execlists_move_to_gpu(ringbuf, vmas); + if (ret) + return ret; + + if (ring == &dev_priv->ring[RCS] && + instp_mode != dev_priv->relative_constants_mode) { + ret = intel_logical_ring_begin(ringbuf, 4); + if (ret) + return ret; + + intel_logical_ring_emit(ringbuf, MI_NOOP); + intel_logical_ring_emit(ringbuf, MI_LOAD_REGISTER_IMM(1)); + intel_logical_ring_emit(ringbuf, INSTPM); + intel_logical_ring_emit(ringbuf, instp_mask << 16 | instp_mode); + intel_logical_ring_advance(ringbuf); + + dev_priv->relative_constants_mode = instp_mode; + } + + ret = ring->emit_bb_start(ringbuf, exec_start, flags); + if (ret) + return ret; + + i915_gem_execbuffer_move_to_active(vmas, ring); + i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj); + return 0; } @@ -363,8 +489,6 @@ static int gen8_init_render_ring(struct intel_engine_cs *ring) static int gen8_emit_bb_start(struct intel_ringbuffer *ringbuf, u64 offset, unsigned flags) { - struct intel_engine_cs *ring = ringbuf->ring; - struct drm_i915_private *dev_priv = ring->dev->dev_private; bool ppgtt = !(flags & I915_DISPATCH_SECURE); int ret; -- GitLab From 14bf993e83e1d6924f4bf4506120a15c4b255e58 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:34 +0100 Subject: [PATCH 0216/9167] drm/i915/bdw: Always use MMIO flips with Execlists The normal flip function places things in the ring in the legacy way, so we either fix that or force MMIO flips always as we do in this patch. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Checkpatch. Fucking again.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 ++ drivers/gpu/drm/i915/intel_lrc.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 245cf4128314..1bd1aa21a8e9 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -9536,6 +9536,8 @@ static bool use_mmio_flip(struct intel_engine_cs *ring, return false; else if (i915.use_mmio_flip > 0) return true; + else if (i915.enable_execlists) + return true; else return ring != obj->ring; } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e1a298f23f50..6f1b64e01a05 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -85,7 +85,8 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists if (enable_execlists == 0) return 0; - if (HAS_LOGICAL_RING_CONTEXTS(dev) && USES_PPGTT(dev)) + if (HAS_LOGICAL_RING_CONTEXTS(dev) && USES_PPGTT(dev) && + i915.use_mmio_flip >= 0) return 1; return 0; -- GitLab From cff990ce7ddd6a43f86757867399a8a64aa29af9 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Mon, 4 Aug 2014 09:18:33 +0300 Subject: [PATCH 0217/9167] ath10k: fix wmi service bitmap debug The 10.x and main firmware branches have conflicting WMI service bitmap definitions. This also fixes WMI services parsing on big-endian hosts and changes debugfs output to be more human friendly. kvalo: remove braces and the last semicolon from SVCSTR() Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.h | 2 +- drivers/net/wireless/ath/ath10k/debug.c | 26 +- drivers/net/wireless/ath/ath10k/wmi.c | 14 +- drivers/net/wireless/ath/ath10k/wmi.h | 369 +++++++++++++++++------- 4 files changed, 292 insertions(+), 119 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index d5c95d46e841..94b1ff2082cf 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -282,7 +282,7 @@ struct ath10k_debug { struct dentry *debugfs_phy; struct ath10k_target_stats target_stats; - u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; + DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_BM_SIZE); struct completion event_stats_compl; diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c index c9e35c87edfb..df1abe7f1fef 100644 --- a/drivers/net/wireless/ath/ath10k/debug.c +++ b/drivers/net/wireless/ath/ath10k/debug.c @@ -115,9 +115,10 @@ static ssize_t ath10k_read_wmi_services(struct file *file, { struct ath10k *ar = file->private_data; char *buf; - unsigned int len = 0, buf_len = 1500; - const char *status; + unsigned int len = 0, buf_len = 4096; + const char *name; ssize_t ret_cnt; + bool enabled; int i; buf = kzalloc(buf_len, GFP_KERNEL); @@ -129,15 +130,22 @@ static ssize_t ath10k_read_wmi_services(struct file *file, if (len > buf_len) len = buf_len; - for (i = 0; i < WMI_SERVICE_LAST; i++) { - if (WMI_SERVICE_IS_ENABLED(ar->debug.wmi_service_bitmap, i)) - status = "enabled"; - else - status = "disabled"; + for (i = 0; i < WMI_MAX_SERVICE; i++) { + enabled = test_bit(i, ar->debug.wmi_service_bitmap); + name = wmi_service_name(i); + + if (!name) { + if (enabled) + len += scnprintf(buf + len, buf_len - len, + "%-40s %s (bit %d)\n", + "unknown", "enabled", i); + + continue; + } len += scnprintf(buf + len, buf_len - len, - "0x%02x - %20s - %s\n", - i, wmi_service_name(i), status); + "%-40s %s\n", + name, enabled ? "enabled" : "-"); } ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index fffb15b1b50b..a381006c8124 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -2080,6 +2080,7 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) { struct wmi_service_ready_event *ev = (void *)skb->data; + DECLARE_BITMAP(svc_bmap, WMI_SERVICE_BM_SIZE) = {}; if (skb->len < sizeof(*ev)) { ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n", @@ -2113,8 +2114,10 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, ar->ath_common.regulatory.current_rd = __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); - ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap, - sizeof(ev->wmi_service_bitmap)); + wmi_10x_svc_map(ev->wmi_service_bitmap, svc_bmap); + ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap)); + ath10k_dbg_dump(ATH10K_DBG_WMI, NULL, "ath10k: 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, @@ -2154,6 +2157,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, 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_BM_SIZE) = {}; if (skb->len < sizeof(*ev)) { ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n", @@ -2180,8 +2184,10 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, ar->ath_common.regulatory.current_rd = __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); - ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap, - sizeof(ev->wmi_service_bitmap)); + wmi_main_svc_map(ev->wmi_service_bitmap, svc_bmap); + ath10k_debug_read_service_map(ar, svc_bmap, sizeof(svc_bmap)); + ath10k_dbg_dump(ATH10K_DBG_WMI, NULL, "ath10k: 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, diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h index 1d8dda3240a5..e70836586756 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h @@ -73,116 +73,279 @@ struct wmi_cmd_hdr { #define HTC_PROTOCOL_VERSION 0x0002 #define WMI_PROTOCOL_VERSION 0x0002 -enum wmi_service_id { - WMI_SERVICE_BEACON_OFFLOAD = 0, /* beacon offload */ - WMI_SERVICE_SCAN_OFFLOAD, /* scan offload */ - WMI_SERVICE_ROAM_OFFLOAD, /* roam offload */ - WMI_SERVICE_BCN_MISS_OFFLOAD, /* beacon miss offload */ - WMI_SERVICE_STA_PWRSAVE, /* fake sleep + basic power save */ - WMI_SERVICE_STA_ADVANCED_PWRSAVE, /* uapsd, pspoll, force sleep */ - WMI_SERVICE_AP_UAPSD, /* uapsd on AP */ - WMI_SERVICE_AP_DFS, /* DFS on AP */ - WMI_SERVICE_11AC, /* supports 11ac */ - WMI_SERVICE_BLOCKACK, /* Supports triggering ADDBA/DELBA from host*/ - WMI_SERVICE_PHYERR, /* PHY error */ - WMI_SERVICE_BCN_FILTER, /* Beacon filter support */ - WMI_SERVICE_RTT, /* RTT (round trip time) support */ - WMI_SERVICE_RATECTRL, /* Rate-control */ - WMI_SERVICE_WOW, /* WOW Support */ - WMI_SERVICE_RATECTRL_CACHE, /* Rate-control caching */ - WMI_SERVICE_IRAM_TIDS, /* TIDs in IRAM */ - WMI_SERVICE_ARPNS_OFFLOAD, /* ARP NS Offload support */ - WMI_SERVICE_NLO, /* Network list offload service */ - WMI_SERVICE_GTK_OFFLOAD, /* GTK offload */ - WMI_SERVICE_SCAN_SCH, /* Scan Scheduler Service */ - WMI_SERVICE_CSA_OFFLOAD, /* CSA offload service */ - WMI_SERVICE_CHATTER, /* Chatter service */ - WMI_SERVICE_COEX_FREQAVOID, /* FW report freq range to avoid */ - WMI_SERVICE_PACKET_POWER_SAVE, /* packet power save service */ - WMI_SERVICE_FORCE_FW_HANG, /* To test fw recovery mechanism */ - WMI_SERVICE_GPIO, /* GPIO service */ - WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, /* Modulated DTIM support */ - WMI_STA_UAPSD_BASIC_AUTO_TRIG, /* UAPSD AC Trigger Generation */ - WMI_STA_UAPSD_VAR_AUTO_TRIG, /* -do- */ - WMI_SERVICE_STA_KEEP_ALIVE, /* STA keep alive mechanism support */ - WMI_SERVICE_TX_ENCAP, /* Packet type for TX encapsulation */ - - WMI_SERVICE_LAST, - WMI_MAX_SERVICE = 64 /* max service */ +enum wmi_service { + WMI_SERVICE_BEACON_OFFLOAD = 0, + WMI_SERVICE_SCAN_OFFLOAD, + WMI_SERVICE_ROAM_OFFLOAD, + WMI_SERVICE_BCN_MISS_OFFLOAD, + WMI_SERVICE_STA_PWRSAVE, + WMI_SERVICE_STA_ADVANCED_PWRSAVE, + WMI_SERVICE_AP_UAPSD, + WMI_SERVICE_AP_DFS, + WMI_SERVICE_11AC, + WMI_SERVICE_BLOCKACK, + WMI_SERVICE_PHYERR, + WMI_SERVICE_BCN_FILTER, + WMI_SERVICE_RTT, + WMI_SERVICE_RATECTRL, + WMI_SERVICE_WOW, + WMI_SERVICE_RATECTRL_CACHE, + WMI_SERVICE_IRAM_TIDS, + WMI_SERVICE_ARPNS_OFFLOAD, + WMI_SERVICE_NLO, + WMI_SERVICE_GTK_OFFLOAD, + WMI_SERVICE_SCAN_SCH, + WMI_SERVICE_CSA_OFFLOAD, + WMI_SERVICE_CHATTER, + WMI_SERVICE_COEX_FREQAVOID, + WMI_SERVICE_PACKET_POWER_SAVE, + WMI_SERVICE_FORCE_FW_HANG, + WMI_SERVICE_GPIO, + WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, + WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, + WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, + WMI_SERVICE_STA_KEEP_ALIVE, + WMI_SERVICE_TX_ENCAP, + WMI_SERVICE_BURST, + WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT, + WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT, +}; + +enum wmi_10x_service { + WMI_10X_SERVICE_BEACON_OFFLOAD = 0, + WMI_10X_SERVICE_SCAN_OFFLOAD, + WMI_10X_SERVICE_ROAM_OFFLOAD, + WMI_10X_SERVICE_BCN_MISS_OFFLOAD, + WMI_10X_SERVICE_STA_PWRSAVE, + WMI_10X_SERVICE_STA_ADVANCED_PWRSAVE, + WMI_10X_SERVICE_AP_UAPSD, + WMI_10X_SERVICE_AP_DFS, + WMI_10X_SERVICE_11AC, + WMI_10X_SERVICE_BLOCKACK, + WMI_10X_SERVICE_PHYERR, + WMI_10X_SERVICE_BCN_FILTER, + WMI_10X_SERVICE_RTT, + WMI_10X_SERVICE_RATECTRL, + WMI_10X_SERVICE_WOW, + WMI_10X_SERVICE_RATECTRL_CACHE, + WMI_10X_SERVICE_IRAM_TIDS, + WMI_10X_SERVICE_BURST, + + /* introduced in 10.2 */ + WMI_10X_SERVICE_SMART_ANTENNA_SW_SUPPORT, + WMI_10X_SERVICE_FORCE_FW_HANG, + WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT, +}; + +enum wmi_main_service { + WMI_MAIN_SERVICE_BEACON_OFFLOAD = 0, + WMI_MAIN_SERVICE_SCAN_OFFLOAD, + WMI_MAIN_SERVICE_ROAM_OFFLOAD, + WMI_MAIN_SERVICE_BCN_MISS_OFFLOAD, + WMI_MAIN_SERVICE_STA_PWRSAVE, + WMI_MAIN_SERVICE_STA_ADVANCED_PWRSAVE, + WMI_MAIN_SERVICE_AP_UAPSD, + WMI_MAIN_SERVICE_AP_DFS, + WMI_MAIN_SERVICE_11AC, + WMI_MAIN_SERVICE_BLOCKACK, + WMI_MAIN_SERVICE_PHYERR, + WMI_MAIN_SERVICE_BCN_FILTER, + WMI_MAIN_SERVICE_RTT, + WMI_MAIN_SERVICE_RATECTRL, + WMI_MAIN_SERVICE_WOW, + WMI_MAIN_SERVICE_RATECTRL_CACHE, + WMI_MAIN_SERVICE_IRAM_TIDS, + WMI_MAIN_SERVICE_ARPNS_OFFLOAD, + WMI_MAIN_SERVICE_NLO, + WMI_MAIN_SERVICE_GTK_OFFLOAD, + WMI_MAIN_SERVICE_SCAN_SCH, + WMI_MAIN_SERVICE_CSA_OFFLOAD, + WMI_MAIN_SERVICE_CHATTER, + WMI_MAIN_SERVICE_COEX_FREQAVOID, + WMI_MAIN_SERVICE_PACKET_POWER_SAVE, + WMI_MAIN_SERVICE_FORCE_FW_HANG, + WMI_MAIN_SERVICE_GPIO, + WMI_MAIN_SERVICE_STA_DTIM_PS_MODULATED_DTIM, + WMI_MAIN_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, + WMI_MAIN_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, + WMI_MAIN_SERVICE_STA_KEEP_ALIVE, + WMI_MAIN_SERVICE_TX_ENCAP, }; static inline char *wmi_service_name(int service_id) { +#define SVCSTR(x) case x: return #x + switch (service_id) { - case WMI_SERVICE_BEACON_OFFLOAD: - return "BEACON_OFFLOAD"; - case WMI_SERVICE_SCAN_OFFLOAD: - return "SCAN_OFFLOAD"; - case WMI_SERVICE_ROAM_OFFLOAD: - return "ROAM_OFFLOAD"; - case WMI_SERVICE_BCN_MISS_OFFLOAD: - return "BCN_MISS_OFFLOAD"; - case WMI_SERVICE_STA_PWRSAVE: - return "STA_PWRSAVE"; - case WMI_SERVICE_STA_ADVANCED_PWRSAVE: - return "STA_ADVANCED_PWRSAVE"; - case WMI_SERVICE_AP_UAPSD: - return "AP_UAPSD"; - case WMI_SERVICE_AP_DFS: - return "AP_DFS"; - case WMI_SERVICE_11AC: - return "11AC"; - case WMI_SERVICE_BLOCKACK: - return "BLOCKACK"; - case WMI_SERVICE_PHYERR: - return "PHYERR"; - case WMI_SERVICE_BCN_FILTER: - return "BCN_FILTER"; - case WMI_SERVICE_RTT: - return "RTT"; - case WMI_SERVICE_RATECTRL: - return "RATECTRL"; - case WMI_SERVICE_WOW: - return "WOW"; - case WMI_SERVICE_RATECTRL_CACHE: - return "RATECTRL CACHE"; - case WMI_SERVICE_IRAM_TIDS: - return "IRAM TIDS"; - case WMI_SERVICE_ARPNS_OFFLOAD: - return "ARPNS_OFFLOAD"; - case WMI_SERVICE_NLO: - return "NLO"; - case WMI_SERVICE_GTK_OFFLOAD: - return "GTK_OFFLOAD"; - case WMI_SERVICE_SCAN_SCH: - return "SCAN_SCH"; - case WMI_SERVICE_CSA_OFFLOAD: - return "CSA_OFFLOAD"; - case WMI_SERVICE_CHATTER: - return "CHATTER"; - case WMI_SERVICE_COEX_FREQAVOID: - return "COEX_FREQAVOID"; - case WMI_SERVICE_PACKET_POWER_SAVE: - return "PACKET_POWER_SAVE"; - case WMI_SERVICE_FORCE_FW_HANG: - return "FORCE FW HANG"; - case WMI_SERVICE_GPIO: - return "GPIO"; - case WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM: - return "MODULATED DTIM"; - case WMI_STA_UAPSD_BASIC_AUTO_TRIG: - return "BASIC UAPSD"; - case WMI_STA_UAPSD_VAR_AUTO_TRIG: - return "VAR UAPSD"; - case WMI_SERVICE_STA_KEEP_ALIVE: - return "STA KEEP ALIVE"; - case WMI_SERVICE_TX_ENCAP: - return "TX ENCAP"; + SVCSTR(WMI_SERVICE_BEACON_OFFLOAD); + SVCSTR(WMI_SERVICE_SCAN_OFFLOAD); + SVCSTR(WMI_SERVICE_ROAM_OFFLOAD); + SVCSTR(WMI_SERVICE_BCN_MISS_OFFLOAD); + SVCSTR(WMI_SERVICE_STA_PWRSAVE); + SVCSTR(WMI_SERVICE_STA_ADVANCED_PWRSAVE); + SVCSTR(WMI_SERVICE_AP_UAPSD); + SVCSTR(WMI_SERVICE_AP_DFS); + SVCSTR(WMI_SERVICE_11AC); + SVCSTR(WMI_SERVICE_BLOCKACK); + SVCSTR(WMI_SERVICE_PHYERR); + SVCSTR(WMI_SERVICE_BCN_FILTER); + SVCSTR(WMI_SERVICE_RTT); + SVCSTR(WMI_SERVICE_RATECTRL); + SVCSTR(WMI_SERVICE_WOW); + SVCSTR(WMI_SERVICE_RATECTRL_CACHE); + SVCSTR(WMI_SERVICE_IRAM_TIDS); + SVCSTR(WMI_SERVICE_ARPNS_OFFLOAD); + SVCSTR(WMI_SERVICE_NLO); + SVCSTR(WMI_SERVICE_GTK_OFFLOAD); + SVCSTR(WMI_SERVICE_SCAN_SCH); + SVCSTR(WMI_SERVICE_CSA_OFFLOAD); + SVCSTR(WMI_SERVICE_CHATTER); + SVCSTR(WMI_SERVICE_COEX_FREQAVOID); + SVCSTR(WMI_SERVICE_PACKET_POWER_SAVE); + SVCSTR(WMI_SERVICE_FORCE_FW_HANG); + SVCSTR(WMI_SERVICE_GPIO); + SVCSTR(WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM); + SVCSTR(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG); + SVCSTR(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG); + SVCSTR(WMI_SERVICE_STA_KEEP_ALIVE); + SVCSTR(WMI_SERVICE_TX_ENCAP); + SVCSTR(WMI_SERVICE_BURST); + SVCSTR(WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT); + SVCSTR(WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT); default: - return "UNKNOWN SERVICE\n"; + return NULL; } + +#undef SVCSTR +} + +#define WMI_MAX_SERVICE 64 + +#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \ + (__le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ + BIT((svc_id)%(sizeof(u32)))) + +#define SVCMAP(x, y) \ + do { \ + if (WMI_SERVICE_IS_ENABLED((in), (x))) \ + __set_bit(y, out); \ + } while (0) + +static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out) +{ + SVCMAP(WMI_10X_SERVICE_BEACON_OFFLOAD, + WMI_SERVICE_BEACON_OFFLOAD); + SVCMAP(WMI_10X_SERVICE_SCAN_OFFLOAD, + WMI_SERVICE_SCAN_OFFLOAD); + SVCMAP(WMI_10X_SERVICE_ROAM_OFFLOAD, + WMI_SERVICE_ROAM_OFFLOAD); + SVCMAP(WMI_10X_SERVICE_BCN_MISS_OFFLOAD, + WMI_SERVICE_BCN_MISS_OFFLOAD); + SVCMAP(WMI_10X_SERVICE_STA_PWRSAVE, + WMI_SERVICE_STA_PWRSAVE); + SVCMAP(WMI_10X_SERVICE_STA_ADVANCED_PWRSAVE, + WMI_SERVICE_STA_ADVANCED_PWRSAVE); + SVCMAP(WMI_10X_SERVICE_AP_UAPSD, + WMI_SERVICE_AP_UAPSD); + SVCMAP(WMI_10X_SERVICE_AP_DFS, + WMI_SERVICE_AP_DFS); + SVCMAP(WMI_10X_SERVICE_11AC, + WMI_SERVICE_11AC); + SVCMAP(WMI_10X_SERVICE_BLOCKACK, + WMI_SERVICE_BLOCKACK); + SVCMAP(WMI_10X_SERVICE_PHYERR, + WMI_SERVICE_PHYERR); + SVCMAP(WMI_10X_SERVICE_BCN_FILTER, + WMI_SERVICE_BCN_FILTER); + SVCMAP(WMI_10X_SERVICE_RTT, + WMI_SERVICE_RTT); + SVCMAP(WMI_10X_SERVICE_RATECTRL, + WMI_SERVICE_RATECTRL); + SVCMAP(WMI_10X_SERVICE_WOW, + WMI_SERVICE_WOW); + SVCMAP(WMI_10X_SERVICE_RATECTRL_CACHE, + WMI_SERVICE_RATECTRL_CACHE); + SVCMAP(WMI_10X_SERVICE_IRAM_TIDS, + WMI_SERVICE_IRAM_TIDS); + SVCMAP(WMI_10X_SERVICE_BURST, + WMI_SERVICE_BURST); + SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_SW_SUPPORT, + WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT); + SVCMAP(WMI_10X_SERVICE_FORCE_FW_HANG, + WMI_SERVICE_FORCE_FW_HANG); + SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT, + WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT); } +static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out) +{ + SVCMAP(WMI_MAIN_SERVICE_BEACON_OFFLOAD, + WMI_SERVICE_BEACON_OFFLOAD); + SVCMAP(WMI_MAIN_SERVICE_SCAN_OFFLOAD, + WMI_SERVICE_SCAN_OFFLOAD); + SVCMAP(WMI_MAIN_SERVICE_ROAM_OFFLOAD, + WMI_SERVICE_ROAM_OFFLOAD); + SVCMAP(WMI_MAIN_SERVICE_BCN_MISS_OFFLOAD, + WMI_SERVICE_BCN_MISS_OFFLOAD); + SVCMAP(WMI_MAIN_SERVICE_STA_PWRSAVE, + WMI_SERVICE_STA_PWRSAVE); + SVCMAP(WMI_MAIN_SERVICE_STA_ADVANCED_PWRSAVE, + WMI_SERVICE_STA_ADVANCED_PWRSAVE); + SVCMAP(WMI_MAIN_SERVICE_AP_UAPSD, + WMI_SERVICE_AP_UAPSD); + SVCMAP(WMI_MAIN_SERVICE_AP_DFS, + WMI_SERVICE_AP_DFS); + SVCMAP(WMI_MAIN_SERVICE_11AC, + WMI_SERVICE_11AC); + SVCMAP(WMI_MAIN_SERVICE_BLOCKACK, + WMI_SERVICE_BLOCKACK); + SVCMAP(WMI_MAIN_SERVICE_PHYERR, + WMI_SERVICE_PHYERR); + SVCMAP(WMI_MAIN_SERVICE_BCN_FILTER, + WMI_SERVICE_BCN_FILTER); + SVCMAP(WMI_MAIN_SERVICE_RTT, + WMI_SERVICE_RTT); + SVCMAP(WMI_MAIN_SERVICE_RATECTRL, + WMI_SERVICE_RATECTRL); + SVCMAP(WMI_MAIN_SERVICE_WOW, + WMI_SERVICE_WOW); + SVCMAP(WMI_MAIN_SERVICE_RATECTRL_CACHE, + WMI_SERVICE_RATECTRL_CACHE); + SVCMAP(WMI_MAIN_SERVICE_IRAM_TIDS, + WMI_SERVICE_IRAM_TIDS); + SVCMAP(WMI_MAIN_SERVICE_ARPNS_OFFLOAD, + WMI_SERVICE_ARPNS_OFFLOAD); + SVCMAP(WMI_MAIN_SERVICE_NLO, + WMI_SERVICE_NLO); + SVCMAP(WMI_MAIN_SERVICE_GTK_OFFLOAD, + WMI_SERVICE_GTK_OFFLOAD); + SVCMAP(WMI_MAIN_SERVICE_SCAN_SCH, + WMI_SERVICE_SCAN_SCH); + SVCMAP(WMI_MAIN_SERVICE_CSA_OFFLOAD, + WMI_SERVICE_CSA_OFFLOAD); + SVCMAP(WMI_MAIN_SERVICE_CHATTER, + WMI_SERVICE_CHATTER); + SVCMAP(WMI_MAIN_SERVICE_COEX_FREQAVOID, + WMI_SERVICE_COEX_FREQAVOID); + SVCMAP(WMI_MAIN_SERVICE_PACKET_POWER_SAVE, + WMI_SERVICE_PACKET_POWER_SAVE); + SVCMAP(WMI_MAIN_SERVICE_FORCE_FW_HANG, + WMI_SERVICE_FORCE_FW_HANG); + SVCMAP(WMI_MAIN_SERVICE_GPIO, + WMI_SERVICE_GPIO); + SVCMAP(WMI_MAIN_SERVICE_STA_DTIM_PS_MODULATED_DTIM, + WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM); + SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, + WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG); + SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, + WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG); + SVCMAP(WMI_MAIN_SERVICE_STA_KEEP_ALIVE, + WMI_SERVICE_STA_KEEP_ALIVE); + SVCMAP(WMI_MAIN_SERVICE_TX_ENCAP, + WMI_SERVICE_TX_ENCAP); +} + +#undef SVCMAP #define WMI_SERVICE_BM_SIZE \ ((WMI_MAX_SERVICE + sizeof(u32) - 1)/sizeof(u32)) @@ -1229,10 +1392,6 @@ struct wlan_host_mem_req { __le32 num_units; } __packed; -#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \ - ((((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ - (1 << ((svc_id)%(sizeof(u32))))) != 0) - /* * The following struct holds optional payload for * wmi_service_ready_event,e.g., 11ac pass some of the -- GitLab From 9ff8b7247dd211158410af4bb5ebbc507182729f Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 5 Aug 2014 14:54:43 +0200 Subject: [PATCH 0218/9167] ath10k: simplify scan debug prints This also reduces the cruft of printing scan event names in capitals. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/wmi.c | 67 +++++++++++++++------------ 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index a381006c8124..f48f29563a4d 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -811,6 +811,42 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) return ret; } +static const char * +ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type, + enum wmi_scan_completion_reason reason) +{ + switch (type) { + case WMI_SCAN_EVENT_STARTED: + return "started"; + case WMI_SCAN_EVENT_COMPLETED: + switch (reason) { + case WMI_SCAN_REASON_COMPLETED: + return "completed"; + case WMI_SCAN_REASON_CANCELLED: + return "completed [cancelled]"; + case WMI_SCAN_REASON_PREEMPTED: + return "completed [preempted]"; + case WMI_SCAN_REASON_TIMEDOUT: + return "completed [timedout]"; + case WMI_SCAN_REASON_MAX: + break; + } + return "completed [unknown]"; + case WMI_SCAN_EVENT_BSS_CHANNEL: + return "bss channel"; + case WMI_SCAN_EVENT_FOREIGN_CHANNEL: + return "foreign channel"; + case WMI_SCAN_EVENT_DEQUEUED: + return "dequeued"; + case WMI_SCAN_EVENT_PREEMPTED: + return "preempted"; + case WMI_SCAN_EVENT_START_FAILED: + return "start failed"; + default: + return "unknown"; + } +} + static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) { struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data; @@ -828,41 +864,22 @@ static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) scan_id = __le32_to_cpu(event->scan_id); vdev_id = __le32_to_cpu(event->vdev_id); - ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENTID\n"); ath10k_dbg(ATH10K_DBG_WMI, - "scan event type %d reason %d freq %d req_id %d " + "scan event %s type %d reason %d freq %d req_id %d " "scan_id %d vdev_id %d\n", + ath10k_wmi_event_scan_type_str(event_type, reason), event_type, reason, freq, req_id, scan_id, vdev_id); spin_lock_bh(&ar->data_lock); switch (event_type) { case WMI_SCAN_EVENT_STARTED: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_STARTED\n"); if (ar->scan.in_progress && ar->scan.is_roc) ieee80211_ready_on_channel(ar->hw); complete(&ar->scan.started); break; case WMI_SCAN_EVENT_COMPLETED: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_COMPLETED\n"); - switch (reason) { - case WMI_SCAN_REASON_COMPLETED: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_COMPLETED\n"); - break; - case WMI_SCAN_REASON_CANCELLED: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_CANCELED\n"); - break; - case WMI_SCAN_REASON_PREEMPTED: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_PREEMPTED\n"); - break; - case WMI_SCAN_REASON_TIMEDOUT: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_TIMEDOUT\n"); - break; - default: - break; - } - ar->scan_channel = NULL; if (!ar->scan.in_progress) { ath10k_warn("no scan requested, ignoring\n"); @@ -883,11 +900,9 @@ static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) ar->scan.in_progress = false; break; case WMI_SCAN_EVENT_BSS_CHANNEL: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_BSS_CHANNEL\n"); ar->scan_channel = NULL; break; case WMI_SCAN_EVENT_FOREIGN_CHANNEL: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_FOREIGN_CHANNEL\n"); ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq); if (ar->scan.in_progress && ar->scan.is_roc && ar->scan.roc_freq == freq) { @@ -895,14 +910,8 @@ static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) } break; case WMI_SCAN_EVENT_DEQUEUED: - ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_DEQUEUED\n"); - break; case WMI_SCAN_EVENT_PREEMPTED: - ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENT_PREEMPTED\n"); - break; case WMI_SCAN_EVENT_START_FAILED: - ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENT_START_FAILED\n"); - break; default: break; } -- GitLab From 5c81c7fd62004be13a3c9345ca25607d14862cc4 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 5 Aug 2014 14:54:44 +0200 Subject: [PATCH 0219/9167] ath10k: introduce a stricter scan state machine This aims at fixing some rare scan bugs related to firmware reporting unexpected scan event sequences. One such bug was if spectral scan phyerr reporting prevented firmware from properly propagating scan events to host. This led to scan timeout. After that next scan would trigger scan completed event first (before scan started event) leading to ar->scan.in_progress and timeout timer states to be overwritten incorrectly and making the very next scan to hang forever. Reported-by: Janusz Dziedzic Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 5 +- drivers/net/wireless/ath/ath10k/core.h | 28 ++- drivers/net/wireless/ath/ath10k/mac.c | 238 +++++++++++++++---------- drivers/net/wireless/ath/ath10k/mac.h | 4 +- drivers/net/wireless/ath/ath10k/wmi.c | 143 +++++++++++---- 5 files changed, 281 insertions(+), 137 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 440c3ff03aec..c090913d10d1 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -665,8 +665,7 @@ static void ath10k_core_restart(struct work_struct *work) switch (ar->state) { case ATH10K_STATE_ON: ar->state = ATH10K_STATE_RESTARTING; - del_timer_sync(&ar->scan.timeout); - ath10k_reset_scan((unsigned long)ar); + ath10k_scan_finish(ar); ieee80211_restart_hw(ar->hw); break; case ATH10K_STATE_OFF: @@ -1086,7 +1085,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, init_completion(&ar->install_key_done); init_completion(&ar->vdev_setup_done); - setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); + INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work); ar->workqueue = create_singlethread_workqueue("ath10k_wq"); if (!ar->workqueue) diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 94b1ff2082cf..95c611db43b8 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -348,6 +348,29 @@ enum ath10k_dev_flags { ATH10K_FLAG_CORE_REGISTERED, }; +enum ath10k_scan_state { + ATH10K_SCAN_IDLE, + ATH10K_SCAN_STARTING, + ATH10K_SCAN_RUNNING, + ATH10K_SCAN_ABORTING, +}; + +static inline const char *ath10k_scan_state_str(enum ath10k_scan_state state) +{ + switch (state) { + case ATH10K_SCAN_IDLE: + return "idle"; + case ATH10K_SCAN_STARTING: + return "starting"; + case ATH10K_SCAN_RUNNING: + return "running"; + case ATH10K_SCAN_ABORTING: + return "aborting"; + } + + return "unknown"; +} + struct ath10k { struct ath_common ath_common; struct ieee80211_hw *hw; @@ -417,10 +440,9 @@ struct ath10k { struct completion started; struct completion completed; struct completion on_channel; - struct timer_list timeout; + struct delayed_work timeout; + enum ath10k_scan_state state; bool is_roc; - bool in_progress; - bool aborting; int vdev_id; int roc_freq; } scan; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 3c7942030361..3bf7ddeb3271 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2159,34 +2159,40 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work) /* Scanning */ /************/ -/* - * This gets called if we dont get a heart-beat during scan. - * This may indicate the FW has hung and we need to abort the - * scan manually to prevent cancel_hw_scan() from deadlocking - */ -void ath10k_reset_scan(unsigned long ptr) +void __ath10k_scan_finish(struct ath10k *ar) { - struct ath10k *ar = (struct ath10k *)ptr; + lockdep_assert_held(&ar->data_lock); - spin_lock_bh(&ar->data_lock); - if (!ar->scan.in_progress) { - spin_unlock_bh(&ar->data_lock); - return; + switch (ar->scan.state) { + 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 + ieee80211_scan_completed(ar->hw, + (ar->scan.state == + ATH10K_SCAN_ABORTING)); + /* fall through */ + case ATH10K_SCAN_STARTING: + ar->scan.state = ATH10K_SCAN_IDLE; + ar->scan_channel = NULL; + ath10k_offchan_tx_purge(ar); + cancel_delayed_work(&ar->scan.timeout); + complete_all(&ar->scan.completed); + break; } +} - ath10k_warn("scan timed out, firmware problem?\n"); - - if (ar->scan.is_roc) - ieee80211_remain_on_channel_expired(ar->hw); - else - ieee80211_scan_completed(ar->hw, 1 /* aborted */); - - ar->scan.in_progress = false; - complete_all(&ar->scan.completed); +void ath10k_scan_finish(struct ath10k *ar) +{ + spin_lock_bh(&ar->data_lock); + __ath10k_scan_finish(ar); spin_unlock_bh(&ar->data_lock); } -static int ath10k_abort_scan(struct ath10k *ar) +static int ath10k_scan_stop(struct ath10k *ar) { struct wmi_stop_scan_arg arg = { .req_id = 1, /* FIXME */ @@ -2197,47 +2203,79 @@ static int ath10k_abort_scan(struct ath10k *ar) lockdep_assert_held(&ar->conf_mutex); - del_timer_sync(&ar->scan.timeout); - - spin_lock_bh(&ar->data_lock); - if (!ar->scan.in_progress) { - spin_unlock_bh(&ar->data_lock); - return 0; - } - - ar->scan.aborting = true; - spin_unlock_bh(&ar->data_lock); - ret = ath10k_wmi_stop_scan(ar, &arg); if (ret) { ath10k_warn("failed to stop wmi scan: %d\n", ret); - spin_lock_bh(&ar->data_lock); - ar->scan.in_progress = false; - ath10k_offchan_tx_purge(ar); - spin_unlock_bh(&ar->data_lock); - return -EIO; + goto out; } ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ); - if (ret == 0) - ath10k_warn("timed out while waiting for scan to stop\n"); + if (ret == 0) { + ath10k_warn("failed to receive scan abortion completion: timed out\n"); + ret = -ETIMEDOUT; + } else if (ret > 0) { + ret = 0; + } - /* scan completion may be done right after we timeout here, so let's - * check the in_progress and tell mac80211 scan is completed. if we - * don't do that and FW fails to send us scan completion indication - * then userspace won't be able to scan anymore */ - ret = 0; +out: + /* Scan state should be updated upon scan completion but in case + * firmware fails to deliver the event (for whatever reason) it is + * desired to clean up scan state anyway. Firmware may have just + * dropped the scan completion event delivery due to transport pipe + * being overflown with data and/or it can recover on its own before + * next scan request is submitted. + */ + spin_lock_bh(&ar->data_lock); + if (ar->scan.state != ATH10K_SCAN_IDLE) + __ath10k_scan_finish(ar); + spin_unlock_bh(&ar->data_lock); + + return ret; +} + +static void ath10k_scan_abort(struct ath10k *ar) +{ + int ret; + + lockdep_assert_held(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); - if (ar->scan.in_progress) { - ath10k_warn("failed to stop scan, it's still in progress\n"); - ar->scan.in_progress = false; - ath10k_offchan_tx_purge(ar); - ret = -ETIMEDOUT; + + switch (ar->scan.state) { + case ATH10K_SCAN_IDLE: + /* This can happen if timeout worker kicked in and called + * abortion while scan completion was being processed. + */ + break; + case ATH10K_SCAN_STARTING: + case ATH10K_SCAN_ABORTING: + ath10k_warn("refusing scan abortion due to invalid scan state: %s (%d)\n", + ath10k_scan_state_str(ar->scan.state), + ar->scan.state); + break; + case ATH10K_SCAN_RUNNING: + ar->scan.state = ATH10K_SCAN_ABORTING; + spin_unlock_bh(&ar->data_lock); + + ret = ath10k_scan_stop(ar); + if (ret) + ath10k_warn("failed to abort scan: %d\n", ret); + + spin_lock_bh(&ar->data_lock); + break; } + spin_unlock_bh(&ar->data_lock); +} - return ret; +void ath10k_scan_timeout_work(struct work_struct *work) +{ + struct ath10k *ar = container_of(work, struct ath10k, + scan.timeout.work); + + mutex_lock(&ar->conf_mutex); + ath10k_scan_abort(ar); + mutex_unlock(&ar->conf_mutex); } static int ath10k_start_scan(struct ath10k *ar, @@ -2253,17 +2291,16 @@ static int ath10k_start_scan(struct ath10k *ar, ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ); if (ret == 0) { - ath10k_abort_scan(ar); - return ret; + ret = ath10k_scan_stop(ar); + if (ret) + ath10k_warn("failed to stop scan: %d\n", ret); + + return -ETIMEDOUT; } - /* the scan can complete earlier, before we even - * start the timer. in that case the timer handler - * checks ar->scan.in_progress and bails out if its - * false. Add a 200ms margin to account event/command - * processing. */ - mod_timer(&ar->scan.timeout, jiffies + - msecs_to_jiffies(arg->max_scan_time+200)); + /* Add a 200ms margin to account for event/command processing */ + ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, + msecs_to_jiffies(arg->max_scan_time+200)); return 0; } @@ -2339,8 +2376,7 @@ void ath10k_halt(struct ath10k *ar) ath10k_monitor_stop(ar); } - del_timer_sync(&ar->scan.timeout); - ath10k_reset_scan((unsigned long)ar); + ath10k_scan_finish(ar); ath10k_peer_cleanup_all(ar); ath10k_core_stop(ar); ath10k_hif_power_down(ar); @@ -2531,6 +2567,7 @@ static void ath10k_stop(struct ieee80211_hw *hw) } mutex_unlock(&ar->conf_mutex); + cancel_delayed_work_sync(&ar->scan.timeout); cancel_work_sync(&ar->restart_work); } @@ -3176,20 +3213,26 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw, mutex_lock(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); - if (ar->scan.in_progress) { - spin_unlock_bh(&ar->data_lock); + switch (ar->scan.state) { + case ATH10K_SCAN_IDLE: + reinit_completion(&ar->scan.started); + reinit_completion(&ar->scan.completed); + ar->scan.state = ATH10K_SCAN_STARTING; + ar->scan.is_roc = false; + ar->scan.vdev_id = arvif->vdev_id; + ret = 0; + break; + case ATH10K_SCAN_STARTING: + case ATH10K_SCAN_RUNNING: + case ATH10K_SCAN_ABORTING: ret = -EBUSY; - goto exit; + break; } - - reinit_completion(&ar->scan.started); - reinit_completion(&ar->scan.completed); - ar->scan.in_progress = true; - ar->scan.aborting = false; - ar->scan.is_roc = false; - ar->scan.vdev_id = arvif->vdev_id; spin_unlock_bh(&ar->data_lock); + if (ret) + goto exit; + memset(&arg, 0, sizeof(arg)); ath10k_wmi_start_scan_init(ar, &arg); arg.vdev_id = arvif->vdev_id; @@ -3223,7 +3266,7 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw, if (ret) { ath10k_warn("failed to start hw scan: %d\n", ret); spin_lock_bh(&ar->data_lock); - ar->scan.in_progress = false; + ar->scan.state = ATH10K_SCAN_IDLE; spin_unlock_bh(&ar->data_lock); } @@ -3236,14 +3279,10 @@ static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { struct ath10k *ar = hw->priv; - int ret; mutex_lock(&ar->conf_mutex); - ret = ath10k_abort_scan(ar); - if (ret) { - ath10k_warn("failed to abort scan: %d\n", ret); - ieee80211_scan_completed(hw, 1 /* aborted */); - } + cancel_delayed_work_sync(&ar->scan.timeout); + ath10k_scan_abort(ar); mutex_unlock(&ar->conf_mutex); } @@ -3666,27 +3705,33 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw, struct ath10k *ar = hw->priv; struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); struct wmi_start_scan_arg arg; - int ret; + int ret = 0; mutex_lock(&ar->conf_mutex); spin_lock_bh(&ar->data_lock); - if (ar->scan.in_progress) { - spin_unlock_bh(&ar->data_lock); + switch (ar->scan.state) { + case ATH10K_SCAN_IDLE: + reinit_completion(&ar->scan.started); + reinit_completion(&ar->scan.completed); + reinit_completion(&ar->scan.on_channel); + ar->scan.state = ATH10K_SCAN_STARTING; + ar->scan.is_roc = true; + ar->scan.vdev_id = arvif->vdev_id; + ar->scan.roc_freq = chan->center_freq; + ret = 0; + break; + case ATH10K_SCAN_STARTING: + case ATH10K_SCAN_RUNNING: + case ATH10K_SCAN_ABORTING: ret = -EBUSY; - goto exit; + break; } - - reinit_completion(&ar->scan.started); - reinit_completion(&ar->scan.completed); - reinit_completion(&ar->scan.on_channel); - ar->scan.in_progress = true; - ar->scan.aborting = false; - ar->scan.is_roc = true; - ar->scan.vdev_id = arvif->vdev_id; - ar->scan.roc_freq = chan->center_freq; spin_unlock_bh(&ar->data_lock); + if (ret) + goto exit; + memset(&arg, 0, sizeof(arg)); ath10k_wmi_start_scan_init(ar, &arg); arg.vdev_id = arvif->vdev_id; @@ -3703,7 +3748,7 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw, if (ret) { ath10k_warn("failed to start roc scan: %d\n", ret); spin_lock_bh(&ar->data_lock); - ar->scan.in_progress = false; + ar->scan.state = ATH10K_SCAN_IDLE; spin_unlock_bh(&ar->data_lock); goto exit; } @@ -3711,7 +3756,11 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw, ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ); if (ret == 0) { ath10k_warn("failed to switch to channel for roc scan\n"); - ath10k_abort_scan(ar); + + ret = ath10k_scan_stop(ar); + if (ret) + ath10k_warn("failed to stop scan: %d\n", ret); + ret = -ETIMEDOUT; goto exit; } @@ -3727,7 +3776,8 @@ static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw) struct ath10k *ar = hw->priv; mutex_lock(&ar->conf_mutex); - ath10k_abort_scan(ar); + cancel_delayed_work_sync(&ar->scan.timeout); + ath10k_scan_abort(ar); mutex_unlock(&ar->conf_mutex); return 0; diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index ef4f84376d7c..e64fce70e9eb 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -31,7 +31,9 @@ void ath10k_mac_destroy(struct ath10k *ar); int ath10k_mac_register(struct ath10k *ar); void ath10k_mac_unregister(struct ath10k *ar); struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id); -void ath10k_reset_scan(unsigned long ptr); +void __ath10k_scan_finish(struct ath10k *ar); +void ath10k_scan_finish(struct ath10k *ar); +void ath10k_scan_timeout_work(struct work_struct *work); void ath10k_offchan_tx_purge(struct ath10k *ar); void ath10k_offchan_tx_work(struct work_struct *work); void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar); diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index f48f29563a4d..23acbadeb8fa 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -811,6 +811,94 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) return ret; } +static void ath10k_wmi_event_scan_started(struct ath10k *ar) +{ + lockdep_assert_held(&ar->data_lock); + + switch (ar->scan.state) { + case ATH10K_SCAN_IDLE: + case ATH10K_SCAN_RUNNING: + case ATH10K_SCAN_ABORTING: + ath10k_warn("received scan started event in an invalid scan state: %s (%d)\n", + ath10k_scan_state_str(ar->scan.state), + ar->scan.state); + break; + case ATH10K_SCAN_STARTING: + ar->scan.state = ATH10K_SCAN_RUNNING; + + if (ar->scan.is_roc) + ieee80211_ready_on_channel(ar->hw); + + complete(&ar->scan.started); + break; + } +} + +static void ath10k_wmi_event_scan_completed(struct ath10k *ar) +{ + lockdep_assert_held(&ar->data_lock); + + switch (ar->scan.state) { + case ATH10K_SCAN_IDLE: + case ATH10K_SCAN_STARTING: + /* One suspected reason scan can be completed while starting is + * if firmware fails to deliver all scan events to the host, + * e.g. when transport pipe is full. This has been observed + * with spectral scan phyerr events starving wmi transport + * pipe. In such case the "scan completed" event should be (and + * is) ignored by the host as it may be just firmware's scan + * state machine recovering. + */ + ath10k_warn("received scan completed event in an invalid scan state: %s (%d)\n", + ath10k_scan_state_str(ar->scan.state), + ar->scan.state); + break; + case ATH10K_SCAN_RUNNING: + case ATH10K_SCAN_ABORTING: + __ath10k_scan_finish(ar); + break; + } +} + +static void ath10k_wmi_event_scan_bss_chan(struct ath10k *ar) +{ + lockdep_assert_held(&ar->data_lock); + + switch (ar->scan.state) { + case ATH10K_SCAN_IDLE: + case ATH10K_SCAN_STARTING: + ath10k_warn("received scan bss chan event in an invalid scan state: %s (%d)\n", + ath10k_scan_state_str(ar->scan.state), + ar->scan.state); + break; + case ATH10K_SCAN_RUNNING: + case ATH10K_SCAN_ABORTING: + ar->scan_channel = NULL; + break; + } +} + +static void ath10k_wmi_event_scan_foreign_chan(struct ath10k *ar, u32 freq) +{ + lockdep_assert_held(&ar->data_lock); + + switch (ar->scan.state) { + case ATH10K_SCAN_IDLE: + case ATH10K_SCAN_STARTING: + ath10k_warn("received scan foreign chan event in an invalid scan state: %s (%d)\n", + ath10k_scan_state_str(ar->scan.state), + ar->scan.state); + break; + case ATH10K_SCAN_RUNNING: + case ATH10K_SCAN_ABORTING: + ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq); + + if (ar->scan.is_roc && ar->scan.roc_freq == freq) + complete(&ar->scan.on_channel); + break; + } +} + static const char * ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type, enum wmi_scan_completion_reason reason) @@ -864,54 +952,32 @@ static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) scan_id = __le32_to_cpu(event->scan_id); vdev_id = __le32_to_cpu(event->vdev_id); + spin_lock_bh(&ar->data_lock); + ath10k_dbg(ATH10K_DBG_WMI, - "scan event %s type %d reason %d freq %d req_id %d " - "scan_id %d vdev_id %d\n", + "scan event %s type %d reason %d freq %d req_id %d scan_id %d vdev_id %d state %s (%d)\n", ath10k_wmi_event_scan_type_str(event_type, reason), - event_type, reason, freq, req_id, scan_id, vdev_id); - - spin_lock_bh(&ar->data_lock); + event_type, reason, freq, req_id, scan_id, vdev_id, + ath10k_scan_state_str(ar->scan.state), ar->scan.state); switch (event_type) { case WMI_SCAN_EVENT_STARTED: - if (ar->scan.in_progress && ar->scan.is_roc) - ieee80211_ready_on_channel(ar->hw); - - complete(&ar->scan.started); + ath10k_wmi_event_scan_started(ar); break; case WMI_SCAN_EVENT_COMPLETED: - ar->scan_channel = NULL; - if (!ar->scan.in_progress) { - ath10k_warn("no scan requested, ignoring\n"); - break; - } - - if (ar->scan.is_roc) { - ath10k_offchan_tx_purge(ar); - - if (!ar->scan.aborting) - ieee80211_remain_on_channel_expired(ar->hw); - } else { - ieee80211_scan_completed(ar->hw, ar->scan.aborting); - } - - del_timer(&ar->scan.timeout); - complete_all(&ar->scan.completed); - ar->scan.in_progress = false; + ath10k_wmi_event_scan_completed(ar); break; case WMI_SCAN_EVENT_BSS_CHANNEL: - ar->scan_channel = NULL; + ath10k_wmi_event_scan_bss_chan(ar); break; case WMI_SCAN_EVENT_FOREIGN_CHANNEL: - ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq); - if (ar->scan.in_progress && ar->scan.is_roc && - ar->scan.roc_freq == freq) { - complete(&ar->scan.on_channel); - } + ath10k_wmi_event_scan_foreign_chan(ar, freq); + break; + case WMI_SCAN_EVENT_START_FAILED: + ath10k_warn("received scan start failure event\n"); break; case WMI_SCAN_EVENT_DEQUEUED: case WMI_SCAN_EVENT_PREEMPTED: - case WMI_SCAN_EVENT_START_FAILED: default: break; } @@ -1171,9 +1237,14 @@ static void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) spin_lock_bh(&ar->data_lock); - if (!ar->scan.in_progress) { - ath10k_warn("chan info event without a scan request?\n"); + switch (ar->scan.state) { + case ATH10K_SCAN_IDLE: + case ATH10K_SCAN_STARTING: + ath10k_warn("received chan info event without a scan request, ignoring\n"); goto exit; + case ATH10K_SCAN_RUNNING: + case ATH10K_SCAN_ABORTING: + break; } idx = freq_to_idx(ar, freq); -- GitLab From e7b541948b7ae542267257a6183341f6a92ed1b8 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 7 Aug 2014 11:03:27 +0200 Subject: [PATCH 0220/9167] ath10k: embed ar_pci inside ar Use the common convention of embedding private structures inside parent structures. This reduces allocations and simplifies pci probing code. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 5 ++--- drivers/net/wireless/ath/ath10k/core.h | 6 ++++-- drivers/net/wireless/ath/ath10k/mac.c | 4 ++-- drivers/net/wireless/ath/ath10k/mac.h | 2 +- drivers/net/wireless/ath/ath10k/pci.c | 25 +++++++++---------------- drivers/net/wireless/ath/ath10k/pci.h | 2 +- 6 files changed, 19 insertions(+), 25 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index c090913d10d1..7f95bd05e343 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1059,12 +1059,12 @@ void ath10k_core_unregister(struct ath10k *ar) } EXPORT_SYMBOL(ath10k_core_unregister); -struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, +struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, const struct ath10k_hif_ops *hif_ops) { struct ath10k *ar; - ar = ath10k_mac_create(); + ar = ath10k_mac_create(priv_size); if (!ar) return NULL; @@ -1074,7 +1074,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, ar->p2p = !!ath10k_p2p; ar->dev = dev; - ar->hif.priv = hif_priv; ar->hif.ops = hif_ops; init_completion(&ar->scan.started); diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index 95c611db43b8..cca6060dbf30 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h @@ -398,7 +398,6 @@ struct ath10k { bool p2p; struct { - void *priv; const struct ath10k_hif_ops *ops; } hif; @@ -532,9 +531,12 @@ struct ath10k { enum ath10k_spectral_mode mode; struct ath10k_spec_scan config; } spectral; + + /* must be last */ + u8 drv_priv[0] __aligned(sizeof(void *)); }; -struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, +struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, const struct ath10k_hif_ops *hif_ops); void ath10k_core_destroy(struct ath10k *ar); diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 3bf7ddeb3271..a5ec7c2502b5 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -4564,12 +4564,12 @@ static struct ieee80211_rate ath10k_rates[] = { #define ath10k_g_rates (ath10k_rates + 0) #define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates)) -struct ath10k *ath10k_mac_create(void) +struct ath10k *ath10k_mac_create(size_t priv_size) { struct ieee80211_hw *hw; struct ath10k *ar; - hw = ieee80211_alloc_hw(sizeof(struct ath10k), &ath10k_ops); + hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops); if (!hw) return NULL; diff --git a/drivers/net/wireless/ath/ath10k/mac.h b/drivers/net/wireless/ath/ath10k/mac.h index e64fce70e9eb..6c80eeada3e2 100644 --- a/drivers/net/wireless/ath/ath10k/mac.h +++ b/drivers/net/wireless/ath/ath10k/mac.h @@ -26,7 +26,7 @@ struct ath10k_generic_iter { int ret; }; -struct ath10k *ath10k_mac_create(void); +struct ath10k *ath10k_mac_create(size_t priv_size); void ath10k_mac_destroy(struct ath10k *ar); int ath10k_mac_register(struct ath10k *ar); void ath10k_mac_unregister(struct ath10k *ar); diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 2d340cc522e3..a2003b66a8bc 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2621,10 +2621,14 @@ static int ath10k_pci_probe(struct pci_dev *pdev, ath10k_dbg(ATH10K_DBG_PCI, "pci probe\n"); - ar_pci = kzalloc(sizeof(*ar_pci), GFP_KERNEL); - if (ar_pci == NULL) + ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, + &ath10k_pci_hif_ops); + if (!ar) { + ath10k_err("failed to allocate core\n"); return -ENOMEM; + } + ar_pci = ath10k_pci_priv(ar); ar_pci->pdev = pdev; ar_pci->dev = &pdev->dev; @@ -2635,7 +2639,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, default: ret = -ENODEV; ath10k_err("Unknown device ID: %d\n", pci_dev->device); - goto err_ar_pci; + goto err_core_destroy; } if (ath10k_pci_target_ps) @@ -2643,13 +2647,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev, ath10k_pci_dump_features(ar_pci); - ar = ath10k_core_create(ar_pci, ar_pci->dev, &ath10k_pci_hif_ops); - if (!ar) { - ath10k_err("failed to create driver core\n"); - ret = -EINVAL; - goto err_ar_pci; - } - ar_pci->ar = ar; atomic_set(&ar_pci->keep_awake_count, 0); @@ -2658,7 +2655,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev, ret = pci_enable_device(pdev); if (ret) { ath10k_err("failed to enable PCI device: %d\n", ret); - goto err_ar; + goto err_core_destroy; } /* Request MMIO resources */ @@ -2742,11 +2739,8 @@ static int ath10k_pci_probe(struct pci_dev *pdev, pci_release_region(pdev, BAR_NUM); err_device: pci_disable_device(pdev); -err_ar: +err_core_destroy: ath10k_core_destroy(ar); -err_ar_pci: - /* call HIF PCI free here */ - kfree(ar_pci); return ret; } @@ -2775,7 +2769,6 @@ static void ath10k_pci_remove(struct pci_dev *pdev) pci_disable_device(pdev); ath10k_core_destroy(ar); - kfree(ar_pci); } MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index 940129209990..531c98aa4a86 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h @@ -202,7 +202,7 @@ struct ath10k_pci { static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) { - return ar->hif.priv; + return (struct ath10k_pci *)ar->drv_priv; } static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr) -- GitLab From c0c378f9907c9e52aa95a87ac4622039a84bac99 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 7 Aug 2014 11:03:28 +0200 Subject: [PATCH 0221/9167] ath10k: remove target soc ps code The soc powersave was disabled by default. It never was fully tested. Some hw apparently had problems with it and the implementation itself had a possible race. Just remove the refcounting and simply wake up the device when probing and put to sleep when removing. kvalo: make ath10k_pci_wake() and _sleep() static Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/ce.c | 68 +--------- drivers/net/wireless/ath/ath10k/pci.c | 185 ++++++-------------------- drivers/net/wireless/ath/ath10k/pci.h | 67 ++-------- 3 files changed, 55 insertions(+), 265 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 4333107ecf37..5117705f7f3d 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -287,10 +287,6 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n", __func__, nbytes, ce_state->src_sz_max); - ret = ath10k_pci_wake(ar); - if (ret) - return ret; - if (unlikely(CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) <= 0)) { ret = -ENOSR; @@ -325,7 +321,6 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, src_ring->write_index = write_index; exit: - ath10k_pci_sleep(ar); return ret; } @@ -407,10 +402,6 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, write_index = dest_ring->write_index; sw_index = dest_ring->sw_index; - ret = ath10k_pci_wake(ar); - if (ret) - goto out; - if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) { struct ce_desc *base = dest_ring->base_addr_owner_space; struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index); @@ -430,11 +421,8 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, } else { ret = -EIO; } - ath10k_pci_sleep(ar); -out: spin_unlock_bh(&ar_pci->ce_lock); - return ret; } @@ -588,7 +576,6 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, unsigned int sw_index = src_ring->sw_index; struct ce_desc *sdesc, *sbase; unsigned int read_index; - int ret; if (src_ring->hw_index == sw_index) { /* @@ -599,18 +586,12 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, * value of the HW index has become stale. */ - ret = ath10k_pci_wake(ar); - if (ret) - return ret; - read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); if (read_index == 0xffffffff) return -ENODEV; read_index &= nentries_mask; src_ring->hw_index = read_index; - - ath10k_pci_sleep(ar); } read_index = src_ring->hw_index; @@ -731,11 +712,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; u32 ctrl_addr = ce_state->ctrl_addr; - int ret; - - ret = ath10k_pci_wake(ar); - if (ret) - return; spin_lock_bh(&ar_pci->ce_lock); @@ -760,7 +736,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) ath10k_ce_engine_int_status_clear(ar, ctrl_addr, CE_WATERMARK_MASK); spin_unlock_bh(&ar_pci->ce_lock); - ath10k_pci_sleep(ar); } /* @@ -771,13 +746,9 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) void ath10k_ce_per_engine_service_any(struct ath10k *ar) { - int ce_id, ret; + int ce_id; u32 intr_summary; - ret = ath10k_pci_wake(ar); - if (ret) - return; - intr_summary = CE_INTERRUPT_SUMMARY(ar); for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) { @@ -789,8 +760,6 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar) ath10k_ce_per_engine_service(ar, ce_id); } - - ath10k_pci_sleep(ar); } /* @@ -805,11 +774,6 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state, { u32 ctrl_addr = ce_state->ctrl_addr; struct ath10k *ar = ce_state->ar; - int ret; - - ret = ath10k_pci_wake(ar); - if (ret) - return; if ((!disable_copy_compl_intr) && (ce_state->send_cb || ce_state->recv_cb)) @@ -818,17 +782,11 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state, ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); ath10k_ce_watermark_intr_disable(ar, ctrl_addr); - - ath10k_pci_sleep(ar); } int ath10k_ce_disable_interrupts(struct ath10k *ar) { - int ce_id, ret; - - ret = ath10k_pci_wake(ar); - if (ret) - return ret; + int ce_id; for (ce_id = 0; ce_id < CE_COUNT; ce_id++) { u32 ctrl_addr = ath10k_ce_base_address(ce_id); @@ -838,8 +796,6 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar) ath10k_ce_watermark_intr_disable(ar, ctrl_addr); } - ath10k_pci_sleep(ar); - return 0; } @@ -1084,10 +1040,6 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); - ret = ath10k_pci_wake(ar); - if (ret) - return ret; - spin_lock_bh(&ar_pci->ce_lock); ce_state->ar = ar; ce_state->id = ce_id; @@ -1101,7 +1053,7 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, if (ret) { ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", ce_id, ret); - goto out; + return ret; } } @@ -1110,13 +1062,11 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, if (ret) { ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", ce_id, ret); - goto out; + return ret; } } -out: - ath10k_pci_sleep(ar); - return ret; + return 0; } static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id) @@ -1140,16 +1090,8 @@ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id) void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) { - int ret; - - ret = ath10k_pci_wake(ar); - if (ret) - return; - ath10k_ce_deinit_src_ring(ar, ce_id); ath10k_ce_deinit_dest_ring(ar, ce_id); - - ath10k_pci_sleep(ar); } int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index a2003b66a8bc..42be18c054ef 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -44,13 +44,9 @@ enum ath10k_pci_reset_mode { ATH10K_PCI_RESET_WARM_ONLY = 1, }; -static unsigned int ath10k_pci_target_ps; static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO; static unsigned int ath10k_pci_reset_mode = ATH10K_PCI_RESET_AUTO; -module_param_named(target_ps, ath10k_pci_target_ps, uint, 0644); -MODULE_PARM_DESC(target_ps, "Enable ath10k Target (SoC) PS option"); - module_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644); MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)"); @@ -389,10 +385,8 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data, * convert it from Target CPU virtual address space * to CE address space */ - ath10k_pci_wake(ar); address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, address); - ath10k_pci_sleep(ar); ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, 0); @@ -474,9 +468,7 @@ static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, if (address >= DRAM_BASE_ADDRESS) return ath10k_pci_diag_read_mem(ar, address, data, sizeof(u32)); - ath10k_pci_wake(ar); *data = ath10k_pci_read32(ar, address); - ath10k_pci_sleep(ar); return 0; } @@ -528,9 +520,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, * to * CE address space */ - ath10k_pci_wake(ar); address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, address); - ath10k_pci_sleep(ar); remaining_bytes = orig_nbytes; ce_data = ce_data_base; @@ -623,51 +613,25 @@ static int ath10k_pci_diag_write_access(struct ath10k *ar, u32 address, return ath10k_pci_diag_write_mem(ar, address, &data, sizeof(u32)); - ath10k_pci_wake(ar); ath10k_pci_write32(ar, address, data); - ath10k_pci_sleep(ar); return 0; } -static bool ath10k_pci_target_is_awake(struct ath10k *ar) +static bool ath10k_pci_is_awake(struct ath10k *ar) { - void __iomem *mem = ath10k_pci_priv(ar)->mem; - u32 val; - val = ioread32(mem + PCIE_LOCAL_BASE_ADDRESS + - RTC_STATE_ADDRESS); - return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON); + u32 val = ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS); + + return RTC_STATE_V_GET(val) == RTC_STATE_V_ON; } -int ath10k_do_pci_wake(struct ath10k *ar) +static int ath10k_pci_wake_wait(struct ath10k *ar) { - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - void __iomem *pci_addr = ar_pci->mem; int tot_delay = 0; int curr_delay = 5; - if (atomic_read(&ar_pci->keep_awake_count) == 0) { - /* Force AWAKE */ - iowrite32(PCIE_SOC_WAKE_V_MASK, - pci_addr + PCIE_LOCAL_BASE_ADDRESS + - PCIE_SOC_WAKE_ADDRESS); - } - atomic_inc(&ar_pci->keep_awake_count); - - if (ar_pci->verified_awake) - return 0; - - for (;;) { - if (ath10k_pci_target_is_awake(ar)) { - ar_pci->verified_awake = true; + while (tot_delay < PCIE_WAKE_TIMEOUT) { + if (ath10k_pci_is_awake(ar)) return 0; - } - - if (tot_delay > PCIE_WAKE_TIMEOUT) { - ath10k_warn("target took longer %d us to wake up (awake count %d)\n", - PCIE_WAKE_TIMEOUT, - atomic_read(&ar_pci->keep_awake_count)); - return -ETIMEDOUT; - } udelay(curr_delay); tot_delay += curr_delay; @@ -675,20 +639,21 @@ int ath10k_do_pci_wake(struct ath10k *ar) if (curr_delay < 50) curr_delay += 5; } + + return -ETIMEDOUT; } -void ath10k_do_pci_sleep(struct ath10k *ar) +static int ath10k_pci_wake(struct ath10k *ar) { - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - void __iomem *pci_addr = ar_pci->mem; + ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, + PCIE_SOC_WAKE_V_MASK); + return ath10k_pci_wake_wait(ar); +} - if (atomic_dec_and_test(&ar_pci->keep_awake_count)) { - /* Allow sleep */ - ar_pci->verified_awake = false; - iowrite32(PCIE_SOC_WAKE_RESET, - pci_addr + PCIE_LOCAL_BASE_ADDRESS + - PCIE_SOC_WAKE_ADDRESS); - } +static void ath10k_pci_sleep(struct ath10k *ar) +{ + ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, + PCIE_SOC_WAKE_RESET); } /* Called by lower (CE) layer when a send to Target completes. */ @@ -1788,8 +1753,6 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar) struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); u32 fw_indicator; - ath10k_pci_wake(ar); - fw_indicator = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); if (fw_indicator & FW_IND_EVENT_PENDING) { @@ -1807,8 +1770,6 @@ static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar) ath10k_warn("early firmware event indicated\n"); } } - - ath10k_pci_sleep(ar); } /* this function effectively clears target memory controller assert line */ @@ -1833,17 +1794,10 @@ static void ath10k_pci_warm_reset_si0(struct ath10k *ar) static int ath10k_pci_warm_reset(struct ath10k *ar) { - int ret = 0; u32 val; ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset\n"); - ret = ath10k_do_pci_wake(ar); - if (ret) { - ath10k_err("failed to wake up target: %d\n", ret); - return ret; - } - /* debug */ val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_CAUSE_ADDRESS); @@ -1915,8 +1869,7 @@ static int ath10k_pci_warm_reset(struct ath10k *ar) ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset complete\n"); - ath10k_do_pci_sleep(ar); - return ret; + return 0; } static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) @@ -1945,14 +1898,10 @@ static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) goto err; } - if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) - /* Force AWAKE forever */ - ath10k_do_pci_wake(ar); - ret = ath10k_pci_ce_init(ar); if (ret) { ath10k_err("failed to initialize CE: %d\n", ret); - goto err_ps; + goto err; } ret = ath10k_ce_disable_interrupts(ar); @@ -2012,9 +1961,6 @@ 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_ps: - if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) - ath10k_do_pci_sleep(ar); err: return ret; } @@ -2078,8 +2024,6 @@ static int ath10k_pci_hif_power_up(struct ath10k *ar) static void ath10k_pci_hif_power_down(struct ath10k *ar) { - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power down\n"); ath10k_pci_free_early_irq(ar); @@ -2087,9 +2031,6 @@ static void ath10k_pci_hif_power_down(struct ath10k *ar) ath10k_pci_deinit_irq(ar); ath10k_pci_ce_deinit(ar); ath10k_pci_warm_reset(ar); - - if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) - ath10k_do_pci_sleep(ar); } #ifdef CONFIG_PM @@ -2236,14 +2177,6 @@ static void ath10k_pci_early_irq_tasklet(unsigned long data) { struct ath10k *ar = (struct ath10k *)data; u32 fw_ind; - int ret; - - ret = ath10k_pci_wake(ar); - if (ret) { - ath10k_warn("failed to wake target in early irq tasklet: %d\n", - ret); - return; - } fw_ind = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); if (fw_ind & FW_IND_EVENT_PENDING) { @@ -2252,7 +2185,6 @@ static void ath10k_pci_early_irq_tasklet(unsigned long data) ath10k_pci_hif_dump_area(ar); } - ath10k_pci_sleep(ar); ath10k_pci_enable_legacy_irq(ar); } @@ -2426,34 +2358,16 @@ static int ath10k_pci_init_irq(struct ath10k *ar) * synchronization checking. */ ar_pci->num_msi_intrs = 0; - ret = ath10k_pci_wake(ar); - if (ret) { - ath10k_warn("failed to wake target: %d\n", ret); - return ret; - } - ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); - ath10k_pci_sleep(ar); return 0; } -static int ath10k_pci_deinit_irq_legacy(struct ath10k *ar) +static void ath10k_pci_deinit_irq_legacy(struct ath10k *ar) { - int ret; - - ret = ath10k_pci_wake(ar); - if (ret) { - ath10k_warn("failed to wake target: %d\n", ret); - return ret; - } - ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, 0); - ath10k_pci_sleep(ar); - - return 0; } static int ath10k_pci_deinit_irq(struct ath10k *ar) @@ -2462,7 +2376,8 @@ static int ath10k_pci_deinit_irq(struct ath10k *ar) switch (ar_pci->num_msi_intrs) { case 0: - return ath10k_pci_deinit_irq_legacy(ar); + ath10k_pci_deinit_irq_legacy(ar); + return 0; case 1: /* fall-through */ case MSI_NUM_REQUEST: @@ -2480,17 +2395,10 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); unsigned long timeout; - int ret; u32 val; ath10k_dbg(ATH10K_DBG_BOOT, "boot waiting target to initialise\n"); - ret = ath10k_pci_wake(ar); - if (ret) { - ath10k_err("failed to wake up target for init: %d\n", ret); - return ret; - } - timeout = jiffies + msecs_to_jiffies(ATH10K_PCI_TARGET_WAIT); do { @@ -2520,8 +2428,7 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar) if (val == 0xffffffff) { ath10k_err("failed to read device register, device is gone\n"); - ret = -EIO; - goto out; + return -EIO; } if (val & FW_IND_EVENT_PENDING) { @@ -2529,38 +2436,26 @@ static int ath10k_pci_wait_for_target_init(struct ath10k *ar) ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, val & ~FW_IND_EVENT_PENDING); ath10k_pci_hif_dump_area(ar); - ret = -ECOMM; - goto out; + return -ECOMM; } if (!(val & FW_IND_INITIALIZED)) { ath10k_err("failed to receive initialized event from target: %08x\n", val); - ret = -ETIMEDOUT; - goto out; + return -ETIMEDOUT; } ath10k_dbg(ATH10K_DBG_BOOT, "boot target initialised\n"); - -out: - ath10k_pci_sleep(ar); - return ret; + return 0; } static int ath10k_pci_cold_reset(struct ath10k *ar) { - int i, ret; + int i; u32 val; ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset\n"); - ret = ath10k_do_pci_wake(ar); - if (ret) { - ath10k_err("failed to wake up target: %d\n", - ret); - return ret; - } - /* Put Target, including PCIe, into RESET. */ val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS); val |= 1; @@ -2584,8 +2479,6 @@ static int ath10k_pci_cold_reset(struct ath10k *ar) msleep(1); } - ath10k_do_pci_sleep(ar); - ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset complete\n"); return 0; @@ -2603,9 +2496,6 @@ static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci) case ATH10K_PCI_FEATURE_MSI_X: ath10k_dbg(ATH10K_DBG_BOOT, "device supports MSI-X\n"); break; - case ATH10K_PCI_FEATURE_SOC_POWER_SAVE: - ath10k_dbg(ATH10K_DBG_BOOT, "QCA98XX SoC power save enabled\n"); - break; } } } @@ -2642,13 +2532,9 @@ static int ath10k_pci_probe(struct pci_dev *pdev, goto err_core_destroy; } - if (ath10k_pci_target_ps) - set_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features); - ath10k_pci_dump_features(ar_pci); ar_pci->ar = ar; - atomic_set(&ar_pci->keep_awake_count, 0); pci_set_drvdata(pdev, ar); @@ -2703,20 +2589,22 @@ static int ath10k_pci_probe(struct pci_dev *pdev, spin_lock_init(&ar_pci->ce_lock); - ret = ath10k_do_pci_wake(ar); + ret = ath10k_pci_wake(ar); if (ret) { - ath10k_err("Failed to get chip id: %d\n", ret); + ath10k_err("failed to wake up: %d\n", ret); goto err_iomap; } chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); - - ath10k_do_pci_sleep(ar); + if (chip_id == 0xffffffff) { + ath10k_err("failed to get chip id\n"); + goto err_sleep; + } ret = ath10k_pci_alloc_ce(ar); if (ret) { ath10k_err("failed to allocate copy engine pipes: %d\n", ret); - goto err_iomap; + goto err_sleep; } ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); @@ -2731,6 +2619,8 @@ static int ath10k_pci_probe(struct pci_dev *pdev, err_free_ce: ath10k_pci_free_ce(ar); +err_sleep: + ath10k_pci_sleep(ar); err_iomap: pci_iounmap(pdev, mem); err_master: @@ -2762,6 +2652,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev) ath10k_core_unregister(ar); ath10k_pci_free_ce(ar); + ath10k_pci_sleep(ar); pci_iounmap(pdev, ar_pci->mem); pci_release_region(pdev, BAR_NUM); diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index 531c98aa4a86..65b1b90cd5d3 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h @@ -137,7 +137,6 @@ struct service_to_pipe { enum ath10k_pci_features { ATH10K_PCI_FEATURE_MSI_X = 0, - ATH10K_PCI_FEATURE_SOC_POWER_SAVE = 1, /* keep last */ ATH10K_PCI_FEATURE_COUNT @@ -183,9 +182,6 @@ struct ath10k_pci { int started; - atomic_t keep_awake_count; - bool verified_awake; - struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; struct ath10k_hif_cb msg_callbacks_current; @@ -205,20 +201,6 @@ static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) return (struct ath10k_pci *)ar->drv_priv; } -static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr) -{ - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - - return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); -} - -static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) -{ - struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - - iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); -} - #define ATH_PCI_RESET_WAIT_MAX 10 /* ms */ #define PCIE_WAKE_TIMEOUT 5000 /* 5ms */ @@ -242,35 +224,17 @@ static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) /* Wait up to this many Ms for a Diagnostic Access CE operation to complete */ #define DIAG_ACCESS_CE_TIMEOUT_MS 10 -/* - * This API allows the Host to access Target registers directly - * and relatively efficiently over PCIe. - * This allows the Host to avoid extra overhead associated with - * sending a message to firmware and waiting for a response message - * from firmware, as is done on other interconnects. - * - * Yet there is some complexity with direct accesses because the - * Target's power state is not known a priori. The Host must issue - * special PCIe reads/writes in order to explicitly wake the Target - * and to verify that it is awake and will remain awake. +/* Target exposes its registers for direct access. However before host can + * access them it needs to make sure the target is awake (ath10k_pci_wake, + * ath10k_pci_wake_wait, ath10k_pci_is_awake). Once target is awake it won't go + * to sleep unless host tells it to (ath10k_pci_sleep). * - * Usage: + * If host tries to access target registers without waking it up it can + * scribble over host memory. * - * Use ath10k_pci_read32 and ath10k_pci_write32 to access Target space. - * These calls must be bracketed by ath10k_pci_wake and - * ath10k_pci_sleep. A single BEGIN/END pair is adequate for - * multiple READ/WRITE operations. - * - * Use ath10k_pci_wake to put the Target in a state in - * which it is legal for the Host to directly access it. This - * may involve waking the Target from a low power state, which - * may take up to 2Ms! - * - * Use ath10k_pci_sleep to tell the Target that as far as - * this code path is concerned, it no longer needs to remain - * directly accessible. BEGIN/END is under a reference counter; - * multiple code paths may issue BEGIN/END on a single targid. + * If target is asleep waking it up may take up to even 2ms. */ + static inline void ath10k_pci_write32(struct ath10k *ar, u32 offset, u32 value) { @@ -296,25 +260,18 @@ static inline void ath10k_pci_soc_write32(struct ath10k *ar, u32 addr, u32 val) ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + addr, val); } -int ath10k_do_pci_wake(struct ath10k *ar); -void ath10k_do_pci_sleep(struct ath10k *ar); - -static inline int ath10k_pci_wake(struct ath10k *ar) +static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) - return ath10k_do_pci_wake(ar); - - return 0; + return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); } -static inline void ath10k_pci_sleep(struct ath10k *ar) +static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) - ath10k_do_pci_sleep(ar); + iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); } #endif /* _PCI_H_ */ -- GitLab From 0edf2577a5927aa8d1521f22da753e1d0c2a4db4 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 7 Aug 2014 11:03:29 +0200 Subject: [PATCH 0222/9167] ath10k: remove pci features var The ATH10K_PCI_FEATURE_MSI_X was originally introduced to support both chips QCA988Xv1 and QCA988Xv2. Since v1 isn't supported anymore it doesn't make sense to keep the feature flag around. Since this is the last one remove the whole thing. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 33 +-------------------------- drivers/net/wireless/ath/ath10k/pci.h | 9 -------- 2 files changed, 1 insertion(+), 41 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 42be18c054ef..bbad9662b0fd 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2317,8 +2317,6 @@ static void ath10k_pci_init_irq_tasklets(struct ath10k *ar) static int ath10k_pci_init_irq(struct ath10k *ar) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); - bool msix_supported = test_bit(ATH10K_PCI_FEATURE_MSI_X, - ar_pci->features); int ret; ath10k_pci_init_irq_tasklets(ar); @@ -2328,7 +2326,7 @@ static int ath10k_pci_init_irq(struct ath10k *ar) ath10k_info("limiting irq mode to: %d\n", ath10k_pci_irq_mode); /* Try MSI-X */ - if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO && msix_supported) { + if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO) { ar_pci->num_msi_intrs = MSI_NUM_REQUEST; ret = pci_enable_msi_range(ar_pci->pdev, ar_pci->num_msi_intrs, ar_pci->num_msi_intrs); @@ -2484,22 +2482,6 @@ static int ath10k_pci_cold_reset(struct ath10k *ar) return 0; } -static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci) -{ - int i; - - for (i = 0; i < ATH10K_PCI_FEATURE_COUNT; i++) { - if (!test_bit(i, ar_pci->features)) - continue; - - switch (i) { - case ATH10K_PCI_FEATURE_MSI_X: - ath10k_dbg(ATH10K_DBG_BOOT, "device supports MSI-X\n"); - break; - } - } -} - static int ath10k_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_dev) { @@ -2521,19 +2503,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev, ar_pci = ath10k_pci_priv(ar); ar_pci->pdev = pdev; ar_pci->dev = &pdev->dev; - - switch (pci_dev->device) { - case QCA988X_2_0_DEVICE_ID: - set_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features); - break; - default: - ret = -ENODEV; - ath10k_err("Unknown device ID: %d\n", pci_dev->device); - goto err_core_destroy; - } - - ath10k_pci_dump_features(ar_pci); - ar_pci->ar = ar; pci_set_drvdata(pdev, ar); diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index 65b1b90cd5d3..662bca3922ef 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h @@ -135,13 +135,6 @@ struct service_to_pipe { u32 pipenum; }; -enum ath10k_pci_features { - ATH10K_PCI_FEATURE_MSI_X = 0, - - /* keep last */ - ATH10K_PCI_FEATURE_COUNT -}; - /* Per-pipe state. */ struct ath10k_pci_pipe { /* Handle of underlying Copy Engine */ @@ -168,8 +161,6 @@ struct ath10k_pci { struct ath10k *ar; void __iomem *mem; - DECLARE_BITMAP(features, ATH10K_PCI_FEATURE_COUNT); - /* * Number of MSI interrupts granted, 0 --> using legacy PCI line * interrupts. -- GitLab From 2986e3efb84fc79e798c1967beec6bb5eede7dee Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 7 Aug 2014 11:03:30 +0200 Subject: [PATCH 0223/9167] ath10k: group some pci probing helpers Make probe/remove functions shorter and easier to understand. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/pci.c | 134 +++++++++++++++----------- 1 file changed, 77 insertions(+), 57 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index bbad9662b0fd..98c029b7d0ab 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c @@ -2482,86 +2482,116 @@ static int ath10k_pci_cold_reset(struct ath10k *ar) return 0; } -static int ath10k_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *pci_dev) +static int ath10k_pci_claim(struct ath10k *ar) { - void __iomem *mem; - int ret = 0; - struct ath10k *ar; - struct ath10k_pci *ar_pci; - u32 lcr_val, chip_id; - - ath10k_dbg(ATH10K_DBG_PCI, "pci probe\n"); - - ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, - &ath10k_pci_hif_ops); - if (!ar) { - ath10k_err("failed to allocate core\n"); - return -ENOMEM; - } - - ar_pci = ath10k_pci_priv(ar); - ar_pci->pdev = pdev; - ar_pci->dev = &pdev->dev; - ar_pci->ar = ar; + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + struct pci_dev *pdev = ar_pci->pdev; + u32 lcr_val; + int ret; pci_set_drvdata(pdev, ar); ret = pci_enable_device(pdev); if (ret) { - ath10k_err("failed to enable PCI device: %d\n", ret); - goto err_core_destroy; + ath10k_err("failed to enable pci device: %d\n", ret); + return ret; } - /* Request MMIO resources */ ret = pci_request_region(pdev, BAR_NUM, "ath"); if (ret) { - ath10k_err("failed to request MMIO region: %d\n", ret); + ath10k_err("failed to request region BAR%d: %d\n", BAR_NUM, + ret); goto err_device; } - /* - * Target structures have a limit of 32 bit DMA pointers. - * DMA pointers can be wider than 32 bits by default on some systems. - */ + /* Target expects 32 bit DMA. Enforce it. */ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { - ath10k_err("failed to set DMA mask to 32-bit: %d\n", ret); + ath10k_err("failed to set dma mask to 32-bit: %d\n", ret); goto err_region; } ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { - ath10k_err("failed to set consistent DMA mask to 32-bit\n"); + ath10k_err("failed to set consistent dma mask to 32-bit: %d\n", + ret); goto err_region; } - /* Set bus master bit in PCI_COMMAND to enable DMA */ pci_set_master(pdev); - /* - * Temporary FIX: disable ASPM - * Will be removed after the OTP is programmed - */ + /* Workaround: Disable ASPM */ pci_read_config_dword(pdev, 0x80, &lcr_val); pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00)); /* Arrange for access to Target SoC registers. */ - mem = pci_iomap(pdev, BAR_NUM, 0); - if (!mem) { - ath10k_err("failed to perform IOMAP for BAR%d\n", BAR_NUM); + ar_pci->mem = pci_iomap(pdev, BAR_NUM, 0); + if (!ar_pci->mem) { + ath10k_err("failed to iomap BAR%d\n", BAR_NUM); ret = -EIO; goto err_master; } - ar_pci->mem = mem; + ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); + return 0; + +err_master: + pci_clear_master(pdev); + +err_region: + pci_release_region(pdev, BAR_NUM); + +err_device: + pci_disable_device(pdev); + + return ret; +} + +static void ath10k_pci_release(struct ath10k *ar) +{ + struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); + struct pci_dev *pdev = ar_pci->pdev; + + pci_iounmap(pdev, ar_pci->mem); + pci_release_region(pdev, BAR_NUM); + pci_clear_master(pdev); + pci_disable_device(pdev); +} + +static int ath10k_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *pci_dev) +{ + int ret = 0; + struct ath10k *ar; + struct ath10k_pci *ar_pci; + u32 chip_id; + + ath10k_dbg(ATH10K_DBG_PCI, "pci probe\n"); + + ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, + &ath10k_pci_hif_ops); + if (!ar) { + ath10k_err("failed to allocate core\n"); + return -ENOMEM; + } + + ar_pci = ath10k_pci_priv(ar); + ar_pci->pdev = pdev; + ar_pci->dev = &pdev->dev; + ar_pci->ar = ar; spin_lock_init(&ar_pci->ce_lock); + ret = ath10k_pci_claim(ar); + if (ret) { + ath10k_err("failed to claim device: %d\n", ret); + goto err_core_destroy; + } + ret = ath10k_pci_wake(ar); if (ret) { ath10k_err("failed to wake up: %d\n", ret); - goto err_iomap; + goto err_release; } chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); @@ -2576,8 +2606,6 @@ static int ath10k_pci_probe(struct pci_dev *pdev, goto err_sleep; } - ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); - ret = ath10k_core_register(ar, chip_id); if (ret) { ath10k_err("failed to register driver core: %d\n", ret); @@ -2588,16 +2616,13 @@ static int ath10k_pci_probe(struct pci_dev *pdev, err_free_ce: ath10k_pci_free_ce(ar); + err_sleep: ath10k_pci_sleep(ar); -err_iomap: - pci_iounmap(pdev, mem); -err_master: - pci_clear_master(pdev); -err_region: - pci_release_region(pdev, BAR_NUM); -err_device: - pci_disable_device(pdev); + +err_release: + ath10k_pci_release(ar); + err_core_destroy: ath10k_core_destroy(ar); @@ -2622,12 +2647,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev) ath10k_core_unregister(ar); ath10k_pci_free_ce(ar); ath10k_pci_sleep(ar); - - pci_iounmap(pdev, ar_pci->mem); - pci_release_region(pdev, BAR_NUM); - pci_clear_master(pdev); - pci_disable_device(pdev); - + ath10k_pci_release(ar); ath10k_core_destroy(ar); } -- GitLab From b7967dc79fbd32ef198b429b2597459a4130207f Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Thu, 7 Aug 2014 11:03:31 +0200 Subject: [PATCH 0224/9167] ath10k: remove htc->stopped This is not necessary anymore. There are no more uncontrolled htc tx entry points. Signed-off-by: Michal Kazior Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 13 +++++-------- drivers/net/wireless/ath/ath10k/htc.c | 16 ---------------- drivers/net/wireless/ath/ath10k/htc.h | 5 +---- 3 files changed, 6 insertions(+), 28 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 7f95bd05e343..d3474b43ac47 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -779,7 +779,7 @@ int ath10k_core_start(struct ath10k *ar) if (status <= 0) { ath10k_warn("wmi service ready event not received"); status = -ETIMEDOUT; - goto err_htc_stop; + goto err_hif_stop; } ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n", @@ -788,25 +788,25 @@ int ath10k_core_start(struct ath10k *ar) status = ath10k_wmi_cmd_init(ar); if (status) { ath10k_err("could not send WMI init command (%d)\n", status); - goto err_htc_stop; + goto err_hif_stop; } status = ath10k_wmi_wait_for_unified_ready(ar); if (status <= 0) { ath10k_err("wmi unified ready event not received\n"); status = -ETIMEDOUT; - goto err_htc_stop; + goto err_hif_stop; } status = ath10k_htt_setup(&ar->htt); if (status) { ath10k_err("failed to setup htt: %d\n", status); - goto err_htc_stop; + goto err_hif_stop; } status = ath10k_debug_start(ar); if (status) - goto err_htc_stop; + 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; @@ -835,8 +835,6 @@ int ath10k_core_start(struct ath10k *ar) return 0; -err_htc_stop: - ath10k_htc_stop(&ar->htc); err_hif_stop: ath10k_hif_stop(ar); err_htt_rx_detach: @@ -881,7 +879,6 @@ void ath10k_core_stop(struct ath10k *ar) ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); ath10k_debug_stop(ar); - ath10k_htc_stop(&ar->htc); ath10k_hif_stop(ar); ath10k_htt_tx_free(&ar->htt); ath10k_htt_rx_free(&ar->htt); diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c index 5fdc40d3b378..7e08bb328847 100644 --- a/drivers/net/wireless/ath/ath10k/htc.c +++ b/drivers/net/wireless/ath/ath10k/htc.c @@ -138,14 +138,6 @@ int ath10k_htc_send(struct ath10k_htc *htc, return -ENOENT; } - /* FIXME: This looks ugly, can we fix it? */ - spin_lock_bh(&htc->tx_lock); - if (htc->stopped) { - spin_unlock_bh(&htc->tx_lock); - return -ESHUTDOWN; - } - spin_unlock_bh(&htc->tx_lock); - skb_push(skb, sizeof(struct ath10k_htc_hdr)); if (ep->tx_credit_flow_enabled) { @@ -846,13 +838,6 @@ int ath10k_htc_start(struct ath10k_htc *htc) return 0; } -void ath10k_htc_stop(struct ath10k_htc *htc) -{ - spin_lock_bh(&htc->tx_lock); - htc->stopped = true; - spin_unlock_bh(&htc->tx_lock); -} - /* registered target arrival callback from the HIF layer */ int ath10k_htc_init(struct ath10k *ar) { @@ -862,7 +847,6 @@ int ath10k_htc_init(struct ath10k *ar) spin_lock_init(&htc->tx_lock); - htc->stopped = false; ath10k_htc_reset_endpoint_states(htc); /* setup HIF layer callbacks */ diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h index 4716d331e6b6..b5a9daacc2c2 100644 --- a/drivers/net/wireless/ath/ath10k/htc.h +++ b/drivers/net/wireless/ath/ath10k/htc.h @@ -332,7 +332,7 @@ struct ath10k_htc { struct ath10k *ar; struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT]; - /* protects endpoint and stopped fields */ + /* protects endpoints */ spinlock_t tx_lock; struct ath10k_htc_ops htc_ops; @@ -345,8 +345,6 @@ struct ath10k_htc { int total_transmit_credits; struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT]; int target_credit_size; - - bool stopped; }; int ath10k_htc_init(struct ath10k *ar); @@ -357,7 +355,6 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc, struct ath10k_htc_svc_conn_resp *conn_resp); int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid, struct sk_buff *packet); -void ath10k_htc_stop(struct ath10k_htc *htc); struct sk_buff *ath10k_htc_alloc_skb(int size); #endif -- GitLab From 743cb1ff191f00fee653212bdbcee1e56086d6ce Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 29 Jul 2014 17:00:21 +0200 Subject: [PATCH 0225/9167] sched/fair: Make calculate_imbalance() independent Rik noticed that calculate_imbalance() relies on update_sd_pick_busiest() to guarantee that busiest->sum_nr_running > busiest->group_capacity_factor. Break this implicit assumption (with the intent of not providing it anymore) by having calculat_imbalance() verify it and not rely on others. Reported-by: Rik van Riel Signed-off-by: Peter Zijlstra Acked-by: Vincent Guittot Cc: Linus Torvalds Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/20140729152631.GW12054@laptop.lan Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index bfa3c86d0d68..e9477e6193fc 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6248,7 +6248,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s return fix_small_imbalance(env, sds); } - if (!busiest->group_imb) { + if (busiest->sum_nr_running > busiest->group_capacity_factor) { /* * Don't want to pull so many tasks that a group would go idle. * Except of course for the group_imb case, since then we might -- GitLab From caeb178c60f4f93f1b45c0bc056b5cf6d217b67f Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Mon, 28 Jul 2014 14:16:28 -0400 Subject: [PATCH 0226/9167] sched/fair: Make update_sd_pick_busiest() return 'true' on a busier sd Currently update_sd_pick_busiest only identifies the busiest sd that is either overloaded, or has a group imbalance. When no sd is imbalanced or overloaded, the load balancer fails to find the busiest domain. This breaks load balancing between domains that are not overloaded, in the !SD_ASYM_PACKING case. This patch makes update_sd_pick_busiest return true when the busiest sd yet is encountered. Groups are ranked in the order overloaded > imbalanced > other, with higher ranked groups getting priority even when their load is lower. This is necessary due to the possibility of unequal capacities and cpumasks between domains within a sched group. Behaviour for SD_ASYM_PACKING does not seem to match the comment, but I have no hardware to test that so I have left the behaviour of that code unchanged. Enum for group classification suggested by Peter Zijlstra. Signed-off-by: Rik van Riel [peterz: replaced sg_lb_stats::group_imb with the new enum group_type in an attempt to avoid endless recalculation] Signed-off-by: Peter Zijlstra Acked-by: Vincent Guittot Acked-by: Michael Neuling Cc: ktkhai@parallels.com Cc: tim.c.chen@linux.intel.com Cc: nicolas.pitre@linaro.org Cc: jhladky@redhat.com Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20140729152743.GI3935@laptop Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 49 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e9477e6193fc..94377254254e 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5559,6 +5559,13 @@ static unsigned long task_h_load(struct task_struct *p) #endif /********** Helpers for find_busiest_group ************************/ + +enum group_type { + group_other = 0, + group_imbalanced, + group_overloaded, +}; + /* * sg_lb_stats - stats of a sched_group required for load_balancing */ @@ -5572,7 +5579,7 @@ struct sg_lb_stats { unsigned int group_capacity_factor; unsigned int idle_cpus; unsigned int group_weight; - int group_imb; /* Is there an imbalance in the group ? */ + enum group_type group_type; int group_has_free_capacity; #ifdef CONFIG_NUMA_BALANCING unsigned int nr_numa_running; @@ -5610,6 +5617,8 @@ static inline void init_sd_lb_stats(struct sd_lb_stats *sds) .total_capacity = 0UL, .busiest_stat = { .avg_load = 0UL, + .sum_nr_running = 0, + .group_type = group_other, }, }; } @@ -5891,6 +5900,18 @@ static inline int sg_capacity_factor(struct lb_env *env, struct sched_group *gro return capacity_factor; } +static enum group_type +group_classify(struct sched_group *group, struct sg_lb_stats *sgs) +{ + if (sgs->sum_nr_running > sgs->group_capacity_factor) + return group_overloaded; + + if (sg_imbalanced(group)) + return group_imbalanced; + + return group_other; +} + /** * update_sg_lb_stats - Update sched_group's statistics for load balancing. * @env: The load balancing environment. @@ -5942,9 +5963,8 @@ static inline void update_sg_lb_stats(struct lb_env *env, sgs->load_per_task = sgs->sum_weighted_load / sgs->sum_nr_running; sgs->group_weight = group->group_weight; - - sgs->group_imb = sg_imbalanced(group); sgs->group_capacity_factor = sg_capacity_factor(env, group); + sgs->group_type = group_classify(group, sgs); if (sgs->group_capacity_factor > sgs->sum_nr_running) sgs->group_has_free_capacity = 1; @@ -5968,13 +5988,19 @@ static bool update_sd_pick_busiest(struct lb_env *env, struct sched_group *sg, struct sg_lb_stats *sgs) { - if (sgs->avg_load <= sds->busiest_stat.avg_load) - return false; + struct sg_lb_stats *busiest = &sds->busiest_stat; - if (sgs->sum_nr_running > sgs->group_capacity_factor) + if (sgs->group_type > busiest->group_type) return true; - if (sgs->group_imb) + if (sgs->group_type < busiest->group_type) + return false; + + if (sgs->avg_load <= busiest->avg_load) + return false; + + /* This is the busiest node in its class. */ + if (!(env->sd->flags & SD_ASYM_PACKING)) return true; /* @@ -5982,8 +6008,7 @@ static bool update_sd_pick_busiest(struct lb_env *env, * numbered CPUs in the group, therefore mark all groups * higher than ourself as busy. */ - if ((env->sd->flags & SD_ASYM_PACKING) && sgs->sum_nr_running && - env->dst_cpu < group_first_cpu(sg)) { + if (sgs->sum_nr_running && env->dst_cpu < group_first_cpu(sg)) { if (!sds->busiest) return true; @@ -6228,7 +6253,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s local = &sds->local_stat; busiest = &sds->busiest_stat; - if (busiest->group_imb) { + if (busiest->group_type == group_imbalanced) { /* * In the group_imb case we cannot rely on group-wide averages * to ensure cpu-load equilibrium, look at wider averages. XXX @@ -6248,7 +6273,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s return fix_small_imbalance(env, sds); } - if (busiest->sum_nr_running > busiest->group_capacity_factor) { + if (busiest->group_type == group_overloaded) { /* * Don't want to pull so many tasks that a group would go idle. * Except of course for the group_imb case, since then we might @@ -6337,7 +6362,7 @@ static struct sched_group *find_busiest_group(struct lb_env *env) * work because they assume all things are equal, which typically * isn't true due to cpus_allowed constraints and the like. */ - if (busiest->group_imb) + if (busiest->group_type == group_imbalanced) goto force_balance; /* SD_BALANCE_NEWIDLE trumps SMP nice when underutilized */ -- GitLab From 9a5d9ba6a3631d55c358fe1bdbaa162a97471a05 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 29 Jul 2014 17:15:11 +0200 Subject: [PATCH 0227/9167] sched/fair: Allow calculate_imbalance() to move idle cpus Allow calculate_imbalance() to 'create' idle cpus in the busiest group if there are idle cpus in the local group. Suggested-by: Rik van Riel Signed-off-by: Peter Zijlstra Acked-by: Vincent Guittot Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20140729152705.GX12054@laptop.lan Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 94377254254e..df1ed176c7b7 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -6273,12 +6273,11 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s return fix_small_imbalance(env, sds); } - if (busiest->group_type == group_overloaded) { - /* - * Don't want to pull so many tasks that a group would go idle. - * Except of course for the group_imb case, since then we might - * have to drop below capacity to reach cpu-load equilibrium. - */ + /* + * If there aren't any idle cpus, avoid creating some. + */ + if (busiest->group_type == group_overloaded && + local->group_type == group_overloaded) { load_above_capacity = (busiest->sum_nr_running - busiest->group_capacity_factor); -- GitLab From aaecac4ad46b35ad308245384d019633fb9bc21b Mon Sep 17 00:00:00 2001 From: Zhihui Zhang Date: Fri, 1 Aug 2014 21:18:03 -0400 Subject: [PATCH 0228/9167] sched: Rename a misleading variable in build_overlap_sched_groups() The child variable in build_overlap_sched_groups() actually refers to the peer or sibling domain of the given CPU. Rename it to sibling to be consistent with the naming in build_group_mask(). Signed-off-by: Zhihui Zhang Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/1406942283-18249-1-git-send-email-zzhsuny@gmail.com Signed-off-by: Ingo Molnar --- kernel/sched/core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1211575a2208..7d1ec6e60535 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -5739,7 +5739,7 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu) const struct cpumask *span = sched_domain_span(sd); struct cpumask *covered = sched_domains_tmpmask; struct sd_data *sdd = sd->private; - struct sched_domain *child; + struct sched_domain *sibling; int i; cpumask_clear(covered); @@ -5750,10 +5750,10 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu) if (cpumask_test_cpu(i, covered)) continue; - child = *per_cpu_ptr(sdd->sd, i); + sibling = *per_cpu_ptr(sdd->sd, i); /* See the comment near build_group_mask(). */ - if (!cpumask_test_cpu(i, sched_domain_span(child))) + if (!cpumask_test_cpu(i, sched_domain_span(sibling))) continue; sg = kzalloc_node(sizeof(struct sched_group) + cpumask_size(), @@ -5763,10 +5763,9 @@ build_overlap_sched_groups(struct sched_domain *sd, int cpu) goto fail; sg_span = sched_group_cpus(sg); - if (child->child) { - child = child->child; - cpumask_copy(sg_span, sched_domain_span(child)); - } else + if (sibling->child) + cpumask_copy(sg_span, sched_domain_span(sibling->child)); + else cpumask_set_cpu(i, sg_span); cpumask_or(covered, covered, sg_span); -- GitLab From b932c03c34f3b03c7364c06aa8cae5b74609fc41 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Mon, 4 Aug 2014 13:23:27 -0400 Subject: [PATCH 0229/9167] sched/numa: Fix off-by-one in capacity check Commit a43455a1d572daf7b730fe12eb747d1e17411365 ensures that task_numa_migrate will call task_numa_compare on the preferred node all the time, even when the preferred node has no free capacity. This could lead to a performance regression if nr_running == capacity on both the source and the destination node. This can be avoided by also checking for nr_running == capacity on the source node, which is one stricter than checking .has_free_capacity. Signed-off-by: Rik van Riel Signed-off-by: Peter Zijlstra Cc: mgorman@suse.de Cc: vincent.guittot@linaro.org Cc: Morten.Rasmussen@arm.com Cc: nicolas.pitre@linaro.org Cc: efault@gmx.de Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1407173008-9334-2-git-send-email-riel@redhat.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index df1ed176c7b7..e1cf419c3c7f 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1206,7 +1206,7 @@ static void task_numa_compare(struct task_numa_env *env, if (!cur) { /* Is there capacity at our destination? */ - if (env->src_stats.has_free_capacity && + if (env->src_stats.nr_running <= env->src_stats.task_capacity && !env->dst_stats.has_free_capacity) goto unlock; -- GitLab From 83d7f2424741c9dc76c21377c9d00d47abaf88df Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Mon, 4 Aug 2014 13:23:28 -0400 Subject: [PATCH 0230/9167] sched/numa: Fix numa capacity computation Commit c61037e9 fixes the phenomenon of 'fantom' cores due to N*frac(smt_power) >= 1 by limiting the capacity to the actual number of cores in the load balancing code. This patch applies the same correction to the NUMA balancing code. Signed-off-by: Rik van Riel Signed-off-by: Peter Zijlstra Cc: mgorman@suse.de Cc: vincent.guittot@linaro.org Cc: Morten.Rasmussen@arm.com Cc: nicolas.pitre@linaro.org Cc: efault@gmx.de Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1407173008-9334-3-git-send-email-riel@redhat.com Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index e1cf419c3c7f..1413c44ce8a1 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -1038,7 +1038,8 @@ struct numa_stats { */ static void update_numa_stats(struct numa_stats *ns, int nid) { - int cpu, cpus = 0; + int smt, cpu, cpus = 0; + unsigned long capacity; memset(ns, 0, sizeof(*ns)); for_each_cpu(cpu, cpumask_of_node(nid)) { @@ -1062,8 +1063,12 @@ static void update_numa_stats(struct numa_stats *ns, int nid) if (!cpus) return; - ns->task_capacity = - DIV_ROUND_CLOSEST(ns->compute_capacity, SCHED_CAPACITY_SCALE); + /* smt := ceil(cpus / capacity), assumes: 1 < smt_power < 2 */ + smt = DIV_ROUND_UP(SCHED_CAPACITY_SCALE * cpus, ns->compute_capacity); + capacity = cpus / smt; /* cores */ + + ns->task_capacity = min_t(unsigned, capacity, + DIV_ROUND_CLOSEST(ns->compute_capacity, SCHED_CAPACITY_SCALE)); ns->has_free_capacity = (ns->nr_running < ns->task_capacity); } -- GitLab From b9d06dd9d1dd3672b391e6387d62aa8dc4e377bd Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Wed, 6 Aug 2014 15:04:44 +0200 Subject: [PATCH 0231/9167] drm/i915: vma/ppgtt lifetime rules VMAs should take a reference of the address space they use. Now, when the fd is closed, it will release the ref that the context was holding, but it will still be referenced by any vmas that are still active. ppgtt_release() should then only be called when the last thing referencing it releases the ref, and it can just call the base cleanup and free the ppgtt. Note that with this we will extend the lifetime of ppgtts which contain shared objects. But all the non-shared objects will get removed as soon as they drop of the active list and for the shared ones the shrinker can eventually reap them. Since we currently can't evict ppgtt pagetables either I don't think that temporary leak is important. Signed-off-by: Michel Thierry [danvet: Add note about potential ppgtt leak with this approach.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 8 ++++++++ drivers/gpu/drm/i915/i915_gem_context.c | 23 +++-------------------- drivers/gpu/drm/i915/i915_gem_gtt.c | 5 +++++ 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 53cc4c083d0d..38b1849a450a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2547,7 +2547,9 @@ void i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj); /* i915_gem_context.c */ #define ctx_to_ppgtt(ctx) container_of((ctx)->vm, struct i915_hw_ppgtt, base) +#define vm_to_ppgtt(vm) container_of(vm, struct i915_hw_ppgtt, base) int __must_check i915_gem_context_init(struct drm_device *dev); +void ppgtt_release(struct kref *kref); void i915_gem_context_fini(struct drm_device *dev); void i915_gem_context_reset(struct drm_device *dev); int i915_gem_context_open(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 9acb2469116a..63aee412b258 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4476,12 +4476,20 @@ struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, void i915_gem_vma_destroy(struct i915_vma *vma) { + struct i915_address_space *vm = NULL; + struct i915_hw_ppgtt *ppgtt = NULL; WARN_ON(vma->node.allocated); /* Keep the vma as a placeholder in the execbuffer reservation lists */ if (!list_empty(&vma->exec_list)) return; + vm = vma->vm; + ppgtt = vm_to_ppgtt(vm); + + if (ppgtt) + kref_put(&ppgtt->ref, ppgtt_release); + list_del(&vma->vma_link); kfree(vma); diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 7a08f3e9e1ae..a509a4bca991 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -108,30 +108,13 @@ static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) return; } - /* - * Make sure vmas are unbound before we take down the drm_mm - * - * FIXME: Proper refcounting should take care of this, this shouldn't be - * needed at all. - */ - if (!list_empty(&vm->active_list)) { - struct i915_vma *vma; - - list_for_each_entry(vma, &vm->active_list, mm_list) - if (WARN_ON(list_empty(&vma->vma_link) || - list_is_singular(&vma->vma_link))) - break; - - i915_gem_evict_vm(&ppgtt->base, true); - } else { - i915_gem_retire_requests(dev); - i915_gem_evict_vm(&ppgtt->base, false); - } + /* vmas should already be unbound */ + WARN_ON(!list_empty(&vm->active_list)); ppgtt->base.cleanup(&ppgtt->base); } -static void ppgtt_release(struct kref *kref) +void ppgtt_release(struct kref *kref) { struct i915_hw_ppgtt *ppgtt = container_of(kref, struct i915_hw_ppgtt, ref); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index b4b7cfd226b7..76dd3b428483 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2148,10 +2148,15 @@ i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, struct i915_address_space *vm) { struct i915_vma *vma; + struct i915_hw_ppgtt *ppgtt = NULL; vma = i915_gem_obj_to_vma(obj, vm); if (!vma) vma = __i915_gem_vma_create(obj, vm); + ppgtt = vm_to_ppgtt(vm); + if (ppgtt) + kref_get(&ppgtt->ref); + return vma; } -- GitLab From ee960be7bb09b201926cb37eaa82fb7da605ea7c Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:45 +0200 Subject: [PATCH 0232/9167] drm/i915: Some cleanups for the ppgtt lifetime handling So when reviewing Michel's patch I've noticed a few things and cleaned them up: - The early checks in ppgtt_release are now redundant: The inactive list should always be empty now, so we can ditch these checks. Even for the aliasing ppgtt (though that's a different confusion) since we tear that down after all the objects are gone. - The ppgtt handling functions are splattered all over. Consolidate them in i915_gem_gtt.c, give them OCD prefixes and add wrappers for get/put. - There was a bit a confusion in ppgtt_release about whether it cares about the active or inactive list. It should care about them both, so augment the WARNINGs to check for both. There's still create_vm_for_ctx left to do, put that is blocked on the removal of ppgtt->ctx. Once that's done we can rename it to i915_ppgtt_create and move it to its siblings for handling ppgtts. v2: Move the ppgtt checks into the inline get/put functions as suggested by Chris. v3: Inline the now redundant ppgtt local variable. Cc: Michel Thierry Cc: Chris Wilson Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 1 - drivers/gpu/drm/i915/i915_gem.c | 5 +--- drivers/gpu/drm/i915/i915_gem_context.c | 36 +++---------------------- drivers/gpu/drm/i915/i915_gem_gtt.c | 20 ++++++++++---- drivers/gpu/drm/i915/i915_gem_gtt.h | 14 +++++++++- 5 files changed, 33 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 38b1849a450a..101fc637eb46 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2549,7 +2549,6 @@ void i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj); #define ctx_to_ppgtt(ctx) container_of((ctx)->vm, struct i915_hw_ppgtt, base) #define vm_to_ppgtt(vm) container_of(vm, struct i915_hw_ppgtt, base) int __must_check i915_gem_context_init(struct drm_device *dev); -void ppgtt_release(struct kref *kref); void i915_gem_context_fini(struct drm_device *dev); void i915_gem_context_reset(struct drm_device *dev); int i915_gem_context_open(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 63aee412b258..8061d45eaa80 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4477,7 +4477,6 @@ struct i915_vma *i915_gem_obj_to_vma(struct drm_i915_gem_object *obj, void i915_gem_vma_destroy(struct i915_vma *vma) { struct i915_address_space *vm = NULL; - struct i915_hw_ppgtt *ppgtt = NULL; WARN_ON(vma->node.allocated); /* Keep the vma as a placeholder in the execbuffer reservation lists */ @@ -4485,10 +4484,8 @@ void i915_gem_vma_destroy(struct i915_vma *vma) return; vm = vma->vm; - ppgtt = vm_to_ppgtt(vm); - if (ppgtt) - kref_put(&ppgtt->ref, ppgtt_release); + i915_ppgtt_put(vm_to_ppgtt(vm)); list_del(&vma->vma_link); diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index a509a4bca991..dc43d0263a01 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -96,33 +96,6 @@ #define GEN6_CONTEXT_ALIGN (64<<10) #define GEN7_CONTEXT_ALIGN 4096 -static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt) -{ - struct drm_device *dev = ppgtt->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct i915_address_space *vm = &ppgtt->base; - - if (ppgtt == dev_priv->mm.aliasing_ppgtt || - (list_empty(&vm->active_list) && list_empty(&vm->inactive_list))) { - ppgtt->base.cleanup(&ppgtt->base); - return; - } - - /* vmas should already be unbound */ - WARN_ON(!list_empty(&vm->active_list)); - - ppgtt->base.cleanup(&ppgtt->base); -} - -void ppgtt_release(struct kref *kref) -{ - struct i915_hw_ppgtt *ppgtt = - container_of(kref, struct i915_hw_ppgtt, ref); - - do_ppgtt_cleanup(ppgtt); - kfree(ppgtt); -} - static size_t get_context_alignment(struct drm_device *dev) { if (IS_GEN6(dev)) @@ -174,8 +147,7 @@ void i915_gem_context_free(struct kref *ctx_ref) ppgtt = ctx_to_ppgtt(ctx); } - if (ppgtt) - kref_put(&ppgtt->ref, ppgtt_release); + i915_ppgtt_put(ppgtt); if (ctx->legacy_hw_ctx.rcs_state) drm_gem_object_unreference(&ctx->legacy_hw_ctx.rcs_state->base); list_del(&ctx->link); @@ -222,7 +194,7 @@ create_vm_for_ctx(struct drm_device *dev, struct intel_context *ctx) if (!ppgtt) return ERR_PTR(-ENOMEM); - ret = i915_gem_init_ppgtt(dev, ppgtt); + ret = i915_ppgtt_init(dev, ppgtt); if (ret) { kfree(ppgtt); return ERR_PTR(ret); @@ -234,7 +206,7 @@ create_vm_for_ctx(struct drm_device *dev, struct intel_context *ctx) static struct intel_context * __create_hw_context(struct drm_device *dev, - struct drm_i915_file_private *file_priv) + struct drm_i915_file_private *file_priv) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_context *ctx; @@ -342,7 +314,7 @@ i915_gem_create_context(struct drm_device *dev, /* For platforms which only have aliasing PPGTT, we fake the * address space and refcounting. */ ctx->vm = &dev_priv->mm.aliasing_ppgtt->base; - kref_get(&dev_priv->mm.aliasing_ppgtt->ref); + i915_ppgtt_get(dev_priv->mm.aliasing_ppgtt); } else ctx->vm = &dev_priv->gtt.base; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 76dd3b428483..6ffa12b72538 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1180,7 +1180,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) return 0; } -int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) +int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) { struct drm_i915_private *dev_priv = dev->dev_private; int ret = 0; @@ -1211,6 +1211,19 @@ int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) return ret; } +void i915_ppgtt_release(struct kref *kref) +{ + struct i915_hw_ppgtt *ppgtt = + container_of(kref, struct i915_hw_ppgtt, ref); + + /* vmas should already be unbound */ + WARN_ON(!list_empty(&ppgtt->base.active_list)); + WARN_ON(!list_empty(&ppgtt->base.inactive_list)); + + ppgtt->base.cleanup(&ppgtt->base); + kfree(ppgtt); +} + static void ppgtt_bind_vma(struct i915_vma *vma, enum i915_cache_level cache_level, @@ -2148,15 +2161,12 @@ i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, struct i915_address_space *vm) { struct i915_vma *vma; - struct i915_hw_ppgtt *ppgtt = NULL; vma = i915_gem_obj_to_vma(obj, vm); if (!vma) vma = __i915_gem_vma_create(obj, vm); - ppgtt = vm_to_ppgtt(vm); - if (ppgtt) - kref_get(&ppgtt->ref); + i915_ppgtt_get(vm_to_ppgtt(vm)); return vma; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 666c938a51e3..c6beb528f955 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -272,7 +272,19 @@ void i915_gem_init_global_gtt(struct drm_device *dev); void i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start, unsigned long mappable_end, unsigned long end); -int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); + +int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); +void i915_ppgtt_release(struct kref *kref); +static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt) +{ + if (ppgtt) + kref_get(&ppgtt->ref); +} +static inline void i915_ppgtt_put(struct i915_hw_ppgtt *ppgtt) +{ + if (ppgtt) + kref_put(&ppgtt->ref, i915_ppgtt_release); +} void i915_check_and_clear_faults(struct drm_device *dev); void i915_gem_suspend_gtt_mappings(struct drm_device *dev); -- GitLab From 8affc2b8c27bfc2d6e70827b746f490b62c44eaa Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 31 Jul 2014 14:45:04 +0800 Subject: [PATCH 0233/9167] perf record: Honour --no-time command line option Time stamps are always implicitely enabled for record currently. The old --time/-T option is a nop. Allow the user to disable timestamps by using --no-time, honouring the existing option. The defaults are unchanged. Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406789104-25863-10-git-send-email-zheng.z.yan@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 1 + tools/perf/util/evsel.c | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4869050e7194..ca0251e8470d 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -781,6 +781,7 @@ static const char * const record_usage[] = { */ static struct record record = { .opts = { + .sample_time = true, .mmap_pages = UINT_MAX, .user_freq = UINT_MAX, .user_interval = ULLONG_MAX, diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 21a373ebea22..92e5235f5377 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -633,9 +633,12 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) if (opts->period) perf_evsel__set_sample_bit(evsel, PERIOD); - if (!perf_missing_features.sample_id_all && - (opts->sample_time || !opts->no_inherit || - target__has_cpu(&opts->target) || per_cpu)) + /* + * When the user explicitely disabled time don't force it here. + */ + if (opts->sample_time && + (!perf_missing_features.sample_id_all && + (!opts->no_inherit || target__has_cpu(&opts->target) || per_cpu))) perf_evsel__set_sample_bit(evsel, TIME); if (opts->raw_samples && !evsel->no_aux_samples) { -- GitLab From 0a8cb85c200c4082ed7e57efd90dd9d18c8d40b6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 6 Jul 2014 14:18:21 +0200 Subject: [PATCH 0234/9167] perf tools: Rename ordered_samples bool to ordered_events The time ordering is generic for all kinds of events, so using generic name 'ordered_events' for ordered_samples bool in perf_tool struct. No functional change was intended. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-07mrqzcuhsks9wfmxrzsvemz@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-kvm.c | 4 ++-- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-timechart.c | 2 +- tools/perf/builtin-trace.c | 2 +- tools/perf/util/session.c | 10 +++++----- tools/perf/util/tool.h | 2 +- 14 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 1ec429fef2be..952b5ece6740 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -297,7 +297,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) .comm = perf_event__process_comm, .exit = perf_event__process_exit, .fork = perf_event__process_fork, - .ordered_samples = true, + .ordered_events = true, .ordering_requires_timestamps = true, }, }; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 9a5a035cb426..c10cc44bae19 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -360,7 +360,7 @@ static struct perf_tool tool = { .exit = perf_event__process_exit, .fork = perf_event__process_fork, .lost = perf_event__process_lost, - .ordered_samples = true, + .ordered_events = true, .ordering_requires_timestamps = true, }; diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 9a02807387d6..ee875cca13b1 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -366,7 +366,7 @@ static int __cmd_inject(struct perf_inject *inject) } else if (inject->sched_stat) { struct perf_evsel *evsel; - inject->tool.ordered_samples = true; + inject->tool.ordered_events = true; evlist__for_each(session->evlist, evsel) { const char *name = perf_evsel__name(evsel); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index bef3376bfaf3..b5721116713b 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -256,7 +256,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, static struct perf_tool perf_kmem = { .sample = process_sample_event, .comm = perf_event__process_comm, - .ordered_samples = true, + .ordered_events = true, }; static double fragmentation(unsigned long n_req, unsigned long n_alloc) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index fe92dfdeab46..a05f43592e0a 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1058,7 +1058,7 @@ static int read_events(struct perf_kvm_stat *kvm) struct perf_tool eops = { .sample = process_sample_event, .comm = perf_event__process_comm, - .ordered_samples = true, + .ordered_events = true, }; struct perf_data_file file = { .path = kvm->file_name, @@ -1311,7 +1311,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, kvm->tool.exit = perf_event__process_exit; kvm->tool.fork = perf_event__process_fork; kvm->tool.lost = process_lost_event; - kvm->tool.ordered_samples = true; + kvm->tool.ordered_events = true; perf_tool__fill_defaults(&kvm->tool); /* set defaults */ diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index 6148afc995c6..c8122d323621 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -852,7 +852,7 @@ static int __cmd_report(bool display_info) struct perf_tool eops = { .sample = process_sample_event, .comm = perf_event__process_comm, - .ordered_samples = true, + .ordered_events = true, }; struct perf_data_file file = { .path = input_name, diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 4a1a6c94a5eb..80e57c84adef 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -194,7 +194,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused) .lost = perf_event__process_lost, .fork = perf_event__process_fork, .build_id = perf_event__process_build_id, - .ordered_samples = true, + .ordered_events = true, }, .input_name = "perf.data", }; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 21d830bafff3..c72cc5a12144 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -578,7 +578,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) .attr = perf_event__process_attr, .tracing_data = perf_event__process_tracing_data, .build_id = perf_event__process_build_id, - .ordered_samples = true, + .ordered_events = true, .ordering_requires_timestamps = true, }, .max_stack = PERF_MAX_STACK_DEPTH, diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index f83c08c0dd87..7c16aeb6b675 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1662,7 +1662,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) .comm = perf_event__process_comm, .lost = perf_event__process_lost, .fork = perf_sched__process_fork_event, - .ordered_samples = true, + .ordered_events = true, }, .cmp_pid = LIST_HEAD_INIT(sched.cmp_pid), .sort_list = LIST_HEAD_INIT(sched.sort_list), diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index f57035b89c15..868c17d09762 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1488,7 +1488,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) .attr = process_attr, .tracing_data = perf_event__process_tracing_data, .build_id = perf_event__process_build_id, - .ordered_samples = true, + .ordered_events = true, .ordering_requires_timestamps = true, }, }; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 2f1a5220c090..912e3b5bb22b 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1920,7 +1920,7 @@ int cmd_timechart(int argc, const char **argv, .fork = process_fork_event, .exit = process_exit_event, .sample = process_sample_event, - .ordered_samples = true, + .ordered_events = true, }, .proc_num = 15, .min_time = 1000000, diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index a6c375224f46..36ae51d61be2 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2209,7 +2209,7 @@ static int trace__replay(struct trace *trace) trace->tool.tracing_data = perf_event__process_tracing_data; trace->tool.build_id = perf_event__process_build_id; - trace->tool.ordered_samples = true; + trace->tool.ordered_events = true; trace->tool.ordering_requires_timestamps = true; /* add tid to output */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 88dfef70c13d..a2c97ff1aa6a 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -104,9 +104,9 @@ struct perf_session *perf_session__new(struct perf_data_file *file, } if (tool && tool->ordering_requires_timestamps && - tool->ordered_samples && !perf_evlist__sample_id_all(session->evlist)) { + tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) { dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); - tool->ordered_samples = false; + tool->ordered_events = false; } return session; @@ -238,7 +238,7 @@ void perf_tool__fill_defaults(struct perf_tool *tool) if (tool->build_id == NULL) tool->build_id = process_finished_round_stub; if (tool->finished_round == NULL) { - if (tool->ordered_samples) + if (tool->ordered_events) tool->finished_round = process_finished_round; else tool->finished_round = process_finished_round_stub; @@ -483,7 +483,7 @@ static int flush_sample_queue(struct perf_session *s, struct ui_progress prog; int ret; - if (!tool->ordered_samples || !limit) + if (!tool->ordered_events || !limit) return 0; if (show_progress) @@ -1062,7 +1062,7 @@ static s64 perf_session__process_event(struct perf_session *session, if (ret) return ret; - if (tool->ordered_samples) { + if (tool->ordered_events) { ret = perf_session_queue_event(session, event, &sample, file_offset); if (ret != -ETIME) diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index 4385816d3d49..f11636966a0f 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -40,7 +40,7 @@ struct perf_tool { event_op2 tracing_data; event_op2 finished_round, build_id; - bool ordered_samples; + bool ordered_events; bool ordering_requires_timestamps; }; -- GitLab From 37e39aa8a8a42ad2fd72b7c7349115dad8297d9c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 6 Jul 2014 14:23:03 +0200 Subject: [PATCH 0235/9167] perf tools: Rename ordered_samples struct to ordered_events Following up with ordered_samples rename for ordered_samples and sample_queue structs to ordered_events and ordered_event structs respectively. Also changing flush_sample_queue function name to ordered_events_flush. No functional change was intended. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-2dkrdvh0bbmzxdse437fcgls@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 2 +- tools/perf/util/session.c | 118 +++++++++++++++++++------------------- tools/perf/util/session.h | 10 ++-- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index a05f43592e0a..258a5274099d 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -785,7 +785,7 @@ static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm) /* flush queue after each round in which we processed events */ if (ntotal) { - kvm->session->ordered_samples.next_flush = flush_time; + kvm->session->ordered_events.next_flush = flush_time; err = kvm->tool.finished_round(&kvm->tool, NULL, kvm->session); if (err) { if (kvm->lost_events) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index a2c97ff1aa6a..6570282a7625 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -75,9 +75,9 @@ struct perf_session *perf_session__new(struct perf_data_file *file, goto out; session->repipe = repipe; - INIT_LIST_HEAD(&session->ordered_samples.samples); - INIT_LIST_HEAD(&session->ordered_samples.sample_cache); - INIT_LIST_HEAD(&session->ordered_samples.to_free); + INIT_LIST_HEAD(&session->ordered_events.samples); + INIT_LIST_HEAD(&session->ordered_events.sample_cache); + INIT_LIST_HEAD(&session->ordered_events.to_free); machines__init(&session->machines); if (file) { @@ -444,7 +444,7 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_HEADER_MAX] = NULL, }; -struct sample_queue { +struct ordered_event { u64 timestamp; u64 file_offset; union perf_event *event; @@ -453,14 +453,14 @@ struct sample_queue { static void perf_session_free_sample_buffers(struct perf_session *session) { - struct ordered_samples *os = &session->ordered_samples; + struct ordered_events *oe = &session->ordered_events; - while (!list_empty(&os->to_free)) { - struct sample_queue *sq; + while (!list_empty(&oe->to_free)) { + struct ordered_event *event; - sq = list_entry(os->to_free.next, struct sample_queue, list); - list_del(&sq->list); - free(sq); + event = list_entry(oe->to_free.next, struct ordered_event, list); + list_del(&event->list); + free(event); } } @@ -470,15 +470,15 @@ static int perf_session_deliver_event(struct perf_session *session, struct perf_tool *tool, u64 file_offset); -static int flush_sample_queue(struct perf_session *s, - struct perf_tool *tool) +static int ordered_events__flush(struct perf_session *s, + struct perf_tool *tool) { - struct ordered_samples *os = &s->ordered_samples; - struct list_head *head = &os->samples; - struct sample_queue *tmp, *iter; + struct ordered_events *oe = &s->ordered_events; + struct list_head *head = &oe->samples; + struct ordered_event *tmp, *iter; struct perf_sample sample; - u64 limit = os->next_flush; - u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL; + u64 limit = oe->next_flush; + u64 last_ts = oe->last_sample ? oe->last_sample->timestamp : 0ULL; bool show_progress = limit == ULLONG_MAX; struct ui_progress prog; int ret; @@ -487,7 +487,7 @@ static int flush_sample_queue(struct perf_session *s, return 0; if (show_progress) - ui_progress__init(&prog, os->nr_samples, "Processing time ordered events..."); + ui_progress__init(&prog, oe->nr_samples, "Processing time ordered events..."); list_for_each_entry_safe(iter, tmp, head, list) { if (session_done()) @@ -506,20 +506,20 @@ static int flush_sample_queue(struct perf_session *s, return ret; } - os->last_flush = iter->timestamp; + oe->last_flush = iter->timestamp; list_del(&iter->list); - list_add(&iter->list, &os->sample_cache); - os->nr_samples--; + list_add(&iter->list, &oe->sample_cache); + oe->nr_samples--; if (show_progress) ui_progress__update(&prog, 1); } if (list_empty(head)) { - os->last_sample = NULL; + oe->last_sample = NULL; } else if (last_ts <= limit) { - os->last_sample = - list_entry(head->prev, struct sample_queue, list); + oe->last_sample = + list_entry(head->prev, struct ordered_event, list); } return 0; @@ -568,27 +568,27 @@ static int process_finished_round(struct perf_tool *tool, union perf_event *event __maybe_unused, struct perf_session *session) { - int ret = flush_sample_queue(session, tool); + int ret = ordered_events__flush(session, tool); if (!ret) - session->ordered_samples.next_flush = session->ordered_samples.max_timestamp; + session->ordered_events.next_flush = session->ordered_events.max_timestamp; return ret; } /* The queue is ordered by time */ -static void __queue_event(struct sample_queue *new, struct perf_session *s) +static void __queue_event(struct ordered_event *new, struct perf_session *s) { - struct ordered_samples *os = &s->ordered_samples; - struct sample_queue *sample = os->last_sample; + struct ordered_events *oe = &s->ordered_events; + struct ordered_event *sample = oe->last_sample; u64 timestamp = new->timestamp; struct list_head *p; - ++os->nr_samples; - os->last_sample = new; + ++oe->nr_samples; + oe->last_sample = new; if (!sample) { - list_add(&new->list, &os->samples); - os->max_timestamp = timestamp; + list_add(&new->list, &oe->samples); + oe->max_timestamp = timestamp; return; } @@ -600,59 +600,59 @@ static void __queue_event(struct sample_queue *new, struct perf_session *s) if (sample->timestamp <= timestamp) { while (sample->timestamp <= timestamp) { p = sample->list.next; - if (p == &os->samples) { - list_add_tail(&new->list, &os->samples); - os->max_timestamp = timestamp; + if (p == &oe->samples) { + list_add_tail(&new->list, &oe->samples); + oe->max_timestamp = timestamp; return; } - sample = list_entry(p, struct sample_queue, list); + sample = list_entry(p, struct ordered_event, list); } list_add_tail(&new->list, &sample->list); } else { while (sample->timestamp > timestamp) { p = sample->list.prev; - if (p == &os->samples) { - list_add(&new->list, &os->samples); + if (p == &oe->samples) { + list_add(&new->list, &oe->samples); return; } - sample = list_entry(p, struct sample_queue, list); + sample = list_entry(p, struct ordered_event, list); } list_add(&new->list, &sample->list); } } -#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue)) +#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) int perf_session_queue_event(struct perf_session *s, union perf_event *event, struct perf_sample *sample, u64 file_offset) { - struct ordered_samples *os = &s->ordered_samples; - struct list_head *sc = &os->sample_cache; + struct ordered_events *oe = &s->ordered_events; + struct list_head *sc = &oe->sample_cache; u64 timestamp = sample->time; - struct sample_queue *new; + struct ordered_event *new; if (!timestamp || timestamp == ~0ULL) return -ETIME; - if (timestamp < s->ordered_samples.last_flush) { + if (timestamp < s->ordered_events.last_flush) { printf("Warning: Timestamp below last timeslice flush\n"); return -EINVAL; } if (!list_empty(sc)) { - new = list_entry(sc->next, struct sample_queue, list); + new = list_entry(sc->next, struct ordered_event, list); list_del(&new->list); - } else if (os->sample_buffer) { - new = os->sample_buffer + os->sample_buffer_idx; - if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER) - os->sample_buffer = NULL; + } else if (oe->sample_buffer) { + new = oe->sample_buffer + oe->sample_buffer_idx; + if (++oe->sample_buffer_idx == MAX_SAMPLE_BUFFER) + oe->sample_buffer = NULL; } else { - os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); - if (!os->sample_buffer) + oe->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); + if (!oe->sample_buffer) return -ENOMEM; - list_add(&os->sample_buffer->list, &os->to_free); - os->sample_buffer_idx = 2; - new = os->sample_buffer + 1; + list_add(&oe->sample_buffer->list, &oe->to_free); + oe->sample_buffer_idx = 2; + new = oe->sample_buffer + 1; } new->timestamp = timestamp; @@ -1222,8 +1222,8 @@ static int __perf_session__process_pipe_events(struct perf_session *session, goto more; done: /* do the final flush for ordered samples */ - session->ordered_samples.next_flush = ULLONG_MAX; - err = flush_sample_queue(session, tool); + session->ordered_events.next_flush = ULLONG_MAX; + err = ordered_events__flush(session, tool); out_err: free(buf); perf_session__warn_about_errors(session, tool); @@ -1368,8 +1368,8 @@ int __perf_session__process_events(struct perf_session *session, out: /* do the final flush for ordered samples */ - session->ordered_samples.next_flush = ULLONG_MAX; - err = flush_sample_queue(session, tool); + session->ordered_events.next_flush = ULLONG_MAX; + err = ordered_events__flush(session, tool); out_err: ui_progress__finish(); perf_session__warn_about_errors(session, tool); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 0321013bd9fd..f6baf935917a 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -12,19 +12,19 @@ #include #include -struct sample_queue; +struct ordered_event; struct ip_callchain; struct thread; -struct ordered_samples { +struct ordered_events { u64 last_flush; u64 next_flush; u64 max_timestamp; struct list_head samples; struct list_head sample_cache; struct list_head to_free; - struct sample_queue *sample_buffer; - struct sample_queue *last_sample; + struct ordered_event *sample_buffer; + struct ordered_event *last_sample; int sample_buffer_idx; unsigned int nr_samples; }; @@ -39,7 +39,7 @@ struct perf_session { bool one_mmap; void *one_mmap_addr; u64 one_mmap_offset; - struct ordered_samples ordered_samples; + struct ordered_events ordered_events; struct perf_data_file *file; }; -- GitLab From fc12482f4f7ae5c6fca13922a1e0898ff9002aa6 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 9 Jun 2014 23:11:30 +0200 Subject: [PATCH 0236/9167] perf tools: Rename ordered_events members Rename 'struct ordered_events' members to fit better the ordered events style. No functional change was intended. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-v0eb2hsmrxbolnoawu5fn92z@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 86 +++++++++++++++++++-------------------- tools/perf/util/session.h | 12 +++--- 2 files changed, 48 insertions(+), 50 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 6570282a7625..619778ef5b58 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -75,8 +75,8 @@ struct perf_session *perf_session__new(struct perf_data_file *file, goto out; session->repipe = repipe; - INIT_LIST_HEAD(&session->ordered_events.samples); - INIT_LIST_HEAD(&session->ordered_events.sample_cache); + INIT_LIST_HEAD(&session->ordered_events.events); + INIT_LIST_HEAD(&session->ordered_events.cache); INIT_LIST_HEAD(&session->ordered_events.to_free); machines__init(&session->machines); @@ -474,11 +474,11 @@ static int ordered_events__flush(struct perf_session *s, struct perf_tool *tool) { struct ordered_events *oe = &s->ordered_events; - struct list_head *head = &oe->samples; + struct list_head *head = &oe->events; struct ordered_event *tmp, *iter; struct perf_sample sample; u64 limit = oe->next_flush; - u64 last_ts = oe->last_sample ? oe->last_sample->timestamp : 0ULL; + u64 last_ts = oe->last ? oe->last->timestamp : 0ULL; bool show_progress = limit == ULLONG_MAX; struct ui_progress prog; int ret; @@ -487,7 +487,7 @@ static int ordered_events__flush(struct perf_session *s, return 0; if (show_progress) - ui_progress__init(&prog, oe->nr_samples, "Processing time ordered events..."); + ui_progress__init(&prog, oe->nr_events, "Processing time ordered events..."); list_for_each_entry_safe(iter, tmp, head, list) { if (session_done()) @@ -508,19 +508,17 @@ static int ordered_events__flush(struct perf_session *s, oe->last_flush = iter->timestamp; list_del(&iter->list); - list_add(&iter->list, &oe->sample_cache); - oe->nr_samples--; + list_add(&iter->list, &oe->cache); + oe->nr_events--; if (show_progress) ui_progress__update(&prog, 1); } - if (list_empty(head)) { - oe->last_sample = NULL; - } else if (last_ts <= limit) { - oe->last_sample = - list_entry(head->prev, struct ordered_event, list); - } + if (list_empty(head)) + oe->last = NULL; + else if (last_ts <= limit) + oe->last = list_entry(head->prev, struct ordered_event, list); return 0; } @@ -579,45 +577,45 @@ static int process_finished_round(struct perf_tool *tool, static void __queue_event(struct ordered_event *new, struct perf_session *s) { struct ordered_events *oe = &s->ordered_events; - struct ordered_event *sample = oe->last_sample; + struct ordered_event *last = oe->last; u64 timestamp = new->timestamp; struct list_head *p; - ++oe->nr_samples; - oe->last_sample = new; + ++oe->nr_events; + oe->last = new; - if (!sample) { - list_add(&new->list, &oe->samples); + if (!last) { + list_add(&new->list, &oe->events); oe->max_timestamp = timestamp; return; } /* - * last_sample might point to some random place in the list as it's + * last event might point to some random place in the list as it's * the last queued event. We expect that the new event is close to * this. */ - if (sample->timestamp <= timestamp) { - while (sample->timestamp <= timestamp) { - p = sample->list.next; - if (p == &oe->samples) { - list_add_tail(&new->list, &oe->samples); + if (last->timestamp <= timestamp) { + while (last->timestamp <= timestamp) { + p = last->list.next; + if (p == &oe->events) { + list_add_tail(&new->list, &oe->events); oe->max_timestamp = timestamp; return; } - sample = list_entry(p, struct ordered_event, list); + last = list_entry(p, struct ordered_event, list); } - list_add_tail(&new->list, &sample->list); + list_add_tail(&new->list, &last->list); } else { - while (sample->timestamp > timestamp) { - p = sample->list.prev; - if (p == &oe->samples) { - list_add(&new->list, &oe->samples); + while (last->timestamp > timestamp) { + p = last->list.prev; + if (p == &oe->events) { + list_add(&new->list, &oe->events); return; } - sample = list_entry(p, struct ordered_event, list); + last = list_entry(p, struct ordered_event, list); } - list_add(&new->list, &sample->list); + list_add(&new->list, &last->list); } } @@ -627,7 +625,7 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event, struct perf_sample *sample, u64 file_offset) { struct ordered_events *oe = &s->ordered_events; - struct list_head *sc = &oe->sample_cache; + struct list_head *cache = &oe->cache; u64 timestamp = sample->time; struct ordered_event *new; @@ -639,20 +637,20 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event, return -EINVAL; } - if (!list_empty(sc)) { - new = list_entry(sc->next, struct ordered_event, list); + if (!list_empty(cache)) { + new = list_entry(cache->next, struct ordered_event, list); list_del(&new->list); - } else if (oe->sample_buffer) { - new = oe->sample_buffer + oe->sample_buffer_idx; - if (++oe->sample_buffer_idx == MAX_SAMPLE_BUFFER) - oe->sample_buffer = NULL; + } else if (oe->buffer) { + new = oe->buffer + oe->buffer_idx; + if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) + oe->buffer = NULL; } else { - oe->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); - if (!oe->sample_buffer) + oe->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); + if (!oe->buffer) return -ENOMEM; - list_add(&oe->sample_buffer->list, &oe->to_free); - oe->sample_buffer_idx = 2; - new = oe->sample_buffer + 1; + list_add(&oe->buffer->list, &oe->to_free); + oe->buffer_idx = 2; + new = oe->buffer + 1; } new->timestamp = timestamp; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index f6baf935917a..419eb50e1cd3 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -20,13 +20,13 @@ struct ordered_events { u64 last_flush; u64 next_flush; u64 max_timestamp; - struct list_head samples; - struct list_head sample_cache; + struct list_head events; + struct list_head cache; struct list_head to_free; - struct ordered_event *sample_buffer; - struct ordered_event *last_sample; - int sample_buffer_idx; - unsigned int nr_samples; + struct ordered_event *buffer; + struct ordered_event *last; + int buffer_idx; + unsigned int nr_events; }; struct perf_session { -- GitLab From c64c7e1a5addf93b7dec98a27b8c48457506aa06 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 10 Jun 2014 21:58:02 +0200 Subject: [PATCH 0237/9167] perf tools: Add ordered_events__(new|delete) interface Adding new ordered events interface to new|delete event buffer: ordered_events__new - allocate event buffer from the cache ordered_events__delete - return event buffer to the cache Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-srwunsy7o5wl17vpt4a10oxp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 169 ++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 71 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 619778ef5b58..ff0188c65783 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -464,6 +464,100 @@ static void perf_session_free_sample_buffers(struct perf_session *session) } } +/* The queue is ordered by time */ +static void queue_event(struct ordered_events *oe, struct ordered_event *new) +{ + struct ordered_event *last = oe->last; + u64 timestamp = new->timestamp; + struct list_head *p; + + ++oe->nr_events; + oe->last = new; + + if (!last) { + list_add(&new->list, &oe->events); + oe->max_timestamp = timestamp; + return; + } + + /* + * last event might point to some random place in the list as it's + * the last queued event. We expect that the new event is close to + * this. + */ + if (last->timestamp <= timestamp) { + while (last->timestamp <= timestamp) { + p = last->list.next; + if (p == &oe->events) { + list_add_tail(&new->list, &oe->events); + oe->max_timestamp = timestamp; + return; + } + last = list_entry(p, struct ordered_event, list); + } + list_add_tail(&new->list, &last->list); + } else { + while (last->timestamp > timestamp) { + p = last->list.prev; + if (p == &oe->events) { + list_add(&new->list, &oe->events); + return; + } + last = list_entry(p, struct ordered_event, list); + } + list_add(&new->list, &last->list); + } +} + +#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) +static struct ordered_event *alloc_event(struct ordered_events *oe) +{ + struct list_head *cache = &oe->cache; + struct ordered_event *new; + + if (!list_empty(cache)) { + new = list_entry(cache->next, struct ordered_event, list); + list_del(&new->list); + } else if (oe->buffer) { + new = oe->buffer + oe->buffer_idx; + if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) + oe->buffer = NULL; + } else { + oe->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); + if (!oe->buffer) + return NULL; + list_add(&oe->buffer->list, &oe->to_free); + + /* First entry is abused to maintain the to_free list. */ + oe->buffer_idx = 2; + new = oe->buffer + 1; + } + + return new; +} + +static struct ordered_event * +ordered_events__new(struct ordered_events *oe, u64 timestamp) +{ + struct ordered_event *new; + + new = alloc_event(oe); + if (new) { + new->timestamp = timestamp; + queue_event(oe, new); + } + + return new; +} + +static void +ordered_events__delete(struct ordered_events *oe, struct ordered_event *event) +{ + list_del(&event->list); + list_add(&event->list, &oe->cache); + oe->nr_events--; +} + static int perf_session_deliver_event(struct perf_session *session, union perf_event *event, struct perf_sample *sample, @@ -506,10 +600,8 @@ static int ordered_events__flush(struct perf_session *s, return ret; } + ordered_events__delete(oe, iter); oe->last_flush = iter->timestamp; - list_del(&iter->list); - list_add(&iter->list, &oe->cache); - oe->nr_events--; if (show_progress) ui_progress__update(&prog, 1); @@ -573,59 +665,10 @@ static int process_finished_round(struct perf_tool *tool, return ret; } -/* The queue is ordered by time */ -static void __queue_event(struct ordered_event *new, struct perf_session *s) -{ - struct ordered_events *oe = &s->ordered_events; - struct ordered_event *last = oe->last; - u64 timestamp = new->timestamp; - struct list_head *p; - - ++oe->nr_events; - oe->last = new; - - if (!last) { - list_add(&new->list, &oe->events); - oe->max_timestamp = timestamp; - return; - } - - /* - * last event might point to some random place in the list as it's - * the last queued event. We expect that the new event is close to - * this. - */ - if (last->timestamp <= timestamp) { - while (last->timestamp <= timestamp) { - p = last->list.next; - if (p == &oe->events) { - list_add_tail(&new->list, &oe->events); - oe->max_timestamp = timestamp; - return; - } - last = list_entry(p, struct ordered_event, list); - } - list_add_tail(&new->list, &last->list); - } else { - while (last->timestamp > timestamp) { - p = last->list.prev; - if (p == &oe->events) { - list_add(&new->list, &oe->events); - return; - } - last = list_entry(p, struct ordered_event, list); - } - list_add(&new->list, &last->list); - } -} - -#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) - int perf_session_queue_event(struct perf_session *s, union perf_event *event, struct perf_sample *sample, u64 file_offset) { struct ordered_events *oe = &s->ordered_events; - struct list_head *cache = &oe->cache; u64 timestamp = sample->time; struct ordered_event *new; @@ -637,28 +680,12 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event, return -EINVAL; } - if (!list_empty(cache)) { - new = list_entry(cache->next, struct ordered_event, list); - list_del(&new->list); - } else if (oe->buffer) { - new = oe->buffer + oe->buffer_idx; - if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) - oe->buffer = NULL; - } else { - oe->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); - if (!oe->buffer) - return -ENOMEM; - list_add(&oe->buffer->list, &oe->to_free); - oe->buffer_idx = 2; - new = oe->buffer + 1; - } + new = ordered_events__new(oe, timestamp); + if (!new) + return -ENOMEM; - new->timestamp = timestamp; new->file_offset = file_offset; new->event = event; - - __queue_event(new, s); - return 0; } -- GitLab From d8836b5d1736632aa1a38a8ed0c9361c96d7c95a Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 5 Jun 2014 10:29:45 +0200 Subject: [PATCH 0238/9167] perf tools: Factor ordered_events__flush to be more generic Centralizing the next_flush calculation under the ordered_events__flush function. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-srwunsy7o5wl17vpt4a10oxp@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 47 ++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index ff0188c65783..72c7b0d3d0dc 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -451,6 +451,11 @@ struct ordered_event { struct list_head list; }; +enum oe_flush { + OE_FLUSH__FINAL, + OE_FLUSH__ROUND, +}; + static void perf_session_free_sample_buffers(struct perf_session *session) { struct ordered_events *oe = &session->ordered_events; @@ -564,8 +569,8 @@ static int perf_session_deliver_event(struct perf_session *session, struct perf_tool *tool, u64 file_offset); -static int ordered_events__flush(struct perf_session *s, - struct perf_tool *tool) +static int __ordered_events__flush(struct perf_session *s, + struct perf_tool *tool) { struct ordered_events *oe = &s->ordered_events; struct list_head *head = &oe->events; @@ -615,6 +620,32 @@ static int ordered_events__flush(struct perf_session *s, return 0; } +static int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, + enum oe_flush how) +{ + struct ordered_events *oe = &s->ordered_events; + int err; + + switch (how) { + case OE_FLUSH__FINAL: + oe->next_flush = ULLONG_MAX; + break; + + case OE_FLUSH__ROUND: + default: + break; + }; + + err = __ordered_events__flush(s, tool); + + if (!err) { + if (how == OE_FLUSH__ROUND) + oe->next_flush = oe->max_timestamp; + } + + return err; +} + /* * When perf record finishes a pass on every buffers, it records this pseudo * event. @@ -658,11 +689,7 @@ static int process_finished_round(struct perf_tool *tool, union perf_event *event __maybe_unused, struct perf_session *session) { - int ret = ordered_events__flush(session, tool); - if (!ret) - session->ordered_events.next_flush = session->ordered_events.max_timestamp; - - return ret; + return ordered_events__flush(session, tool, OE_FLUSH__ROUND); } int perf_session_queue_event(struct perf_session *s, union perf_event *event, @@ -1247,8 +1274,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session, goto more; done: /* do the final flush for ordered samples */ - session->ordered_events.next_flush = ULLONG_MAX; - err = ordered_events__flush(session, tool); + err = ordered_events__flush(session, tool, OE_FLUSH__FINAL); out_err: free(buf); perf_session__warn_about_errors(session, tool); @@ -1393,8 +1419,7 @@ int __perf_session__process_events(struct perf_session *session, out: /* do the final flush for ordered samples */ - session->ordered_events.next_flush = ULLONG_MAX; - err = ordered_events__flush(session, tool); + err = ordered_events__flush(session, tool, OE_FLUSH__FINAL); out_err: ui_progress__finish(); perf_session__warn_about_errors(session, tool); -- GitLab From 8d99a6ceebe862ac4afd832cdab332ee7b3b5599 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Wed, 11 Jun 2014 15:09:35 +0200 Subject: [PATCH 0239/9167] perf tools: Limit ordered events queue size Add limit to the ordered events queue allocation. This way we will be able to control the size of the queue buffers. There's no limit at the moment (it's set to (u64) -1). The config code will come in following patches. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-lw1ny3mk4ctb6su5ght5rsng@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 12 +++++++++--- tools/perf/util/session.h | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 72c7b0d3d0dc..8d4538c91076 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -78,6 +78,8 @@ struct perf_session *perf_session__new(struct perf_data_file *file, INIT_LIST_HEAD(&session->ordered_events.events); INIT_LIST_HEAD(&session->ordered_events.cache); INIT_LIST_HEAD(&session->ordered_events.to_free); + session->ordered_events.max_alloc_size = (u64) -1; + session->ordered_events.cur_alloc_size = 0; machines__init(&session->machines); if (file) { @@ -518,7 +520,7 @@ static void queue_event(struct ordered_events *oe, struct ordered_event *new) static struct ordered_event *alloc_event(struct ordered_events *oe) { struct list_head *cache = &oe->cache; - struct ordered_event *new; + struct ordered_event *new = NULL; if (!list_empty(cache)) { new = list_entry(cache->next, struct ordered_event, list); @@ -527,10 +529,14 @@ static struct ordered_event *alloc_event(struct ordered_events *oe) new = oe->buffer + oe->buffer_idx; if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) oe->buffer = NULL; - } else { - oe->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new)); + } else if (oe->cur_alloc_size < oe->max_alloc_size) { + size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); + + oe->buffer = malloc(size); if (!oe->buffer) return NULL; + + oe->cur_alloc_size += size; list_add(&oe->buffer->list, &oe->to_free); /* First entry is abused to maintain the to_free list. */ diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 419eb50e1cd3..e2fbaf2567e1 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -20,6 +20,8 @@ struct ordered_events { u64 last_flush; u64 next_flush; u64 max_timestamp; + u64 max_alloc_size; + u64 cur_alloc_size; struct list_head events; struct list_head cache; struct list_head to_free; -- GitLab From d40b4a15ab2bfcfa7d946b69ca1f12c93b22d169 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 1 Aug 2014 13:01:04 -0300 Subject: [PATCH 0240/9167] perf tools: Flush ordered events in case of allocation failure In previous patches we added a limit for ordered events queue allocation size. If we reach this size we need to flush (part of) the queue to get some free buffers. The current functionality is not affected, because the limit is hard coded to (u64) -1. The configuration code for size will come in following patches. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-ggcas0xdq847fi85bz73do2e@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 2 +- tools/perf/util/session.c | 29 +++++++++++++++++++++++++++-- tools/perf/util/session.h | 3 ++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 258a5274099d..7ccceadcd9f8 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -732,7 +732,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx, return -1; } - err = perf_session_queue_event(kvm->session, event, &sample, 0); + err = perf_session_queue_event(kvm->session, event, &kvm->tool, &sample, 0); /* * FIXME: Here we can't consume the event, as perf_session_queue_event will * point to it, and it'll get possibly overwritten by the kernel. diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 8d4538c91076..bd2483b6b446 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -14,6 +14,7 @@ #include "util.h" #include "cpumap.h" #include "perf_regs.h" +#include "asm/bug.h" static int perf_session__open(struct perf_session *session) { @@ -456,6 +457,7 @@ struct ordered_event { enum oe_flush { OE_FLUSH__FINAL, OE_FLUSH__ROUND, + OE_FLUSH__HALF, }; static void perf_session_free_sample_buffers(struct perf_session *session) @@ -637,6 +639,23 @@ static int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, oe->next_flush = ULLONG_MAX; break; + case OE_FLUSH__HALF: + { + struct ordered_event *first, *last; + struct list_head *head = &oe->events; + + first = list_entry(head->next, struct ordered_event, list); + last = oe->last; + + /* Warn if we are called before any event got allocated. */ + if (WARN_ONCE(!last || list_empty(head), "empty queue")) + return 0; + + oe->next_flush = first->timestamp; + oe->next_flush += (last->timestamp - first->timestamp) / 2; + break; + } + case OE_FLUSH__ROUND: default: break; @@ -699,7 +718,8 @@ static int process_finished_round(struct perf_tool *tool, } int perf_session_queue_event(struct perf_session *s, union perf_event *event, - struct perf_sample *sample, u64 file_offset) + struct perf_tool *tool, struct perf_sample *sample, + u64 file_offset) { struct ordered_events *oe = &s->ordered_events; u64 timestamp = sample->time; @@ -714,6 +734,11 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event, } new = ordered_events__new(oe, timestamp); + if (!new) { + ordered_events__flush(s, tool, OE_FLUSH__HALF); + new = ordered_events__new(oe, timestamp); + } + if (!new) return -ENOMEM; @@ -1121,7 +1146,7 @@ static s64 perf_session__process_event(struct perf_session *session, return ret; if (tool->ordered_events) { - ret = perf_session_queue_event(session, event, &sample, + ret = perf_session_queue_event(session, event, tool, &sample, file_offset); if (ret != -ETIME) return ret; diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index e2fbaf2567e1..a09e3c8d825a 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -67,7 +67,8 @@ int perf_session__process_events(struct perf_session *session, struct perf_tool *tool); int perf_session_queue_event(struct perf_session *s, union perf_event *event, - struct perf_sample *sample, u64 file_offset); + struct perf_tool *tool, struct perf_sample *sample, + u64 file_offset); void perf_tool__fill_defaults(struct perf_tool *tool); -- GitLab From 79a30fe4f3758c98e1b7a474952b9701d513e580 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 10 Jun 2014 22:31:35 +0200 Subject: [PATCH 0241/9167] perf tools: Make perf_session__deliver_event global Making perf_session__deliver_event global function, as it will be called from another object in following patch. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-rz7s2b8uwv567bigckh75gvk@git.kernel.org [ Fixup naming to match class__method schema, as now is more widely exposed ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 23 ++++++++--------------- tools/perf/util/session.h | 5 +++++ 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index bd2483b6b446..ed6b7f14631f 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -571,12 +571,6 @@ ordered_events__delete(struct ordered_events *oe, struct ordered_event *event) oe->nr_events--; } -static int perf_session_deliver_event(struct perf_session *session, - union perf_event *event, - struct perf_sample *sample, - struct perf_tool *tool, - u64 file_offset); - static int __ordered_events__flush(struct perf_session *s, struct perf_tool *tool) { @@ -607,8 +601,8 @@ static int __ordered_events__flush(struct perf_session *s, if (ret) pr_err("Can't parse sample, err = %d\n", ret); else { - ret = perf_session_deliver_event(s, iter->event, &sample, tool, - iter->file_offset); + ret = perf_session__deliver_event(s, iter->event, &sample, tool, + iter->file_offset); if (ret) return ret; } @@ -1003,11 +997,10 @@ perf_session__deliver_sample(struct perf_session *session, &sample->read.one, machine); } -static int perf_session_deliver_event(struct perf_session *session, - union perf_event *event, - struct perf_sample *sample, - struct perf_tool *tool, - u64 file_offset) +int perf_session__deliver_event(struct perf_session *session, + union perf_event *event, + struct perf_sample *sample, + struct perf_tool *tool, u64 file_offset) { struct perf_evsel *evsel; struct machine *machine; @@ -1152,8 +1145,8 @@ static s64 perf_session__process_event(struct perf_session *session, return ret; } - return perf_session_deliver_event(session, event, &sample, tool, - file_offset); + return perf_session__deliver_event(session, event, &sample, tool, + file_offset); } void perf_event_header__bswap(struct perf_event_header *hdr) diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index a09e3c8d825a..03da1cb14dc1 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -72,6 +72,11 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event, void perf_tool__fill_defaults(struct perf_tool *tool); +int perf_session__deliver_event(struct perf_session *session, + union perf_event *event, + struct perf_sample *sample, + struct perf_tool *tool, u64 file_offset); + int perf_session__resolve_callchain(struct perf_session *session, struct perf_evsel *evsel, struct thread *thread, -- GitLab From 5f86b80b85f0dcd05fd1471eac6984181a707c4f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 1 Aug 2014 13:02:58 -0300 Subject: [PATCH 0242/9167] perf tools: Create ordered-events object Move ordered events code into separated object ordered-events.[ch]. No functional change was intended. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-1ge3rilgudszbl87cejm1tfg@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile.perf | 2 + tools/perf/util/ordered-events.c | 196 +++++++++++++++++++++++++++++ tools/perf/util/ordered-events.h | 41 ++++++ tools/perf/util/session.c | 206 ------------------------------- tools/perf/util/session.h | 17 +-- 5 files changed, 240 insertions(+), 222 deletions(-) create mode 100644 tools/perf/util/ordered-events.c create mode 100644 tools/perf/util/ordered-events.h diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 2240974b7745..1ea31e275b4d 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -263,6 +263,7 @@ LIB_H += util/xyarray.h LIB_H += util/header.h LIB_H += util/help.h LIB_H += util/session.h +LIB_H += util/ordered-events.h LIB_H += util/strbuf.h LIB_H += util/strlist.h LIB_H += util/strfilter.h @@ -347,6 +348,7 @@ LIB_OBJS += $(OUTPUT)util/machine.o LIB_OBJS += $(OUTPUT)util/map.o LIB_OBJS += $(OUTPUT)util/pstack.o LIB_OBJS += $(OUTPUT)util/session.o +LIB_OBJS += $(OUTPUT)util/ordered-events.o LIB_OBJS += $(OUTPUT)util/comm.o LIB_OBJS += $(OUTPUT)util/thread.o LIB_OBJS += $(OUTPUT)util/thread_map.o diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c new file mode 100644 index 000000000000..95f8211ccdde --- /dev/null +++ b/tools/perf/util/ordered-events.c @@ -0,0 +1,196 @@ +#include +#include "ordered-events.h" +#include "evlist.h" +#include "session.h" +#include "asm/bug.h" +#include "debug.h" + +static void queue_event(struct ordered_events *oe, struct ordered_event *new) +{ + struct ordered_event *last = oe->last; + u64 timestamp = new->timestamp; + struct list_head *p; + + ++oe->nr_events; + oe->last = new; + + if (!last) { + list_add(&new->list, &oe->events); + oe->max_timestamp = timestamp; + return; + } + + /* + * last event might point to some random place in the list as it's + * the last queued event. We expect that the new event is close to + * this. + */ + if (last->timestamp <= timestamp) { + while (last->timestamp <= timestamp) { + p = last->list.next; + if (p == &oe->events) { + list_add_tail(&new->list, &oe->events); + oe->max_timestamp = timestamp; + return; + } + last = list_entry(p, struct ordered_event, list); + } + list_add_tail(&new->list, &last->list); + } else { + while (last->timestamp > timestamp) { + p = last->list.prev; + if (p == &oe->events) { + list_add(&new->list, &oe->events); + return; + } + last = list_entry(p, struct ordered_event, list); + } + list_add(&new->list, &last->list); + } +} + +#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) +static struct ordered_event *alloc_event(struct ordered_events *oe) +{ + struct list_head *cache = &oe->cache; + struct ordered_event *new = NULL; + + if (!list_empty(cache)) { + new = list_entry(cache->next, struct ordered_event, list); + list_del(&new->list); + } else if (oe->buffer) { + new = oe->buffer + oe->buffer_idx; + if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) + oe->buffer = NULL; + } else if (oe->cur_alloc_size < oe->max_alloc_size) { + size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); + + oe->buffer = malloc(size); + if (!oe->buffer) + return NULL; + + oe->cur_alloc_size += size; + list_add(&oe->buffer->list, &oe->to_free); + + /* First entry is abused to maintain the to_free list. */ + oe->buffer_idx = 2; + new = oe->buffer + 1; + } + + return new; +} + +struct ordered_event * +ordered_events__new(struct ordered_events *oe, u64 timestamp) +{ + struct ordered_event *new; + + new = alloc_event(oe); + if (new) { + new->timestamp = timestamp; + queue_event(oe, new); + } + + return new; +} + +void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event) +{ + list_del(&event->list); + list_add(&event->list, &oe->cache); + oe->nr_events--; +} + +static int __ordered_events__flush(struct perf_session *s, + struct perf_tool *tool) +{ + struct ordered_events *oe = &s->ordered_events; + struct list_head *head = &oe->events; + struct ordered_event *tmp, *iter; + struct perf_sample sample; + u64 limit = oe->next_flush; + u64 last_ts = oe->last ? oe->last->timestamp : 0ULL; + bool show_progress = limit == ULLONG_MAX; + struct ui_progress prog; + int ret; + + if (!tool->ordered_events || !limit) + return 0; + + if (show_progress) + ui_progress__init(&prog, oe->nr_events, "Processing time ordered events..."); + + list_for_each_entry_safe(iter, tmp, head, list) { + if (session_done()) + return 0; + + if (iter->timestamp > limit) + break; + + ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample); + if (ret) + pr_err("Can't parse sample, err = %d\n", ret); + else { + ret = perf_session__deliver_event(s, iter->event, &sample, tool, + iter->file_offset); + if (ret) + return ret; + } + + ordered_events__delete(oe, iter); + oe->last_flush = iter->timestamp; + + if (show_progress) + ui_progress__update(&prog, 1); + } + + if (list_empty(head)) + oe->last = NULL; + else if (last_ts <= limit) + oe->last = list_entry(head->prev, struct ordered_event, list); + + return 0; +} + +int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, + enum oe_flush how) +{ + struct ordered_events *oe = &s->ordered_events; + int err; + + switch (how) { + case OE_FLUSH__FINAL: + oe->next_flush = ULLONG_MAX; + break; + + case OE_FLUSH__HALF: + { + struct ordered_event *first, *last; + struct list_head *head = &oe->events; + + first = list_entry(head->next, struct ordered_event, list); + last = oe->last; + + /* Warn if we are called before any event got allocated. */ + if (WARN_ONCE(!last || list_empty(head), "empty queue")) + return 0; + + oe->next_flush = first->timestamp; + oe->next_flush += (last->timestamp - first->timestamp) / 2; + break; + } + + case OE_FLUSH__ROUND: + default: + break; + }; + + err = __ordered_events__flush(s, tool); + + if (!err) { + if (how == OE_FLUSH__ROUND) + oe->next_flush = oe->max_timestamp; + } + + return err; +} diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h new file mode 100644 index 000000000000..8309983bdd70 --- /dev/null +++ b/tools/perf/util/ordered-events.h @@ -0,0 +1,41 @@ +#ifndef __ORDERED_EVENTS_H +#define __ORDERED_EVENTS_H + +#include +#include "tool.h" + +struct perf_session; + +struct ordered_event { + u64 timestamp; + u64 file_offset; + union perf_event *event; + struct list_head list; +}; + +enum oe_flush { + OE_FLUSH__FINAL, + OE_FLUSH__ROUND, + OE_FLUSH__HALF, +}; + +struct ordered_events { + u64 last_flush; + u64 next_flush; + u64 max_timestamp; + u64 max_alloc_size; + u64 cur_alloc_size; + struct list_head events; + struct list_head cache; + struct list_head to_free; + struct ordered_event *buffer; + struct ordered_event *last; + int buffer_idx; + unsigned int nr_events; +}; + +struct ordered_event *ordered_events__new(struct ordered_events *oe, u64 timestamp); +void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event); +int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, + enum oe_flush how); +#endif /* __ORDERED_EVENTS_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index ed6b7f14631f..0ccf051247f6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -14,7 +14,6 @@ #include "util.h" #include "cpumap.h" #include "perf_regs.h" -#include "asm/bug.h" static int perf_session__open(struct perf_session *session) { @@ -447,19 +446,6 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_HEADER_MAX] = NULL, }; -struct ordered_event { - u64 timestamp; - u64 file_offset; - union perf_event *event; - struct list_head list; -}; - -enum oe_flush { - OE_FLUSH__FINAL, - OE_FLUSH__ROUND, - OE_FLUSH__HALF, -}; - static void perf_session_free_sample_buffers(struct perf_session *session) { struct ordered_events *oe = &session->ordered_events; @@ -473,198 +459,6 @@ static void perf_session_free_sample_buffers(struct perf_session *session) } } -/* The queue is ordered by time */ -static void queue_event(struct ordered_events *oe, struct ordered_event *new) -{ - struct ordered_event *last = oe->last; - u64 timestamp = new->timestamp; - struct list_head *p; - - ++oe->nr_events; - oe->last = new; - - if (!last) { - list_add(&new->list, &oe->events); - oe->max_timestamp = timestamp; - return; - } - - /* - * last event might point to some random place in the list as it's - * the last queued event. We expect that the new event is close to - * this. - */ - if (last->timestamp <= timestamp) { - while (last->timestamp <= timestamp) { - p = last->list.next; - if (p == &oe->events) { - list_add_tail(&new->list, &oe->events); - oe->max_timestamp = timestamp; - return; - } - last = list_entry(p, struct ordered_event, list); - } - list_add_tail(&new->list, &last->list); - } else { - while (last->timestamp > timestamp) { - p = last->list.prev; - if (p == &oe->events) { - list_add(&new->list, &oe->events); - return; - } - last = list_entry(p, struct ordered_event, list); - } - list_add(&new->list, &last->list); - } -} - -#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct ordered_event)) -static struct ordered_event *alloc_event(struct ordered_events *oe) -{ - struct list_head *cache = &oe->cache; - struct ordered_event *new = NULL; - - if (!list_empty(cache)) { - new = list_entry(cache->next, struct ordered_event, list); - list_del(&new->list); - } else if (oe->buffer) { - new = oe->buffer + oe->buffer_idx; - if (++oe->buffer_idx == MAX_SAMPLE_BUFFER) - oe->buffer = NULL; - } else if (oe->cur_alloc_size < oe->max_alloc_size) { - size_t size = MAX_SAMPLE_BUFFER * sizeof(*new); - - oe->buffer = malloc(size); - if (!oe->buffer) - return NULL; - - oe->cur_alloc_size += size; - list_add(&oe->buffer->list, &oe->to_free); - - /* First entry is abused to maintain the to_free list. */ - oe->buffer_idx = 2; - new = oe->buffer + 1; - } - - return new; -} - -static struct ordered_event * -ordered_events__new(struct ordered_events *oe, u64 timestamp) -{ - struct ordered_event *new; - - new = alloc_event(oe); - if (new) { - new->timestamp = timestamp; - queue_event(oe, new); - } - - return new; -} - -static void -ordered_events__delete(struct ordered_events *oe, struct ordered_event *event) -{ - list_del(&event->list); - list_add(&event->list, &oe->cache); - oe->nr_events--; -} - -static int __ordered_events__flush(struct perf_session *s, - struct perf_tool *tool) -{ - struct ordered_events *oe = &s->ordered_events; - struct list_head *head = &oe->events; - struct ordered_event *tmp, *iter; - struct perf_sample sample; - u64 limit = oe->next_flush; - u64 last_ts = oe->last ? oe->last->timestamp : 0ULL; - bool show_progress = limit == ULLONG_MAX; - struct ui_progress prog; - int ret; - - if (!tool->ordered_events || !limit) - return 0; - - if (show_progress) - ui_progress__init(&prog, oe->nr_events, "Processing time ordered events..."); - - list_for_each_entry_safe(iter, tmp, head, list) { - if (session_done()) - return 0; - - if (iter->timestamp > limit) - break; - - ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample); - if (ret) - pr_err("Can't parse sample, err = %d\n", ret); - else { - ret = perf_session__deliver_event(s, iter->event, &sample, tool, - iter->file_offset); - if (ret) - return ret; - } - - ordered_events__delete(oe, iter); - oe->last_flush = iter->timestamp; - - if (show_progress) - ui_progress__update(&prog, 1); - } - - if (list_empty(head)) - oe->last = NULL; - else if (last_ts <= limit) - oe->last = list_entry(head->prev, struct ordered_event, list); - - return 0; -} - -static int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, - enum oe_flush how) -{ - struct ordered_events *oe = &s->ordered_events; - int err; - - switch (how) { - case OE_FLUSH__FINAL: - oe->next_flush = ULLONG_MAX; - break; - - case OE_FLUSH__HALF: - { - struct ordered_event *first, *last; - struct list_head *head = &oe->events; - - first = list_entry(head->next, struct ordered_event, list); - last = oe->last; - - /* Warn if we are called before any event got allocated. */ - if (WARN_ONCE(!last || list_empty(head), "empty queue")) - return 0; - - oe->next_flush = first->timestamp; - oe->next_flush += (last->timestamp - first->timestamp) / 2; - break; - } - - case OE_FLUSH__ROUND: - default: - break; - }; - - err = __ordered_events__flush(s, tool); - - if (!err) { - if (how == OE_FLUSH__ROUND) - oe->next_flush = oe->max_timestamp; - } - - return err; -} - /* * When perf record finishes a pass on every buffers, it records this pseudo * event. diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 03da1cb14dc1..0630e658f8be 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -9,28 +9,13 @@ #include "symbol.h" #include "thread.h" #include "data.h" +#include "ordered-events.h" #include #include -struct ordered_event; struct ip_callchain; struct thread; -struct ordered_events { - u64 last_flush; - u64 next_flush; - u64 max_timestamp; - u64 max_alloc_size; - u64 cur_alloc_size; - struct list_head events; - struct list_head cache; - struct list_head to_free; - struct ordered_event *buffer; - struct ordered_event *last; - int buffer_idx; - unsigned int nr_events; -}; - struct perf_session { struct perf_header header; struct machines machines; -- GitLab From fa4e5c67a2d169b9ef83f51b94e1d4a562ddfc0f Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 15 Jun 2014 19:46:08 +0200 Subject: [PATCH 0243/9167] perf tools: Use list_move in ordered_events_delete function As Namhyung pointed out we can use list_move in ordered_events_delete. Signed-off-by: Jiri Olsa Suggested-by: Namhyung Kim Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-m8ae5s5cuwyytitgb6iqilid@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ordered-events.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index 95f8211ccdde..be6a48ce3eea 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c @@ -96,8 +96,7 @@ ordered_events__new(struct ordered_events *oe, u64 timestamp) void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event) { - list_del(&event->list); - list_add(&event->list, &oe->cache); + list_move(&event->list, &oe->cache); oe->nr_events--; } -- GitLab From 36522f5cf2ad280c971557e04120d52f9330ed36 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 10 Jun 2014 22:47:40 +0200 Subject: [PATCH 0244/9167] perf tools: Add ordered_events__init function Adding ordered_events__init function for struct ordered_events struct initialization. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-g6dx35hed8g14eh1ygx4uzp6@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ordered-events.c | 9 +++++++++ tools/perf/util/ordered-events.h | 1 + tools/perf/util/session.c | 6 +----- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index be6a48ce3eea..7b8923e12dc7 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c @@ -193,3 +193,12 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, return err; } + +void ordered_events__init(struct ordered_events *oe) +{ + INIT_LIST_HEAD(&oe->events); + INIT_LIST_HEAD(&oe->cache); + INIT_LIST_HEAD(&oe->to_free); + oe->max_alloc_size = (u64) -1; + oe->cur_alloc_size = 0; +} diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h index 8309983bdd70..62f9945319b6 100644 --- a/tools/perf/util/ordered-events.h +++ b/tools/perf/util/ordered-events.h @@ -38,4 +38,5 @@ struct ordered_event *ordered_events__new(struct ordered_events *oe, u64 timesta void ordered_events__delete(struct ordered_events *oe, struct ordered_event *event); int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, enum oe_flush how); +void ordered_events__init(struct ordered_events *oe); #endif /* __ORDERED_EVENTS_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0ccf051247f6..7f5851e433bb 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -75,11 +75,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file, goto out; session->repipe = repipe; - INIT_LIST_HEAD(&session->ordered_events.events); - INIT_LIST_HEAD(&session->ordered_events.cache); - INIT_LIST_HEAD(&session->ordered_events.to_free); - session->ordered_events.max_alloc_size = (u64) -1; - session->ordered_events.cur_alloc_size = 0; + ordered_events__init(&session->ordered_events); machines__init(&session->machines); if (file) { -- GitLab From adc56ed1e01f1c43fc7bf75340f11f4ad5e11145 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 10 Jun 2014 22:50:03 +0200 Subject: [PATCH 0245/9167] perf tools: Add ordered_events__free function Adding ordered_events__free function to release all the struct ordered_events data. It's replacement for former perf_session_free_sample_buffers function. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-urraa8ccay4o14wambjraws7@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ordered-events.c | 11 +++++++++++ tools/perf/util/ordered-events.h | 1 + tools/perf/util/session.c | 17 ++--------------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index 7b8923e12dc7..381d5fea1131 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c @@ -202,3 +202,14 @@ void ordered_events__init(struct ordered_events *oe) oe->max_alloc_size = (u64) -1; oe->cur_alloc_size = 0; } + +void ordered_events__free(struct ordered_events *oe) +{ + while (!list_empty(&oe->to_free)) { + struct ordered_event *event; + + event = list_entry(oe->to_free.next, struct ordered_event, list); + list_del(&event->list); + free(event); + } +} diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h index 62f9945319b6..6036bd657073 100644 --- a/tools/perf/util/ordered-events.h +++ b/tools/perf/util/ordered-events.h @@ -39,4 +39,5 @@ void ordered_events__delete(struct ordered_events *oe, struct ordered_event *eve int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, enum oe_flush how); void ordered_events__init(struct ordered_events *oe); +void ordered_events__free(struct ordered_events *oe); #endif /* __ORDERED_EVENTS_H */ diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 7f5851e433bb..7d8dbf213d64 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -442,19 +442,6 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_HEADER_MAX] = NULL, }; -static void perf_session_free_sample_buffers(struct perf_session *session) -{ - struct ordered_events *oe = &session->ordered_events; - - while (!list_empty(&oe->to_free)) { - struct ordered_event *event; - - event = list_entry(oe->to_free.next, struct ordered_event, list); - list_del(&event->list); - free(event); - } -} - /* * When perf record finishes a pass on every buffers, it records this pseudo * event. @@ -1092,7 +1079,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session, out_err: free(buf); perf_session__warn_about_errors(session, tool); - perf_session_free_sample_buffers(session); + ordered_events__free(&session->ordered_events); return err; } @@ -1237,7 +1224,7 @@ int __perf_session__process_events(struct perf_session *session, out_err: ui_progress__finish(); perf_session__warn_about_errors(session, tool); - perf_session_free_sample_buffers(session); + ordered_events__free(&session->ordered_events); session->one_mmap = false; return err; } -- GitLab From 94c0655fc16b0c09edc21cadddbeef95c408f3e7 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 6 Jun 2014 05:27:28 -0400 Subject: [PATCH 0246/9167] perf tools: Add perf_config_u64 function Adding perf_config_u64 function to be able to parse 'llong' values out of config file. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-ni6gqdlvw7khp74r9htvklkb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cache.h | 1 + tools/perf/util/config.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 7b176dd02e1a..5cf9e1b5989d 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -22,6 +22,7 @@ typedef int (*config_fn_t)(const char *, const char *, void *); extern int perf_default_config(const char *, const char *, void *); extern int perf_config(config_fn_t fn, void *); extern int perf_config_int(const char *, const char *); +extern u64 perf_config_u64(const char *, const char *); extern int perf_config_bool(const char *, const char *); extern int config_error_nonbool(const char *); extern const char *perf_config_dirname(const char *, const char *); diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 1e5e2e5af6b1..9970b8b0190b 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -286,6 +286,21 @@ static int parse_unit_factor(const char *end, unsigned long *val) return 0; } +static int perf_parse_llong(const char *value, long long *ret) +{ + if (value && *value) { + char *end; + long long val = strtoll(value, &end, 0); + unsigned long factor = 1; + + if (!parse_unit_factor(end, &factor)) + return 0; + *ret = val * factor; + return 1; + } + return 0; +} + static int perf_parse_long(const char *value, long *ret) { if (value && *value) { @@ -307,6 +322,15 @@ static void die_bad_config(const char *name) die("bad config value for '%s'", name); } +u64 perf_config_u64(const char *name, const char *value) +{ + long long ret = 0; + + if (!perf_parse_llong(value, &ret)) + die_bad_config(name); + return (u64) ret; +} + int perf_config_int(const char *name, const char *value) { long ret = 0; -- GitLab From 94786b67b5f4577c16486e8eb10ff045e59f80ef Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 5 Jun 2014 11:00:20 +0200 Subject: [PATCH 0247/9167] perf tools: Add report.queue-size config file option Adding report.queue-size config file option to setup the maximum allocation size for session's struct ordered_events object. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-lm42mbpu0cwljpyy8vw5y26n@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 13 ++++++++++++- tools/perf/util/ordered-events.h | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c72cc5a12144..041e93da13e4 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -58,17 +58,19 @@ struct report { const char *symbol_filter_str; float min_percent; u64 nr_entries; + u64 queue_size; DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); }; static int report__config(const char *var, const char *value, void *cb) { + struct report *rep = cb; + if (!strcmp(var, "report.group")) { symbol_conf.event_group = perf_config_bool(var, value); return 0; } if (!strcmp(var, "report.percent-limit")) { - struct report *rep = cb; rep->min_percent = strtof(value, NULL); return 0; } @@ -76,6 +78,10 @@ static int report__config(const char *var, const char *value, void *cb) symbol_conf.cumulate_callchain = perf_config_bool(var, value); return 0; } + if (!strcmp(var, "report.queue-size")) { + rep->queue_size = perf_config_u64(var, value); + return 0; + } return perf_default_config(var, value, cb); } @@ -714,6 +720,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) if (session == NULL) return -ENOMEM; + if (report.queue_size) { + ordered_events__set_alloc_size(&session->ordered_events, + report.queue_size); + } + report.session = session; has_br_stack = perf_header__has_feat(&session->header, diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h index 6036bd657073..2ce847fb48a5 100644 --- a/tools/perf/util/ordered-events.h +++ b/tools/perf/util/ordered-events.h @@ -40,4 +40,10 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, enum oe_flush how); void ordered_events__init(struct ordered_events *oe); void ordered_events__free(struct ordered_events *oe); + +static inline +void ordered_events__set_alloc_size(struct ordered_events *oe, u64 size) +{ + oe->max_alloc_size = size; +} #endif /* __ORDERED_EVENTS_H */ -- GitLab From cee3ab9caa7ae5ee81027e60c0109063664d9217 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 11 Jul 2014 14:49:54 +0200 Subject: [PATCH 0248/9167] perf tools: Add debug prints for ordered events queue Adding some prints for ordered events queue, to help debug issues. Adding debug_ordered_events debug variable to be able to enable ordered events debug messages using: $ perf --debug ordered-events=2 report ... Also using oe pointer in perf_session__queue_event instead of chained session variable dereferencing. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-7p3mnnopjvsp9nmk9msqcfkm@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/debug.c | 36 +++++++++++++++++++++++++++++++- tools/perf/util/debug.h | 8 +++++++ tools/perf/util/ordered-events.c | 26 +++++++++++++++++++++++ tools/perf/util/session.c | 4 +++- 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c index 71d419362634..ba357f3226c6 100644 --- a/tools/perf/util/debug.c +++ b/tools/perf/util/debug.c @@ -13,8 +13,12 @@ #include "util.h" #include "target.h" +#define NSECS_PER_SEC 1000000000ULL +#define NSECS_PER_USEC 1000ULL + int verbose; bool dump_trace = false, quiet = false; +int debug_ordered_events; static int _eprintf(int level, int var, const char *fmt, va_list args) { @@ -42,6 +46,35 @@ int eprintf(int level, int var, const char *fmt, ...) return ret; } +static int __eprintf_time(u64 t, const char *fmt, va_list args) +{ + int ret = 0; + u64 secs, usecs, nsecs = t; + + secs = nsecs / NSECS_PER_SEC; + nsecs -= secs * NSECS_PER_SEC; + usecs = nsecs / NSECS_PER_USEC; + + ret = fprintf(stderr, "[%13" PRIu64 ".%06" PRIu64 "] ", + secs, usecs); + ret += vfprintf(stderr, fmt, args); + return ret; +} + +int eprintf_time(int level, int var, u64 t, const char *fmt, ...) +{ + int ret = 0; + va_list args; + + if (var >= level) { + va_start(args, fmt); + ret = __eprintf_time(t, fmt, args); + va_end(args); + } + + return ret; +} + /* * Overloading libtraceevent standard info print * function, display with -v in perf. @@ -110,7 +143,8 @@ static struct debug_variable { const char *name; int *ptr; } debug_variables[] = { - { .name = "verbose", .ptr = &verbose }, + { .name = "verbose", .ptr = &verbose }, + { .name = "ordered-events", .ptr = &debug_ordered_events}, { .name = NULL, } }; diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 89fb6b0f7ab2..6944ea3a119b 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -10,6 +10,7 @@ extern int verbose; extern bool quiet, dump_trace; +extern int debug_ordered_events; #ifndef pr_fmt #define pr_fmt(fmt) fmt @@ -29,6 +30,12 @@ extern bool quiet, dump_trace; #define pr_debug3(fmt, ...) pr_debugN(3, pr_fmt(fmt), ##__VA_ARGS__) #define pr_debug4(fmt, ...) pr_debugN(4, pr_fmt(fmt), ##__VA_ARGS__) +#define pr_time_N(n, var, t, fmt, ...) \ + eprintf_time(n, var, t, fmt, ##__VA_ARGS__) + +#define pr_oe_time(t, fmt, ...) pr_time_N(1, debug_ordered_events, t, pr_fmt(fmt), ##__VA_ARGS__) +#define pr_oe_time2(t, fmt, ...) pr_time_N(2, debug_ordered_events, t, pr_fmt(fmt), ##__VA_ARGS__) + int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void trace_event(union perf_event *event); @@ -38,6 +45,7 @@ int ui__warning(const char *format, ...) __attribute__((format(printf, 1, 2))); void pr_stat(const char *fmt, ...); int eprintf(int level, int var, const char *fmt, ...) __attribute__((format(printf, 3, 4))); +int eprintf_time(int level, int var, u64 t, const char *fmt, ...) __attribute__((format(printf, 4, 5))); int perf_debug_option(const char *str); diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index 381d5fea1131..8a8aeab8e7ec 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c @@ -1,10 +1,16 @@ #include +#include #include "ordered-events.h" #include "evlist.h" #include "session.h" #include "asm/bug.h" #include "debug.h" +#define pr_N(n, fmt, ...) \ + eprintf(n, debug_ordered_events, fmt, ##__VA_ARGS__) + +#define pr(fmt, ...) pr_N(1, pr_fmt(fmt), ##__VA_ARGS__) + static void queue_event(struct ordered_events *oe, struct ordered_event *new) { struct ordered_event *last = oe->last; @@ -14,6 +20,8 @@ static void queue_event(struct ordered_events *oe, struct ordered_event *new) ++oe->nr_events; oe->last = new; + pr_oe_time2(timestamp, "queue_event nr_events %u\n", oe->nr_events); + if (!last) { list_add(&new->list, &oe->events); oe->max_timestamp = timestamp; @@ -69,12 +77,17 @@ static struct ordered_event *alloc_event(struct ordered_events *oe) if (!oe->buffer) return NULL; + pr("alloc size %" PRIu64 "B (+%zu), max %" PRIu64 "B\n", + oe->cur_alloc_size, size, oe->max_alloc_size); + oe->cur_alloc_size += size; list_add(&oe->buffer->list, &oe->to_free); /* First entry is abused to maintain the to_free list. */ oe->buffer_idx = 2; new = oe->buffer + 1; + } else { + pr("allocation limit reached %" PRIu64 "B\n", oe->max_alloc_size); } return new; @@ -155,6 +168,11 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, enum oe_flush how) { struct ordered_events *oe = &s->ordered_events; + static const char * const str[] = { + "FINAL", + "ROUND", + "HALF ", + }; int err; switch (how) { @@ -184,6 +202,10 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, break; }; + pr_oe_time(oe->next_flush, "next_flush - ordered_events__flush PRE %s, nr_events %u\n", + str[how], oe->nr_events); + pr_oe_time(oe->max_timestamp, "max_timestamp\n"); + err = __ordered_events__flush(s, tool); if (!err) { @@ -191,6 +213,10 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, oe->next_flush = oe->max_timestamp; } + pr_oe_time(oe->next_flush, "next_flush - ordered_events__flush POST %s, nr_events %u\n", + str[how], oe->nr_events); + pr_oe_time(oe->last_flush, "last_flush\n"); + return err; } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 7d8dbf213d64..462be2749462 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -499,8 +499,10 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event, if (!timestamp || timestamp == ~0ULL) return -ETIME; - if (timestamp < s->ordered_events.last_flush) { + if (timestamp < oe->last_flush) { printf("Warning: Timestamp below last timeslice flush\n"); + pr_oe_time(timestamp, "out of order event"); + pr_oe_time(oe->last_flush, "last flush"); return -EINVAL; } -- GitLab From b0a45203a75a800015828ac89f2945981019b65b Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 12 Jun 2014 09:50:11 +0200 Subject: [PATCH 0249/9167] perf tools: Allow out of order messages in forced flush In forced flush (OE_FLUSH__HALF) we break the rules of the flush timestamp via PERF_RECORD_FINISHED_ROUND event, so we could get out of order event. Do not force error in this case plus changing the output warning to use WARN_ONCE. Signed-off-by: Jiri Olsa Acked-by: David Ahern Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-8q8794a8nlmpd1u8xrqmcyd2@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/ordered-events.c | 4 ++++ tools/perf/util/ordered-events.h | 2 ++ tools/perf/util/session.c | 12 +++++++++--- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index 8a8aeab8e7ec..706ce1a66169 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c @@ -169,6 +169,7 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, { struct ordered_events *oe = &s->ordered_events; static const char * const str[] = { + "NONE", "FINAL", "ROUND", "HALF ", @@ -198,6 +199,7 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, } case OE_FLUSH__ROUND: + case OE_FLUSH__NONE: default: break; }; @@ -211,6 +213,8 @@ int ordered_events__flush(struct perf_session *s, struct perf_tool *tool, if (!err) { if (how == OE_FLUSH__ROUND) oe->next_flush = oe->max_timestamp; + + oe->last_flush_type = how; } pr_oe_time(oe->next_flush, "next_flush - ordered_events__flush POST %s, nr_events %u\n", diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h index 2ce847fb48a5..3b2f20542a01 100644 --- a/tools/perf/util/ordered-events.h +++ b/tools/perf/util/ordered-events.h @@ -14,6 +14,7 @@ struct ordered_event { }; enum oe_flush { + OE_FLUSH__NONE, OE_FLUSH__FINAL, OE_FLUSH__ROUND, OE_FLUSH__HALF, @@ -32,6 +33,7 @@ struct ordered_events { struct ordered_event *last; int buffer_idx; unsigned int nr_events; + enum oe_flush last_flush_type; }; struct ordered_event *ordered_events__new(struct ordered_events *oe, u64 timestamp); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 462be2749462..7e27f1eb260c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -14,6 +14,7 @@ #include "util.h" #include "cpumap.h" #include "perf_regs.h" +#include "asm/bug.h" static int perf_session__open(struct perf_session *session) { @@ -500,10 +501,15 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event, return -ETIME; if (timestamp < oe->last_flush) { - printf("Warning: Timestamp below last timeslice flush\n"); + WARN_ONCE(1, "Timestamp below last timeslice flush\n"); + pr_oe_time(timestamp, "out of order event"); - pr_oe_time(oe->last_flush, "last flush"); - return -EINVAL; + pr_oe_time(oe->last_flush, "last flush, last_flush_type %d\n", + oe->last_flush_type); + + /* We could get out of order messages after forced flush. */ + if (oe->last_flush_type != OE_FLUSH__HALF) + return -EINVAL; } new = ordered_events__new(oe, timestamp); -- GitLab From 63914aca8f7e7a75d0ee027af7b1755c69cc1e2c Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 1 Aug 2014 17:46:54 +0200 Subject: [PATCH 0250/9167] perf tools: Show better error message in case we fail to open counters due to EBUSY error Showing better error message in case we fail to open counters due to the EBUSY error. If we detect oprofile daemon process running, we now display following message for EBUSY error: $ perf record ls Error: The PMU counters are busy/taken by another profiler. We found oprofile daemon running, please stop it and try again. In case oprofiled was not detected the current error message stays: $ perf record ls Error: The sys_perf_event_open() syscall returned with 16 (Device or resource busy) for event (cycles). /bin/dmesg may provide additional information. No CONFIG_PERF_EVENTS=y kernel support configured? Also changing PERF_FLAG_FD_CLOEXEC detection code not to display error in case of EBUSY error, as it currently does: $ perf record ls Error: perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error 16 (Device or resource busy) perf_event_open(..., 0) failed unexpectedly with error 16 (Device or resource busy) The PMU counters are busy/taken by another profiler. We found oprofile daemon running, please stop it and try again. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: William Cohen Cc: Yann Droneaud Link: http://lkml.kernel.org/r/1406908014-8312-1-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cloexec.c | 4 ++-- tools/perf/util/evsel.c | 6 ++++++ tools/perf/util/util.c | 36 ++++++++++++++++++++++++++++++++++++ tools/perf/util/util.h | 1 + 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index c5d05ec17220..dede0c388ed4 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -25,7 +25,7 @@ static int perf_flag_probe(void) return 1; } - WARN_ONCE(err != EINVAL, + WARN_ONCE(err != EINVAL && err != EBUSY, "perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n", err, strerror(err)); @@ -33,7 +33,7 @@ static int perf_flag_probe(void) fd = sys_perf_event_open(&attr, 0, -1, -1, 0); err = errno; - if (WARN_ONCE(fd < 0, + if (WARN_ONCE(fd < 0 && err != EBUSY, "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n", err, strerror(err))) return -1; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 92e5235f5377..0c8919decac8 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2039,6 +2039,12 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, "No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it."); #endif break; + case EBUSY: + if (find_process("oprofiled")) + return scnprintf(msg, size, + "The PMU counters are busy/taken by another profiler.\n" + "We found oprofile daemon running, please stop it and try again."); + break; default: break; } diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index e52e7461911b..b82a93cb1694 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -536,3 +536,39 @@ void mem_bswap_64(void *src, int byte_size) ++m; } } + +bool find_process(const char *name) +{ + size_t len = strlen(name); + DIR *dir; + struct dirent *d; + int ret = -1; + + dir = opendir(procfs__mountpoint()); + if (!dir) + return -1; + + /* Walk through the directory. */ + while (ret && (d = readdir(dir)) != NULL) { + char path[PATH_MAX]; + char *data; + size_t size; + + if ((d->d_type != DT_DIR) || + !strcmp(".", d->d_name) || + !strcmp("..", d->d_name)) + continue; + + scnprintf(path, sizeof(path), "%s/%s/comm", + procfs__mountpoint(), d->d_name); + + if (filename__read_str(path, &data, &size)) + continue; + + ret = strncmp(name, data, len); + free(data); + } + + closedir(dir); + return ret ? false : true; +} diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 38af77550c75..03a1ea2266b8 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -346,4 +346,5 @@ void mem_bswap_64(void *src, int byte_size); void mem_bswap_32(void *src, int byte_size); const char *get_filename_for_perf_kvm(void); +bool find_process(const char *name); #endif /* GIT_COMPAT_UTIL_H */ -- GitLab From 64c40908938953d7afa90e9363327875286349e5 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 1 Aug 2014 14:59:31 +0900 Subject: [PATCH 0251/9167] perf kmem: Do not ignore mmap events The perf kmem command didn't process mmap events for some unknown reason and it instead gets symbol info from a running kernel. This is problematic if perf kmem record was run on a different kernel. This patch adds the mmap event handlers and reverts the commit e727ca73f85d ("perf kmem: Resolve kernel symbols again"). Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406872771-23933-1-git-send-email-namhyung@kernel.org [ Fixed up merge conflict with Jiri's ordered_events rename patch set ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kmem.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index b5721116713b..84b82397a28e 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -256,6 +256,8 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused, static struct perf_tool perf_kmem = { .sample = process_sample_event, .comm = perf_event__process_comm, + .mmap = perf_event__process_mmap, + .mmap2 = perf_event__process_mmap2, .ordered_events = true, }; @@ -424,9 +426,6 @@ static int __cmd_kmem(void) if (session == NULL) return -ENOMEM; - if (perf_session__create_kernel_maps(session) < 0) - goto out_delete; - if (!perf_session__has_traces(session, "kmem record")) goto out_delete; -- GitLab From 56c7d79e49776084b852e451bda5f59dc3bcf894 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 29 Jul 2014 15:57:19 +0900 Subject: [PATCH 0252/9167] perf tools: Fix make PYTHON override Thomas reported that make PYTHON=python2 is not work on some systems. I can reproduce it on my ArchLinux box too. This is because it's overridden by config/feature-checks/Makefile regardless of PYTHON setting. I guess it's a bug slipped into during the feature checking change. Actually, we don't need to check python-config in the feature-checks. We can just pass appropriate FEATURE_CHECK_*FLAGS. Reported-by: Thomas Ilsche Signed-off-by: Namhyung Kim Tested-by: Thomas Ilsche Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Thomas Ilsche Link: http://lkml.kernel.org/r/1406617040-26909-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/config/Makefile | 34 +++++++++++++++-------- tools/perf/config/feature-checks/Makefile | 18 ++---------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 1f67aa02d240..e05d8f99424d 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -120,6 +120,23 @@ ifdef PARSER_DEBUG CFLAGS += -DPARSER_DEBUG endif +ifndef NO_LIBPYTHON + override PYTHON := \ + $(call get-executable-or-default,PYTHON,python) + override PYTHON_CONFIG := \ + $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config) + + PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) + + PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) + PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) + + FEATURE_CHECK_CFLAGS-libpython := $(PYTHON_EMBED_CCOPTS) + FEATURE_CHECK_LDFLAGS-libpython := $(PYTHON_EMBED_LDOPTS) + FEATURE_CHECK_CFLAGS-libpython-version := $(PYTHON_EMBED_CCOPTS) + FEATURE_CHECK_LDFLAGS-libpython-version := $(PYTHON_EMBED_LDOPTS) +endif + CFLAGS += -fno-omit-frame-pointer CFLAGS += -ggdb3 CFLAGS += -funwind-tables @@ -482,21 +499,14 @@ define disable-python_code NO_LIBPYTHON := 1 endef -override PYTHON := \ - $(call get-executable-or-default,PYTHON,python) - -ifndef PYTHON - $(call disable-python,python interpreter) +ifdef NO_LIBPYTHON + $(call disable-python) else - PYTHON_WORD := $(call shell-wordify,$(PYTHON)) - - ifdef NO_LIBPYTHON - $(call disable-python) + ifndef PYTHON + $(call disable-python,python interpreter) else - - override PYTHON_CONFIG := \ - $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config) + PYTHON_WORD := $(call shell-wordify,$(PYTHON)) ifndef PYTHON_CONFIG $(call disable-python,python-config tool) diff --git a/tools/perf/config/feature-checks/Makefile b/tools/perf/config/feature-checks/Makefile index 6088f8d8a434..72ab2984718e 100644 --- a/tools/perf/config/feature-checks/Makefile +++ b/tools/perf/config/feature-checks/Makefile @@ -101,25 +101,11 @@ FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) test-libperl.bin: $(BUILD) $(FLAGS_PERL_EMBED) -override PYTHON := python -override PYTHON_CONFIG := python-config - -escape-for-shell-sq = $(subst ','\'',$(1)) -shell-sq = '$(escape-for-shell-sq)' - -PYTHON_CONFIG_SQ = $(call shell-sq,$(PYTHON_CONFIG)) - -PYTHON_EMBED_LDOPTS = $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) -PYTHON_EMBED_LDFLAGS = $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) -PYTHON_EMBED_LIBADD = $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -PYTHON_EMBED_CCOPTS = $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) -FLAGS_PYTHON_EMBED = $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) - test-libpython.bin: - $(BUILD) $(FLAGS_PYTHON_EMBED) + $(BUILD) test-libpython-version.bin: - $(BUILD) $(FLAGS_PYTHON_EMBED) + $(BUILD) test-libbfd.bin: $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl -- GitLab From 8246de88e95ddef7508f5601d7af85c3ab9e476b Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 31 Jul 2014 14:47:35 +0900 Subject: [PATCH 0253/9167] perf tools: Left-align output contents Now perf left-aligns column headers but the contents does not. It should have same alignment. This requires a change in pid sort key - it consists of two part (pid and comm). As length of comm can be vary it'd be better to change the order of them. Thanks to Jiri Olsa for pointing this out. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406785662-5534-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/sort.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 14e5a039bc45..eda9ee836cee 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -70,12 +70,12 @@ static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { const char *comm = thread__comm_str(he->thread); - return repsep_snprintf(bf, size, "%*s:%5d", width - 6, - comm ?: "", he->thread->tid); + return repsep_snprintf(bf, size, "%5d:%-*s", he->thread->tid, + width - 6, comm ?: ""); } struct sort_entry sort_thread = { - .se_header = "Command: Pid", + .se_header = " Pid:Command", .se_cmp = sort__thread_cmp, .se_snprintf = hist_entry__thread_snprintf, .se_width_idx = HISTC_THREAD, @@ -106,7 +106,7 @@ sort__comm_sort(struct hist_entry *left, struct hist_entry *right) static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { - return repsep_snprintf(bf, size, "%*s", width, comm__str(he->comm)); + return repsep_snprintf(bf, size, "%-*s", width, comm__str(he->comm)); } struct sort_entry sort_comm = { @@ -305,7 +305,7 @@ static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width __maybe_unused) { - return repsep_snprintf(bf, size, "%s", he->srcline); + return repsep_snprintf(bf, size, "%-s", he->srcline); } struct sort_entry sort_srcline = { -- GitLab From d675107ce6fa988102851e0b0ef06e46c8aa7ac6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 31 Jul 2014 14:47:36 +0900 Subject: [PATCH 0254/9167] perf tools: Make __hpp__fmt() receive an additional len argument So that it can properly handle alignment requirements later. To do that, add percent_color_len_snprintf() fucntion to help coloring of overhead columns. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406785662-5534-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 14 ++++++----- tools/perf/ui/gtk/hists.c | 8 ++++--- tools/perf/ui/hist.c | 43 +++++++++++++++++----------------- tools/perf/util/color.c | 16 +++++++++++++ tools/perf/util/color.h | 1 + tools/perf/util/hist.h | 4 ++-- 6 files changed, 54 insertions(+), 32 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index a94b11fc5e00..02507ba944e3 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -653,17 +653,18 @@ struct hpp_arg { static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...) { struct hpp_arg *arg = hpp->ptr; - int ret; + int ret, len; va_list args; double percent; va_start(args, fmt); + len = va_arg(args, int); percent = va_arg(args, double); va_end(args); ui_browser__set_percent_color(arg->b, percent, arg->current_entry); - ret = scnprintf(hpp->buf, hpp->size, fmt, percent); + ret = scnprintf(hpp->buf, hpp->size, fmt, len, percent); slsmg_printf("%s", hpp->buf); advance_hpp(hpp, ret); @@ -681,7 +682,7 @@ hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\ struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, __hpp_get_##_field, " %6.2f%%", \ + return __hpp__fmt(hpp, he, __hpp_get_##_field, " %*.2f%%", 6, \ __hpp__slsmg_color_printf, true); \ } @@ -697,13 +698,14 @@ hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\ struct hist_entry *he) \ { \ if (!symbol_conf.cumulate_callchain) { \ - int ret = scnprintf(hpp->buf, hpp->size, "%8s", "N/A"); \ + int ret = scnprintf(hpp->buf, hpp->size, \ + "%*s", 8, "N/A"); \ slsmg_printf("%s", hpp->buf); \ \ return ret; \ } \ - return __hpp__fmt(hpp, he, __hpp_get_acc_##_field, " %6.2f%%", \ - __hpp__slsmg_color_printf, true); \ + return __hpp__fmt(hpp, he, __hpp_get_acc_##_field, " %*.2f%%", \ + 6, __hpp__slsmg_color_printf, true); \ } __HPP_COLOR_PERCENT_FN(overhead, period) diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 6ca60e482cdc..91f6cd7d2312 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -11,6 +11,7 @@ static int __percent_color_snprintf(struct perf_hpp *hpp, const char *fmt, ...) { int ret = 0; + int len; va_list args; double percent; const char *markup; @@ -18,6 +19,7 @@ static int __percent_color_snprintf(struct perf_hpp *hpp, const char *fmt, ...) size_t size = hpp->size; va_start(args, fmt); + len = va_arg(args, int); percent = va_arg(args, double); va_end(args); @@ -25,7 +27,7 @@ static int __percent_color_snprintf(struct perf_hpp *hpp, const char *fmt, ...) if (markup) ret += scnprintf(buf, size, markup); - ret += scnprintf(buf + ret, size - ret, fmt, percent); + ret += scnprintf(buf + ret, size - ret, fmt, len, percent); if (markup) ret += scnprintf(buf + ret, size - ret, ""); @@ -43,7 +45,7 @@ static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \ + return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", 6, \ __percent_color_snprintf, true); \ } @@ -57,7 +59,7 @@ static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, " %6.2f%%", \ + return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, " %*.2f%%", 6, \ __percent_color_snprintf, true); \ } diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index 498adb23c02e..c6cffbd0b0e1 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -16,7 +16,7 @@ }) int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, - hpp_field_fn get_field, const char *fmt, + hpp_field_fn get_field, const char *fmt, int len, hpp_snprint_fn print_fn, bool fmt_percent) { int ret; @@ -32,9 +32,9 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, if (total) percent = 100.0 * get_field(he) / total; - ret = hpp__call_print_fn(hpp, print_fn, fmt, percent); + ret = hpp__call_print_fn(hpp, print_fn, fmt, len, percent); } else - ret = hpp__call_print_fn(hpp, print_fn, fmt, get_field(he)); + ret = hpp__call_print_fn(hpp, print_fn, fmt, len, get_field(he)); if (perf_evsel__is_group_event(evsel)) { int prev_idx, idx_delta; @@ -60,19 +60,19 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, */ if (fmt_percent) { ret += hpp__call_print_fn(hpp, print_fn, - fmt, 0.0); + fmt, len, 0.0); } else { ret += hpp__call_print_fn(hpp, print_fn, - fmt, 0ULL); + fmt, len, 0ULL); } } if (fmt_percent) { - ret += hpp__call_print_fn(hpp, print_fn, fmt, + ret += hpp__call_print_fn(hpp, print_fn, fmt, len, 100.0 * period / total); } else { ret += hpp__call_print_fn(hpp, print_fn, fmt, - period); + len, period); } prev_idx = perf_evsel__group_idx(evsel); @@ -86,10 +86,10 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, */ if (fmt_percent) { ret += hpp__call_print_fn(hpp, print_fn, - fmt, 0.0); + fmt, len, 0.0); } else { ret += hpp__call_print_fn(hpp, print_fn, - fmt, 0ULL); + fmt, len, 0ULL); } } } @@ -105,7 +105,7 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, } int __hpp__fmt_acc(struct perf_hpp *hpp, struct hist_entry *he, - hpp_field_fn get_field, const char *fmt, + hpp_field_fn get_field, const char *fmt, int len, hpp_snprint_fn print_fn, bool fmt_percent) { if (!symbol_conf.cumulate_callchain) { @@ -113,7 +113,7 @@ int __hpp__fmt_acc(struct perf_hpp *hpp, struct hist_entry *he, fmt_percent ? 8 : 12, "N/A"); } - return __hpp__fmt(hpp, he, get_field, fmt, print_fn, fmt_percent); + return __hpp__fmt(hpp, he, get_field, fmt, len, print_fn, fmt_percent); } static int field_cmp(u64 field_a, u64 field_b) @@ -221,11 +221,12 @@ static int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...) va_list args; ssize_t ssize = hpp->size; double percent; - int ret; + int ret, len; va_start(args, fmt); + len = va_arg(args, int); percent = va_arg(args, double); - ret = value_color_snprintf(hpp->buf, hpp->size, fmt, percent); + ret = percent_color_len_snprintf(hpp->buf, hpp->size, fmt, len, percent); va_end(args); return (ret >= ssize) ? (ssize - 1) : ret; @@ -253,7 +254,7 @@ static u64 he_get_##_field(struct hist_entry *he) \ static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%", \ + return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", 6, \ hpp_color_scnprintf, true); \ } @@ -261,8 +262,8 @@ static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ - return __hpp__fmt(hpp, he, he_get_##_field, fmt, \ + int len = symbol_conf.field_sep ? 1 : 6; \ + return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", len, \ hpp_entry_scnprintf, true); \ } @@ -281,7 +282,7 @@ static u64 he_get_acc_##_field(struct hist_entry *he) \ static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, " %6.2f%%", \ + return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, " %*.2f%%", 6, \ hpp_color_scnprintf, true); \ } @@ -289,8 +290,8 @@ static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%"; \ - return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, fmt, \ + int len = symbol_conf.field_sep ? 1 : 6; \ + return __hpp__fmt_acc(hpp, he, he_get_##_field, " %*.2f%%", len, \ hpp_entry_scnprintf, true); \ } @@ -309,8 +310,8 @@ static u64 he_get_raw_##_field(struct hist_entry *he) \ static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64; \ - return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt, \ + int len = symbol_conf.field_sep ? 1 : 11; \ + return __hpp__fmt(hpp, he, he_get_raw_##_field, " %*"PRIu64, len, \ hpp_entry_scnprintf, false); \ } diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 87b8672eb413..f4654183d391 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -335,3 +335,19 @@ int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...) va_end(args); return value_color_snprintf(bf, size, fmt, percent); } + +int percent_color_len_snprintf(char *bf, size_t size, const char *fmt, ...) +{ + va_list args; + int len; + double percent; + const char *color; + + va_start(args, fmt); + len = va_arg(args, int); + percent = va_arg(args, double); + va_end(args); + + color = get_percent_color(percent); + return color_snprintf(bf, size, color, fmt, len, percent); +} diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h index 7ff30a62a132..0a594b8a0c26 100644 --- a/tools/perf/util/color.h +++ b/tools/perf/util/color.h @@ -41,6 +41,7 @@ int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf); int value_color_snprintf(char *bf, size_t size, const char *fmt, double value); int percent_color_snprintf(char *bf, size_t size, const char *fmt, ...); +int percent_color_len_snprintf(char *bf, size_t size, const char *fmt, ...); int percent_color_fprintf(FILE *fp, const char *fmt, double percent); const char *get_percent_color(double percent); diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 742f49a85725..13d074db9ef1 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -267,10 +267,10 @@ typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front); typedef int (*hpp_snprint_fn)(struct perf_hpp *hpp, const char *fmt, ...); int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, - hpp_field_fn get_field, const char *fmt, + hpp_field_fn get_field, const char *fmt, int len, hpp_snprint_fn print_fn, bool fmt_percent); int __hpp__fmt_acc(struct perf_hpp *hpp, struct hist_entry *he, - hpp_field_fn get_field, const char *fmt, + hpp_field_fn get_field, const char *fmt, int len, hpp_snprint_fn print_fn, bool fmt_percent); static inline void advance_hpp(struct perf_hpp *hpp, int inc) -- GitLab From e0d66c74b09f5103eef441a98b68056c4dae4cac Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 31 Jul 2014 14:47:37 +0900 Subject: [PATCH 0255/9167] perf tools: Save column length in perf_hpp_fmt Save column length in the hpp format and pass it to print functions. This is a preparation for users to control column width in the output. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406785662-5534-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 2 +- tools/perf/ui/hist.c | 135 ++++++++++++++++++++++----------- tools/perf/util/hist.h | 2 + tools/perf/util/sort.c | 3 +- 4 files changed, 94 insertions(+), 48 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 02507ba944e3..c1d8d3925fe1 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -849,7 +849,7 @@ static int hists__scnprintf_headers(char *buf, size_t size, struct hists *hists) if (perf_hpp__should_skip(fmt)) continue; - /* We need to add the length of the columns header. */ + /* We need to ensure length of the columns header. */ perf_hpp__reset_width(fmt, hists); ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index c6cffbd0b0e1..e28ca972d046 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -110,7 +110,7 @@ int __hpp__fmt_acc(struct perf_hpp *hpp, struct hist_entry *he, { if (!symbol_conf.cumulate_callchain) { return snprintf(hpp->buf, hpp->size, "%*s", - fmt_percent ? 8 : 12, "N/A"); + fmt_percent ? len + 2 : len + 1, "N/A"); } return __hpp__fmt(hpp, he, get_field, fmt, len, print_fn, fmt_percent); @@ -190,32 +190,31 @@ static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b, return ret; } -#define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ -static int hpp__header_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ - struct perf_hpp *hpp, \ - struct perf_evsel *evsel) \ -{ \ - int len = _min_width; \ - \ - if (symbol_conf.event_group) \ - len = max(len, evsel->nr_members * _unit_width); \ - \ - return scnprintf(hpp->buf, hpp->size, "%*s", len, _str); \ -} - -#define __HPP_WIDTH_FN(_type, _min_width, _unit_width) \ -static int hpp__width_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ +#define __HPP_WIDTH_FN(_type, _str) \ +static int hpp__width_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp __maybe_unused, \ struct perf_evsel *evsel) \ { \ - int len = _min_width; \ + int len = fmt->len; \ \ if (symbol_conf.event_group) \ - len = max(len, evsel->nr_members * _unit_width); \ + len = max(len, evsel->nr_members * len); \ + \ + if (len < (int)strlen(_str)) \ + len = strlen(_str); \ \ return len; \ } +#define __HPP_HEADER_FN(_type, _str) \ +static int hpp__header_##_type(struct perf_hpp_fmt *fmt, \ + struct perf_hpp *hpp, \ + struct perf_evsel *evsel) \ +{ \ + int len = hpp__width_##_type(fmt, hpp, evsel); \ + return scnprintf(hpp->buf, hpp->size, "%*s", len, _str); \ +} + static int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...) { va_list args; @@ -251,18 +250,19 @@ static u64 he_get_##_field(struct hist_entry *he) \ return he->stat._field; \ } \ \ -static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ +static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", 6, \ + int len = fmt->len - 2; /* 2 for a space and a % sign */ \ + return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", len, \ hpp_color_scnprintf, true); \ } #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ -static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ +static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - int len = symbol_conf.field_sep ? 1 : 6; \ + int len = symbol_conf.field_sep ? 1 : fmt->len - 2; \ return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", len, \ hpp_entry_scnprintf, true); \ } @@ -279,18 +279,19 @@ static u64 he_get_acc_##_field(struct hist_entry *he) \ return he->stat_acc->_field; \ } \ \ -static int hpp__color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ +static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, " %*.2f%%", 6, \ + int len = fmt->len - 2; /* 2 for a space and a % sign */ \ + return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, " %*.2f%%", len, \ hpp_color_scnprintf, true); \ } #define __HPP_ENTRY_ACC_PERCENT_FN(_type, _field) \ -static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ +static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - int len = symbol_conf.field_sep ? 1 : 6; \ + int len = symbol_conf.field_sep ? 1 : fmt->len - 2; \ return __hpp__fmt_acc(hpp, he, he_get_##_field, " %*.2f%%", len, \ hpp_entry_scnprintf, true); \ } @@ -307,10 +308,10 @@ static u64 he_get_raw_##_field(struct hist_entry *he) \ return he->stat._field; \ } \ \ -static int hpp__entry_##_type(struct perf_hpp_fmt *_fmt __maybe_unused, \ +static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - int len = symbol_conf.field_sep ? 1 : 11; \ + int len = symbol_conf.field_sep ? 1 : fmt->len - 1; \ return __hpp__fmt(hpp, he, he_get_raw_##_field, " %*"PRIu64, len, \ hpp_entry_scnprintf, false); \ } @@ -322,37 +323,38 @@ static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ } -#define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width) \ -__HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ -__HPP_WIDTH_FN(_type, _min_width, _unit_width) \ +#define HPP_PERCENT_FNS(_type, _str, _field) \ +__HPP_WIDTH_FN(_type, _str) \ +__HPP_HEADER_FN(_type, _str) \ __HPP_COLOR_PERCENT_FN(_type, _field) \ __HPP_ENTRY_PERCENT_FN(_type, _field) \ __HPP_SORT_FN(_type, _field) -#define HPP_PERCENT_ACC_FNS(_type, _str, _field, _min_width, _unit_width)\ -__HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ -__HPP_WIDTH_FN(_type, _min_width, _unit_width) \ +#define HPP_PERCENT_ACC_FNS(_type, _str, _field) \ +__HPP_WIDTH_FN(_type, _str) \ +__HPP_HEADER_FN(_type, _str) \ __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ __HPP_ENTRY_ACC_PERCENT_FN(_type, _field) \ __HPP_SORT_ACC_FN(_type, _field) -#define HPP_RAW_FNS(_type, _str, _field, _min_width, _unit_width) \ -__HPP_HEADER_FN(_type, _str, _min_width, _unit_width) \ -__HPP_WIDTH_FN(_type, _min_width, _unit_width) \ +#define HPP_RAW_FNS(_type, _str, _field) \ +__HPP_WIDTH_FN(_type, _str) \ +__HPP_HEADER_FN(_type, _str) \ __HPP_ENTRY_RAW_FN(_type, _field) \ __HPP_SORT_RAW_FN(_type, _field) -__HPP_HEADER_FN(overhead_self, "Self", 8, 8) +__HPP_WIDTH_FN(overhead_self, "Self") +__HPP_HEADER_FN(overhead_self, "Self") -HPP_PERCENT_FNS(overhead, "Overhead", period, 8, 8) -HPP_PERCENT_FNS(overhead_sys, "sys", period_sys, 8, 8) -HPP_PERCENT_FNS(overhead_us, "usr", period_us, 8, 8) -HPP_PERCENT_FNS(overhead_guest_sys, "guest sys", period_guest_sys, 9, 8) -HPP_PERCENT_FNS(overhead_guest_us, "guest usr", period_guest_us, 9, 8) -HPP_PERCENT_ACC_FNS(overhead_acc, "Children", period, 8, 8) +HPP_PERCENT_FNS(overhead, "Overhead", period) +HPP_PERCENT_FNS(overhead_sys, "sys", period_sys) +HPP_PERCENT_FNS(overhead_us, "usr", period_us) +HPP_PERCENT_FNS(overhead_guest_sys, "guest sys", period_guest_sys) +HPP_PERCENT_FNS(overhead_guest_us, "guest usr", period_guest_us) +HPP_PERCENT_ACC_FNS(overhead_acc, "Children", period) -HPP_RAW_FNS(samples, "Samples", nr_events, 12, 12) -HPP_RAW_FNS(period, "Period", period, 12, 12) +HPP_RAW_FNS(samples, "Samples", nr_events) +HPP_RAW_FNS(period, "Period", period) static int64_t hpp__nop_cmp(struct hist_entry *a __maybe_unused, struct hist_entry *b __maybe_unused) @@ -453,6 +455,8 @@ void perf_hpp__init(void) perf_hpp__format[PERF_HPP__OVERHEAD].header = hpp__header_overhead_self; + perf_hpp__format[PERF_HPP__OVERHEAD].width = + hpp__width_overhead_self; } perf_hpp__column_enable(PERF_HPP__OVERHEAD); @@ -519,6 +523,7 @@ void perf_hpp__cancel_cumulate(void) perf_hpp__column_disable(PERF_HPP__OVERHEAD_ACC); perf_hpp__format[PERF_HPP__OVERHEAD].header = hpp__header_overhead; + perf_hpp__format[PERF_HPP__OVERHEAD].width = hpp__width_overhead; } void perf_hpp__setup_output_field(void) @@ -623,3 +628,41 @@ unsigned int hists__sort_list_width(struct hists *hists) return ret; } + +void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists) +{ + int idx; + + if (perf_hpp__is_sort_entry(fmt)) + return perf_hpp__reset_sort_width(fmt, hists); + + for (idx = 0; idx < PERF_HPP__MAX_INDEX; idx++) { + if (fmt == &perf_hpp__format[idx]) + break; + } + + if (idx == PERF_HPP__MAX_INDEX) + return; + + switch (idx) { + case PERF_HPP__OVERHEAD: + case PERF_HPP__OVERHEAD_SYS: + case PERF_HPP__OVERHEAD_US: + case PERF_HPP__OVERHEAD_ACC: + fmt->len = 8; + break; + + case PERF_HPP__OVERHEAD_GUEST_SYS: + case PERF_HPP__OVERHEAD_GUEST_US: + fmt->len = 9; + break; + + case PERF_HPP__SAMPLES: + case PERF_HPP__PERIOD: + fmt->len = 12; + break; + + default: + break; + } +} diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 13d074db9ef1..a7ae890f4c71 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -207,6 +207,7 @@ struct perf_hpp_fmt { struct list_head list; struct list_head sort_list; bool elide; + int len; }; extern struct list_head perf_hpp__list; @@ -261,6 +262,7 @@ static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format) } void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists); +void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists); typedef u64 (*hpp_field_fn)(struct hist_entry *he); typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index eda9ee836cee..a7f8a7b0eced 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1194,7 +1194,7 @@ bool perf_hpp__same_sort_entry(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b) return hse_a->se == hse_b->se; } -void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists) +void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists) { struct hpp_sort_entry *hse; @@ -1265,6 +1265,7 @@ __sort_dimension__alloc_hpp(struct sort_dimension *sd) INIT_LIST_HEAD(&hse->hpp.list); INIT_LIST_HEAD(&hse->hpp.sort_list); hse->hpp.elide = false; + hse->hpp.len = 0; return hse; } -- GitLab From 5b5916696051b88e63f3726cc3db44bf9561bad9 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 31 Jul 2014 14:47:38 +0900 Subject: [PATCH 0256/9167] perf report: Honor column width setting Set column width and do not change it if user gives -w/--column-widths option. It'll truncate longer symbols than the width if exists. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406785662-5534-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 18 +++++--- tools/perf/ui/gtk/hists.c | 10 ++-- tools/perf/ui/hist.c | 84 +++++++++++++++++++++++----------- tools/perf/ui/stdio/hist.c | 4 +- tools/perf/util/hist.h | 14 +++--- tools/perf/util/sort.c | 49 ++++++++++++-------- 6 files changed, 116 insertions(+), 63 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index c1d8d3925fe1..e07d4e848d5c 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -678,12 +678,12 @@ static u64 __hpp_get_##_field(struct hist_entry *he) \ } \ \ static int \ -hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\ +hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, __hpp_get_##_field, " %*.2f%%", 6, \ - __hpp__slsmg_color_printf, true); \ + return hpp__fmt(fmt, hpp, he, __hpp_get_##_field, " %*.2f%%", \ + __hpp__slsmg_color_printf, true); \ } #define __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ @@ -693,19 +693,20 @@ static u64 __hpp_get_acc_##_field(struct hist_entry *he) \ } \ \ static int \ -hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused,\ +hist_browser__hpp_color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ if (!symbol_conf.cumulate_callchain) { \ + int len = fmt->user_len ?: fmt->len; \ int ret = scnprintf(hpp->buf, hpp->size, \ - "%*s", 8, "N/A"); \ + "%*s", len, "N/A"); \ slsmg_printf("%s", hpp->buf); \ \ return ret; \ } \ - return __hpp__fmt(hpp, he, __hpp_get_acc_##_field, " %*.2f%%", \ - 6, __hpp__slsmg_color_printf, true); \ + return hpp__fmt(fmt, hpp, he, __hpp_get_acc_##_field, \ + " %*.2f%%", __hpp__slsmg_color_printf, true); \ } __HPP_COLOR_PERCENT_FN(overhead, period) @@ -1549,6 +1550,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, memset(options, 0, sizeof(options)); + if (symbol_conf.col_width_list_str) + perf_hpp__set_user_width(symbol_conf.col_width_list_str); + while (1) { const struct thread *thread = NULL; const struct dso *dso = NULL; diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 91f6cd7d2312..897b2e140428 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -41,12 +41,12 @@ static u64 he_get_##_field(struct hist_entry *he) \ return he->stat._field; \ } \ \ -static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ +static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", 6, \ - __percent_color_snprintf, true); \ + return hpp__fmt(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ + __percent_color_snprintf, true); \ } #define __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ @@ -59,8 +59,8 @@ static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, struct perf_hpp *hpp, \ struct hist_entry *he) \ { \ - return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, " %*.2f%%", 6, \ - __percent_color_snprintf, true); \ + return hpp__fmt_acc(fmt, hpp, he, he_get_acc_##_field, " %*.2f%%", \ + __percent_color_snprintf, true); \ } __HPP_COLOR_PERCENT_FN(overhead, period) diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index e28ca972d046..b2d60a95f01d 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -15,9 +15,9 @@ __ret; \ }) -int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, - hpp_field_fn get_field, const char *fmt, int len, - hpp_snprint_fn print_fn, bool fmt_percent) +static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, + hpp_field_fn get_field, const char *fmt, int len, + hpp_snprint_fn print_fn, bool fmt_percent) { int ret; struct hists *hists = he->hists; @@ -104,16 +104,35 @@ int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, return ret; } -int __hpp__fmt_acc(struct perf_hpp *hpp, struct hist_entry *he, - hpp_field_fn get_field, const char *fmt, int len, - hpp_snprint_fn print_fn, bool fmt_percent) +int hpp__fmt(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, + struct hist_entry *he, hpp_field_fn get_field, + const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent) +{ + int len = fmt->user_len ?: fmt->len; + + if (symbol_conf.field_sep) { + return __hpp__fmt(hpp, he, get_field, fmtstr, 1, + print_fn, fmt_percent); + } + + if (fmt_percent) + len -= 2; /* 2 for a space and a % sign */ + else + len -= 1; + + return __hpp__fmt(hpp, he, get_field, fmtstr, len, print_fn, fmt_percent); +} + +int hpp__fmt_acc(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, + struct hist_entry *he, hpp_field_fn get_field, + const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent) { if (!symbol_conf.cumulate_callchain) { - return snprintf(hpp->buf, hpp->size, "%*s", - fmt_percent ? len + 2 : len + 1, "N/A"); + int len = fmt->user_len ?: fmt->len; + return snprintf(hpp->buf, hpp->size, " %*s", len - 1, "N/A"); } - return __hpp__fmt(hpp, he, get_field, fmt, len, print_fn, fmt_percent); + return hpp__fmt(fmt, hpp, he, get_field, fmtstr, print_fn, fmt_percent); } static int field_cmp(u64 field_a, u64 field_b) @@ -195,10 +214,10 @@ static int hpp__width_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp __maybe_unused, \ struct perf_evsel *evsel) \ { \ - int len = fmt->len; \ + int len = fmt->user_len ?: fmt->len; \ \ if (symbol_conf.event_group) \ - len = max(len, evsel->nr_members * len); \ + len = max(len, evsel->nr_members * fmt->len); \ \ if (len < (int)strlen(_str)) \ len = strlen(_str); \ @@ -253,18 +272,16 @@ static u64 he_get_##_field(struct hist_entry *he) \ static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - int len = fmt->len - 2; /* 2 for a space and a % sign */ \ - return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", len, \ - hpp_color_scnprintf, true); \ + return hpp__fmt(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ + hpp_color_scnprintf, true); \ } #define __HPP_ENTRY_PERCENT_FN(_type, _field) \ static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - int len = symbol_conf.field_sep ? 1 : fmt->len - 2; \ - return __hpp__fmt(hpp, he, he_get_##_field, " %*.2f%%", len, \ - hpp_entry_scnprintf, true); \ + return hpp__fmt(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ + hpp_entry_scnprintf, true); \ } #define __HPP_SORT_FN(_type, _field) \ @@ -282,18 +299,16 @@ static u64 he_get_acc_##_field(struct hist_entry *he) \ static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - int len = fmt->len - 2; /* 2 for a space and a % sign */ \ - return __hpp__fmt_acc(hpp, he, he_get_acc_##_field, " %*.2f%%", len, \ - hpp_color_scnprintf, true); \ + return hpp__fmt_acc(fmt, hpp, he, he_get_acc_##_field, " %*.2f%%", \ + hpp_color_scnprintf, true); \ } #define __HPP_ENTRY_ACC_PERCENT_FN(_type, _field) \ static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - int len = symbol_conf.field_sep ? 1 : fmt->len - 2; \ - return __hpp__fmt_acc(hpp, he, he_get_##_field, " %*.2f%%", len, \ - hpp_entry_scnprintf, true); \ + return hpp__fmt_acc(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ + hpp_entry_scnprintf, true); \ } #define __HPP_SORT_ACC_FN(_type, _field) \ @@ -311,9 +326,8 @@ static u64 he_get_raw_##_field(struct hist_entry *he) \ static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - int len = symbol_conf.field_sep ? 1 : fmt->len - 1; \ - return __hpp__fmt(hpp, he, he_get_raw_##_field, " %*"PRIu64, len, \ - hpp_entry_scnprintf, false); \ + return hpp__fmt(fmt, hpp, he, he_get_raw_##_field, " %*"PRIu64, \ + hpp_entry_scnprintf, false); \ } #define __HPP_SORT_RAW_FN(_type, _field) \ @@ -666,3 +680,21 @@ void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists) break; } } + +void perf_hpp__set_user_width(const char *width_list_str) +{ + struct perf_hpp_fmt *fmt; + const char *ptr = width_list_str; + + perf_hpp__for_each_format(fmt) { + char *p; + + int len = strtol(ptr, &p, 10); + fmt->user_len = len; + + if (*p == ',') + ptr = p + 1; + else + break; + } +} diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c index 40af0acb4fe9..15b451acbde6 100644 --- a/tools/perf/ui/stdio/hist.c +++ b/tools/perf/ui/stdio/hist.c @@ -395,10 +395,12 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, init_rem_hits(); - perf_hpp__for_each_format(fmt) perf_hpp__reset_width(fmt, hists); + if (symbol_conf.col_width_list_str) + perf_hpp__set_user_width(symbol_conf.col_width_list_str); + if (!show_header) goto print_entries; diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index a7ae890f4c71..2e70003fcd00 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -208,6 +208,7 @@ struct perf_hpp_fmt { struct list_head sort_list; bool elide; int len; + int user_len; }; extern struct list_head perf_hpp__list; @@ -263,17 +264,18 @@ static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format) void perf_hpp__reset_width(struct perf_hpp_fmt *fmt, struct hists *hists); void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists); +void perf_hpp__set_user_width(const char *width_list_str); typedef u64 (*hpp_field_fn)(struct hist_entry *he); typedef int (*hpp_callback_fn)(struct perf_hpp *hpp, bool front); typedef int (*hpp_snprint_fn)(struct perf_hpp *hpp, const char *fmt, ...); -int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he, - hpp_field_fn get_field, const char *fmt, int len, - hpp_snprint_fn print_fn, bool fmt_percent); -int __hpp__fmt_acc(struct perf_hpp *hpp, struct hist_entry *he, - hpp_field_fn get_field, const char *fmt, int len, - hpp_snprint_fn print_fn, bool fmt_percent); +int hpp__fmt(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, + struct hist_entry *he, hpp_field_fn get_field, + const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent); +int hpp__fmt_acc(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, + struct hist_entry *he, hpp_field_fn get_field, + const char *fmtstr, hpp_snprint_fn print_fn, bool fmt_percent); static inline void advance_hpp(struct perf_hpp *hpp, int inc) { diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index a7f8a7b0eced..153b3803f0b7 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -70,8 +70,10 @@ static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { const char *comm = thread__comm_str(he->thread); - return repsep_snprintf(bf, size, "%5d:%-*s", he->thread->tid, - width - 6, comm ?: ""); + + width = max(7U, width) - 6; + return repsep_snprintf(bf, size, "%5d:%-*.*s", he->thread->tid, + width, width, comm ?: ""); } struct sort_entry sort_thread = { @@ -106,7 +108,7 @@ sort__comm_sort(struct hist_entry *left, struct hist_entry *right) static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { - return repsep_snprintf(bf, size, "%-*s", width, comm__str(he->comm)); + return repsep_snprintf(bf, size, "%-*.*s", width, width, comm__str(he->comm)); } struct sort_entry sort_comm = { @@ -152,10 +154,10 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf, if (map && map->dso) { const char *dso_name = !verbose ? map->dso->short_name : map->dso->long_name; - return repsep_snprintf(bf, size, "%-*s", width, dso_name); + return repsep_snprintf(bf, size, "%-*.*s", width, width, dso_name); } - return repsep_snprintf(bf, size, "%-*s", width, "[unknown]"); + return repsep_snprintf(bf, size, "%-*.*s", width, width, "[unknown]"); } static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf, @@ -257,7 +259,10 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym, width - ret, ""); } - return ret; + if (ret > width) + bf[width] = '\0'; + + return width; } static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, @@ -302,10 +307,9 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right) } static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf, - size_t size, - unsigned int width __maybe_unused) + size_t size, unsigned int width) { - return repsep_snprintf(bf, size, "%-s", he->srcline); + return repsep_snprintf(bf, size, "%*.*-s", width, width, he->srcline); } struct sort_entry sort_srcline = { @@ -332,7 +336,7 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right) static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { - return repsep_snprintf(bf, size, "%-*s", width, + return repsep_snprintf(bf, size, "%-*.*s", width, width, he->parent ? he->parent->name : "[other]"); } @@ -354,7 +358,7 @@ sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right) static int hist_entry__cpu_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width) { - return repsep_snprintf(bf, size, "%*d", width, he->cpu); + return repsep_snprintf(bf, size, "%*.*d", width, width, he->cpu); } struct sort_entry sort_cpu = { @@ -484,7 +488,7 @@ static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf, else if (he->branch_info->flags.mispred) out = "Y"; - return repsep_snprintf(bf, size, "%-*s", width, out); + return repsep_snprintf(bf, size, "%-*.*s", width, width, out); } /* --sort daddr_sym */ @@ -1210,12 +1214,14 @@ static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct perf_evsel *evsel) { struct hpp_sort_entry *hse; - size_t len; + size_t len = fmt->user_len; hse = container_of(fmt, struct hpp_sort_entry, hpp); - len = hists__col_len(&evsel->hists, hse->se->se_width_idx); - return scnprintf(hpp->buf, hpp->size, "%-*s", len, hse->se->se_header); + if (!len) + len = hists__col_len(&evsel->hists, hse->se->se_width_idx); + + return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, hse->se->se_header); } static int __sort__hpp_width(struct perf_hpp_fmt *fmt, @@ -1223,20 +1229,26 @@ static int __sort__hpp_width(struct perf_hpp_fmt *fmt, struct perf_evsel *evsel) { struct hpp_sort_entry *hse; + size_t len = fmt->user_len; hse = container_of(fmt, struct hpp_sort_entry, hpp); - return hists__col_len(&evsel->hists, hse->se->se_width_idx); + if (!len) + len = hists__col_len(&evsel->hists, hse->se->se_width_idx); + + return len; } static int __sort__hpp_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he) { struct hpp_sort_entry *hse; - size_t len; + size_t len = fmt->user_len; hse = container_of(fmt, struct hpp_sort_entry, hpp); - len = hists__col_len(he->hists, hse->se->se_width_idx); + + if (!len) + len = hists__col_len(he->hists, hse->se->se_width_idx); return hse->se->se_snprintf(he, hpp->buf, hpp->size, len); } @@ -1266,6 +1278,7 @@ __sort_dimension__alloc_hpp(struct sort_dimension *sd) INIT_LIST_HEAD(&hse->hpp.sort_list); hse->hpp.elide = false; hse->hpp.len = 0; + hse->hpp.user_len = 0; return hse; } -- GitLab From cf59002fdebc9c00ee29233e65bc39dd69e0eaf6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 31 Jul 2014 14:47:39 +0900 Subject: [PATCH 0257/9167] perf top: Add -w option for setting column width Add -w/--column-widths option like perf report does so that users are able to see symbols even with some very long C++ library/functions. It can be a list separated by comma for each column. $ perf top -w 0,20,30 The value of 0 means there's no limit. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406785662-5534-6-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-report.txt | 2 +- tools/perf/Documentation/perf-top.txt | 6 ++++++ tools/perf/builtin-top.c | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt index d2b59af62bc0..d561e0214f52 100644 --- a/tools/perf/Documentation/perf-report.txt +++ b/tools/perf/Documentation/perf-report.txt @@ -147,7 +147,7 @@ OPTIONS -w:: --column-widths=:: Force each column width to the provided list, for large terminal - readability. + readability. 0 means no limit (default behavior). -t:: --field-separator=:: diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt index 180ae02137a5..28fdee394880 100644 --- a/tools/perf/Documentation/perf-top.txt +++ b/tools/perf/Documentation/perf-top.txt @@ -193,6 +193,12 @@ Default is to monitor all CPUS. sum of shown entries will be always 100%. "absolute" means it retains the original value before and after the filter is applied. +-w:: +--column-widths=:: + Force each column width to the provided list, for large terminal + readability. 0 means no limit (default behavior). + + INTERACTIVE PROMPTING KEYS -------------------------- diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 377971dc89a3..bde216b2071c 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1131,6 +1131,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) "Don't show entries under that percent", parse_percent_limit), OPT_CALLBACK(0, "percentage", NULL, "relative|absolute", "How to display percentage of filtered entries", parse_filter_percentage), + OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str, + "width[,width...]", + "don't try to adjust column width, use these fixed values"), OPT_END() }; const char * const top_usage[] = { -- GitLab From 1ecd44533a8a724f64d4305abb69836ca73c7390 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 31 Jul 2014 14:47:40 +0900 Subject: [PATCH 0258/9167] perf tools: Add name field into perf_hpp_fmt It makes the code a bit simpler and easier to debug IMHO. I guess it can also remove similar code in perf diff, but let's keep it for a future work. :) Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406785662-5534-7-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/gtk/hists.c | 4 +- tools/perf/ui/hist.c | 136 +++++++++++++++++--------------------- tools/perf/util/hist.h | 1 + tools/perf/util/sort.c | 6 +- 4 files changed, 66 insertions(+), 81 deletions(-) diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c index 897b2e140428..f3fa4258b256 100644 --- a/tools/perf/ui/gtk/hists.c +++ b/tools/perf/ui/gtk/hists.c @@ -207,10 +207,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists, if (perf_hpp__is_sort_entry(fmt)) sym_col = col_idx; - fmt->header(fmt, &hpp, hists_to_evsel(hists)); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view), - -1, ltrim(s), + -1, fmt->name, renderer, "markup", col_idx++, NULL); } diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index b2d60a95f01d..b5fa7019d2e2 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -209,29 +209,26 @@ static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b, return ret; } -#define __HPP_WIDTH_FN(_type, _str) \ -static int hpp__width_##_type(struct perf_hpp_fmt *fmt, \ - struct perf_hpp *hpp __maybe_unused, \ - struct perf_evsel *evsel) \ -{ \ - int len = fmt->user_len ?: fmt->len; \ - \ - if (symbol_conf.event_group) \ - len = max(len, evsel->nr_members * fmt->len); \ - \ - if (len < (int)strlen(_str)) \ - len = strlen(_str); \ - \ - return len; \ -} - -#define __HPP_HEADER_FN(_type, _str) \ -static int hpp__header_##_type(struct perf_hpp_fmt *fmt, \ - struct perf_hpp *hpp, \ - struct perf_evsel *evsel) \ -{ \ - int len = hpp__width_##_type(fmt, hpp, evsel); \ - return scnprintf(hpp->buf, hpp->size, "%*s", len, _str); \ +static int hpp__width_fn(struct perf_hpp_fmt *fmt, + struct perf_hpp *hpp __maybe_unused, + struct perf_evsel *evsel) +{ + int len = fmt->user_len ?: fmt->len; + + if (symbol_conf.event_group) + len = max(len, evsel->nr_members * fmt->len); + + if (len < (int)strlen(fmt->name)) + len = strlen(fmt->name); + + return len; +} + +static int hpp__header_fn(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, + struct perf_evsel *evsel) +{ + int len = hpp__width_fn(fmt, hpp, evsel); + return scnprintf(hpp->buf, hpp->size, "%*s", len, fmt->name); } static int hpp_color_scnprintf(struct perf_hpp *hpp, const char *fmt, ...) @@ -337,38 +334,29 @@ static int64_t hpp__sort_##_type(struct hist_entry *a, struct hist_entry *b) \ } -#define HPP_PERCENT_FNS(_type, _str, _field) \ -__HPP_WIDTH_FN(_type, _str) \ -__HPP_HEADER_FN(_type, _str) \ +#define HPP_PERCENT_FNS(_type, _field) \ __HPP_COLOR_PERCENT_FN(_type, _field) \ __HPP_ENTRY_PERCENT_FN(_type, _field) \ __HPP_SORT_FN(_type, _field) -#define HPP_PERCENT_ACC_FNS(_type, _str, _field) \ -__HPP_WIDTH_FN(_type, _str) \ -__HPP_HEADER_FN(_type, _str) \ +#define HPP_PERCENT_ACC_FNS(_type, _field) \ __HPP_COLOR_ACC_PERCENT_FN(_type, _field) \ __HPP_ENTRY_ACC_PERCENT_FN(_type, _field) \ __HPP_SORT_ACC_FN(_type, _field) -#define HPP_RAW_FNS(_type, _str, _field) \ -__HPP_WIDTH_FN(_type, _str) \ -__HPP_HEADER_FN(_type, _str) \ +#define HPP_RAW_FNS(_type, _field) \ __HPP_ENTRY_RAW_FN(_type, _field) \ __HPP_SORT_RAW_FN(_type, _field) -__HPP_WIDTH_FN(overhead_self, "Self") -__HPP_HEADER_FN(overhead_self, "Self") +HPP_PERCENT_FNS(overhead, period) +HPP_PERCENT_FNS(overhead_sys, period_sys) +HPP_PERCENT_FNS(overhead_us, period_us) +HPP_PERCENT_FNS(overhead_guest_sys, period_guest_sys) +HPP_PERCENT_FNS(overhead_guest_us, period_guest_us) +HPP_PERCENT_ACC_FNS(overhead_acc, period) -HPP_PERCENT_FNS(overhead, "Overhead", period) -HPP_PERCENT_FNS(overhead_sys, "sys", period_sys) -HPP_PERCENT_FNS(overhead_us, "usr", period_us) -HPP_PERCENT_FNS(overhead_guest_sys, "guest sys", period_guest_sys) -HPP_PERCENT_FNS(overhead_guest_us, "guest usr", period_guest_us) -HPP_PERCENT_ACC_FNS(overhead_acc, "Children", period) - -HPP_RAW_FNS(samples, "Samples", nr_events) -HPP_RAW_FNS(period, "Period", period) +HPP_RAW_FNS(samples, nr_events) +HPP_RAW_FNS(period, period) static int64_t hpp__nop_cmp(struct hist_entry *a __maybe_unused, struct hist_entry *b __maybe_unused) @@ -376,47 +364,50 @@ static int64_t hpp__nop_cmp(struct hist_entry *a __maybe_unused, return 0; } -#define HPP__COLOR_PRINT_FNS(_name) \ +#define HPP__COLOR_PRINT_FNS(_name, _fn) \ { \ - .header = hpp__header_ ## _name, \ - .width = hpp__width_ ## _name, \ - .color = hpp__color_ ## _name, \ - .entry = hpp__entry_ ## _name, \ + .name = _name, \ + .header = hpp__header_fn, \ + .width = hpp__width_fn, \ + .color = hpp__color_ ## _fn, \ + .entry = hpp__entry_ ## _fn, \ .cmp = hpp__nop_cmp, \ .collapse = hpp__nop_cmp, \ - .sort = hpp__sort_ ## _name, \ + .sort = hpp__sort_ ## _fn, \ } -#define HPP__COLOR_ACC_PRINT_FNS(_name) \ +#define HPP__COLOR_ACC_PRINT_FNS(_name, _fn) \ { \ - .header = hpp__header_ ## _name, \ - .width = hpp__width_ ## _name, \ - .color = hpp__color_ ## _name, \ - .entry = hpp__entry_ ## _name, \ + .name = _name, \ + .header = hpp__header_fn, \ + .width = hpp__width_fn, \ + .color = hpp__color_ ## _fn, \ + .entry = hpp__entry_ ## _fn, \ .cmp = hpp__nop_cmp, \ .collapse = hpp__nop_cmp, \ - .sort = hpp__sort_ ## _name, \ + .sort = hpp__sort_ ## _fn, \ } -#define HPP__PRINT_FNS(_name) \ +#define HPP__PRINT_FNS(_name, _fn) \ { \ - .header = hpp__header_ ## _name, \ - .width = hpp__width_ ## _name, \ - .entry = hpp__entry_ ## _name, \ + .name = _name, \ + .header = hpp__header_fn, \ + .width = hpp__width_fn, \ + .entry = hpp__entry_ ## _fn, \ .cmp = hpp__nop_cmp, \ .collapse = hpp__nop_cmp, \ - .sort = hpp__sort_ ## _name, \ + .sort = hpp__sort_ ## _fn, \ } struct perf_hpp_fmt perf_hpp__format[] = { - HPP__COLOR_PRINT_FNS(overhead), - HPP__COLOR_PRINT_FNS(overhead_sys), - HPP__COLOR_PRINT_FNS(overhead_us), - HPP__COLOR_PRINT_FNS(overhead_guest_sys), - HPP__COLOR_PRINT_FNS(overhead_guest_us), - HPP__COLOR_ACC_PRINT_FNS(overhead_acc), - HPP__PRINT_FNS(samples), - HPP__PRINT_FNS(period) + HPP__COLOR_PRINT_FNS("Overhead", overhead), + HPP__COLOR_PRINT_FNS("sys", overhead_sys), + HPP__COLOR_PRINT_FNS("usr", overhead_us), + HPP__COLOR_PRINT_FNS("guest sys", overhead_guest_sys), + HPP__COLOR_PRINT_FNS("guest usr", overhead_guest_us), + HPP__COLOR_ACC_PRINT_FNS("Children", overhead_acc), + HPP__PRINT_FNS("Samples", samples), + HPP__PRINT_FNS("Period", period) }; LIST_HEAD(perf_hpp__list); @@ -466,11 +457,7 @@ void perf_hpp__init(void) if (symbol_conf.cumulate_callchain) { perf_hpp__column_enable(PERF_HPP__OVERHEAD_ACC); - - perf_hpp__format[PERF_HPP__OVERHEAD].header = - hpp__header_overhead_self; - perf_hpp__format[PERF_HPP__OVERHEAD].width = - hpp__width_overhead_self; + perf_hpp__format[PERF_HPP__OVERHEAD].name = "Self"; } perf_hpp__column_enable(PERF_HPP__OVERHEAD); @@ -536,8 +523,7 @@ void perf_hpp__cancel_cumulate(void) return; perf_hpp__column_disable(PERF_HPP__OVERHEAD_ACC); - perf_hpp__format[PERF_HPP__OVERHEAD].header = hpp__header_overhead; - perf_hpp__format[PERF_HPP__OVERHEAD].width = hpp__width_overhead; + perf_hpp__format[PERF_HPP__OVERHEAD].name = "Overhead"; } void perf_hpp__setup_output_field(void) diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 2e70003fcd00..95405a8fbd95 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -192,6 +192,7 @@ struct perf_hpp { }; struct perf_hpp_fmt { + const char *name; int (*header)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct perf_evsel *evsel); int (*width)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 153b3803f0b7..b4a805e5e440 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1206,8 +1206,7 @@ void perf_hpp__reset_sort_width(struct perf_hpp_fmt *fmt, struct hists *hists) return; hse = container_of(fmt, struct hpp_sort_entry, hpp); - hists__new_col_len(hists, hse->se->se_width_idx, - strlen(hse->se->se_header)); + hists__new_col_len(hists, hse->se->se_width_idx, strlen(fmt->name)); } static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, @@ -1221,7 +1220,7 @@ static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, if (!len) len = hists__col_len(&evsel->hists, hse->se->se_width_idx); - return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, hse->se->se_header); + return scnprintf(hpp->buf, hpp->size, "%-*.*s", len, len, fmt->name); } static int __sort__hpp_width(struct perf_hpp_fmt *fmt, @@ -1265,6 +1264,7 @@ __sort_dimension__alloc_hpp(struct sort_dimension *sd) } hse->se = sd->entry; + hse->hpp.name = sd->entry->se_header; hse->hpp.header = __sort__hpp_header; hse->hpp.width = __sort__hpp_width; hse->hpp.entry = __sort__hpp_entry; -- GitLab From 59dc9f2534569d11a55c8b5dbe93c36f2b2fa506 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 31 Jul 2014 14:47:41 +0900 Subject: [PATCH 0259/9167] perf tools: Fix column alignment when headers aren't shown on TUI If user sets ui.show-headers config option to false, it didn't calculate default column width so it broke the alignment. This is because it does the calculation just before showing headers. Move it to the beginning of the hist browser so that it can be called regardless of the config option. Reported-by: Jiri Olsa Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406785662-5534-8-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index e07d4e848d5c..045c1e16ac59 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -850,9 +850,6 @@ static int hists__scnprintf_headers(char *buf, size_t size, struct hists *hists) if (perf_hpp__should_skip(fmt)) continue; - /* We need to ensure length of the columns header. */ - perf_hpp__reset_width(fmt, hists); - ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists)); if (advance_hpp_check(&dummy_hpp, ret)) break; @@ -1501,6 +1498,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, char buf[64]; char script_opt[64]; int delay_secs = hbt ? hbt->refresh : 0; + struct perf_hpp_fmt *fmt; #define HIST_BROWSER_HELP_COMMON \ "h/?/F1 Show this window\n" \ @@ -1550,6 +1548,9 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, memset(options, 0, sizeof(options)); + perf_hpp__for_each_format(fmt) + perf_hpp__reset_width(fmt, hists); + if (symbol_conf.col_width_list_str) perf_hpp__set_user_width(symbol_conf.col_width_list_str); -- GitLab From 038fa0b9739d7f375f3f61a2ce4f78ad44329f66 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Sun, 3 Aug 2014 14:10:36 +0200 Subject: [PATCH 0260/9167] perf tools: Fix PERF_FLAG_FD_CLOEXEC flag probing event type open counters due to EBUSY error We were using PERF_COUNT_SW_CPU_CLOCK as an probing event type. Using expected PERF_TYPE_SOFTWARE type instead. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Cc: William Cohen Cc: Yann Droneaud Link: http://lkml.kernel.org/r/20140803121036.GA1181@krava.brq.redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cloexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index dede0c388ed4..5073c01af618 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -9,7 +9,7 @@ static int perf_flag_probe(void) { /* use 'safest' configuration as used in perf_evsel__fallback() */ struct perf_event_attr attr = { - .type = PERF_COUNT_SW_CPU_CLOCK, + .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_CLOCK, }; int fd; -- GitLab From d6a947fb6cdff3a19db93895c746f70b5903a965 Mon Sep 17 00:00:00 2001 From: Thomas Ilsche Date: Mon, 4 Aug 2014 15:03:15 +0200 Subject: [PATCH 0261/9167] perf tools: Default to python version 2 According to PEP 394 recommendation [1], it's more portable to use python2 rather than plain python to refer python binary version 2. Since there're distros using python3 by default like Arch, and we don't support python3 (yet), it'd be better using python2 explicitly. But older versions (prior to 2.7) seem not to provide python2 but just python. Given that it's only old version, try python2 first and then fallback to python. It'll ensure that it always points to python 2.x. I tested (compiles and perf script runs) with the combinations: 1) python -> python2.x, python-config -> python2.x-config python2 N/A, python2-config N/A 2) python -> python3.x, python-config -> python3.x-config python2 -> python2.x, python2-config -> python2.x-config 3) python -> python2.x, python-config -> python2.x-config python2 -> python2.x, python2-config -> python2.x-config 4) python -> python2.x, python-config -> python2.x-config python2 -> python2.x, python2-config N/A Based on / replaces the patch 2/2 by Namhyung Kim. [1] https://www.python.org/dev/peps/pep-0394 Based-on-patch-by: Namhyung Kim Signed-off-by: Thomas Ilsche Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/53DF8493.6070206@tu-dresden.de Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/config/Makefile | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index e05d8f99424d..75d4c237b03d 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile @@ -121,10 +121,16 @@ ifdef PARSER_DEBUG endif ifndef NO_LIBPYTHON - override PYTHON := \ - $(call get-executable-or-default,PYTHON,python) + # Try different combinations to accommodate systems that only have + # python[2][-config] in weird combinations but always preferring + # python2 and python2-config as per pep-0394. If we catch a + # python[-config] in version 3, the version check will kill it. + PYTHON2 := $(if $(call get-executable,python2),python2,python) + override PYTHON := $(call get-executable-or-default,PYTHON,$(PYTHON2)) + PYTHON2_CONFIG := \ + $(if $(call get-executable,$(PYTHON)-config),$(PYTHON)-config,python-config) override PYTHON_CONFIG := \ - $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config) + $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON2_CONFIG)) PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) -- GitLab From 3220574143147db7c9f9b00c8dc6efcbacad44cc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 12 Aug 2014 09:41:10 +0800 Subject: [PATCH 0262/9167] regulator: tps65023: Remove duplicate test for I2C_FUNC_SMBUS_BYTE_DATA functionality Since commit b42261078a91 ("regmap: i2c: fallback to SMBus if the adapter does not support standard I2C"), regmap-i2c will check the I2C_FUNC_SMBUS_[BYTE|WORD]_DATA functionality based on the regmap_config setting if the adapter does not support standard I2C. So remove the I2C_FUNC_SMBUS_BYTE_DATA functionality check in the driver code. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65023-regulator.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index 3ef67a86115c..7380af8bd50d 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c @@ -211,9 +211,6 @@ static int tps_65023_probe(struct i2c_client *client, int i; int error; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) - return -EIO; - /** * init_data points to array of regulator_init structures * coming from the board-evm file. -- GitLab From 0f7c29ce90c4d20c23de5657e1e2c2eabf51d69a Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 30 Jul 2014 12:08:56 +0200 Subject: [PATCH 0263/9167] perf/x86/intel: Update Intel models The model number descriptions got a bit messy, clean them up. Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Linus Torvalds Link: http://lkml.kernel.org/n/tip-oo3xclxdoy8s7ubssn929vaj@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel.c | 51 +++++++++++++------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 2502d0d9d246..38d1f6d024ff 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -2367,15 +2367,15 @@ __init int intel_pmu_init(void) * Install the hw-cache-events table: */ switch (boot_cpu_data.x86_model) { - case 14: /* 65 nm core solo/duo, "Yonah" */ + case 14: /* 65nm Core "Yonah" */ pr_cont("Core events, "); break; - case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */ + case 15: /* 65nm Core2 "Merom" */ x86_add_quirk(intel_clovertown_quirk); - case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */ - case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */ - case 29: /* six-core 45 nm xeon "Dunnington" */ + case 22: /* 65nm Core2 "Merom-L" */ + case 23: /* 45nm Core2 "Penryn" */ + case 29: /* 45nm Core2 "Dunnington (MP) */ memcpy(hw_cache_event_ids, core2_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -2386,9 +2386,9 @@ __init int intel_pmu_init(void) pr_cont("Core2 events, "); break; - case 26: /* 45 nm nehalem, "Bloomfield" */ - case 30: /* 45 nm nehalem, "Lynnfield" */ - case 46: /* 45 nm nehalem-ex, "Beckton" */ + case 30: /* 45nm Nehalem */ + case 26: /* 45nm Nehalem-EP */ + case 46: /* 45nm Nehalem-EX */ memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids, sizeof(hw_cache_event_ids)); memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs, @@ -2415,11 +2415,11 @@ __init int intel_pmu_init(void) pr_cont("Nehalem events, "); break; - case 28: /* Atom */ - case 38: /* Lincroft */ - case 39: /* Penwell */ - case 53: /* Cloverview */ - case 54: /* Cedarview */ + case 28: /* 45nm Atom "Pineview" */ + case 38: /* 45nm Atom "Lincroft" */ + case 39: /* 32nm Atom "Penwell" */ + case 53: /* 32nm Atom "Cloverview" */ + case 54: /* 32nm Atom "Cedarview" */ memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -2430,8 +2430,8 @@ __init int intel_pmu_init(void) pr_cont("Atom events, "); break; - case 55: /* Atom 22nm "Silvermont" */ - case 77: /* Avoton "Silvermont" */ + case 55: /* 22nm Atom "Silvermont" */ + case 77: /* 22nm Atom "Silvermont Avoton/Rangely" */ memcpy(hw_cache_event_ids, slm_hw_cache_event_ids, sizeof(hw_cache_event_ids)); memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs, @@ -2446,9 +2446,9 @@ __init int intel_pmu_init(void) pr_cont("Silvermont events, "); break; - case 37: /* 32 nm nehalem, "Clarkdale" */ - case 44: /* 32 nm nehalem, "Gulftown" */ - case 47: /* 32 nm Xeon E7 */ + case 37: /* 32nm Westmere */ + case 44: /* 32nm Westmere-EP */ + case 47: /* 32nm Westmere-EX */ memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids, sizeof(hw_cache_event_ids)); memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs, @@ -2474,8 +2474,8 @@ __init int intel_pmu_init(void) pr_cont("Westmere events, "); break; - case 42: /* SandyBridge */ - case 45: /* SandyBridge, "Romely-EP" */ + case 42: /* 32nm SandyBridge */ + case 45: /* 32nm SandyBridge-E/EN/EP */ x86_add_quirk(intel_sandybridge_quirk); memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); @@ -2506,8 +2506,9 @@ __init int intel_pmu_init(void) pr_cont("SandyBridge events, "); break; - case 58: /* IvyBridge */ - case 62: /* IvyBridge EP */ + + case 58: /* 22nm IvyBridge */ + case 62: /* 22nm IvyBridge-EP/EX */ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); /* dTLB-load-misses on IVB is different than SNB */ @@ -2539,11 +2540,11 @@ __init int intel_pmu_init(void) break; - case 60: /* Haswell Client */ - case 70: - case 71: + case 60: /* 22nm Haswell */ case 63: case 69: + case 70: + case 71: x86_pmu.late_ack = true; memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs, sizeof(hw_cache_extra_regs)); -- GitLab From f86977620ee4635f26befcf436700493a38ce002 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 1 Aug 2014 14:33:01 +0200 Subject: [PATCH 0264/9167] perf: Set owner pointer for kernel events Adding fake EVENT_OWNER_KERNEL owner pointer value for kernel perf events, so we could distinguish it from user events, which needs special care in following patch. Signed-off-by: Jiri Olsa Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Mark Rutland Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Mark Rutland Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1406896382-18404-3-git-send-email-jolsa@kernel.org Signed-off-by: Ingo Molnar --- kernel/events/core.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 1cf24b3e42ec..bbb3ca22f07c 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -119,6 +119,13 @@ static int cpu_function_call(int cpu, int (*func) (void *info), void *info) return data.ret; } +#define EVENT_OWNER_KERNEL ((void *) -1) + +static bool is_kernel_event(struct perf_event *event) +{ + return event->owner == EVENT_OWNER_KERNEL; +} + #define PERF_FLAG_ALL (PERF_FLAG_FD_NO_GROUP |\ PERF_FLAG_FD_OUTPUT |\ PERF_FLAG_PID_CGROUP |\ @@ -3312,16 +3319,12 @@ static void free_event(struct perf_event *event) } /* - * Called when the last reference to the file is gone. + * Remove user event from the owner task. */ -static void put_event(struct perf_event *event) +static void perf_remove_from_owner(struct perf_event *event) { - struct perf_event_context *ctx = event->ctx; struct task_struct *owner; - if (!atomic_long_dec_and_test(&event->refcount)) - return; - rcu_read_lock(); owner = ACCESS_ONCE(event->owner); /* @@ -3354,6 +3357,20 @@ static void put_event(struct perf_event *event) mutex_unlock(&owner->perf_event_mutex); put_task_struct(owner); } +} + +/* + * Called when the last reference to the file is gone. + */ +static void put_event(struct perf_event *event) +{ + struct perf_event_context *ctx = event->ctx; + + if (!atomic_long_dec_and_test(&event->refcount)) + return; + + if (!is_kernel_event(event)) + perf_remove_from_owner(event); WARN_ON_ONCE(ctx->parent_ctx); /* @@ -7366,6 +7383,9 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, goto err; } + /* Mark owner so we could distinguish it from user events. */ + event->owner = EVENT_OWNER_KERNEL; + account_event(event); ctx = find_get_context(event->pmu, task, cpu); -- GitLab From fadfe7be6e50de7f03913833b33c56cd8fb66bac Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Fri, 1 Aug 2014 14:33:02 +0200 Subject: [PATCH 0265/9167] perf: Add queued work to remove orphaned child events In cases when the owner task exits before the workload and the workload made some forks, all the events stay in until the last workload process exits. Thats' because each child event holds parent reference. We want to release all children events once the parent is gone, because at that time there's no process to read them anyway, so they're just eating resources. This removal races with process exit, which removes all events and fork, which clone events. To be clear of those two, adding work queue to remove orphaned child for context in case such event is detected. Using delayed work queue (with delay == 1), because we queue this work under perf scheduler callbacks. Normal work queue tries to wake up the queue process, which deadlocks on rq->lock in this place. Also preventing clones from abandoned parent event. Signed-off-by: Jiri Olsa Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Mark Rutland Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Corey Ashford Cc: Frederic Weisbecker Cc: Mark Rutland Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1406896382-18404-4-git-send-email-jolsa@kernel.org Signed-off-by: Ingo Molnar --- include/linux/perf_event.h | 4 ++ kernel/events/core.c | 87 +++++++++++++++++++++++++++++++++++++- 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 707617a8c0f6..ef5b62bdb103 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -52,6 +52,7 @@ struct perf_guest_info_callbacks { #include #include #include +#include #include struct perf_callchain_entry { @@ -507,6 +508,9 @@ struct perf_event_context { int nr_cgroups; /* cgroup evts */ int nr_branch_stack; /* branch_stack evt */ struct rcu_head rcu_head; + + struct delayed_work orphans_remove; + bool orphans_remove_sched; }; /* diff --git a/kernel/events/core.c b/kernel/events/core.c index bbb3ca22f07c..a25460559b4f 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -46,6 +46,8 @@ #include +static struct workqueue_struct *perf_wq; + struct remote_function_call { struct task_struct *p; int (*func)(void *info); @@ -1381,6 +1383,45 @@ static void perf_group_detach(struct perf_event *event) perf_event__header_size(tmp); } +/* + * User event without the task. + */ +static bool is_orphaned_event(struct perf_event *event) +{ + return event && !is_kernel_event(event) && !event->owner; +} + +/* + * Event has a parent but parent's task finished and it's + * alive only because of children holding refference. + */ +static bool is_orphaned_child(struct perf_event *event) +{ + return is_orphaned_event(event->parent); +} + +static void orphans_remove_work(struct work_struct *work); + +static void schedule_orphans_remove(struct perf_event_context *ctx) +{ + if (!ctx->task || ctx->orphans_remove_sched || !perf_wq) + return; + + if (queue_delayed_work(perf_wq, &ctx->orphans_remove, 1)) { + get_ctx(ctx); + ctx->orphans_remove_sched = true; + } +} + +static int __init perf_workqueue_init(void) +{ + perf_wq = create_singlethread_workqueue("perf"); + WARN(!perf_wq, "failed to create perf workqueue\n"); + return perf_wq ? 0 : -1; +} + +core_initcall(perf_workqueue_init); + static inline int event_filter_match(struct perf_event *event) { @@ -1430,6 +1471,9 @@ event_sched_out(struct perf_event *event, if (event->attr.exclusive || !cpuctx->active_oncpu) cpuctx->exclusive = 0; + if (is_orphaned_child(event)) + schedule_orphans_remove(ctx); + perf_pmu_enable(event->pmu); } @@ -1732,6 +1776,9 @@ event_sched_in(struct perf_event *event, if (event->attr.exclusive) cpuctx->exclusive = 1; + if (is_orphaned_child(event)) + schedule_orphans_remove(ctx); + out: perf_pmu_enable(event->pmu); @@ -3074,6 +3121,7 @@ static void __perf_event_init_context(struct perf_event_context *ctx) INIT_LIST_HEAD(&ctx->flexible_groups); INIT_LIST_HEAD(&ctx->event_list); atomic_set(&ctx->refcount, 1); + INIT_DELAYED_WORK(&ctx->orphans_remove, orphans_remove_work); } static struct perf_event_context * @@ -3405,6 +3453,42 @@ static int perf_release(struct inode *inode, struct file *file) return 0; } +/* + * Remove all orphanes events from the context. + */ +static void orphans_remove_work(struct work_struct *work) +{ + struct perf_event_context *ctx; + struct perf_event *event, *tmp; + + ctx = container_of(work, struct perf_event_context, + orphans_remove.work); + + mutex_lock(&ctx->mutex); + list_for_each_entry_safe(event, tmp, &ctx->event_list, event_entry) { + struct perf_event *parent_event = event->parent; + + if (!is_orphaned_child(event)) + continue; + + perf_remove_from_context(event, true); + + mutex_lock(&parent_event->child_mutex); + list_del_init(&event->child_list); + mutex_unlock(&parent_event->child_mutex); + + free_event(event); + put_event(parent_event); + } + + raw_spin_lock_irq(&ctx->lock); + ctx->orphans_remove_sched = false; + raw_spin_unlock_irq(&ctx->lock); + mutex_unlock(&ctx->mutex); + + put_ctx(ctx); +} + u64 perf_event_read_value(struct perf_event *event, u64 *enabled, u64 *running) { struct perf_event *child; @@ -7709,7 +7793,8 @@ inherit_event(struct perf_event *parent_event, if (IS_ERR(child_event)) return child_event; - if (!atomic_long_inc_not_zero(&parent_event->refcount)) { + if (is_orphaned_event(parent_event) || + !atomic_long_inc_not_zero(&parent_event->refcount)) { free_event(child_event); return NULL; } -- GitLab From 514b2346df385fce61cefb940813207758648136 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 30 Jul 2014 15:22:12 +0800 Subject: [PATCH 0266/9167] perf/x86/uncore: Declare some functions and variables Prepare for moving hardware specific code to seperate files. Signed-off-by: Yan, Zheng Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Linus Torvalds Cc: Stephane Eranian Cc: eranian@google.com Cc: andi@firstfloor.org Link: http://lkml.kernel.org/r/1406704935-27708-1-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 149 +++++++++--------- arch/x86/kernel/cpu/perf_event_intel_uncore.h | 32 ++-- 2 files changed, 98 insertions(+), 83 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index cfc6f9dfcd90..cfe235334b3c 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -1,24 +1,33 @@ #include "perf_event_intel_uncore.h" static struct intel_uncore_type *empty_uncore[] = { NULL, }; -static struct intel_uncore_type **msr_uncores = empty_uncore; -static struct intel_uncore_type **pci_uncores = empty_uncore; -/* pci bus to socket mapping */ -static int pcibus_to_physid[256] = { [0 ... 255] = -1, }; +struct intel_uncore_type **uncore_msr_uncores = empty_uncore; +struct intel_uncore_type **uncore_pci_uncores = empty_uncore; -static struct pci_dev *extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX]; +static bool pcidrv_registered; +struct pci_driver *uncore_pci_driver; +/* pci bus to socket mapping */ +int uncore_pcibus_to_physid[256] = { [0 ... 255] = -1, }; +struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX]; static DEFINE_RAW_SPINLOCK(uncore_box_lock); - /* mask of cpus that collect uncore events */ static cpumask_t uncore_cpu_mask; /* constraint for the fixed counter */ -static struct event_constraint constraint_fixed = +static struct event_constraint uncore_constraint_fixed = EVENT_CONSTRAINT(~0ULL, 1 << UNCORE_PMC_IDX_FIXED, ~0ULL); -static struct event_constraint constraint_empty = +struct event_constraint uncore_constraint_empty = EVENT_CONSTRAINT(0, 0, 0); +ssize_t uncore_event_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct uncore_event_desc *event = + container_of(attr, struct uncore_event_desc, attr); + return sprintf(buf, "%s", event->config); +} + #define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ ((1ULL << (n)) - 1))) @@ -66,18 +75,12 @@ DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4"); DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31"); DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63"); -static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box); -static void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box); -static void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event); -static void uncore_pmu_event_read(struct perf_event *event); - -static struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) +struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) { return container_of(event->pmu, struct intel_uncore_pmu, pmu); } -static struct intel_uncore_box * -uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) +struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) { struct intel_uncore_box *box; @@ -98,7 +101,7 @@ uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu) return *per_cpu_ptr(pmu->box, cpu); } -static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) +struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) { /* * perf core schedules event on the basis of cpu, uncore events are @@ -107,7 +110,7 @@ static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event) return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id()); } -static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) +u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event) { u64 count; @@ -119,7 +122,7 @@ static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_eve /* * generic get constraint function for shared match/mask registers. */ -static struct event_constraint * +struct event_constraint * uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event) { struct intel_uncore_extra_reg *er; @@ -154,10 +157,10 @@ uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event) return NULL; } - return &constraint_empty; + return &uncore_constraint_empty; } -static void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event) +void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event) { struct intel_uncore_extra_reg *er; struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; @@ -178,7 +181,7 @@ static void uncore_put_constraint(struct intel_uncore_box *box, struct perf_even reg1->alloc = 0; } -static u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx) +u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx) { struct intel_uncore_extra_reg *er; unsigned long flags; @@ -627,7 +630,7 @@ __snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *eve if (alloc & (0x1 << i)) atomic_sub(1 << (i * 6), &er->ref); } - return &constraint_empty; + return &uncore_constraint_empty; } static u64 snbep_cbox_filter_mask(int fields) @@ -746,7 +749,7 @@ snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event) config1 = snbep_pcu_alter_er(event, idx, false); goto again; } - return &constraint_empty; + return &uncore_constraint_empty; } if (!uncore_box_is_fake(box)) { @@ -841,7 +844,7 @@ static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_eve if (reg1->idx != EXTRA_REG_NONE) { int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER; - struct pci_dev *filter_pdev = extra_pci_dev[box->phys_id][idx]; + struct pci_dev *filter_pdev = uncore_extra_pci_dev[box->phys_id][idx]; WARN_ON_ONCE(!filter_pdev); if (filter_pdev) { pci_write_config_dword(filter_pdev, reg1->reg, @@ -1035,7 +1038,7 @@ static int snbep_pci2phy_map_init(int devid) */ for (i = 0; i < 8; i++) { if (nodeid == ((config >> (3 * i)) & 0x7)) { - pcibus_to_physid[bus] = i; + uncore_pcibus_to_physid[bus] = i; break; } } @@ -1048,10 +1051,10 @@ static int snbep_pci2phy_map_init(int devid) */ i = -1; for (bus = 255; bus >= 0; bus--) { - if (pcibus_to_physid[bus] >= 0) - i = pcibus_to_physid[bus]; + if (uncore_pcibus_to_physid[bus] >= 0) + i = uncore_pcibus_to_physid[bus]; else - pcibus_to_physid[bus] = i; + uncore_pcibus_to_physid[bus] = i; } } @@ -1939,7 +1942,7 @@ static int snb_pci2phy_map_init(int devid) bus = dev->bus->number; - pcibus_to_physid[bus] = 0; + uncore_pcibus_to_physid[bus] = 0; pci_dev_put(dev); @@ -2639,7 +2642,7 @@ nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event nhmex_mbox_put_shared_reg(box, idx[0]); if (alloc & 0x2) nhmex_mbox_put_shared_reg(box, idx[1]); - return &constraint_empty; + return &uncore_constraint_empty; } static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) @@ -2963,7 +2966,7 @@ nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event } return NULL; } - return &constraint_empty; + return &uncore_constraint_empty; } static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) @@ -3140,7 +3143,7 @@ static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_eve hwc->event_base = uncore_perf_ctr(box, hwc->idx); } -static void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event) +void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event) { u64 prev_count, new_count, delta; int shift; @@ -3201,14 +3204,14 @@ static enum hrtimer_restart uncore_pmu_hrtimer(struct hrtimer *hrtimer) return HRTIMER_RESTART; } -static void uncore_pmu_start_hrtimer(struct intel_uncore_box *box) +void uncore_pmu_start_hrtimer(struct intel_uncore_box *box) { __hrtimer_start_range_ns(&box->hrtimer, ns_to_ktime(box->hrtimer_duration), 0, HRTIMER_MODE_REL_PINNED, 0); } -static void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box) +void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box) { hrtimer_cancel(&box->hrtimer); } @@ -3291,7 +3294,7 @@ uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *eve } if (event->attr.config == UNCORE_FIXED_EVENT) - return &constraint_fixed; + return &uncore_constraint_fixed; if (type->constraints) { for_each_event_constraint(c, type->constraints) { @@ -3496,7 +3499,7 @@ static void uncore_pmu_event_del(struct perf_event *event, int flags) event->hw.last_tag = ~0ULL; } -static void uncore_pmu_event_read(struct perf_event *event) +void uncore_pmu_event_read(struct perf_event *event) { struct intel_uncore_box *box = uncore_event_to_box(event); uncore_perf_event_update(box, event); @@ -3758,9 +3761,6 @@ static int __init uncore_types_init(struct intel_uncore_type **types) return ret; } -static struct pci_driver *uncore_pci_driver; -static bool pcidrv_registered; - /* * add a pci uncore device */ @@ -3771,17 +3771,18 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id struct intel_uncore_type *type; int phys_id; - phys_id = pcibus_to_physid[pdev->bus->number]; + phys_id = uncore_pcibus_to_physid[pdev->bus->number]; if (phys_id < 0) return -ENODEV; if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) { - extra_pci_dev[phys_id][UNCORE_PCI_DEV_IDX(id->driver_data)] = pdev; + int idx = UNCORE_PCI_DEV_IDX(id->driver_data); + uncore_extra_pci_dev[phys_id][idx] = pdev; pci_set_drvdata(pdev, NULL); return 0; } - type = pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)]; + type = uncore_pci_uncores[UNCORE_PCI_DEV_TYPE(id->driver_data)]; box = uncore_alloc_box(type, NUMA_NO_NODE); if (!box) return -ENOMEM; @@ -3813,13 +3814,13 @@ static void uncore_pci_remove(struct pci_dev *pdev) { struct intel_uncore_box *box = pci_get_drvdata(pdev); struct intel_uncore_pmu *pmu; - int i, cpu, phys_id = pcibus_to_physid[pdev->bus->number]; + int i, cpu, phys_id = uncore_pcibus_to_physid[pdev->bus->number]; box = pci_get_drvdata(pdev); if (!box) { for (i = 0; i < UNCORE_EXTRA_PCI_DEV_MAX; i++) { - if (extra_pci_dev[phys_id][i] == pdev) { - extra_pci_dev[phys_id][i] = NULL; + if (uncore_extra_pci_dev[phys_id][i] == pdev) { + uncore_extra_pci_dev[phys_id][i] = NULL; break; } } @@ -3857,28 +3858,28 @@ static int __init uncore_pci_init(void) ret = snbep_pci2phy_map_init(0x3ce0); if (ret) return ret; - pci_uncores = snbep_pci_uncores; + uncore_pci_uncores = snbep_pci_uncores; uncore_pci_driver = &snbep_uncore_pci_driver; break; case 62: /* IvyTown */ ret = snbep_pci2phy_map_init(0x0e1e); if (ret) return ret; - pci_uncores = ivt_pci_uncores; + uncore_pci_uncores = ivt_pci_uncores; uncore_pci_driver = &ivt_uncore_pci_driver; break; case 42: /* Sandy Bridge */ ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_SNB_IMC); if (ret) return ret; - pci_uncores = snb_pci_uncores; + uncore_pci_uncores = snb_pci_uncores; uncore_pci_driver = &snb_uncore_pci_driver; break; case 58: /* Ivy Bridge */ ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_IVB_IMC); if (ret) return ret; - pci_uncores = snb_pci_uncores; + uncore_pci_uncores = snb_pci_uncores; uncore_pci_driver = &ivb_uncore_pci_driver; break; case 60: /* Haswell */ @@ -3886,14 +3887,14 @@ static int __init uncore_pci_init(void) ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_HSW_IMC); if (ret) return ret; - pci_uncores = snb_pci_uncores; + uncore_pci_uncores = snb_pci_uncores; uncore_pci_driver = &hsw_uncore_pci_driver; break; default: return 0; } - ret = uncore_types_init(pci_uncores); + ret = uncore_types_init(uncore_pci_uncores); if (ret) return ret; @@ -3904,7 +3905,7 @@ static int __init uncore_pci_init(void) if (ret == 0) pcidrv_registered = true; else - uncore_types_exit(pci_uncores); + uncore_types_exit(uncore_pci_uncores); return ret; } @@ -3914,7 +3915,7 @@ static void __init uncore_pci_exit(void) if (pcidrv_registered) { pcidrv_registered = false; pci_unregister_driver(uncore_pci_driver); - uncore_types_exit(pci_uncores); + uncore_types_exit(uncore_pci_uncores); } } @@ -3940,8 +3941,8 @@ static void uncore_cpu_dying(int cpu) struct intel_uncore_box *box; int i, j; - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; + for (i = 0; uncore_msr_uncores[i]; i++) { + type = uncore_msr_uncores[i]; for (j = 0; j < type->num_boxes; j++) { pmu = &type->pmus[j]; box = *per_cpu_ptr(pmu->box, cpu); @@ -3961,8 +3962,8 @@ static int uncore_cpu_starting(int cpu) phys_id = topology_physical_package_id(cpu); - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; + for (i = 0; uncore_msr_uncores[i]; i++) { + type = uncore_msr_uncores[i]; for (j = 0; j < type->num_boxes; j++) { pmu = &type->pmus[j]; box = *per_cpu_ptr(pmu->box, cpu); @@ -4002,8 +4003,8 @@ static int uncore_cpu_prepare(int cpu, int phys_id) struct intel_uncore_box *box; int i, j; - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; + for (i = 0; uncore_msr_uncores[i]; i++) { + type = uncore_msr_uncores[i]; for (j = 0; j < type->num_boxes; j++) { pmu = &type->pmus[j]; if (pmu->func_id < 0) @@ -4083,8 +4084,8 @@ static void uncore_event_exit_cpu(int cpu) if (target >= 0) cpumask_set_cpu(target, &uncore_cpu_mask); - uncore_change_context(msr_uncores, cpu, target); - uncore_change_context(pci_uncores, cpu, target); + uncore_change_context(uncore_msr_uncores, cpu, target); + uncore_change_context(uncore_pci_uncores, cpu, target); } static void uncore_event_init_cpu(int cpu) @@ -4099,8 +4100,8 @@ static void uncore_event_init_cpu(int cpu) cpumask_set_cpu(cpu, &uncore_cpu_mask); - uncore_change_context(msr_uncores, -1, cpu); - uncore_change_context(pci_uncores, -1, cpu); + uncore_change_context(uncore_msr_uncores, -1, cpu); + uncore_change_context(uncore_pci_uncores, -1, cpu); } static int uncore_cpu_notifier(struct notifier_block *self, @@ -4168,18 +4169,18 @@ static int __init uncore_cpu_init(void) case 30: case 37: /* Westmere */ case 44: - msr_uncores = nhm_msr_uncores; + uncore_msr_uncores = nhm_msr_uncores; break; case 42: /* Sandy Bridge */ case 58: /* Ivy Bridge */ if (snb_uncore_cbox.num_boxes > max_cores) snb_uncore_cbox.num_boxes = max_cores; - msr_uncores = snb_msr_uncores; + uncore_msr_uncores = snb_msr_uncores; break; case 45: /* Sandy Bridge-EP */ if (snbep_uncore_cbox.num_boxes > max_cores) snbep_uncore_cbox.num_boxes = max_cores; - msr_uncores = snbep_msr_uncores; + uncore_msr_uncores = snbep_msr_uncores; break; case 46: /* Nehalem-EX */ uncore_nhmex = true; @@ -4188,19 +4189,19 @@ static int __init uncore_cpu_init(void) nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events; if (nhmex_uncore_cbox.num_boxes > max_cores) nhmex_uncore_cbox.num_boxes = max_cores; - msr_uncores = nhmex_msr_uncores; + uncore_msr_uncores = nhmex_msr_uncores; break; case 62: /* IvyTown */ if (ivt_uncore_cbox.num_boxes > max_cores) ivt_uncore_cbox.num_boxes = max_cores; - msr_uncores = ivt_msr_uncores; + uncore_msr_uncores = ivt_msr_uncores; break; default: return 0; } - ret = uncore_types_init(msr_uncores); + ret = uncore_types_init(uncore_msr_uncores); if (ret) return ret; @@ -4213,16 +4214,16 @@ static int __init uncore_pmus_register(void) struct intel_uncore_type *type; int i, j; - for (i = 0; msr_uncores[i]; i++) { - type = msr_uncores[i]; + for (i = 0; uncore_msr_uncores[i]; i++) { + type = uncore_msr_uncores[i]; for (j = 0; j < type->num_boxes; j++) { pmu = &type->pmus[j]; uncore_pmu_register(pmu); } } - for (i = 0; pci_uncores[i]; i++) { - type = pci_uncores[i]; + for (i = 0; uncore_pci_uncores[i]; i++) { + type = uncore_pci_uncores[i]; for (j = 0; j < type->num_boxes; j++) { pmu = &type->pmus[j]; uncore_pmu_register(pmu); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 90236f0c94a9..e5b5fd7554af 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -505,6 +505,9 @@ struct uncore_event_desc { const char *config; }; +ssize_t uncore_event_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf); + #define INTEL_UNCORE_EVENT_DESC(_name, _config) \ { \ .attr = __ATTR(_name, 0444, uncore_event_show, NULL), \ @@ -522,15 +525,6 @@ static ssize_t __uncore_##_var##_show(struct kobject *kobj, \ static struct kobj_attribute format_attr_##_var = \ __ATTR(_name, 0444, __uncore_##_var##_show, NULL) - -static ssize_t uncore_event_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct uncore_event_desc *event = - container_of(attr, struct uncore_event_desc, attr); - return sprintf(buf, "%s", event->config); -} - static inline unsigned uncore_pci_box_ctl(struct intel_uncore_box *box) { return box->pmu->type->box_ctl; @@ -694,3 +688,23 @@ static inline bool uncore_box_is_fake(struct intel_uncore_box *box) { return (box->phys_id < 0); } + +struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event); +struct intel_uncore_box *uncore_pmu_to_box(struct intel_uncore_pmu *pmu, int cpu); +struct intel_uncore_box *uncore_event_to_box(struct perf_event *event); +u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event); +void uncore_pmu_start_hrtimer(struct intel_uncore_box *box); +void uncore_pmu_cancel_hrtimer(struct intel_uncore_box *box); +void uncore_pmu_event_read(struct perf_event *event); +void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event); +struct event_constraint * +uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event); +void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event); +u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx); + +extern struct intel_uncore_type **uncore_msr_uncores; +extern struct intel_uncore_type **uncore_pci_uncores; +extern struct pci_driver *uncore_pci_driver; +extern int uncore_pcibus_to_physid[256]; +extern struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX]; +extern struct event_constraint uncore_constraint_empty; -- GitLab From 92807ffdf32c380a09cfa396c853e97303826103 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 30 Jul 2014 15:22:13 +0800 Subject: [PATCH 0267/9167] perf/x86/uncore: Move NHM/SNB/IVB specific code to seperate file Signed-off-by: Yan, Zheng Signed-off-by: Peter Zijlstra Cc: Andi Kleen Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Stephane Eranian Cc: eranian@google.com Link: http://lkml.kernel.org/r/1406704935-27708-2-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/Makefile | 3 +- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 531 +-------------- arch/x86/kernel/cpu/perf_event_intel_uncore.h | 56 +- .../kernel/cpu/perf_event_intel_uncore_snb.c | 603 ++++++++++++++++++ 4 files changed, 620 insertions(+), 573 deletions(-) create mode 100644 arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 7fd54f09b011..5ca8f4a39106 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -36,7 +36,8 @@ obj-$(CONFIG_CPU_SUP_AMD) += perf_event_amd_iommu.o endif obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o perf_event_intel_rapl.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o perf_event_intel_uncore_snb.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o endif diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index cfe235334b3c..feb085c8ca4e 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -37,8 +37,6 @@ DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); -DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28"); -DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31"); DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); @@ -1605,508 +1603,6 @@ static struct pci_driver ivt_uncore_pci_driver = { }; /* end of IvyTown uncore support */ -/* Sandy Bridge uncore support */ -static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - if (hwc->idx < UNCORE_PMC_IDX_FIXED) - wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); - else - wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); -} - -static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - wrmsrl(event->hw.config_base, 0); -} - -static void snb_uncore_msr_init_box(struct intel_uncore_box *box) -{ - if (box->pmu->pmu_idx == 0) { - wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, - SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL); - } -} - -static struct uncore_event_desc snb_uncore_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), - { /* end: all zeroes */ }, -}; - -static struct attribute *snb_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_cmask5.attr, - NULL, -}; - -static struct attribute_group snb_uncore_format_group = { - .name = "format", - .attrs = snb_uncore_formats_attr, -}; - -static struct intel_uncore_ops snb_uncore_msr_ops = { - .init_box = snb_uncore_msr_init_box, - .disable_event = snb_uncore_msr_disable_event, - .enable_event = snb_uncore_msr_enable_event, - .read_counter = uncore_msr_read_counter, -}; - -static struct event_constraint snb_uncore_cbox_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x80, 0x1), - UNCORE_EVENT_CONSTRAINT(0x83, 0x1), - EVENT_CONSTRAINT_END -}; - -static struct intel_uncore_type snb_uncore_cbox = { - .name = "cbox", - .num_counters = 2, - .num_boxes = 4, - .perf_ctr_bits = 44, - .fixed_ctr_bits = 48, - .perf_ctr = SNB_UNC_CBO_0_PER_CTR0, - .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0, - .fixed_ctr = SNB_UNC_FIXED_CTR, - .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL, - .single_fixed = 1, - .event_mask = SNB_UNC_RAW_EVENT_MASK, - .msr_offset = SNB_UNC_CBO_MSR_OFFSET, - .constraints = snb_uncore_cbox_constraints, - .ops = &snb_uncore_msr_ops, - .format_group = &snb_uncore_format_group, - .event_descs = snb_uncore_events, -}; - -static struct intel_uncore_type *snb_msr_uncores[] = { - &snb_uncore_cbox, - NULL, -}; - -enum { - SNB_PCI_UNCORE_IMC, -}; - -static struct uncore_event_desc snb_uncore_imc_events[] = { - INTEL_UNCORE_EVENT_DESC(data_reads, "event=0x01"), - INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"), - INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"), - - INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"), - INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"), - INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"), - - { /* end: all zeroes */ }, -}; - -#define SNB_UNCORE_PCI_IMC_EVENT_MASK 0xff -#define SNB_UNCORE_PCI_IMC_BAR_OFFSET 0x48 - -/* page size multiple covering all config regs */ -#define SNB_UNCORE_PCI_IMC_MAP_SIZE 0x6000 - -#define SNB_UNCORE_PCI_IMC_DATA_READS 0x1 -#define SNB_UNCORE_PCI_IMC_DATA_READS_BASE 0x5050 -#define SNB_UNCORE_PCI_IMC_DATA_WRITES 0x2 -#define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE 0x5054 -#define SNB_UNCORE_PCI_IMC_CTR_BASE SNB_UNCORE_PCI_IMC_DATA_READS_BASE - -static struct attribute *snb_uncore_imc_formats_attr[] = { - &format_attr_event.attr, - NULL, -}; - -static struct attribute_group snb_uncore_imc_format_group = { - .name = "format", - .attrs = snb_uncore_imc_formats_attr, -}; - -static void snb_uncore_imc_init_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET; - resource_size_t addr; - u32 pci_dword; - - pci_read_config_dword(pdev, where, &pci_dword); - addr = pci_dword; - -#ifdef CONFIG_PHYS_ADDR_T_64BIT - pci_read_config_dword(pdev, where + 4, &pci_dword); - addr |= ((resource_size_t)pci_dword << 32); -#endif - - addr &= ~(PAGE_SIZE - 1); - - box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE); - box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL; -} - -static void snb_uncore_imc_enable_box(struct intel_uncore_box *box) -{} - -static void snb_uncore_imc_disable_box(struct intel_uncore_box *box) -{} - -static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{} - -static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event) -{} - -static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - return (u64)*(unsigned int *)(box->io_addr + hwc->event_base); -} - -/* - * custom event_init() function because we define our own fixed, free - * running counters, so we do not want to conflict with generic uncore - * logic. Also simplifies processing - */ -static int snb_uncore_imc_event_init(struct perf_event *event) -{ - struct intel_uncore_pmu *pmu; - struct intel_uncore_box *box; - struct hw_perf_event *hwc = &event->hw; - u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK; - int idx, base; - - if (event->attr.type != event->pmu->type) - return -ENOENT; - - pmu = uncore_event_to_pmu(event); - /* no device found for this pmu */ - if (pmu->func_id < 0) - return -ENOENT; - - /* Sampling not supported yet */ - if (hwc->sample_period) - return -EINVAL; - - /* unsupported modes and filters */ - if (event->attr.exclude_user || - event->attr.exclude_kernel || - event->attr.exclude_hv || - event->attr.exclude_idle || - event->attr.exclude_host || - event->attr.exclude_guest || - event->attr.sample_period) /* no sampling */ - return -EINVAL; - - /* - * Place all uncore events for a particular physical package - * onto a single cpu - */ - if (event->cpu < 0) - return -EINVAL; - - /* check only supported bits are set */ - if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK) - return -EINVAL; - - box = uncore_pmu_to_box(pmu, event->cpu); - if (!box || box->cpu < 0) - return -EINVAL; - - event->cpu = box->cpu; - - event->hw.idx = -1; - event->hw.last_tag = ~0ULL; - event->hw.extra_reg.idx = EXTRA_REG_NONE; - event->hw.branch_reg.idx = EXTRA_REG_NONE; - /* - * check event is known (whitelist, determines counter) - */ - switch (cfg) { - case SNB_UNCORE_PCI_IMC_DATA_READS: - base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE; - idx = UNCORE_PMC_IDX_FIXED; - break; - case SNB_UNCORE_PCI_IMC_DATA_WRITES: - base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE; - idx = UNCORE_PMC_IDX_FIXED + 1; - break; - default: - return -EINVAL; - } - - /* must be done before validate_group */ - event->hw.event_base = base; - event->hw.config = cfg; - event->hw.idx = idx; - - /* no group validation needed, we have free running counters */ - - return 0; -} - -static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - return 0; -} - -static void snb_uncore_imc_event_start(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - u64 count; - - if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) - return; - - event->hw.state = 0; - box->n_active++; - - list_add_tail(&event->active_entry, &box->active_list); - - count = snb_uncore_imc_read_counter(box, event); - local64_set(&event->hw.prev_count, count); - - if (box->n_active == 1) - uncore_pmu_start_hrtimer(box); -} - -static void snb_uncore_imc_event_stop(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - struct hw_perf_event *hwc = &event->hw; - - if (!(hwc->state & PERF_HES_STOPPED)) { - box->n_active--; - - WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); - hwc->state |= PERF_HES_STOPPED; - - list_del(&event->active_entry); - - if (box->n_active == 0) - uncore_pmu_cancel_hrtimer(box); - } - - if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { - /* - * Drain the remaining delta count out of a event - * that we are disabling: - */ - uncore_perf_event_update(box, event); - hwc->state |= PERF_HES_UPTODATE; - } -} - -static int snb_uncore_imc_event_add(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - struct hw_perf_event *hwc = &event->hw; - - if (!box) - return -ENODEV; - - hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; - if (!(flags & PERF_EF_START)) - hwc->state |= PERF_HES_ARCH; - - snb_uncore_imc_event_start(event, 0); - - box->n_events++; - - return 0; -} - -static void snb_uncore_imc_event_del(struct perf_event *event, int flags) -{ - struct intel_uncore_box *box = uncore_event_to_box(event); - int i; - - snb_uncore_imc_event_stop(event, PERF_EF_UPDATE); - - for (i = 0; i < box->n_events; i++) { - if (event == box->event_list[i]) { - --box->n_events; - break; - } - } -} - -static int snb_pci2phy_map_init(int devid) -{ - struct pci_dev *dev = NULL; - int bus; - - dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev); - if (!dev) - return -ENOTTY; - - bus = dev->bus->number; - - uncore_pcibus_to_physid[bus] = 0; - - pci_dev_put(dev); - - return 0; -} - -static struct pmu snb_uncore_imc_pmu = { - .task_ctx_nr = perf_invalid_context, - .event_init = snb_uncore_imc_event_init, - .add = snb_uncore_imc_event_add, - .del = snb_uncore_imc_event_del, - .start = snb_uncore_imc_event_start, - .stop = snb_uncore_imc_event_stop, - .read = uncore_pmu_event_read, -}; - -static struct intel_uncore_ops snb_uncore_imc_ops = { - .init_box = snb_uncore_imc_init_box, - .enable_box = snb_uncore_imc_enable_box, - .disable_box = snb_uncore_imc_disable_box, - .disable_event = snb_uncore_imc_disable_event, - .enable_event = snb_uncore_imc_enable_event, - .hw_config = snb_uncore_imc_hw_config, - .read_counter = snb_uncore_imc_read_counter, -}; - -static struct intel_uncore_type snb_uncore_imc = { - .name = "imc", - .num_counters = 2, - .num_boxes = 1, - .fixed_ctr_bits = 32, - .fixed_ctr = SNB_UNCORE_PCI_IMC_CTR_BASE, - .event_descs = snb_uncore_imc_events, - .format_group = &snb_uncore_imc_format_group, - .perf_ctr = SNB_UNCORE_PCI_IMC_DATA_READS_BASE, - .event_mask = SNB_UNCORE_PCI_IMC_EVENT_MASK, - .ops = &snb_uncore_imc_ops, - .pmu = &snb_uncore_imc_pmu, -}; - -static struct intel_uncore_type *snb_pci_uncores[] = { - [SNB_PCI_UNCORE_IMC] = &snb_uncore_imc, - NULL, -}; - -static DEFINE_PCI_DEVICE_TABLE(snb_uncore_pci_ids) = { - { /* IMC */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SNB_IMC), - .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), - }, - { /* end: all zeroes */ }, -}; - -static DEFINE_PCI_DEVICE_TABLE(ivb_uncore_pci_ids) = { - { /* IMC */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC), - .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), - }, - { /* end: all zeroes */ }, -}; - -static DEFINE_PCI_DEVICE_TABLE(hsw_uncore_pci_ids) = { - { /* IMC */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC), - .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), - }, - { /* end: all zeroes */ }, -}; - -static struct pci_driver snb_uncore_pci_driver = { - .name = "snb_uncore", - .id_table = snb_uncore_pci_ids, -}; - -static struct pci_driver ivb_uncore_pci_driver = { - .name = "ivb_uncore", - .id_table = ivb_uncore_pci_ids, -}; - -static struct pci_driver hsw_uncore_pci_driver = { - .name = "hsw_uncore", - .id_table = hsw_uncore_pci_ids, -}; - -/* end of Sandy Bridge uncore support */ - -/* Nehalem uncore support */ -static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box) -{ - wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0); -} - -static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) -{ - wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); -} - -static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - if (hwc->idx < UNCORE_PMC_IDX_FIXED) - wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); - else - wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN); -} - -static struct attribute *nhm_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_cmask8.attr, - NULL, -}; - -static struct attribute_group nhm_uncore_format_group = { - .name = "format", - .attrs = nhm_uncore_formats_attr, -}; - -static struct uncore_event_desc nhm_uncore_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), - INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"), - INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"), - INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"), - INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"), - INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"), - INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"), - INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"), - INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"), - { /* end: all zeroes */ }, -}; - -static struct intel_uncore_ops nhm_uncore_msr_ops = { - .disable_box = nhm_uncore_msr_disable_box, - .enable_box = nhm_uncore_msr_enable_box, - .disable_event = snb_uncore_msr_disable_event, - .enable_event = nhm_uncore_msr_enable_event, - .read_counter = uncore_msr_read_counter, -}; - -static struct intel_uncore_type nhm_uncore = { - .name = "", - .num_counters = 8, - .num_boxes = 1, - .perf_ctr_bits = 48, - .fixed_ctr_bits = 48, - .event_ctl = NHM_UNC_PERFEVTSEL0, - .perf_ctr = NHM_UNC_UNCORE_PMC0, - .fixed_ctr = NHM_UNC_FIXED_CTR, - .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL, - .event_mask = NHM_UNC_RAW_EVENT_MASK, - .event_descs = nhm_uncore_events, - .ops = &nhm_uncore_msr_ops, - .format_group = &nhm_uncore_format_group, -}; - -static struct intel_uncore_type *nhm_msr_uncores[] = { - &nhm_uncore, - NULL, -}; -/* end of Nehalem uncore support */ - /* Nehalem-EX uncore support */ DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); @@ -3869,31 +3365,22 @@ static int __init uncore_pci_init(void) uncore_pci_driver = &ivt_uncore_pci_driver; break; case 42: /* Sandy Bridge */ - ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_SNB_IMC); - if (ret) - return ret; - uncore_pci_uncores = snb_pci_uncores; - uncore_pci_driver = &snb_uncore_pci_driver; + ret = snb_uncore_pci_init(); break; case 58: /* Ivy Bridge */ - ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_IVB_IMC); - if (ret) - return ret; - uncore_pci_uncores = snb_pci_uncores; - uncore_pci_driver = &ivb_uncore_pci_driver; + ret = ivb_uncore_pci_init(); break; case 60: /* Haswell */ case 69: /* Haswell Celeron */ - ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_HSW_IMC); - if (ret) - return ret; - uncore_pci_uncores = snb_pci_uncores; - uncore_pci_driver = &hsw_uncore_pci_driver; + ret = hsw_uncore_pci_init(); break; default: return 0; } + if (ret) + return ret; + ret = uncore_types_init(uncore_pci_uncores); if (ret) return ret; @@ -4169,13 +3656,11 @@ static int __init uncore_cpu_init(void) case 30: case 37: /* Westmere */ case 44: - uncore_msr_uncores = nhm_msr_uncores; + nhm_uncore_cpu_init(); break; case 42: /* Sandy Bridge */ case 58: /* Ivy Bridge */ - if (snb_uncore_cbox.num_boxes > max_cores) - snb_uncore_cbox.num_boxes = max_cores; - uncore_msr_uncores = snb_msr_uncores; + snb_uncore_cpu_init(); break; case 45: /* Sandy Bridge-EP */ if (snbep_uncore_cbox.num_boxes > max_cores) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index e5b5fd7554af..86699caaacd8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -24,55 +24,6 @@ #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) -/* SNB event control */ -#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff -#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 -#define SNB_UNC_CTL_EDGE_DET (1 << 18) -#define SNB_UNC_CTL_EN (1 << 22) -#define SNB_UNC_CTL_INVERT (1 << 23) -#define SNB_UNC_CTL_CMASK_MASK 0x1f000000 -#define NHM_UNC_CTL_CMASK_MASK 0xff000000 -#define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0) - -#define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ - SNB_UNC_CTL_UMASK_MASK | \ - SNB_UNC_CTL_EDGE_DET | \ - SNB_UNC_CTL_INVERT | \ - SNB_UNC_CTL_CMASK_MASK) - -#define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ - SNB_UNC_CTL_UMASK_MASK | \ - SNB_UNC_CTL_EDGE_DET | \ - SNB_UNC_CTL_INVERT | \ - NHM_UNC_CTL_CMASK_MASK) - -/* SNB global control register */ -#define SNB_UNC_PERF_GLOBAL_CTL 0x391 -#define SNB_UNC_FIXED_CTR_CTRL 0x394 -#define SNB_UNC_FIXED_CTR 0x395 - -/* SNB uncore global control */ -#define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1) -#define SNB_UNC_GLOBAL_CTL_EN (1 << 29) - -/* SNB Cbo register */ -#define SNB_UNC_CBO_0_PERFEVTSEL0 0x700 -#define SNB_UNC_CBO_0_PER_CTR0 0x706 -#define SNB_UNC_CBO_MSR_OFFSET 0x10 - -/* NHM global control register */ -#define NHM_UNC_PERF_GLOBAL_CTL 0x391 -#define NHM_UNC_FIXED_CTR 0x394 -#define NHM_UNC_FIXED_CTR_CTRL 0x395 - -/* NHM uncore global control */ -#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1) -#define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32) - -/* NHM uncore register */ -#define NHM_UNC_PERFEVTSEL0 0x3c0 -#define NHM_UNC_UNCORE_PMC0 0x3b0 - /* SNB-EP Box level control */ #define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) #define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) @@ -708,3 +659,10 @@ extern struct pci_driver *uncore_pci_driver; extern int uncore_pcibus_to_physid[256]; extern struct pci_dev *uncore_extra_pci_dev[UNCORE_SOCKET_MAX][UNCORE_EXTRA_PCI_DEV_MAX]; extern struct event_constraint uncore_constraint_empty; + +/* perf_event_intel_uncore_snb.c */ +int snb_uncore_pci_init(void); +int ivb_uncore_pci_init(void); +int hsw_uncore_pci_init(void); +void snb_uncore_cpu_init(void); +void nhm_uncore_cpu_init(void); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c new file mode 100644 index 000000000000..6e7811f3ea73 --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c @@ -0,0 +1,603 @@ +/* Nehalem/SandBridge/Haswell uncore support */ +#include "perf_event_intel_uncore.h" + +/* SNB event control */ +#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff +#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00 +#define SNB_UNC_CTL_EDGE_DET (1 << 18) +#define SNB_UNC_CTL_EN (1 << 22) +#define SNB_UNC_CTL_INVERT (1 << 23) +#define SNB_UNC_CTL_CMASK_MASK 0x1f000000 +#define NHM_UNC_CTL_CMASK_MASK 0xff000000 +#define NHM_UNC_FIXED_CTR_CTL_EN (1 << 0) + +#define SNB_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ + SNB_UNC_CTL_UMASK_MASK | \ + SNB_UNC_CTL_EDGE_DET | \ + SNB_UNC_CTL_INVERT | \ + SNB_UNC_CTL_CMASK_MASK) + +#define NHM_UNC_RAW_EVENT_MASK (SNB_UNC_CTL_EV_SEL_MASK | \ + SNB_UNC_CTL_UMASK_MASK | \ + SNB_UNC_CTL_EDGE_DET | \ + SNB_UNC_CTL_INVERT | \ + NHM_UNC_CTL_CMASK_MASK) + +/* SNB global control register */ +#define SNB_UNC_PERF_GLOBAL_CTL 0x391 +#define SNB_UNC_FIXED_CTR_CTRL 0x394 +#define SNB_UNC_FIXED_CTR 0x395 + +/* SNB uncore global control */ +#define SNB_UNC_GLOBAL_CTL_CORE_ALL ((1 << 4) - 1) +#define SNB_UNC_GLOBAL_CTL_EN (1 << 29) + +/* SNB Cbo register */ +#define SNB_UNC_CBO_0_PERFEVTSEL0 0x700 +#define SNB_UNC_CBO_0_PER_CTR0 0x706 +#define SNB_UNC_CBO_MSR_OFFSET 0x10 + +/* NHM global control register */ +#define NHM_UNC_PERF_GLOBAL_CTL 0x391 +#define NHM_UNC_FIXED_CTR 0x394 +#define NHM_UNC_FIXED_CTR_CTRL 0x395 + +/* NHM uncore global control */ +#define NHM_UNC_GLOBAL_CTL_EN_PC_ALL ((1ULL << 8) - 1) +#define NHM_UNC_GLOBAL_CTL_EN_FC (1ULL << 32) + +/* NHM uncore register */ +#define NHM_UNC_PERFEVTSEL0 0x3c0 +#define NHM_UNC_UNCORE_PMC0 0x3b0 + +DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); +DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); +DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); +DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); +DEFINE_UNCORE_FORMAT_ATTR(cmask5, cmask, "config:24-28"); +DEFINE_UNCORE_FORMAT_ATTR(cmask8, cmask, "config:24-31"); + +/* Sandy Bridge uncore support */ +static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + if (hwc->idx < UNCORE_PMC_IDX_FIXED) + wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); + else + wrmsrl(hwc->config_base, SNB_UNC_CTL_EN); +} + +static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + wrmsrl(event->hw.config_base, 0); +} + +static void snb_uncore_msr_init_box(struct intel_uncore_box *box) +{ + if (box->pmu->pmu_idx == 0) { + wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, + SNB_UNC_GLOBAL_CTL_EN | SNB_UNC_GLOBAL_CTL_CORE_ALL); + } +} + +static struct uncore_event_desc snb_uncore_events[] = { + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), + { /* end: all zeroes */ }, +}; + +static struct attribute *snb_uncore_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_cmask5.attr, + NULL, +}; + +static struct attribute_group snb_uncore_format_group = { + .name = "format", + .attrs = snb_uncore_formats_attr, +}; + +static struct intel_uncore_ops snb_uncore_msr_ops = { + .init_box = snb_uncore_msr_init_box, + .disable_event = snb_uncore_msr_disable_event, + .enable_event = snb_uncore_msr_enable_event, + .read_counter = uncore_msr_read_counter, +}; + +static struct event_constraint snb_uncore_cbox_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x80, 0x1), + UNCORE_EVENT_CONSTRAINT(0x83, 0x1), + EVENT_CONSTRAINT_END +}; + +static struct intel_uncore_type snb_uncore_cbox = { + .name = "cbox", + .num_counters = 2, + .num_boxes = 4, + .perf_ctr_bits = 44, + .fixed_ctr_bits = 48, + .perf_ctr = SNB_UNC_CBO_0_PER_CTR0, + .event_ctl = SNB_UNC_CBO_0_PERFEVTSEL0, + .fixed_ctr = SNB_UNC_FIXED_CTR, + .fixed_ctl = SNB_UNC_FIXED_CTR_CTRL, + .single_fixed = 1, + .event_mask = SNB_UNC_RAW_EVENT_MASK, + .msr_offset = SNB_UNC_CBO_MSR_OFFSET, + .constraints = snb_uncore_cbox_constraints, + .ops = &snb_uncore_msr_ops, + .format_group = &snb_uncore_format_group, + .event_descs = snb_uncore_events, +}; + +static struct intel_uncore_type *snb_msr_uncores[] = { + &snb_uncore_cbox, + NULL, +}; + +void snb_uncore_cpu_init(void) +{ + uncore_msr_uncores = snb_msr_uncores; + if (snb_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) + snb_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; +} + +enum { + SNB_PCI_UNCORE_IMC, +}; + +static struct uncore_event_desc snb_uncore_imc_events[] = { + INTEL_UNCORE_EVENT_DESC(data_reads, "event=0x01"), + INTEL_UNCORE_EVENT_DESC(data_reads.scale, "6.103515625e-5"), + INTEL_UNCORE_EVENT_DESC(data_reads.unit, "MiB"), + + INTEL_UNCORE_EVENT_DESC(data_writes, "event=0x02"), + INTEL_UNCORE_EVENT_DESC(data_writes.scale, "6.103515625e-5"), + INTEL_UNCORE_EVENT_DESC(data_writes.unit, "MiB"), + + { /* end: all zeroes */ }, +}; + +#define SNB_UNCORE_PCI_IMC_EVENT_MASK 0xff +#define SNB_UNCORE_PCI_IMC_BAR_OFFSET 0x48 + +/* page size multiple covering all config regs */ +#define SNB_UNCORE_PCI_IMC_MAP_SIZE 0x6000 + +#define SNB_UNCORE_PCI_IMC_DATA_READS 0x1 +#define SNB_UNCORE_PCI_IMC_DATA_READS_BASE 0x5050 +#define SNB_UNCORE_PCI_IMC_DATA_WRITES 0x2 +#define SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE 0x5054 +#define SNB_UNCORE_PCI_IMC_CTR_BASE SNB_UNCORE_PCI_IMC_DATA_READS_BASE + +static struct attribute *snb_uncore_imc_formats_attr[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group snb_uncore_imc_format_group = { + .name = "format", + .attrs = snb_uncore_imc_formats_attr, +}; + +static void snb_uncore_imc_init_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + int where = SNB_UNCORE_PCI_IMC_BAR_OFFSET; + resource_size_t addr; + u32 pci_dword; + + pci_read_config_dword(pdev, where, &pci_dword); + addr = pci_dword; + +#ifdef CONFIG_PHYS_ADDR_T_64BIT + pci_read_config_dword(pdev, where + 4, &pci_dword); + addr |= ((resource_size_t)pci_dword << 32); +#endif + + addr &= ~(PAGE_SIZE - 1); + + box->io_addr = ioremap(addr, SNB_UNCORE_PCI_IMC_MAP_SIZE); + box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL; +} + +static void snb_uncore_imc_enable_box(struct intel_uncore_box *box) +{} + +static void snb_uncore_imc_disable_box(struct intel_uncore_box *box) +{} + +static void snb_uncore_imc_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{} + +static void snb_uncore_imc_disable_event(struct intel_uncore_box *box, struct perf_event *event) +{} + +static u64 snb_uncore_imc_read_counter(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + return (u64)*(unsigned int *)(box->io_addr + hwc->event_base); +} + +/* + * custom event_init() function because we define our own fixed, free + * running counters, so we do not want to conflict with generic uncore + * logic. Also simplifies processing + */ +static int snb_uncore_imc_event_init(struct perf_event *event) +{ + struct intel_uncore_pmu *pmu; + struct intel_uncore_box *box; + struct hw_perf_event *hwc = &event->hw; + u64 cfg = event->attr.config & SNB_UNCORE_PCI_IMC_EVENT_MASK; + int idx, base; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + pmu = uncore_event_to_pmu(event); + /* no device found for this pmu */ + if (pmu->func_id < 0) + return -ENOENT; + + /* Sampling not supported yet */ + if (hwc->sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest || + event->attr.sample_period) /* no sampling */ + return -EINVAL; + + /* + * Place all uncore events for a particular physical package + * onto a single cpu + */ + if (event->cpu < 0) + return -EINVAL; + + /* check only supported bits are set */ + if (event->attr.config & ~SNB_UNCORE_PCI_IMC_EVENT_MASK) + return -EINVAL; + + box = uncore_pmu_to_box(pmu, event->cpu); + if (!box || box->cpu < 0) + return -EINVAL; + + event->cpu = box->cpu; + + event->hw.idx = -1; + event->hw.last_tag = ~0ULL; + event->hw.extra_reg.idx = EXTRA_REG_NONE; + event->hw.branch_reg.idx = EXTRA_REG_NONE; + /* + * check event is known (whitelist, determines counter) + */ + switch (cfg) { + case SNB_UNCORE_PCI_IMC_DATA_READS: + base = SNB_UNCORE_PCI_IMC_DATA_READS_BASE; + idx = UNCORE_PMC_IDX_FIXED; + break; + case SNB_UNCORE_PCI_IMC_DATA_WRITES: + base = SNB_UNCORE_PCI_IMC_DATA_WRITES_BASE; + idx = UNCORE_PMC_IDX_FIXED + 1; + break; + default: + return -EINVAL; + } + + /* must be done before validate_group */ + event->hw.event_base = base; + event->hw.config = cfg; + event->hw.idx = idx; + + /* no group validation needed, we have free running counters */ + + return 0; +} + +static int snb_uncore_imc_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + return 0; +} + +static void snb_uncore_imc_event_start(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + u64 count; + + if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) + return; + + event->hw.state = 0; + box->n_active++; + + list_add_tail(&event->active_entry, &box->active_list); + + count = snb_uncore_imc_read_counter(box, event); + local64_set(&event->hw.prev_count, count); + + if (box->n_active == 1) + uncore_pmu_start_hrtimer(box); +} + +static void snb_uncore_imc_event_stop(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + struct hw_perf_event *hwc = &event->hw; + + if (!(hwc->state & PERF_HES_STOPPED)) { + box->n_active--; + + WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); + hwc->state |= PERF_HES_STOPPED; + + list_del(&event->active_entry); + + if (box->n_active == 0) + uncore_pmu_cancel_hrtimer(box); + } + + if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { + /* + * Drain the remaining delta count out of a event + * that we are disabling: + */ + uncore_perf_event_update(box, event); + hwc->state |= PERF_HES_UPTODATE; + } +} + +static int snb_uncore_imc_event_add(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + struct hw_perf_event *hwc = &event->hw; + + if (!box) + return -ENODEV; + + hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; + if (!(flags & PERF_EF_START)) + hwc->state |= PERF_HES_ARCH; + + snb_uncore_imc_event_start(event, 0); + + box->n_events++; + + return 0; +} + +static void snb_uncore_imc_event_del(struct perf_event *event, int flags) +{ + struct intel_uncore_box *box = uncore_event_to_box(event); + int i; + + snb_uncore_imc_event_stop(event, PERF_EF_UPDATE); + + for (i = 0; i < box->n_events; i++) { + if (event == box->event_list[i]) { + --box->n_events; + break; + } + } +} + +static int snb_pci2phy_map_init(int devid) +{ + struct pci_dev *dev = NULL; + int bus; + + dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, dev); + if (!dev) + return -ENOTTY; + + bus = dev->bus->number; + + uncore_pcibus_to_physid[bus] = 0; + + pci_dev_put(dev); + + return 0; +} + +static struct pmu snb_uncore_imc_pmu = { + .task_ctx_nr = perf_invalid_context, + .event_init = snb_uncore_imc_event_init, + .add = snb_uncore_imc_event_add, + .del = snb_uncore_imc_event_del, + .start = snb_uncore_imc_event_start, + .stop = snb_uncore_imc_event_stop, + .read = uncore_pmu_event_read, +}; + +static struct intel_uncore_ops snb_uncore_imc_ops = { + .init_box = snb_uncore_imc_init_box, + .enable_box = snb_uncore_imc_enable_box, + .disable_box = snb_uncore_imc_disable_box, + .disable_event = snb_uncore_imc_disable_event, + .enable_event = snb_uncore_imc_enable_event, + .hw_config = snb_uncore_imc_hw_config, + .read_counter = snb_uncore_imc_read_counter, +}; + +static struct intel_uncore_type snb_uncore_imc = { + .name = "imc", + .num_counters = 2, + .num_boxes = 1, + .fixed_ctr_bits = 32, + .fixed_ctr = SNB_UNCORE_PCI_IMC_CTR_BASE, + .event_descs = snb_uncore_imc_events, + .format_group = &snb_uncore_imc_format_group, + .perf_ctr = SNB_UNCORE_PCI_IMC_DATA_READS_BASE, + .event_mask = SNB_UNCORE_PCI_IMC_EVENT_MASK, + .ops = &snb_uncore_imc_ops, + .pmu = &snb_uncore_imc_pmu, +}; + +static struct intel_uncore_type *snb_pci_uncores[] = { + [SNB_PCI_UNCORE_IMC] = &snb_uncore_imc, + NULL, +}; + +static DEFINE_PCI_DEVICE_TABLE(snb_uncore_pci_ids) = { + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SNB_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, + { /* end: all zeroes */ }, +}; + +static DEFINE_PCI_DEVICE_TABLE(ivb_uncore_pci_ids) = { + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IVB_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, + { /* end: all zeroes */ }, +}; + +static DEFINE_PCI_DEVICE_TABLE(hsw_uncore_pci_ids) = { + { /* IMC */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC), + .driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0), + }, + { /* end: all zeroes */ }, +}; + +static struct pci_driver snb_uncore_pci_driver = { + .name = "snb_uncore", + .id_table = snb_uncore_pci_ids, +}; + +static struct pci_driver ivb_uncore_pci_driver = { + .name = "ivb_uncore", + .id_table = ivb_uncore_pci_ids, +}; + +static struct pci_driver hsw_uncore_pci_driver = { + .name = "hsw_uncore", + .id_table = hsw_uncore_pci_ids, +}; + +int snb_uncore_pci_init(void) +{ + int ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_SNB_IMC); + if (ret) + return ret; + uncore_pci_uncores = snb_pci_uncores; + uncore_pci_driver = &snb_uncore_pci_driver; + return 0; +} + +int ivb_uncore_pci_init(void) +{ + int ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_IVB_IMC); + if (ret) + return ret; + uncore_pci_uncores = snb_pci_uncores; + uncore_pci_driver = &ivb_uncore_pci_driver; + return 0; +} + +int hsw_uncore_pci_init(void) +{ + int ret = snb_pci2phy_map_init(PCI_DEVICE_ID_INTEL_HSW_IMC); + if (ret) + return ret; + uncore_pci_uncores = snb_pci_uncores; + uncore_pci_driver = &hsw_uncore_pci_driver; + return 0; +} + +/* end of Sandy Bridge uncore support */ + +/* Nehalem uncore support */ +static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box) +{ + wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, 0); +} + +static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box) +{ + wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC); +} + +static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + if (hwc->idx < UNCORE_PMC_IDX_FIXED) + wrmsrl(hwc->config_base, hwc->config | SNB_UNC_CTL_EN); + else + wrmsrl(hwc->config_base, NHM_UNC_FIXED_CTR_CTL_EN); +} + +static struct attribute *nhm_uncore_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_cmask8.attr, + NULL, +}; + +static struct attribute_group nhm_uncore_format_group = { + .name = "format", + .attrs = nhm_uncore_formats_attr, +}; + +static struct uncore_event_desc nhm_uncore_events[] = { + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), + INTEL_UNCORE_EVENT_DESC(qmc_writes_full_any, "event=0x2f,umask=0x0f"), + INTEL_UNCORE_EVENT_DESC(qmc_normal_reads_any, "event=0x2c,umask=0x0f"), + INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_reads, "event=0x20,umask=0x01"), + INTEL_UNCORE_EVENT_DESC(qhl_request_ioh_writes, "event=0x20,umask=0x02"), + INTEL_UNCORE_EVENT_DESC(qhl_request_remote_reads, "event=0x20,umask=0x04"), + INTEL_UNCORE_EVENT_DESC(qhl_request_remote_writes, "event=0x20,umask=0x08"), + INTEL_UNCORE_EVENT_DESC(qhl_request_local_reads, "event=0x20,umask=0x10"), + INTEL_UNCORE_EVENT_DESC(qhl_request_local_writes, "event=0x20,umask=0x20"), + { /* end: all zeroes */ }, +}; + +static struct intel_uncore_ops nhm_uncore_msr_ops = { + .disable_box = nhm_uncore_msr_disable_box, + .enable_box = nhm_uncore_msr_enable_box, + .disable_event = snb_uncore_msr_disable_event, + .enable_event = nhm_uncore_msr_enable_event, + .read_counter = uncore_msr_read_counter, +}; + +static struct intel_uncore_type nhm_uncore = { + .name = "", + .num_counters = 8, + .num_boxes = 1, + .perf_ctr_bits = 48, + .fixed_ctr_bits = 48, + .event_ctl = NHM_UNC_PERFEVTSEL0, + .perf_ctr = NHM_UNC_UNCORE_PMC0, + .fixed_ctr = NHM_UNC_FIXED_CTR, + .fixed_ctl = NHM_UNC_FIXED_CTR_CTRL, + .event_mask = NHM_UNC_RAW_EVENT_MASK, + .event_descs = nhm_uncore_events, + .ops = &nhm_uncore_msr_ops, + .format_group = &nhm_uncore_format_group, +}; + +static struct intel_uncore_type *nhm_msr_uncores[] = { + &nhm_uncore, + NULL, +}; + +void nhm_uncore_cpu_init(void) +{ + uncore_msr_uncores = nhm_msr_uncores; +} + +/* end of Nehalem uncore support */ -- GitLab From 8268fdfc45b747bcb3351464efefbdf611aeea9b Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 30 Jul 2014 15:22:14 +0800 Subject: [PATCH 0268/9167] perf/x86/uncore: Move SNB/IVB-EP specific code to seperate file Signed-off-by: Yan, Zheng Signed-off-by: Peter Zijlstra Cc: Andi Kleen Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Paul Mackerras Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406704935-27708-3-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/Makefile | 1 + arch/x86/kernel/cpu/perf_event_intel_uncore.c | 1465 +-------------- arch/x86/kernel/cpu/perf_event_intel_uncore.h | 164 +- .../cpu/perf_event_intel_uncore_snbep.c | 1644 +++++++++++++++++ 4 files changed, 1655 insertions(+), 1619 deletions(-) create mode 100644 arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 5ca8f4a39106..7dee8664573a 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -37,6 +37,7 @@ endif obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o perf_event_intel_uncore_snb.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore_snbep.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o endif diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index feb085c8ca4e..cf6966a37580 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -32,46 +32,10 @@ ssize_t uncore_event_show(struct kobject *kobj, ((1ULL << (n)) - 1))) DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); -DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); -DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); -DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); -DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); -DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); -DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); -DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); -DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8"); -DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); -DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47"); -DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); -DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22"); -DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); -DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60"); -DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7"); -DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); -DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); -DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31"); -DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51"); -DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35"); -DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31"); -DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17"); -DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12"); -DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8"); -DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4"); -DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31"); -DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63"); -DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51"); -DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35"); -DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31"); -DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17"); -DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12"); -DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8"); -DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4"); -DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31"); -DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63"); struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) { @@ -194,1415 +158,6 @@ u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx) return config; } -/* Sandy Bridge-EP uncore support */ -static struct intel_uncore_type snbep_uncore_cbox; -static struct intel_uncore_type snbep_uncore_pcu; - -static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - int box_ctl = uncore_pci_box_ctl(box); - u32 config = 0; - - if (!pci_read_config_dword(pdev, box_ctl, &config)) { - config |= SNBEP_PMON_BOX_CTL_FRZ; - pci_write_config_dword(pdev, box_ctl, config); - } -} - -static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - int box_ctl = uncore_pci_box_ctl(box); - u32 config = 0; - - if (!pci_read_config_dword(pdev, box_ctl, &config)) { - config &= ~SNBEP_PMON_BOX_CTL_FRZ; - pci_write_config_dword(pdev, box_ctl, config); - } -} - -static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - - pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); -} - -static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - - pci_write_config_dword(pdev, hwc->config_base, hwc->config); -} - -static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - u64 count = 0; - - pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); - pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); - - return count; -} - -static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - - pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, SNBEP_PMON_BOX_CTL_INT); -} - -static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) -{ - u64 config; - unsigned msr; - - msr = uncore_msr_box_ctl(box); - if (msr) { - rdmsrl(msr, config); - config |= SNBEP_PMON_BOX_CTL_FRZ; - wrmsrl(msr, config); - } -} - -static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box) -{ - u64 config; - unsigned msr; - - msr = uncore_msr_box_ctl(box); - if (msr) { - rdmsrl(msr, config); - config &= ~SNBEP_PMON_BOX_CTL_FRZ; - wrmsrl(msr, config); - } -} - -static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - - if (reg1->idx != EXTRA_REG_NONE) - wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0)); - - wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); -} - -static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box, - struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - wrmsrl(hwc->config_base, hwc->config); -} - -static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) -{ - unsigned msr = uncore_msr_box_ctl(box); - - if (msr) - wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); -} - -static struct attribute *snbep_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - NULL, -}; - -static struct attribute *snbep_uncore_ubox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh5.attr, - NULL, -}; - -static struct attribute *snbep_uncore_cbox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_tid_en.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - &format_attr_filter_tid.attr, - &format_attr_filter_nid.attr, - &format_attr_filter_state.attr, - &format_attr_filter_opc.attr, - NULL, -}; - -static struct attribute *snbep_uncore_pcu_formats_attr[] = { - &format_attr_event_ext.attr, - &format_attr_occ_sel.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh5.attr, - &format_attr_occ_invert.attr, - &format_attr_occ_edge.attr, - &format_attr_filter_band0.attr, - &format_attr_filter_band1.attr, - &format_attr_filter_band2.attr, - &format_attr_filter_band3.attr, - NULL, -}; - -static struct attribute *snbep_uncore_qpi_formats_attr[] = { - &format_attr_event_ext.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - &format_attr_match_rds.attr, - &format_attr_match_rnid30.attr, - &format_attr_match_rnid4.attr, - &format_attr_match_dnid.attr, - &format_attr_match_mc.attr, - &format_attr_match_opc.attr, - &format_attr_match_vnw.attr, - &format_attr_match0.attr, - &format_attr_match1.attr, - &format_attr_mask_rds.attr, - &format_attr_mask_rnid30.attr, - &format_attr_mask_rnid4.attr, - &format_attr_mask_dnid.attr, - &format_attr_mask_mc.attr, - &format_attr_mask_opc.attr, - &format_attr_mask_vnw.attr, - &format_attr_mask0.attr, - &format_attr_mask1.attr, - NULL, -}; - -static struct uncore_event_desc snbep_uncore_imc_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), - INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"), - INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"), - { /* end: all zeroes */ }, -}; - -static struct uncore_event_desc snbep_uncore_qpi_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), - INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), - INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x102,umask=0x08"), - INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x103,umask=0x04"), - { /* end: all zeroes */ }, -}; - -static struct attribute_group snbep_uncore_format_group = { - .name = "format", - .attrs = snbep_uncore_formats_attr, -}; - -static struct attribute_group snbep_uncore_ubox_format_group = { - .name = "format", - .attrs = snbep_uncore_ubox_formats_attr, -}; - -static struct attribute_group snbep_uncore_cbox_format_group = { - .name = "format", - .attrs = snbep_uncore_cbox_formats_attr, -}; - -static struct attribute_group snbep_uncore_pcu_format_group = { - .name = "format", - .attrs = snbep_uncore_pcu_formats_attr, -}; - -static struct attribute_group snbep_uncore_qpi_format_group = { - .name = "format", - .attrs = snbep_uncore_qpi_formats_attr, -}; - -#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \ - .init_box = snbep_uncore_msr_init_box, \ - .disable_box = snbep_uncore_msr_disable_box, \ - .enable_box = snbep_uncore_msr_enable_box, \ - .disable_event = snbep_uncore_msr_disable_event, \ - .enable_event = snbep_uncore_msr_enable_event, \ - .read_counter = uncore_msr_read_counter - -static struct intel_uncore_ops snbep_uncore_msr_ops = { - SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), -}; - -#define SNBEP_UNCORE_PCI_OPS_COMMON_INIT() \ - .init_box = snbep_uncore_pci_init_box, \ - .disable_box = snbep_uncore_pci_disable_box, \ - .enable_box = snbep_uncore_pci_enable_box, \ - .disable_event = snbep_uncore_pci_disable_event, \ - .read_counter = snbep_uncore_pci_read_counter - -static struct intel_uncore_ops snbep_uncore_pci_ops = { - SNBEP_UNCORE_PCI_OPS_COMMON_INIT(), - .enable_event = snbep_uncore_pci_enable_event, \ -}; - -static struct event_constraint snbep_uncore_cbox_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x01, 0x1), - UNCORE_EVENT_CONSTRAINT(0x02, 0x3), - UNCORE_EVENT_CONSTRAINT(0x04, 0x3), - UNCORE_EVENT_CONSTRAINT(0x05, 0x3), - UNCORE_EVENT_CONSTRAINT(0x07, 0x3), - UNCORE_EVENT_CONSTRAINT(0x09, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x1), - UNCORE_EVENT_CONSTRAINT(0x12, 0x3), - UNCORE_EVENT_CONSTRAINT(0x13, 0x3), - UNCORE_EVENT_CONSTRAINT(0x1b, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1c, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1d, 0xc), - UNCORE_EVENT_CONSTRAINT(0x1e, 0xc), - EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff), - UNCORE_EVENT_CONSTRAINT(0x21, 0x3), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x31, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - UNCORE_EVENT_CONSTRAINT(0x35, 0x3), - UNCORE_EVENT_CONSTRAINT(0x36, 0x1), - UNCORE_EVENT_CONSTRAINT(0x37, 0x3), - UNCORE_EVENT_CONSTRAINT(0x38, 0x3), - UNCORE_EVENT_CONSTRAINT(0x39, 0x3), - UNCORE_EVENT_CONSTRAINT(0x3b, 0x1), - EVENT_CONSTRAINT_END -}; - -static struct event_constraint snbep_uncore_r2pcie_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x10, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x3), - UNCORE_EVENT_CONSTRAINT(0x12, 0x1), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x24, 0x3), - UNCORE_EVENT_CONSTRAINT(0x25, 0x3), - UNCORE_EVENT_CONSTRAINT(0x26, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - EVENT_CONSTRAINT_END -}; - -static struct event_constraint snbep_uncore_r3qpi_constraints[] = { - UNCORE_EVENT_CONSTRAINT(0x10, 0x3), - UNCORE_EVENT_CONSTRAINT(0x11, 0x3), - UNCORE_EVENT_CONSTRAINT(0x12, 0x3), - UNCORE_EVENT_CONSTRAINT(0x13, 0x1), - UNCORE_EVENT_CONSTRAINT(0x20, 0x3), - UNCORE_EVENT_CONSTRAINT(0x21, 0x3), - UNCORE_EVENT_CONSTRAINT(0x22, 0x3), - UNCORE_EVENT_CONSTRAINT(0x23, 0x3), - UNCORE_EVENT_CONSTRAINT(0x24, 0x3), - UNCORE_EVENT_CONSTRAINT(0x25, 0x3), - UNCORE_EVENT_CONSTRAINT(0x26, 0x3), - UNCORE_EVENT_CONSTRAINT(0x28, 0x3), - UNCORE_EVENT_CONSTRAINT(0x29, 0x3), - UNCORE_EVENT_CONSTRAINT(0x2a, 0x3), - UNCORE_EVENT_CONSTRAINT(0x2b, 0x3), - UNCORE_EVENT_CONSTRAINT(0x2c, 0x3), - UNCORE_EVENT_CONSTRAINT(0x2d, 0x3), - UNCORE_EVENT_CONSTRAINT(0x2e, 0x3), - UNCORE_EVENT_CONSTRAINT(0x2f, 0x3), - UNCORE_EVENT_CONSTRAINT(0x30, 0x3), - UNCORE_EVENT_CONSTRAINT(0x31, 0x3), - UNCORE_EVENT_CONSTRAINT(0x32, 0x3), - UNCORE_EVENT_CONSTRAINT(0x33, 0x3), - UNCORE_EVENT_CONSTRAINT(0x34, 0x3), - UNCORE_EVENT_CONSTRAINT(0x36, 0x3), - UNCORE_EVENT_CONSTRAINT(0x37, 0x3), - UNCORE_EVENT_CONSTRAINT(0x38, 0x3), - UNCORE_EVENT_CONSTRAINT(0x39, 0x3), - EVENT_CONSTRAINT_END -}; - -static struct intel_uncore_type snbep_uncore_ubox = { - .name = "ubox", - .num_counters = 2, - .num_boxes = 1, - .perf_ctr_bits = 44, - .fixed_ctr_bits = 48, - .perf_ctr = SNBEP_U_MSR_PMON_CTR0, - .event_ctl = SNBEP_U_MSR_PMON_CTL0, - .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK, - .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, - .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, - .ops = &snbep_uncore_msr_ops, - .format_group = &snbep_uncore_ubox_format_group, -}; - -static struct extra_reg snbep_uncore_cbox_extra_regs[] = { - SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, - SNBEP_CBO_PMON_CTL_TID_EN, 0x1), - SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), - SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6), - SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), - SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6), - SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), - SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6), - SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6), - SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa), - SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa), - SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2), - SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2), - SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2), - SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2), - SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa), - SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa), - SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2), - SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2), - SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2), - SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2), - EVENT_EXTRA_END -}; - -static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct intel_uncore_extra_reg *er = &box->shared_regs[0]; - int i; - - if (uncore_box_is_fake(box)) - return; - - for (i = 0; i < 5; i++) { - if (reg1->alloc & (0x1 << i)) - atomic_sub(1 << (i * 6), &er->ref); - } - reg1->alloc = 0; -} - -static struct event_constraint * -__snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event, - u64 (*cbox_filter_mask)(int fields)) -{ - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct intel_uncore_extra_reg *er = &box->shared_regs[0]; - int i, alloc = 0; - unsigned long flags; - u64 mask; - - if (reg1->idx == EXTRA_REG_NONE) - return NULL; - - raw_spin_lock_irqsave(&er->lock, flags); - for (i = 0; i < 5; i++) { - if (!(reg1->idx & (0x1 << i))) - continue; - if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i))) - continue; - - mask = cbox_filter_mask(0x1 << i); - if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) || - !((reg1->config ^ er->config) & mask)) { - atomic_add(1 << (i * 6), &er->ref); - er->config &= ~mask; - er->config |= reg1->config & mask; - alloc |= (0x1 << i); - } else { - break; - } - } - raw_spin_unlock_irqrestore(&er->lock, flags); - if (i < 5) - goto fail; - - if (!uncore_box_is_fake(box)) - reg1->alloc |= alloc; - - return NULL; -fail: - for (; i >= 0; i--) { - if (alloc & (0x1 << i)) - atomic_sub(1 << (i * 6), &er->ref); - } - return &uncore_constraint_empty; -} - -static u64 snbep_cbox_filter_mask(int fields) -{ - u64 mask = 0; - - if (fields & 0x1) - mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID; - if (fields & 0x2) - mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID; - if (fields & 0x4) - mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE; - if (fields & 0x8) - mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC; - - return mask; -} - -static struct event_constraint * -snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask); -} - -static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct extra_reg *er; - int idx = 0; - - for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) { - if (er->event != (event->hw.config & er->config_mask)) - continue; - idx |= er->idx; - } - - if (idx) { - reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + - SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; - reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx); - reg1->idx = idx; - } - return 0; -} - -static struct intel_uncore_ops snbep_uncore_cbox_ops = { - SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), - .hw_config = snbep_cbox_hw_config, - .get_constraint = snbep_cbox_get_constraint, - .put_constraint = snbep_cbox_put_constraint, -}; - -static struct intel_uncore_type snbep_uncore_cbox = { - .name = "cbox", - .num_counters = 4, - .num_boxes = 8, - .perf_ctr_bits = 44, - .event_ctl = SNBEP_C0_MSR_PMON_CTL0, - .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, - .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, - .msr_offset = SNBEP_CBO_MSR_OFFSET, - .num_shared_regs = 1, - .constraints = snbep_uncore_cbox_constraints, - .ops = &snbep_uncore_cbox_ops, - .format_group = &snbep_uncore_cbox_format_group, -}; - -static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - u64 config = reg1->config; - - if (new_idx > reg1->idx) - config <<= 8 * (new_idx - reg1->idx); - else - config >>= 8 * (reg1->idx - new_idx); - - if (modify) { - hwc->config += new_idx - reg1->idx; - reg1->config = config; - reg1->idx = new_idx; - } - return config; -} - -static struct event_constraint * -snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct intel_uncore_extra_reg *er = &box->shared_regs[0]; - unsigned long flags; - int idx = reg1->idx; - u64 mask, config1 = reg1->config; - bool ok = false; - - if (reg1->idx == EXTRA_REG_NONE || - (!uncore_box_is_fake(box) && reg1->alloc)) - return NULL; -again: - mask = 0xffULL << (idx * 8); - raw_spin_lock_irqsave(&er->lock, flags); - if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) || - !((config1 ^ er->config) & mask)) { - atomic_add(1 << (idx * 8), &er->ref); - er->config &= ~mask; - er->config |= config1 & mask; - ok = true; - } - raw_spin_unlock_irqrestore(&er->lock, flags); - - if (!ok) { - idx = (idx + 1) % 4; - if (idx != reg1->idx) { - config1 = snbep_pcu_alter_er(event, idx, false); - goto again; - } - return &uncore_constraint_empty; - } - - if (!uncore_box_is_fake(box)) { - if (idx != reg1->idx) - snbep_pcu_alter_er(event, idx, true); - reg1->alloc = 1; - } - return NULL; -} - -static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct intel_uncore_extra_reg *er = &box->shared_regs[0]; - - if (uncore_box_is_fake(box) || !reg1->alloc) - return; - - atomic_sub(1 << (reg1->idx * 8), &er->ref); - reg1->alloc = 0; -} - -static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK; - - if (ev_sel >= 0xb && ev_sel <= 0xe) { - reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; - reg1->idx = ev_sel - 0xb; - reg1->config = event->attr.config1 & (0xff << reg1->idx); - } - return 0; -} - -static struct intel_uncore_ops snbep_uncore_pcu_ops = { - SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), - .hw_config = snbep_pcu_hw_config, - .get_constraint = snbep_pcu_get_constraint, - .put_constraint = snbep_pcu_put_constraint, -}; - -static struct intel_uncore_type snbep_uncore_pcu = { - .name = "pcu", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, - .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, - .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, - .num_shared_regs = 1, - .ops = &snbep_uncore_pcu_ops, - .format_group = &snbep_uncore_pcu_format_group, -}; - -static struct intel_uncore_type *snbep_msr_uncores[] = { - &snbep_uncore_ubox, - &snbep_uncore_cbox, - &snbep_uncore_pcu, - NULL, -}; - -enum { - SNBEP_PCI_QPI_PORT0_FILTER, - SNBEP_PCI_QPI_PORT1_FILTER, -}; - -static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - - if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) { - reg1->idx = 0; - reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0; - reg1->config = event->attr.config1; - reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0; - reg2->config = event->attr.config2; - } - return 0; -} - -static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - - if (reg1->idx != EXTRA_REG_NONE) { - int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER; - struct pci_dev *filter_pdev = uncore_extra_pci_dev[box->phys_id][idx]; - WARN_ON_ONCE(!filter_pdev); - if (filter_pdev) { - pci_write_config_dword(filter_pdev, reg1->reg, - (u32)reg1->config); - pci_write_config_dword(filter_pdev, reg1->reg + 4, - (u32)(reg1->config >> 32)); - pci_write_config_dword(filter_pdev, reg2->reg, - (u32)reg2->config); - pci_write_config_dword(filter_pdev, reg2->reg + 4, - (u32)(reg2->config >> 32)); - } - } - - pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); -} - -static struct intel_uncore_ops snbep_uncore_qpi_ops = { - SNBEP_UNCORE_PCI_OPS_COMMON_INIT(), - .enable_event = snbep_qpi_enable_event, - .hw_config = snbep_qpi_hw_config, - .get_constraint = uncore_get_constraint, - .put_constraint = uncore_put_constraint, -}; - -#define SNBEP_UNCORE_PCI_COMMON_INIT() \ - .perf_ctr = SNBEP_PCI_PMON_CTR0, \ - .event_ctl = SNBEP_PCI_PMON_CTL0, \ - .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \ - .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ - .ops = &snbep_uncore_pci_ops, \ - .format_group = &snbep_uncore_format_group - -static struct intel_uncore_type snbep_uncore_ha = { - .name = "ha", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_imc = { - .name = "imc", - .num_counters = 4, - .num_boxes = 4, - .perf_ctr_bits = 48, - .fixed_ctr_bits = 48, - .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, - .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, - .event_descs = snbep_uncore_imc_events, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_qpi = { - .name = "qpi", - .num_counters = 4, - .num_boxes = 2, - .perf_ctr_bits = 48, - .perf_ctr = SNBEP_PCI_PMON_CTR0, - .event_ctl = SNBEP_PCI_PMON_CTL0, - .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_PCI_PMON_BOX_CTL, - .num_shared_regs = 1, - .ops = &snbep_uncore_qpi_ops, - .event_descs = snbep_uncore_qpi_events, - .format_group = &snbep_uncore_qpi_format_group, -}; - - -static struct intel_uncore_type snbep_uncore_r2pcie = { - .name = "r2pcie", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 44, - .constraints = snbep_uncore_r2pcie_constraints, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type snbep_uncore_r3qpi = { - .name = "r3qpi", - .num_counters = 3, - .num_boxes = 2, - .perf_ctr_bits = 44, - .constraints = snbep_uncore_r3qpi_constraints, - SNBEP_UNCORE_PCI_COMMON_INIT(), -}; - -enum { - SNBEP_PCI_UNCORE_HA, - SNBEP_PCI_UNCORE_IMC, - SNBEP_PCI_UNCORE_QPI, - SNBEP_PCI_UNCORE_R2PCIE, - SNBEP_PCI_UNCORE_R3QPI, -}; - -static struct intel_uncore_type *snbep_pci_uncores[] = { - [SNBEP_PCI_UNCORE_HA] = &snbep_uncore_ha, - [SNBEP_PCI_UNCORE_IMC] = &snbep_uncore_imc, - [SNBEP_PCI_UNCORE_QPI] = &snbep_uncore_qpi, - [SNBEP_PCI_UNCORE_R2PCIE] = &snbep_uncore_r2pcie, - [SNBEP_PCI_UNCORE_R3QPI] = &snbep_uncore_r3qpi, - NULL, -}; - -static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { - { /* Home Agent */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0), - }, - { /* MC Channel 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0), - }, - { /* MC Channel 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1), - }, - { /* MC Channel 2 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2), - }, - { /* MC Channel 3 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3), - }, - { /* QPI Port 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0), - }, - { /* QPI Port 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1), - }, - { /* R2PCIe */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0), - }, - { /* R3QPI Link 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0), - }, - { /* R3QPI Link 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), - .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1), - }, - { /* QPI Port 0 filter */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86), - .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, - SNBEP_PCI_QPI_PORT0_FILTER), - }, - { /* QPI Port 0 filter */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96), - .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, - SNBEP_PCI_QPI_PORT1_FILTER), - }, - { /* end: all zeroes */ } -}; - -static struct pci_driver snbep_uncore_pci_driver = { - .name = "snbep_uncore", - .id_table = snbep_uncore_pci_ids, -}; - -/* - * build pci bus to socket mapping - */ -static int snbep_pci2phy_map_init(int devid) -{ - struct pci_dev *ubox_dev = NULL; - int i, bus, nodeid; - int err = 0; - u32 config = 0; - - while (1) { - /* find the UBOX device */ - ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev); - if (!ubox_dev) - break; - bus = ubox_dev->bus->number; - /* get the Node ID of the local register */ - err = pci_read_config_dword(ubox_dev, 0x40, &config); - if (err) - break; - nodeid = config; - /* get the Node ID mapping */ - err = pci_read_config_dword(ubox_dev, 0x54, &config); - if (err) - break; - /* - * every three bits in the Node ID mapping register maps - * to a particular node. - */ - for (i = 0; i < 8; i++) { - if (nodeid == ((config >> (3 * i)) & 0x7)) { - uncore_pcibus_to_physid[bus] = i; - break; - } - } - } - - if (!err) { - /* - * For PCI bus with no UBOX device, find the next bus - * that has UBOX device and use its mapping. - */ - i = -1; - for (bus = 255; bus >= 0; bus--) { - if (uncore_pcibus_to_physid[bus] >= 0) - i = uncore_pcibus_to_physid[bus]; - else - uncore_pcibus_to_physid[bus] = i; - } - } - - if (ubox_dev) - pci_dev_put(ubox_dev); - - return err ? pcibios_err_to_errno(err) : 0; -} -/* end of Sandy Bridge-EP uncore support */ - -/* IvyTown uncore support */ -static void ivt_uncore_msr_init_box(struct intel_uncore_box *box) -{ - unsigned msr = uncore_msr_box_ctl(box); - if (msr) - wrmsrl(msr, IVT_PMON_BOX_CTL_INT); -} - -static void ivt_uncore_pci_init_box(struct intel_uncore_box *box) -{ - struct pci_dev *pdev = box->pci_dev; - - pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVT_PMON_BOX_CTL_INT); -} - -#define IVT_UNCORE_MSR_OPS_COMMON_INIT() \ - .init_box = ivt_uncore_msr_init_box, \ - .disable_box = snbep_uncore_msr_disable_box, \ - .enable_box = snbep_uncore_msr_enable_box, \ - .disable_event = snbep_uncore_msr_disable_event, \ - .enable_event = snbep_uncore_msr_enable_event, \ - .read_counter = uncore_msr_read_counter - -static struct intel_uncore_ops ivt_uncore_msr_ops = { - IVT_UNCORE_MSR_OPS_COMMON_INIT(), -}; - -static struct intel_uncore_ops ivt_uncore_pci_ops = { - .init_box = ivt_uncore_pci_init_box, - .disable_box = snbep_uncore_pci_disable_box, - .enable_box = snbep_uncore_pci_enable_box, - .disable_event = snbep_uncore_pci_disable_event, - .enable_event = snbep_uncore_pci_enable_event, - .read_counter = snbep_uncore_pci_read_counter, -}; - -#define IVT_UNCORE_PCI_COMMON_INIT() \ - .perf_ctr = SNBEP_PCI_PMON_CTR0, \ - .event_ctl = SNBEP_PCI_PMON_CTL0, \ - .event_mask = IVT_PMON_RAW_EVENT_MASK, \ - .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ - .ops = &ivt_uncore_pci_ops, \ - .format_group = &ivt_uncore_format_group - -static struct attribute *ivt_uncore_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - NULL, -}; - -static struct attribute *ivt_uncore_ubox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh5.attr, - NULL, -}; - -static struct attribute *ivt_uncore_cbox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_tid_en.attr, - &format_attr_thresh8.attr, - &format_attr_filter_tid.attr, - &format_attr_filter_link.attr, - &format_attr_filter_state2.attr, - &format_attr_filter_nid2.attr, - &format_attr_filter_opc2.attr, - NULL, -}; - -static struct attribute *ivt_uncore_pcu_formats_attr[] = { - &format_attr_event_ext.attr, - &format_attr_occ_sel.attr, - &format_attr_edge.attr, - &format_attr_thresh5.attr, - &format_attr_occ_invert.attr, - &format_attr_occ_edge.attr, - &format_attr_filter_band0.attr, - &format_attr_filter_band1.attr, - &format_attr_filter_band2.attr, - &format_attr_filter_band3.attr, - NULL, -}; - -static struct attribute *ivt_uncore_qpi_formats_attr[] = { - &format_attr_event_ext.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_thresh8.attr, - &format_attr_match_rds.attr, - &format_attr_match_rnid30.attr, - &format_attr_match_rnid4.attr, - &format_attr_match_dnid.attr, - &format_attr_match_mc.attr, - &format_attr_match_opc.attr, - &format_attr_match_vnw.attr, - &format_attr_match0.attr, - &format_attr_match1.attr, - &format_attr_mask_rds.attr, - &format_attr_mask_rnid30.attr, - &format_attr_mask_rnid4.attr, - &format_attr_mask_dnid.attr, - &format_attr_mask_mc.attr, - &format_attr_mask_opc.attr, - &format_attr_mask_vnw.attr, - &format_attr_mask0.attr, - &format_attr_mask1.attr, - NULL, -}; - -static struct attribute_group ivt_uncore_format_group = { - .name = "format", - .attrs = ivt_uncore_formats_attr, -}; - -static struct attribute_group ivt_uncore_ubox_format_group = { - .name = "format", - .attrs = ivt_uncore_ubox_formats_attr, -}; - -static struct attribute_group ivt_uncore_cbox_format_group = { - .name = "format", - .attrs = ivt_uncore_cbox_formats_attr, -}; - -static struct attribute_group ivt_uncore_pcu_format_group = { - .name = "format", - .attrs = ivt_uncore_pcu_formats_attr, -}; - -static struct attribute_group ivt_uncore_qpi_format_group = { - .name = "format", - .attrs = ivt_uncore_qpi_formats_attr, -}; - -static struct intel_uncore_type ivt_uncore_ubox = { - .name = "ubox", - .num_counters = 2, - .num_boxes = 1, - .perf_ctr_bits = 44, - .fixed_ctr_bits = 48, - .perf_ctr = SNBEP_U_MSR_PMON_CTR0, - .event_ctl = SNBEP_U_MSR_PMON_CTL0, - .event_mask = IVT_U_MSR_PMON_RAW_EVENT_MASK, - .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, - .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, - .ops = &ivt_uncore_msr_ops, - .format_group = &ivt_uncore_ubox_format_group, -}; - -static struct extra_reg ivt_uncore_cbox_extra_regs[] = { - SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, - SNBEP_CBO_PMON_CTL_TID_EN, 0x1), - SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), - - SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4), - SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), - SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc), - SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), - SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc), - SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), - SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc), - SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), - SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc), - SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18), - SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18), - SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18), - SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18), - SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8), - SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10), - SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8), - EVENT_EXTRA_END -}; - -static u64 ivt_cbox_filter_mask(int fields) -{ - u64 mask = 0; - - if (fields & 0x1) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_TID; - if (fields & 0x2) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_LINK; - if (fields & 0x4) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_STATE; - if (fields & 0x8) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_NID; - if (fields & 0x10) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_OPC; - - return mask; -} - -static struct event_constraint * -ivt_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - return __snbep_cbox_get_constraint(box, event, ivt_cbox_filter_mask); -} - -static int ivt_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct extra_reg *er; - int idx = 0; - - for (er = ivt_uncore_cbox_extra_regs; er->msr; er++) { - if (er->event != (event->hw.config & er->config_mask)) - continue; - idx |= er->idx; - } - - if (idx) { - reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + - SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; - reg1->config = event->attr.config1 & ivt_cbox_filter_mask(idx); - reg1->idx = idx; - } - return 0; -} - -static void ivt_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - - if (reg1->idx != EXTRA_REG_NONE) { - u64 filter = uncore_shared_reg_config(box, 0); - wrmsrl(reg1->reg, filter & 0xffffffff); - wrmsrl(reg1->reg + 6, filter >> 32); - } - - wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); -} - -static struct intel_uncore_ops ivt_uncore_cbox_ops = { - .init_box = ivt_uncore_msr_init_box, - .disable_box = snbep_uncore_msr_disable_box, - .enable_box = snbep_uncore_msr_enable_box, - .disable_event = snbep_uncore_msr_disable_event, - .enable_event = ivt_cbox_enable_event, - .read_counter = uncore_msr_read_counter, - .hw_config = ivt_cbox_hw_config, - .get_constraint = ivt_cbox_get_constraint, - .put_constraint = snbep_cbox_put_constraint, -}; - -static struct intel_uncore_type ivt_uncore_cbox = { - .name = "cbox", - .num_counters = 4, - .num_boxes = 15, - .perf_ctr_bits = 44, - .event_ctl = SNBEP_C0_MSR_PMON_CTL0, - .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, - .event_mask = IVT_CBO_MSR_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, - .msr_offset = SNBEP_CBO_MSR_OFFSET, - .num_shared_regs = 1, - .constraints = snbep_uncore_cbox_constraints, - .ops = &ivt_uncore_cbox_ops, - .format_group = &ivt_uncore_cbox_format_group, -}; - -static struct intel_uncore_ops ivt_uncore_pcu_ops = { - IVT_UNCORE_MSR_OPS_COMMON_INIT(), - .hw_config = snbep_pcu_hw_config, - .get_constraint = snbep_pcu_get_constraint, - .put_constraint = snbep_pcu_put_constraint, -}; - -static struct intel_uncore_type ivt_uncore_pcu = { - .name = "pcu", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, - .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, - .event_mask = IVT_PCU_MSR_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, - .num_shared_regs = 1, - .ops = &ivt_uncore_pcu_ops, - .format_group = &ivt_uncore_pcu_format_group, -}; - -static struct intel_uncore_type *ivt_msr_uncores[] = { - &ivt_uncore_ubox, - &ivt_uncore_cbox, - &ivt_uncore_pcu, - NULL, -}; - -static struct intel_uncore_type ivt_uncore_ha = { - .name = "ha", - .num_counters = 4, - .num_boxes = 2, - .perf_ctr_bits = 48, - IVT_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type ivt_uncore_imc = { - .name = "imc", - .num_counters = 4, - .num_boxes = 8, - .perf_ctr_bits = 48, - .fixed_ctr_bits = 48, - .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, - .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, - IVT_UNCORE_PCI_COMMON_INIT(), -}; - -/* registers in IRP boxes are not properly aligned */ -static unsigned ivt_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4}; -static unsigned ivt_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0}; - -static void ivt_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - - pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], - hwc->config | SNBEP_PMON_CTL_EN); -} - -static void ivt_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - - pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], hwc->config); -} - -static u64 ivt_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event) -{ - struct pci_dev *pdev = box->pci_dev; - struct hw_perf_event *hwc = &event->hw; - u64 count = 0; - - pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx], (u32 *)&count); - pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1); - - return count; -} - -static struct intel_uncore_ops ivt_uncore_irp_ops = { - .init_box = ivt_uncore_pci_init_box, - .disable_box = snbep_uncore_pci_disable_box, - .enable_box = snbep_uncore_pci_enable_box, - .disable_event = ivt_uncore_irp_disable_event, - .enable_event = ivt_uncore_irp_enable_event, - .read_counter = ivt_uncore_irp_read_counter, -}; - -static struct intel_uncore_type ivt_uncore_irp = { - .name = "irp", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - .event_mask = IVT_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_PCI_PMON_BOX_CTL, - .ops = &ivt_uncore_irp_ops, - .format_group = &ivt_uncore_format_group, -}; - -static struct intel_uncore_ops ivt_uncore_qpi_ops = { - .init_box = ivt_uncore_pci_init_box, - .disable_box = snbep_uncore_pci_disable_box, - .enable_box = snbep_uncore_pci_enable_box, - .disable_event = snbep_uncore_pci_disable_event, - .enable_event = snbep_qpi_enable_event, - .read_counter = snbep_uncore_pci_read_counter, - .hw_config = snbep_qpi_hw_config, - .get_constraint = uncore_get_constraint, - .put_constraint = uncore_put_constraint, -}; - -static struct intel_uncore_type ivt_uncore_qpi = { - .name = "qpi", - .num_counters = 4, - .num_boxes = 3, - .perf_ctr_bits = 48, - .perf_ctr = SNBEP_PCI_PMON_CTR0, - .event_ctl = SNBEP_PCI_PMON_CTL0, - .event_mask = IVT_QPI_PCI_PMON_RAW_EVENT_MASK, - .box_ctl = SNBEP_PCI_PMON_BOX_CTL, - .num_shared_regs = 1, - .ops = &ivt_uncore_qpi_ops, - .format_group = &ivt_uncore_qpi_format_group, -}; - -static struct intel_uncore_type ivt_uncore_r2pcie = { - .name = "r2pcie", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 44, - .constraints = snbep_uncore_r2pcie_constraints, - IVT_UNCORE_PCI_COMMON_INIT(), -}; - -static struct intel_uncore_type ivt_uncore_r3qpi = { - .name = "r3qpi", - .num_counters = 3, - .num_boxes = 2, - .perf_ctr_bits = 44, - .constraints = snbep_uncore_r3qpi_constraints, - IVT_UNCORE_PCI_COMMON_INIT(), -}; - -enum { - IVT_PCI_UNCORE_HA, - IVT_PCI_UNCORE_IMC, - IVT_PCI_UNCORE_IRP, - IVT_PCI_UNCORE_QPI, - IVT_PCI_UNCORE_R2PCIE, - IVT_PCI_UNCORE_R3QPI, -}; - -static struct intel_uncore_type *ivt_pci_uncores[] = { - [IVT_PCI_UNCORE_HA] = &ivt_uncore_ha, - [IVT_PCI_UNCORE_IMC] = &ivt_uncore_imc, - [IVT_PCI_UNCORE_IRP] = &ivt_uncore_irp, - [IVT_PCI_UNCORE_QPI] = &ivt_uncore_qpi, - [IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie, - [IVT_PCI_UNCORE_R3QPI] = &ivt_uncore_r3qpi, - NULL, -}; - -static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { - { /* Home Agent 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 0), - }, - { /* Home Agent 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 1), - }, - { /* MC0 Channel 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 0), - }, - { /* MC0 Channel 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 1), - }, - { /* MC0 Channel 3 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 2), - }, - { /* MC0 Channel 4 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 3), - }, - { /* MC1 Channel 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 4), - }, - { /* MC1 Channel 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 5), - }, - { /* MC1 Channel 3 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 6), - }, - { /* MC1 Channel 4 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7), - }, - { /* IRP */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IRP, 0), - }, - { /* QPI0 Port 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0), - }, - { /* QPI0 Port 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 1), - }, - { /* QPI1 Port 2 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 2), - }, - { /* R2PCIe */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R2PCIE, 0), - }, - { /* R3QPI0 Link 0 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 0), - }, - { /* R3QPI0 Link 1 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 1), - }, - { /* R3QPI1 Link 2 */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2), - }, - { /* QPI Port 0 filter */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86), - .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, - SNBEP_PCI_QPI_PORT0_FILTER), - }, - { /* QPI Port 0 filter */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96), - .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, - SNBEP_PCI_QPI_PORT1_FILTER), - }, - { /* end: all zeroes */ } -}; - -static struct pci_driver ivt_uncore_pci_driver = { - .name = "ivt_uncore", - .id_table = ivt_uncore_pci_ids, -}; -/* end of IvyTown uncore support */ - /* Nehalem-EX uncore support */ DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); @@ -3351,18 +1906,10 @@ static int __init uncore_pci_init(void) switch (boot_cpu_data.x86_model) { case 45: /* Sandy Bridge-EP */ - ret = snbep_pci2phy_map_init(0x3ce0); - if (ret) - return ret; - uncore_pci_uncores = snbep_pci_uncores; - uncore_pci_driver = &snbep_uncore_pci_driver; + ret = snbep_uncore_pci_init(); break; case 62: /* IvyTown */ - ret = snbep_pci2phy_map_init(0x0e1e); - if (ret) - return ret; - uncore_pci_uncores = ivt_pci_uncores; - uncore_pci_driver = &ivt_uncore_pci_driver; + ret = ivt_uncore_pci_init(); break; case 42: /* Sandy Bridge */ ret = snb_uncore_pci_init(); @@ -3663,9 +2210,7 @@ static int __init uncore_cpu_init(void) snb_uncore_cpu_init(); break; case 45: /* Sandy Bridge-EP */ - if (snbep_uncore_cbox.num_boxes > max_cores) - snbep_uncore_cbox.num_boxes = max_cores; - uncore_msr_uncores = snbep_msr_uncores; + snbep_uncore_cpu_init(); break; case 46: /* Nehalem-EX */ uncore_nhmex = true; @@ -3677,9 +2222,7 @@ static int __init uncore_cpu_init(void) uncore_msr_uncores = nhmex_msr_uncores; break; case 62: /* IvyTown */ - if (ivt_uncore_cbox.num_boxes > max_cores) - ivt_uncore_cbox.num_boxes = max_cores; - uncore_msr_uncores = ivt_msr_uncores; + ivt_uncore_cpu_init(); break; default: diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 86699caaacd8..538be93b5f19 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -24,164 +24,6 @@ #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) -/* SNB-EP Box level control */ -#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) -#define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) -#define SNBEP_PMON_BOX_CTL_FRZ (1 << 8) -#define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16) -#define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ - SNBEP_PMON_BOX_CTL_RST_CTRS | \ - SNBEP_PMON_BOX_CTL_FRZ_EN) -/* SNB-EP event control */ -#define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff -#define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00 -#define SNBEP_PMON_CTL_RST (1 << 17) -#define SNBEP_PMON_CTL_EDGE_DET (1 << 18) -#define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) -#define SNBEP_PMON_CTL_EN (1 << 22) -#define SNBEP_PMON_CTL_INVERT (1 << 23) -#define SNBEP_PMON_CTL_TRESH_MASK 0xff000000 -#define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_UMASK_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_PMON_CTL_TRESH_MASK) - -/* SNB-EP Ubox event control */ -#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000 -#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_UMASK_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_U_MSR_PMON_CTL_TRESH_MASK) - -#define SNBEP_CBO_PMON_CTL_TID_EN (1 << 19) -#define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \ - SNBEP_CBO_PMON_CTL_TID_EN) - -/* SNB-EP PCU event control */ -#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000 -#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000 -#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30) -#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31) -#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_EV_SEL_EXT | \ - SNBEP_PMON_CTL_INVERT | \ - SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) - -#define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_RAW_EVENT_MASK | \ - SNBEP_PMON_CTL_EV_SEL_EXT) - -/* SNB-EP pci control register */ -#define SNBEP_PCI_PMON_BOX_CTL 0xf4 -#define SNBEP_PCI_PMON_CTL0 0xd8 -/* SNB-EP pci counter register */ -#define SNBEP_PCI_PMON_CTR0 0xa0 - -/* SNB-EP home agent register */ -#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40 -#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44 -#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48 -/* SNB-EP memory controller register */ -#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0 -#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0 -/* SNB-EP QPI register */ -#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228 -#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c -#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238 -#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c - -/* SNB-EP Ubox register */ -#define SNBEP_U_MSR_PMON_CTR0 0xc16 -#define SNBEP_U_MSR_PMON_CTL0 0xc10 - -#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08 -#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09 - -/* SNB-EP Cbo register */ -#define SNBEP_C0_MSR_PMON_CTR0 0xd16 -#define SNBEP_C0_MSR_PMON_CTL0 0xd10 -#define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04 -#define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14 -#define SNBEP_CBO_MSR_OFFSET 0x20 - -#define SNBEP_CB0_MSR_PMON_BOX_FILTER_TID 0x1f -#define SNBEP_CB0_MSR_PMON_BOX_FILTER_NID 0x3fc00 -#define SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE 0x7c0000 -#define SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC 0xff800000 - -#define SNBEP_CBO_EVENT_EXTRA_REG(e, m, i) { \ - .event = (e), \ - .msr = SNBEP_C0_MSR_PMON_BOX_FILTER, \ - .config_mask = (m), \ - .idx = (i) \ -} - -/* SNB-EP PCU register */ -#define SNBEP_PCU_MSR_PMON_CTR0 0xc36 -#define SNBEP_PCU_MSR_PMON_CTL0 0xc30 -#define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24 -#define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34 -#define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK 0xffffffff -#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc -#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd - -/* IVT event control */ -#define IVT_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ - SNBEP_PMON_BOX_CTL_RST_CTRS) -#define IVT_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_UMASK_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PMON_CTL_TRESH_MASK) -/* IVT Ubox */ -#define IVT_U_MSR_PMON_GLOBAL_CTL 0xc00 -#define IVT_U_PMON_GLOBAL_FRZ_ALL (1 << 31) -#define IVT_U_PMON_GLOBAL_UNFRZ_ALL (1 << 29) - -#define IVT_U_MSR_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_UMASK_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_U_MSR_PMON_CTL_TRESH_MASK) -/* IVT Cbo */ -#define IVT_CBO_MSR_PMON_RAW_EVENT_MASK (IVT_PMON_RAW_EVENT_MASK | \ - SNBEP_CBO_PMON_CTL_TID_EN) - -#define IVT_CB0_MSR_PMON_BOX_FILTER_TID (0x1fULL << 0) -#define IVT_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 5) -#define IVT_CB0_MSR_PMON_BOX_FILTER_STATE (0x3fULL << 17) -#define IVT_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32) -#define IVT_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52) -#define IVT_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61) -#define IVT_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62) -#define IVT_CB0_MSR_PMON_BOX_FILTER_IOSC (0x1ULL << 63) - -/* IVT home agent */ -#define IVT_HA_PCI_PMON_CTL_Q_OCC_RST (1 << 16) -#define IVT_HA_PCI_PMON_RAW_EVENT_MASK \ - (IVT_PMON_RAW_EVENT_MASK | \ - IVT_HA_PCI_PMON_CTL_Q_OCC_RST) -/* IVT PCU */ -#define IVT_PCU_MSR_PMON_RAW_EVENT_MASK \ - (SNBEP_PMON_CTL_EV_SEL_MASK | \ - SNBEP_PMON_CTL_EV_SEL_EXT | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ - SNBEP_PMON_CTL_EDGE_DET | \ - SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ - SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) -/* IVT QPI */ -#define IVT_QPI_PCI_PMON_RAW_EVENT_MASK \ - (IVT_PMON_RAW_EVENT_MASK | \ - SNBEP_PMON_CTL_EV_SEL_EXT) - /* NHM-EX event control */ #define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff #define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00 @@ -666,3 +508,9 @@ int ivb_uncore_pci_init(void); int hsw_uncore_pci_init(void); void snb_uncore_cpu_init(void); void nhm_uncore_cpu_init(void); + +/* perf_event_intel_uncore_snbep.c */ +int snbep_uncore_pci_init(void); +void snbep_uncore_cpu_init(void); +int ivt_uncore_pci_init(void); +void ivt_uncore_cpu_init(void); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c new file mode 100644 index 000000000000..30468f434e9e --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c @@ -0,0 +1,1644 @@ +/* SandyBridge-EP/IvyTown uncore support */ +#include "perf_event_intel_uncore.h" + + +/* SNB-EP Box level control */ +#define SNBEP_PMON_BOX_CTL_RST_CTRL (1 << 0) +#define SNBEP_PMON_BOX_CTL_RST_CTRS (1 << 1) +#define SNBEP_PMON_BOX_CTL_FRZ (1 << 8) +#define SNBEP_PMON_BOX_CTL_FRZ_EN (1 << 16) +#define SNBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ + SNBEP_PMON_BOX_CTL_RST_CTRS | \ + SNBEP_PMON_BOX_CTL_FRZ_EN) +/* SNB-EP event control */ +#define SNBEP_PMON_CTL_EV_SEL_MASK 0x000000ff +#define SNBEP_PMON_CTL_UMASK_MASK 0x0000ff00 +#define SNBEP_PMON_CTL_RST (1 << 17) +#define SNBEP_PMON_CTL_EDGE_DET (1 << 18) +#define SNBEP_PMON_CTL_EV_SEL_EXT (1 << 21) +#define SNBEP_PMON_CTL_EN (1 << 22) +#define SNBEP_PMON_CTL_INVERT (1 << 23) +#define SNBEP_PMON_CTL_TRESH_MASK 0xff000000 +#define SNBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PMON_CTL_UMASK_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_PMON_CTL_INVERT | \ + SNBEP_PMON_CTL_TRESH_MASK) + +/* SNB-EP Ubox event control */ +#define SNBEP_U_MSR_PMON_CTL_TRESH_MASK 0x1f000000 +#define SNBEP_U_MSR_PMON_RAW_EVENT_MASK \ + (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PMON_CTL_UMASK_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_PMON_CTL_INVERT | \ + SNBEP_U_MSR_PMON_CTL_TRESH_MASK) + +#define SNBEP_CBO_PMON_CTL_TID_EN (1 << 19) +#define SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK (SNBEP_PMON_RAW_EVENT_MASK | \ + SNBEP_CBO_PMON_CTL_TID_EN) + +/* SNB-EP PCU event control */ +#define SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK 0x0000c000 +#define SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK 0x1f000000 +#define SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT (1 << 30) +#define SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET (1 << 31) +#define SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ + (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_PMON_CTL_EV_SEL_EXT | \ + SNBEP_PMON_CTL_INVERT | \ + SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) + +#define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK \ + (SNBEP_PMON_RAW_EVENT_MASK | \ + SNBEP_PMON_CTL_EV_SEL_EXT) + +/* SNB-EP pci control register */ +#define SNBEP_PCI_PMON_BOX_CTL 0xf4 +#define SNBEP_PCI_PMON_CTL0 0xd8 +/* SNB-EP pci counter register */ +#define SNBEP_PCI_PMON_CTR0 0xa0 + +/* SNB-EP home agent register */ +#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH0 0x40 +#define SNBEP_HA_PCI_PMON_BOX_ADDRMATCH1 0x44 +#define SNBEP_HA_PCI_PMON_BOX_OPCODEMATCH 0x48 +/* SNB-EP memory controller register */ +#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTL 0xf0 +#define SNBEP_MC_CHy_PCI_PMON_FIXED_CTR 0xd0 +/* SNB-EP QPI register */ +#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH0 0x228 +#define SNBEP_Q_Py_PCI_PMON_PKT_MATCH1 0x22c +#define SNBEP_Q_Py_PCI_PMON_PKT_MASK0 0x238 +#define SNBEP_Q_Py_PCI_PMON_PKT_MASK1 0x23c + +/* SNB-EP Ubox register */ +#define SNBEP_U_MSR_PMON_CTR0 0xc16 +#define SNBEP_U_MSR_PMON_CTL0 0xc10 + +#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTL 0xc08 +#define SNBEP_U_MSR_PMON_UCLK_FIXED_CTR 0xc09 + +/* SNB-EP Cbo register */ +#define SNBEP_C0_MSR_PMON_CTR0 0xd16 +#define SNBEP_C0_MSR_PMON_CTL0 0xd10 +#define SNBEP_C0_MSR_PMON_BOX_CTL 0xd04 +#define SNBEP_C0_MSR_PMON_BOX_FILTER 0xd14 +#define SNBEP_CBO_MSR_OFFSET 0x20 + +#define SNBEP_CB0_MSR_PMON_BOX_FILTER_TID 0x1f +#define SNBEP_CB0_MSR_PMON_BOX_FILTER_NID 0x3fc00 +#define SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE 0x7c0000 +#define SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC 0xff800000 + +#define SNBEP_CBO_EVENT_EXTRA_REG(e, m, i) { \ + .event = (e), \ + .msr = SNBEP_C0_MSR_PMON_BOX_FILTER, \ + .config_mask = (m), \ + .idx = (i) \ +} + +/* SNB-EP PCU register */ +#define SNBEP_PCU_MSR_PMON_CTR0 0xc36 +#define SNBEP_PCU_MSR_PMON_CTL0 0xc30 +#define SNBEP_PCU_MSR_PMON_BOX_CTL 0xc24 +#define SNBEP_PCU_MSR_PMON_BOX_FILTER 0xc34 +#define SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK 0xffffffff +#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc +#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd + +/* IVT event control */ +#define IVT_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ + SNBEP_PMON_BOX_CTL_RST_CTRS) +#define IVT_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PMON_CTL_UMASK_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_PMON_CTL_TRESH_MASK) +/* IVT Ubox */ +#define IVT_U_MSR_PMON_GLOBAL_CTL 0xc00 +#define IVT_U_PMON_GLOBAL_FRZ_ALL (1 << 31) +#define IVT_U_PMON_GLOBAL_UNFRZ_ALL (1 << 29) + +#define IVT_U_MSR_PMON_RAW_EVENT_MASK \ + (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PMON_CTL_UMASK_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_U_MSR_PMON_CTL_TRESH_MASK) +/* IVT Cbo */ +#define IVT_CBO_MSR_PMON_RAW_EVENT_MASK (IVT_PMON_RAW_EVENT_MASK | \ + SNBEP_CBO_PMON_CTL_TID_EN) + +#define IVT_CB0_MSR_PMON_BOX_FILTER_TID (0x1fULL << 0) +#define IVT_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 5) +#define IVT_CB0_MSR_PMON_BOX_FILTER_STATE (0x3fULL << 17) +#define IVT_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32) +#define IVT_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52) +#define IVT_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61) +#define IVT_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62) +#define IVT_CB0_MSR_PMON_BOX_FILTER_IOSC (0x1ULL << 63) + +/* IVT home agent */ +#define IVT_HA_PCI_PMON_CTL_Q_OCC_RST (1 << 16) +#define IVT_HA_PCI_PMON_RAW_EVENT_MASK \ + (IVT_PMON_RAW_EVENT_MASK | \ + IVT_HA_PCI_PMON_CTL_Q_OCC_RST) +/* IVT PCU */ +#define IVT_PCU_MSR_PMON_RAW_EVENT_MASK \ + (SNBEP_PMON_CTL_EV_SEL_MASK | \ + SNBEP_PMON_CTL_EV_SEL_EXT | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ + SNBEP_PMON_CTL_EDGE_DET | \ + SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ + SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) +/* IVT QPI */ +#define IVT_QPI_PCI_PMON_RAW_EVENT_MASK \ + (IVT_PMON_RAW_EVENT_MASK | \ + SNBEP_PMON_CTL_EV_SEL_EXT) + +#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ + ((1ULL << (n)) - 1))) + +DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); +DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21"); +DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); +DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); +DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19"); +DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); +DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); +DEFINE_UNCORE_FORMAT_ATTR(thresh5, thresh, "config:24-28"); +DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15"); +DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30"); +DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51"); +DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4"); +DEFINE_UNCORE_FORMAT_ATTR(filter_link, filter_link, "config1:5-8"); +DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17"); +DEFINE_UNCORE_FORMAT_ATTR(filter_nid2, filter_nid, "config1:32-47"); +DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22"); +DEFINE_UNCORE_FORMAT_ATTR(filter_state2, filter_state, "config1:17-22"); +DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31"); +DEFINE_UNCORE_FORMAT_ATTR(filter_opc2, filter_opc, "config1:52-60"); +DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7"); +DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15"); +DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23"); +DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31"); +DEFINE_UNCORE_FORMAT_ATTR(match_rds, match_rds, "config1:48-51"); +DEFINE_UNCORE_FORMAT_ATTR(match_rnid30, match_rnid30, "config1:32-35"); +DEFINE_UNCORE_FORMAT_ATTR(match_rnid4, match_rnid4, "config1:31"); +DEFINE_UNCORE_FORMAT_ATTR(match_dnid, match_dnid, "config1:13-17"); +DEFINE_UNCORE_FORMAT_ATTR(match_mc, match_mc, "config1:9-12"); +DEFINE_UNCORE_FORMAT_ATTR(match_opc, match_opc, "config1:5-8"); +DEFINE_UNCORE_FORMAT_ATTR(match_vnw, match_vnw, "config1:3-4"); +DEFINE_UNCORE_FORMAT_ATTR(match0, match0, "config1:0-31"); +DEFINE_UNCORE_FORMAT_ATTR(match1, match1, "config1:32-63"); +DEFINE_UNCORE_FORMAT_ATTR(mask_rds, mask_rds, "config2:48-51"); +DEFINE_UNCORE_FORMAT_ATTR(mask_rnid30, mask_rnid30, "config2:32-35"); +DEFINE_UNCORE_FORMAT_ATTR(mask_rnid4, mask_rnid4, "config2:31"); +DEFINE_UNCORE_FORMAT_ATTR(mask_dnid, mask_dnid, "config2:13-17"); +DEFINE_UNCORE_FORMAT_ATTR(mask_mc, mask_mc, "config2:9-12"); +DEFINE_UNCORE_FORMAT_ATTR(mask_opc, mask_opc, "config2:5-8"); +DEFINE_UNCORE_FORMAT_ATTR(mask_vnw, mask_vnw, "config2:3-4"); +DEFINE_UNCORE_FORMAT_ATTR(mask0, mask0, "config2:0-31"); +DEFINE_UNCORE_FORMAT_ATTR(mask1, mask1, "config2:32-63"); + +static void snbep_uncore_pci_disable_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + int box_ctl = uncore_pci_box_ctl(box); + u32 config = 0; + + if (!pci_read_config_dword(pdev, box_ctl, &config)) { + config |= SNBEP_PMON_BOX_CTL_FRZ; + pci_write_config_dword(pdev, box_ctl, config); + } +} + +static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + int box_ctl = uncore_pci_box_ctl(box); + u32 config = 0; + + if (!pci_read_config_dword(pdev, box_ctl, &config)) { + config &= ~SNBEP_PMON_BOX_CTL_FRZ; + pci_write_config_dword(pdev, box_ctl, config); + } +} + +static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); +} + +static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, hwc->config_base, hwc->config); +} + +static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + u64 count = 0; + + pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count); + pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1); + + return count; +} + +static void snbep_uncore_pci_init_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + + pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, SNBEP_PMON_BOX_CTL_INT); +} + +static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box) +{ + u64 config; + unsigned msr; + + msr = uncore_msr_box_ctl(box); + if (msr) { + rdmsrl(msr, config); + config |= SNBEP_PMON_BOX_CTL_FRZ; + wrmsrl(msr, config); + } +} + +static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box) +{ + u64 config; + unsigned msr; + + msr = uncore_msr_box_ctl(box); + if (msr) { + rdmsrl(msr, config); + config &= ~SNBEP_PMON_BOX_CTL_FRZ; + wrmsrl(msr, config); + } +} + +static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + + if (reg1->idx != EXTRA_REG_NONE) + wrmsrl(reg1->reg, uncore_shared_reg_config(box, 0)); + + wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); +} + +static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box, + struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + wrmsrl(hwc->config_base, hwc->config); +} + +static void snbep_uncore_msr_init_box(struct intel_uncore_box *box) +{ + unsigned msr = uncore_msr_box_ctl(box); + + if (msr) + wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT); +} + +static struct attribute *snbep_uncore_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh8.attr, + NULL, +}; + +static struct attribute *snbep_uncore_ubox_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh5.attr, + NULL, +}; + +static struct attribute *snbep_uncore_cbox_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_tid_en.attr, + &format_attr_inv.attr, + &format_attr_thresh8.attr, + &format_attr_filter_tid.attr, + &format_attr_filter_nid.attr, + &format_attr_filter_state.attr, + &format_attr_filter_opc.attr, + NULL, +}; + +static struct attribute *snbep_uncore_pcu_formats_attr[] = { + &format_attr_event_ext.attr, + &format_attr_occ_sel.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh5.attr, + &format_attr_occ_invert.attr, + &format_attr_occ_edge.attr, + &format_attr_filter_band0.attr, + &format_attr_filter_band1.attr, + &format_attr_filter_band2.attr, + &format_attr_filter_band3.attr, + NULL, +}; + +static struct attribute *snbep_uncore_qpi_formats_attr[] = { + &format_attr_event_ext.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh8.attr, + &format_attr_match_rds.attr, + &format_attr_match_rnid30.attr, + &format_attr_match_rnid4.attr, + &format_attr_match_dnid.attr, + &format_attr_match_mc.attr, + &format_attr_match_opc.attr, + &format_attr_match_vnw.attr, + &format_attr_match0.attr, + &format_attr_match1.attr, + &format_attr_mask_rds.attr, + &format_attr_mask_rnid30.attr, + &format_attr_mask_rnid4.attr, + &format_attr_mask_dnid.attr, + &format_attr_mask_mc.attr, + &format_attr_mask_opc.attr, + &format_attr_mask_vnw.attr, + &format_attr_mask0.attr, + &format_attr_mask1.attr, + NULL, +}; + +static struct uncore_event_desc snbep_uncore_imc_events[] = { + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"), + INTEL_UNCORE_EVENT_DESC(cas_count_read, "event=0x04,umask=0x03"), + INTEL_UNCORE_EVENT_DESC(cas_count_write, "event=0x04,umask=0x0c"), + { /* end: all zeroes */ }, +}; + +static struct uncore_event_desc snbep_uncore_qpi_events[] = { + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x14"), + INTEL_UNCORE_EVENT_DESC(txl_flits_active, "event=0x00,umask=0x06"), + INTEL_UNCORE_EVENT_DESC(drs_data, "event=0x102,umask=0x08"), + INTEL_UNCORE_EVENT_DESC(ncb_data, "event=0x103,umask=0x04"), + { /* end: all zeroes */ }, +}; + +static struct attribute_group snbep_uncore_format_group = { + .name = "format", + .attrs = snbep_uncore_formats_attr, +}; + +static struct attribute_group snbep_uncore_ubox_format_group = { + .name = "format", + .attrs = snbep_uncore_ubox_formats_attr, +}; + +static struct attribute_group snbep_uncore_cbox_format_group = { + .name = "format", + .attrs = snbep_uncore_cbox_formats_attr, +}; + +static struct attribute_group snbep_uncore_pcu_format_group = { + .name = "format", + .attrs = snbep_uncore_pcu_formats_attr, +}; + +static struct attribute_group snbep_uncore_qpi_format_group = { + .name = "format", + .attrs = snbep_uncore_qpi_formats_attr, +}; + +#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \ + .init_box = snbep_uncore_msr_init_box, \ + .disable_box = snbep_uncore_msr_disable_box, \ + .enable_box = snbep_uncore_msr_enable_box, \ + .disable_event = snbep_uncore_msr_disable_event, \ + .enable_event = snbep_uncore_msr_enable_event, \ + .read_counter = uncore_msr_read_counter + +static struct intel_uncore_ops snbep_uncore_msr_ops = { + SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), +}; + +#define SNBEP_UNCORE_PCI_OPS_COMMON_INIT() \ + .init_box = snbep_uncore_pci_init_box, \ + .disable_box = snbep_uncore_pci_disable_box, \ + .enable_box = snbep_uncore_pci_enable_box, \ + .disable_event = snbep_uncore_pci_disable_event, \ + .read_counter = snbep_uncore_pci_read_counter + +static struct intel_uncore_ops snbep_uncore_pci_ops = { + SNBEP_UNCORE_PCI_OPS_COMMON_INIT(), + .enable_event = snbep_uncore_pci_enable_event, \ +}; + +static struct event_constraint snbep_uncore_cbox_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x01, 0x1), + UNCORE_EVENT_CONSTRAINT(0x02, 0x3), + UNCORE_EVENT_CONSTRAINT(0x04, 0x3), + UNCORE_EVENT_CONSTRAINT(0x05, 0x3), + UNCORE_EVENT_CONSTRAINT(0x07, 0x3), + UNCORE_EVENT_CONSTRAINT(0x09, 0x3), + UNCORE_EVENT_CONSTRAINT(0x11, 0x1), + UNCORE_EVENT_CONSTRAINT(0x12, 0x3), + UNCORE_EVENT_CONSTRAINT(0x13, 0x3), + UNCORE_EVENT_CONSTRAINT(0x1b, 0xc), + UNCORE_EVENT_CONSTRAINT(0x1c, 0xc), + UNCORE_EVENT_CONSTRAINT(0x1d, 0xc), + UNCORE_EVENT_CONSTRAINT(0x1e, 0xc), + EVENT_CONSTRAINT_OVERLAP(0x1f, 0xe, 0xff), + UNCORE_EVENT_CONSTRAINT(0x21, 0x3), + UNCORE_EVENT_CONSTRAINT(0x23, 0x3), + UNCORE_EVENT_CONSTRAINT(0x31, 0x3), + UNCORE_EVENT_CONSTRAINT(0x32, 0x3), + UNCORE_EVENT_CONSTRAINT(0x33, 0x3), + UNCORE_EVENT_CONSTRAINT(0x34, 0x3), + UNCORE_EVENT_CONSTRAINT(0x35, 0x3), + UNCORE_EVENT_CONSTRAINT(0x36, 0x1), + UNCORE_EVENT_CONSTRAINT(0x37, 0x3), + UNCORE_EVENT_CONSTRAINT(0x38, 0x3), + UNCORE_EVENT_CONSTRAINT(0x39, 0x3), + UNCORE_EVENT_CONSTRAINT(0x3b, 0x1), + EVENT_CONSTRAINT_END +}; + +static struct event_constraint snbep_uncore_r2pcie_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x10, 0x3), + UNCORE_EVENT_CONSTRAINT(0x11, 0x3), + UNCORE_EVENT_CONSTRAINT(0x12, 0x1), + UNCORE_EVENT_CONSTRAINT(0x23, 0x3), + UNCORE_EVENT_CONSTRAINT(0x24, 0x3), + UNCORE_EVENT_CONSTRAINT(0x25, 0x3), + UNCORE_EVENT_CONSTRAINT(0x26, 0x3), + UNCORE_EVENT_CONSTRAINT(0x32, 0x3), + UNCORE_EVENT_CONSTRAINT(0x33, 0x3), + UNCORE_EVENT_CONSTRAINT(0x34, 0x3), + EVENT_CONSTRAINT_END +}; + +static struct event_constraint snbep_uncore_r3qpi_constraints[] = { + UNCORE_EVENT_CONSTRAINT(0x10, 0x3), + UNCORE_EVENT_CONSTRAINT(0x11, 0x3), + UNCORE_EVENT_CONSTRAINT(0x12, 0x3), + UNCORE_EVENT_CONSTRAINT(0x13, 0x1), + UNCORE_EVENT_CONSTRAINT(0x20, 0x3), + UNCORE_EVENT_CONSTRAINT(0x21, 0x3), + UNCORE_EVENT_CONSTRAINT(0x22, 0x3), + UNCORE_EVENT_CONSTRAINT(0x23, 0x3), + UNCORE_EVENT_CONSTRAINT(0x24, 0x3), + UNCORE_EVENT_CONSTRAINT(0x25, 0x3), + UNCORE_EVENT_CONSTRAINT(0x26, 0x3), + UNCORE_EVENT_CONSTRAINT(0x28, 0x3), + UNCORE_EVENT_CONSTRAINT(0x29, 0x3), + UNCORE_EVENT_CONSTRAINT(0x2a, 0x3), + UNCORE_EVENT_CONSTRAINT(0x2b, 0x3), + UNCORE_EVENT_CONSTRAINT(0x2c, 0x3), + UNCORE_EVENT_CONSTRAINT(0x2d, 0x3), + UNCORE_EVENT_CONSTRAINT(0x2e, 0x3), + UNCORE_EVENT_CONSTRAINT(0x2f, 0x3), + UNCORE_EVENT_CONSTRAINT(0x30, 0x3), + UNCORE_EVENT_CONSTRAINT(0x31, 0x3), + UNCORE_EVENT_CONSTRAINT(0x32, 0x3), + UNCORE_EVENT_CONSTRAINT(0x33, 0x3), + UNCORE_EVENT_CONSTRAINT(0x34, 0x3), + UNCORE_EVENT_CONSTRAINT(0x36, 0x3), + UNCORE_EVENT_CONSTRAINT(0x37, 0x3), + UNCORE_EVENT_CONSTRAINT(0x38, 0x3), + UNCORE_EVENT_CONSTRAINT(0x39, 0x3), + EVENT_CONSTRAINT_END +}; + +static struct intel_uncore_type snbep_uncore_ubox = { + .name = "ubox", + .num_counters = 2, + .num_boxes = 1, + .perf_ctr_bits = 44, + .fixed_ctr_bits = 48, + .perf_ctr = SNBEP_U_MSR_PMON_CTR0, + .event_ctl = SNBEP_U_MSR_PMON_CTL0, + .event_mask = SNBEP_U_MSR_PMON_RAW_EVENT_MASK, + .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, + .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, + .ops = &snbep_uncore_msr_ops, + .format_group = &snbep_uncore_ubox_format_group, +}; + +static struct extra_reg snbep_uncore_cbox_extra_regs[] = { + SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, + SNBEP_CBO_PMON_CTL_TID_EN, 0x1), + SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), + SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0x6), + SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), + SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0x6), + SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), + SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0x6), + SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0x6), + SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0xa), + SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0xa), + SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x2), + SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x2), + SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x2), + SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x2), + SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0xa), + SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0xa), + SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x2), + SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x2), + SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x2), + SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x2), + EVENT_EXTRA_END +}; + +static void snbep_cbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct intel_uncore_extra_reg *er = &box->shared_regs[0]; + int i; + + if (uncore_box_is_fake(box)) + return; + + for (i = 0; i < 5; i++) { + if (reg1->alloc & (0x1 << i)) + atomic_sub(1 << (i * 6), &er->ref); + } + reg1->alloc = 0; +} + +static struct event_constraint * +__snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event, + u64 (*cbox_filter_mask)(int fields)) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct intel_uncore_extra_reg *er = &box->shared_regs[0]; + int i, alloc = 0; + unsigned long flags; + u64 mask; + + if (reg1->idx == EXTRA_REG_NONE) + return NULL; + + raw_spin_lock_irqsave(&er->lock, flags); + for (i = 0; i < 5; i++) { + if (!(reg1->idx & (0x1 << i))) + continue; + if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i))) + continue; + + mask = cbox_filter_mask(0x1 << i); + if (!__BITS_VALUE(atomic_read(&er->ref), i, 6) || + !((reg1->config ^ er->config) & mask)) { + atomic_add(1 << (i * 6), &er->ref); + er->config &= ~mask; + er->config |= reg1->config & mask; + alloc |= (0x1 << i); + } else { + break; + } + } + raw_spin_unlock_irqrestore(&er->lock, flags); + if (i < 5) + goto fail; + + if (!uncore_box_is_fake(box)) + reg1->alloc |= alloc; + + return NULL; +fail: + for (; i >= 0; i--) { + if (alloc & (0x1 << i)) + atomic_sub(1 << (i * 6), &er->ref); + } + return &uncore_constraint_empty; +} + +static u64 snbep_cbox_filter_mask(int fields) +{ + u64 mask = 0; + + if (fields & 0x1) + mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_TID; + if (fields & 0x2) + mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_NID; + if (fields & 0x4) + mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_STATE; + if (fields & 0x8) + mask |= SNBEP_CB0_MSR_PMON_BOX_FILTER_OPC; + + return mask; +} + +static struct event_constraint * +snbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + return __snbep_cbox_get_constraint(box, event, snbep_cbox_filter_mask); +} + +static int snbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct extra_reg *er; + int idx = 0; + + for (er = snbep_uncore_cbox_extra_regs; er->msr; er++) { + if (er->event != (event->hw.config & er->config_mask)) + continue; + idx |= er->idx; + } + + if (idx) { + reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + + SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; + reg1->config = event->attr.config1 & snbep_cbox_filter_mask(idx); + reg1->idx = idx; + } + return 0; +} + +static struct intel_uncore_ops snbep_uncore_cbox_ops = { + SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), + .hw_config = snbep_cbox_hw_config, + .get_constraint = snbep_cbox_get_constraint, + .put_constraint = snbep_cbox_put_constraint, +}; + +static struct intel_uncore_type snbep_uncore_cbox = { + .name = "cbox", + .num_counters = 4, + .num_boxes = 8, + .perf_ctr_bits = 44, + .event_ctl = SNBEP_C0_MSR_PMON_CTL0, + .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, + .event_mask = SNBEP_CBO_MSR_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, + .msr_offset = SNBEP_CBO_MSR_OFFSET, + .num_shared_regs = 1, + .constraints = snbep_uncore_cbox_constraints, + .ops = &snbep_uncore_cbox_ops, + .format_group = &snbep_uncore_cbox_format_group, +}; + +static u64 snbep_pcu_alter_er(struct perf_event *event, int new_idx, bool modify) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + u64 config = reg1->config; + + if (new_idx > reg1->idx) + config <<= 8 * (new_idx - reg1->idx); + else + config >>= 8 * (reg1->idx - new_idx); + + if (modify) { + hwc->config += new_idx - reg1->idx; + reg1->config = config; + reg1->idx = new_idx; + } + return config; +} + +static struct event_constraint * +snbep_pcu_get_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct intel_uncore_extra_reg *er = &box->shared_regs[0]; + unsigned long flags; + int idx = reg1->idx; + u64 mask, config1 = reg1->config; + bool ok = false; + + if (reg1->idx == EXTRA_REG_NONE || + (!uncore_box_is_fake(box) && reg1->alloc)) + return NULL; +again: + mask = 0xffULL << (idx * 8); + raw_spin_lock_irqsave(&er->lock, flags); + if (!__BITS_VALUE(atomic_read(&er->ref), idx, 8) || + !((config1 ^ er->config) & mask)) { + atomic_add(1 << (idx * 8), &er->ref); + er->config &= ~mask; + er->config |= config1 & mask; + ok = true; + } + raw_spin_unlock_irqrestore(&er->lock, flags); + + if (!ok) { + idx = (idx + 1) % 4; + if (idx != reg1->idx) { + config1 = snbep_pcu_alter_er(event, idx, false); + goto again; + } + return &uncore_constraint_empty; + } + + if (!uncore_box_is_fake(box)) { + if (idx != reg1->idx) + snbep_pcu_alter_er(event, idx, true); + reg1->alloc = 1; + } + return NULL; +} + +static void snbep_pcu_put_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct intel_uncore_extra_reg *er = &box->shared_regs[0]; + + if (uncore_box_is_fake(box) || !reg1->alloc) + return; + + atomic_sub(1 << (reg1->idx * 8), &er->ref); + reg1->alloc = 0; +} + +static int snbep_pcu_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + int ev_sel = hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK; + + if (ev_sel >= 0xb && ev_sel <= 0xe) { + reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER; + reg1->idx = ev_sel - 0xb; + reg1->config = event->attr.config1 & (0xff << reg1->idx); + } + return 0; +} + +static struct intel_uncore_ops snbep_uncore_pcu_ops = { + SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), + .hw_config = snbep_pcu_hw_config, + .get_constraint = snbep_pcu_get_constraint, + .put_constraint = snbep_pcu_put_constraint, +}; + +static struct intel_uncore_type snbep_uncore_pcu = { + .name = "pcu", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, + .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, + .event_mask = SNBEP_PCU_MSR_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, + .num_shared_regs = 1, + .ops = &snbep_uncore_pcu_ops, + .format_group = &snbep_uncore_pcu_format_group, +}; + +static struct intel_uncore_type *snbep_msr_uncores[] = { + &snbep_uncore_ubox, + &snbep_uncore_cbox, + &snbep_uncore_pcu, + NULL, +}; + +void snbep_uncore_cpu_init(void) +{ + if (snbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) + snbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; + uncore_msr_uncores = snbep_msr_uncores; +} + +enum { + SNBEP_PCI_QPI_PORT0_FILTER, + SNBEP_PCI_QPI_PORT1_FILTER, +}; + +static int snbep_qpi_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + + if ((hwc->config & SNBEP_PMON_CTL_EV_SEL_MASK) == 0x38) { + reg1->idx = 0; + reg1->reg = SNBEP_Q_Py_PCI_PMON_PKT_MATCH0; + reg1->config = event->attr.config1; + reg2->reg = SNBEP_Q_Py_PCI_PMON_PKT_MASK0; + reg2->config = event->attr.config2; + } + return 0; +} + +static void snbep_qpi_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + + if (reg1->idx != EXTRA_REG_NONE) { + int idx = box->pmu->pmu_idx + SNBEP_PCI_QPI_PORT0_FILTER; + struct pci_dev *filter_pdev = uncore_extra_pci_dev[box->phys_id][idx]; + WARN_ON_ONCE(!filter_pdev); + if (filter_pdev) { + pci_write_config_dword(filter_pdev, reg1->reg, + (u32)reg1->config); + pci_write_config_dword(filter_pdev, reg1->reg + 4, + (u32)(reg1->config >> 32)); + pci_write_config_dword(filter_pdev, reg2->reg, + (u32)reg2->config); + pci_write_config_dword(filter_pdev, reg2->reg + 4, + (u32)(reg2->config >> 32)); + } + } + + pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); +} + +static struct intel_uncore_ops snbep_uncore_qpi_ops = { + SNBEP_UNCORE_PCI_OPS_COMMON_INIT(), + .enable_event = snbep_qpi_enable_event, + .hw_config = snbep_qpi_hw_config, + .get_constraint = uncore_get_constraint, + .put_constraint = uncore_put_constraint, +}; + +#define SNBEP_UNCORE_PCI_COMMON_INIT() \ + .perf_ctr = SNBEP_PCI_PMON_CTR0, \ + .event_ctl = SNBEP_PCI_PMON_CTL0, \ + .event_mask = SNBEP_PMON_RAW_EVENT_MASK, \ + .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ + .ops = &snbep_uncore_pci_ops, \ + .format_group = &snbep_uncore_format_group + +static struct intel_uncore_type snbep_uncore_ha = { + .name = "ha", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type snbep_uncore_imc = { + .name = "imc", + .num_counters = 4, + .num_boxes = 4, + .perf_ctr_bits = 48, + .fixed_ctr_bits = 48, + .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, + .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, + .event_descs = snbep_uncore_imc_events, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type snbep_uncore_qpi = { + .name = "qpi", + .num_counters = 4, + .num_boxes = 2, + .perf_ctr_bits = 48, + .perf_ctr = SNBEP_PCI_PMON_CTR0, + .event_ctl = SNBEP_PCI_PMON_CTL0, + .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_PCI_PMON_BOX_CTL, + .num_shared_regs = 1, + .ops = &snbep_uncore_qpi_ops, + .event_descs = snbep_uncore_qpi_events, + .format_group = &snbep_uncore_qpi_format_group, +}; + + +static struct intel_uncore_type snbep_uncore_r2pcie = { + .name = "r2pcie", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 44, + .constraints = snbep_uncore_r2pcie_constraints, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type snbep_uncore_r3qpi = { + .name = "r3qpi", + .num_counters = 3, + .num_boxes = 2, + .perf_ctr_bits = 44, + .constraints = snbep_uncore_r3qpi_constraints, + SNBEP_UNCORE_PCI_COMMON_INIT(), +}; + +enum { + SNBEP_PCI_UNCORE_HA, + SNBEP_PCI_UNCORE_IMC, + SNBEP_PCI_UNCORE_QPI, + SNBEP_PCI_UNCORE_R2PCIE, + SNBEP_PCI_UNCORE_R3QPI, +}; + +static struct intel_uncore_type *snbep_pci_uncores[] = { + [SNBEP_PCI_UNCORE_HA] = &snbep_uncore_ha, + [SNBEP_PCI_UNCORE_IMC] = &snbep_uncore_imc, + [SNBEP_PCI_UNCORE_QPI] = &snbep_uncore_qpi, + [SNBEP_PCI_UNCORE_R2PCIE] = &snbep_uncore_r2pcie, + [SNBEP_PCI_UNCORE_R3QPI] = &snbep_uncore_r3qpi, + NULL, +}; + +static DEFINE_PCI_DEVICE_TABLE(snbep_uncore_pci_ids) = { + { /* Home Agent */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_HA), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_HA, 0), + }, + { /* MC Channel 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC0), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 0), + }, + { /* MC Channel 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC1), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 1), + }, + { /* MC Channel 2 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC2), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 2), + }, + { /* MC Channel 3 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_IMC3), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_IMC, 3), + }, + { /* QPI Port 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI0), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 0), + }, + { /* QPI Port 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_QPI1), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_QPI, 1), + }, + { /* R2PCIe */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R2PCIE), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R2PCIE, 0), + }, + { /* R3QPI Link 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI0), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 0), + }, + { /* R3QPI Link 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_UNC_R3QPI1), + .driver_data = UNCORE_PCI_DEV_DATA(SNBEP_PCI_UNCORE_R3QPI, 1), + }, + { /* QPI Port 0 filter */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c86), + .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, + SNBEP_PCI_QPI_PORT0_FILTER), + }, + { /* QPI Port 0 filter */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3c96), + .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, + SNBEP_PCI_QPI_PORT1_FILTER), + }, + { /* end: all zeroes */ } +}; + +static struct pci_driver snbep_uncore_pci_driver = { + .name = "snbep_uncore", + .id_table = snbep_uncore_pci_ids, +}; + +/* + * build pci bus to socket mapping + */ +static int snbep_pci2phy_map_init(int devid) +{ + struct pci_dev *ubox_dev = NULL; + int i, bus, nodeid; + int err = 0; + u32 config = 0; + + while (1) { + /* find the UBOX device */ + ubox_dev = pci_get_device(PCI_VENDOR_ID_INTEL, devid, ubox_dev); + if (!ubox_dev) + break; + bus = ubox_dev->bus->number; + /* get the Node ID of the local register */ + err = pci_read_config_dword(ubox_dev, 0x40, &config); + if (err) + break; + nodeid = config; + /* get the Node ID mapping */ + err = pci_read_config_dword(ubox_dev, 0x54, &config); + if (err) + break; + /* + * every three bits in the Node ID mapping register maps + * to a particular node. + */ + for (i = 0; i < 8; i++) { + if (nodeid == ((config >> (3 * i)) & 0x7)) { + uncore_pcibus_to_physid[bus] = i; + break; + } + } + } + + if (!err) { + /* + * For PCI bus with no UBOX device, find the next bus + * that has UBOX device and use its mapping. + */ + i = -1; + for (bus = 255; bus >= 0; bus--) { + if (uncore_pcibus_to_physid[bus] >= 0) + i = uncore_pcibus_to_physid[bus]; + else + uncore_pcibus_to_physid[bus] = i; + } + } + + if (ubox_dev) + pci_dev_put(ubox_dev); + + return err ? pcibios_err_to_errno(err) : 0; +} + +int snbep_uncore_pci_init(void) +{ + int ret = snbep_pci2phy_map_init(0x3ce0); + if (ret) + return ret; + uncore_pci_uncores = snbep_pci_uncores; + uncore_pci_driver = &snbep_uncore_pci_driver; + return 0; +} +/* end of Sandy Bridge-EP uncore support */ + +/* IvyTown uncore support */ +static void ivt_uncore_msr_init_box(struct intel_uncore_box *box) +{ + unsigned msr = uncore_msr_box_ctl(box); + if (msr) + wrmsrl(msr, IVT_PMON_BOX_CTL_INT); +} + +static void ivt_uncore_pci_init_box(struct intel_uncore_box *box) +{ + struct pci_dev *pdev = box->pci_dev; + + pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVT_PMON_BOX_CTL_INT); +} + +#define IVT_UNCORE_MSR_OPS_COMMON_INIT() \ + .init_box = ivt_uncore_msr_init_box, \ + .disable_box = snbep_uncore_msr_disable_box, \ + .enable_box = snbep_uncore_msr_enable_box, \ + .disable_event = snbep_uncore_msr_disable_event, \ + .enable_event = snbep_uncore_msr_enable_event, \ + .read_counter = uncore_msr_read_counter + +static struct intel_uncore_ops ivt_uncore_msr_ops = { + IVT_UNCORE_MSR_OPS_COMMON_INIT(), +}; + +static struct intel_uncore_ops ivt_uncore_pci_ops = { + .init_box = ivt_uncore_pci_init_box, + .disable_box = snbep_uncore_pci_disable_box, + .enable_box = snbep_uncore_pci_enable_box, + .disable_event = snbep_uncore_pci_disable_event, + .enable_event = snbep_uncore_pci_enable_event, + .read_counter = snbep_uncore_pci_read_counter, +}; + +#define IVT_UNCORE_PCI_COMMON_INIT() \ + .perf_ctr = SNBEP_PCI_PMON_CTR0, \ + .event_ctl = SNBEP_PCI_PMON_CTL0, \ + .event_mask = IVT_PMON_RAW_EVENT_MASK, \ + .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ + .ops = &ivt_uncore_pci_ops, \ + .format_group = &ivt_uncore_format_group + +static struct attribute *ivt_uncore_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh8.attr, + NULL, +}; + +static struct attribute *ivt_uncore_ubox_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh5.attr, + NULL, +}; + +static struct attribute *ivt_uncore_cbox_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_tid_en.attr, + &format_attr_thresh8.attr, + &format_attr_filter_tid.attr, + &format_attr_filter_link.attr, + &format_attr_filter_state2.attr, + &format_attr_filter_nid2.attr, + &format_attr_filter_opc2.attr, + NULL, +}; + +static struct attribute *ivt_uncore_pcu_formats_attr[] = { + &format_attr_event_ext.attr, + &format_attr_occ_sel.attr, + &format_attr_edge.attr, + &format_attr_thresh5.attr, + &format_attr_occ_invert.attr, + &format_attr_occ_edge.attr, + &format_attr_filter_band0.attr, + &format_attr_filter_band1.attr, + &format_attr_filter_band2.attr, + &format_attr_filter_band3.attr, + NULL, +}; + +static struct attribute *ivt_uncore_qpi_formats_attr[] = { + &format_attr_event_ext.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_thresh8.attr, + &format_attr_match_rds.attr, + &format_attr_match_rnid30.attr, + &format_attr_match_rnid4.attr, + &format_attr_match_dnid.attr, + &format_attr_match_mc.attr, + &format_attr_match_opc.attr, + &format_attr_match_vnw.attr, + &format_attr_match0.attr, + &format_attr_match1.attr, + &format_attr_mask_rds.attr, + &format_attr_mask_rnid30.attr, + &format_attr_mask_rnid4.attr, + &format_attr_mask_dnid.attr, + &format_attr_mask_mc.attr, + &format_attr_mask_opc.attr, + &format_attr_mask_vnw.attr, + &format_attr_mask0.attr, + &format_attr_mask1.attr, + NULL, +}; + +static struct attribute_group ivt_uncore_format_group = { + .name = "format", + .attrs = ivt_uncore_formats_attr, +}; + +static struct attribute_group ivt_uncore_ubox_format_group = { + .name = "format", + .attrs = ivt_uncore_ubox_formats_attr, +}; + +static struct attribute_group ivt_uncore_cbox_format_group = { + .name = "format", + .attrs = ivt_uncore_cbox_formats_attr, +}; + +static struct attribute_group ivt_uncore_pcu_format_group = { + .name = "format", + .attrs = ivt_uncore_pcu_formats_attr, +}; + +static struct attribute_group ivt_uncore_qpi_format_group = { + .name = "format", + .attrs = ivt_uncore_qpi_formats_attr, +}; + +static struct intel_uncore_type ivt_uncore_ubox = { + .name = "ubox", + .num_counters = 2, + .num_boxes = 1, + .perf_ctr_bits = 44, + .fixed_ctr_bits = 48, + .perf_ctr = SNBEP_U_MSR_PMON_CTR0, + .event_ctl = SNBEP_U_MSR_PMON_CTL0, + .event_mask = IVT_U_MSR_PMON_RAW_EVENT_MASK, + .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, + .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, + .ops = &ivt_uncore_msr_ops, + .format_group = &ivt_uncore_ubox_format_group, +}; + +static struct extra_reg ivt_uncore_cbox_extra_regs[] = { + SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, + SNBEP_CBO_PMON_CTL_TID_EN, 0x1), + SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), + SNBEP_CBO_EVENT_EXTRA_REG(0x1134, 0xffff, 0x4), + SNBEP_CBO_EVENT_EXTRA_REG(0x4134, 0xffff, 0xc), + SNBEP_CBO_EVENT_EXTRA_REG(0x5134, 0xffff, 0xc), + SNBEP_CBO_EVENT_EXTRA_REG(0x0334, 0xffff, 0x4), + SNBEP_CBO_EVENT_EXTRA_REG(0x4334, 0xffff, 0xc), + SNBEP_CBO_EVENT_EXTRA_REG(0x0534, 0xffff, 0x4), + SNBEP_CBO_EVENT_EXTRA_REG(0x4534, 0xffff, 0xc), + SNBEP_CBO_EVENT_EXTRA_REG(0x0934, 0xffff, 0x4), + SNBEP_CBO_EVENT_EXTRA_REG(0x4934, 0xffff, 0xc), + SNBEP_CBO_EVENT_EXTRA_REG(0x0135, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x0335, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x2135, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x2335, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x4135, 0xffff, 0x18), + SNBEP_CBO_EVENT_EXTRA_REG(0x4335, 0xffff, 0x18), + SNBEP_CBO_EVENT_EXTRA_REG(0x4435, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x4835, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x4a35, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x5035, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x8135, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x8335, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x0136, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x0336, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x2136, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x2336, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x4136, 0xffff, 0x18), + SNBEP_CBO_EVENT_EXTRA_REG(0x4336, 0xffff, 0x18), + SNBEP_CBO_EVENT_EXTRA_REG(0x4436, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x4836, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x4a36, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x5036, 0xffff, 0x8), + SNBEP_CBO_EVENT_EXTRA_REG(0x8136, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x8336, 0xffff, 0x10), + SNBEP_CBO_EVENT_EXTRA_REG(0x4037, 0x40ff, 0x8), + EVENT_EXTRA_END +}; + +static u64 ivt_cbox_filter_mask(int fields) +{ + u64 mask = 0; + + if (fields & 0x1) + mask |= IVT_CB0_MSR_PMON_BOX_FILTER_TID; + if (fields & 0x2) + mask |= IVT_CB0_MSR_PMON_BOX_FILTER_LINK; + if (fields & 0x4) + mask |= IVT_CB0_MSR_PMON_BOX_FILTER_STATE; + if (fields & 0x8) + mask |= IVT_CB0_MSR_PMON_BOX_FILTER_NID; + if (fields & 0x10) + mask |= IVT_CB0_MSR_PMON_BOX_FILTER_OPC; + + return mask; +} + +static struct event_constraint * +ivt_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + return __snbep_cbox_get_constraint(box, event, ivt_cbox_filter_mask); +} + +static int ivt_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct extra_reg *er; + int idx = 0; + + for (er = ivt_uncore_cbox_extra_regs; er->msr; er++) { + if (er->event != (event->hw.config & er->config_mask)) + continue; + idx |= er->idx; + } + + if (idx) { + reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + + SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; + reg1->config = event->attr.config1 & ivt_cbox_filter_mask(idx); + reg1->idx = idx; + } + return 0; +} + +static void ivt_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + + if (reg1->idx != EXTRA_REG_NONE) { + u64 filter = uncore_shared_reg_config(box, 0); + wrmsrl(reg1->reg, filter & 0xffffffff); + wrmsrl(reg1->reg + 6, filter >> 32); + } + + wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); +} + +static struct intel_uncore_ops ivt_uncore_cbox_ops = { + .init_box = ivt_uncore_msr_init_box, + .disable_box = snbep_uncore_msr_disable_box, + .enable_box = snbep_uncore_msr_enable_box, + .disable_event = snbep_uncore_msr_disable_event, + .enable_event = ivt_cbox_enable_event, + .read_counter = uncore_msr_read_counter, + .hw_config = ivt_cbox_hw_config, + .get_constraint = ivt_cbox_get_constraint, + .put_constraint = snbep_cbox_put_constraint, +}; + +static struct intel_uncore_type ivt_uncore_cbox = { + .name = "cbox", + .num_counters = 4, + .num_boxes = 15, + .perf_ctr_bits = 44, + .event_ctl = SNBEP_C0_MSR_PMON_CTL0, + .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, + .event_mask = IVT_CBO_MSR_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, + .msr_offset = SNBEP_CBO_MSR_OFFSET, + .num_shared_regs = 1, + .constraints = snbep_uncore_cbox_constraints, + .ops = &ivt_uncore_cbox_ops, + .format_group = &ivt_uncore_cbox_format_group, +}; + +static struct intel_uncore_ops ivt_uncore_pcu_ops = { + IVT_UNCORE_MSR_OPS_COMMON_INIT(), + .hw_config = snbep_pcu_hw_config, + .get_constraint = snbep_pcu_get_constraint, + .put_constraint = snbep_pcu_put_constraint, +}; + +static struct intel_uncore_type ivt_uncore_pcu = { + .name = "pcu", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, + .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, + .event_mask = IVT_PCU_MSR_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, + .num_shared_regs = 1, + .ops = &ivt_uncore_pcu_ops, + .format_group = &ivt_uncore_pcu_format_group, +}; + +static struct intel_uncore_type *ivt_msr_uncores[] = { + &ivt_uncore_ubox, + &ivt_uncore_cbox, + &ivt_uncore_pcu, + NULL, +}; + +void ivt_uncore_cpu_init(void) +{ + if (ivt_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) + ivt_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; + uncore_msr_uncores = ivt_msr_uncores; +} + +static struct intel_uncore_type ivt_uncore_ha = { + .name = "ha", + .num_counters = 4, + .num_boxes = 2, + .perf_ctr_bits = 48, + IVT_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type ivt_uncore_imc = { + .name = "imc", + .num_counters = 4, + .num_boxes = 8, + .perf_ctr_bits = 48, + .fixed_ctr_bits = 48, + .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, + .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, + IVT_UNCORE_PCI_COMMON_INIT(), +}; + +/* registers in IRP boxes are not properly aligned */ +static unsigned ivt_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4}; +static unsigned ivt_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0}; + +static void ivt_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], + hwc->config | SNBEP_PMON_CTL_EN); +} + +static void ivt_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + + pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], hwc->config); +} + +static u64 ivt_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event) +{ + struct pci_dev *pdev = box->pci_dev; + struct hw_perf_event *hwc = &event->hw; + u64 count = 0; + + pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx], (u32 *)&count); + pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1); + + return count; +} + +static struct intel_uncore_ops ivt_uncore_irp_ops = { + .init_box = ivt_uncore_pci_init_box, + .disable_box = snbep_uncore_pci_disable_box, + .enable_box = snbep_uncore_pci_enable_box, + .disable_event = ivt_uncore_irp_disable_event, + .enable_event = ivt_uncore_irp_enable_event, + .read_counter = ivt_uncore_irp_read_counter, +}; + +static struct intel_uncore_type ivt_uncore_irp = { + .name = "irp", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + .event_mask = IVT_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_PCI_PMON_BOX_CTL, + .ops = &ivt_uncore_irp_ops, + .format_group = &ivt_uncore_format_group, +}; + +static struct intel_uncore_ops ivt_uncore_qpi_ops = { + .init_box = ivt_uncore_pci_init_box, + .disable_box = snbep_uncore_pci_disable_box, + .enable_box = snbep_uncore_pci_enable_box, + .disable_event = snbep_uncore_pci_disable_event, + .enable_event = snbep_qpi_enable_event, + .read_counter = snbep_uncore_pci_read_counter, + .hw_config = snbep_qpi_hw_config, + .get_constraint = uncore_get_constraint, + .put_constraint = uncore_put_constraint, +}; + +static struct intel_uncore_type ivt_uncore_qpi = { + .name = "qpi", + .num_counters = 4, + .num_boxes = 3, + .perf_ctr_bits = 48, + .perf_ctr = SNBEP_PCI_PMON_CTR0, + .event_ctl = SNBEP_PCI_PMON_CTL0, + .event_mask = IVT_QPI_PCI_PMON_RAW_EVENT_MASK, + .box_ctl = SNBEP_PCI_PMON_BOX_CTL, + .num_shared_regs = 1, + .ops = &ivt_uncore_qpi_ops, + .format_group = &ivt_uncore_qpi_format_group, +}; + +static struct intel_uncore_type ivt_uncore_r2pcie = { + .name = "r2pcie", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 44, + .constraints = snbep_uncore_r2pcie_constraints, + IVT_UNCORE_PCI_COMMON_INIT(), +}; + +static struct intel_uncore_type ivt_uncore_r3qpi = { + .name = "r3qpi", + .num_counters = 3, + .num_boxes = 2, + .perf_ctr_bits = 44, + .constraints = snbep_uncore_r3qpi_constraints, + IVT_UNCORE_PCI_COMMON_INIT(), +}; + +enum { + IVT_PCI_UNCORE_HA, + IVT_PCI_UNCORE_IMC, + IVT_PCI_UNCORE_IRP, + IVT_PCI_UNCORE_QPI, + IVT_PCI_UNCORE_R2PCIE, + IVT_PCI_UNCORE_R3QPI, +}; + +static struct intel_uncore_type *ivt_pci_uncores[] = { + [IVT_PCI_UNCORE_HA] = &ivt_uncore_ha, + [IVT_PCI_UNCORE_IMC] = &ivt_uncore_imc, + [IVT_PCI_UNCORE_IRP] = &ivt_uncore_irp, + [IVT_PCI_UNCORE_QPI] = &ivt_uncore_qpi, + [IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie, + [IVT_PCI_UNCORE_R3QPI] = &ivt_uncore_r3qpi, + NULL, +}; + +static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { + { /* Home Agent 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 0), + }, + { /* Home Agent 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 1), + }, + { /* MC0 Channel 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 0), + }, + { /* MC0 Channel 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 1), + }, + { /* MC0 Channel 3 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 2), + }, + { /* MC0 Channel 4 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 3), + }, + { /* MC1 Channel 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 4), + }, + { /* MC1 Channel 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 5), + }, + { /* MC1 Channel 3 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 6), + }, + { /* MC1 Channel 4 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7), + }, + { /* IRP */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IRP, 0), + }, + { /* QPI0 Port 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0), + }, + { /* QPI0 Port 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 1), + }, + { /* QPI1 Port 2 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 2), + }, + { /* R2PCIe */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R2PCIE, 0), + }, + { /* R3QPI0 Link 0 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 0), + }, + { /* R3QPI0 Link 1 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 1), + }, + { /* R3QPI1 Link 2 */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), + .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2), + }, + { /* QPI Port 0 filter */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86), + .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, + SNBEP_PCI_QPI_PORT0_FILTER), + }, + { /* QPI Port 0 filter */ + PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe96), + .driver_data = UNCORE_PCI_DEV_DATA(UNCORE_EXTRA_PCI_DEV, + SNBEP_PCI_QPI_PORT1_FILTER), + }, + { /* end: all zeroes */ } +}; + +static struct pci_driver ivt_uncore_pci_driver = { + .name = "ivt_uncore", + .id_table = ivt_uncore_pci_ids, +}; + +int ivt_uncore_pci_init(void) +{ + int ret = snbep_pci2phy_map_init(0x0e1e); + if (ret) + return ret; + uncore_pci_uncores = ivt_pci_uncores; + uncore_pci_driver = &ivt_uncore_pci_driver; + return 0; +} +/* end of IvyTown uncore support */ -- GitLab From c1e46580c3b7bf25053519cf39f01a2f9ea4d865 Mon Sep 17 00:00:00 2001 From: "Yan, Zheng" Date: Wed, 30 Jul 2014 15:22:15 +0800 Subject: [PATCH 0269/9167] perf/x86/uncore: move NHM-EX/WSM-EX specific code to seperate file Signed-off-by: Yan, Zheng Signed-off-by: Peter Zijlstra Cc: Andi Kleen Cc: Arnaldo Carvalho de Melo Cc: Borislav Petkov Cc: Paul Mackerras Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406704935-27708-4-git-send-email-zheng.z.yan@intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/Makefile | 2 +- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 1038 +------------- arch/x86/kernel/cpu/perf_event_intel_uncore.h | 185 +-- .../cpu/perf_event_intel_uncore_nhmex.c | 1221 +++++++++++++++++ 4 files changed, 1227 insertions(+), 1219 deletions(-) create mode 100644 arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 7dee8664573a..7e1fd4e08552 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -37,7 +37,7 @@ endif obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_p6.o perf_event_knc.o perf_event_p4.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_lbr.o perf_event_intel_ds.o perf_event_intel.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore.o perf_event_intel_uncore_snb.o -obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore_snbep.o +obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_uncore_snbep.o perf_event_intel_uncore_nhmex.o obj-$(CONFIG_CPU_SUP_INTEL) += perf_event_intel_rapl.o endif diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index cf6966a37580..b1f84d9ccc48 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -28,15 +28,6 @@ ssize_t uncore_event_show(struct kobject *kobj, return sprintf(buf, "%s", event->config); } -#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ - ((1ULL << (n)) - 1))) - -DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); -DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); -DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); -DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); -DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); - struct intel_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) { return container_of(event->pmu, struct intel_uncore_pmu, pmu); @@ -158,1025 +149,6 @@ u64 uncore_shared_reg_config(struct intel_uncore_box *box, int idx) return config; } -/* Nehalem-EX uncore support */ -DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); -DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); -DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); -DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63"); - -static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box) -{ - wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL); -} - -static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box) -{ - unsigned msr = uncore_msr_box_ctl(box); - u64 config; - - if (msr) { - rdmsrl(msr, config); - config &= ~((1ULL << uncore_num_counters(box)) - 1); - /* WBox has a fixed counter */ - if (uncore_msr_fixed_ctl(box)) - config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN; - wrmsrl(msr, config); - } -} - -static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box) -{ - unsigned msr = uncore_msr_box_ctl(box); - u64 config; - - if (msr) { - rdmsrl(msr, config); - config |= (1ULL << uncore_num_counters(box)) - 1; - /* WBox has a fixed counter */ - if (uncore_msr_fixed_ctl(box)) - config |= NHMEX_W_PMON_GLOBAL_FIXED_EN; - wrmsrl(msr, config); - } -} - -static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - wrmsrl(event->hw.config_base, 0); -} - -static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - - if (hwc->idx >= UNCORE_PMC_IDX_FIXED) - wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0); - else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0) - wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); - else - wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); -} - -#define NHMEX_UNCORE_OPS_COMMON_INIT() \ - .init_box = nhmex_uncore_msr_init_box, \ - .disable_box = nhmex_uncore_msr_disable_box, \ - .enable_box = nhmex_uncore_msr_enable_box, \ - .disable_event = nhmex_uncore_msr_disable_event, \ - .read_counter = uncore_msr_read_counter - -static struct intel_uncore_ops nhmex_uncore_ops = { - NHMEX_UNCORE_OPS_COMMON_INIT(), - .enable_event = nhmex_uncore_msr_enable_event, -}; - -static struct attribute *nhmex_uncore_ubox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_edge.attr, - NULL, -}; - -static struct attribute_group nhmex_uncore_ubox_format_group = { - .name = "format", - .attrs = nhmex_uncore_ubox_formats_attr, -}; - -static struct intel_uncore_type nhmex_uncore_ubox = { - .name = "ubox", - .num_counters = 1, - .num_boxes = 1, - .perf_ctr_bits = 48, - .event_ctl = NHMEX_U_MSR_PMON_EV_SEL, - .perf_ctr = NHMEX_U_MSR_PMON_CTR, - .event_mask = NHMEX_U_PMON_RAW_EVENT_MASK, - .box_ctl = NHMEX_U_MSR_PMON_GLOBAL_CTL, - .ops = &nhmex_uncore_ops, - .format_group = &nhmex_uncore_ubox_format_group -}; - -static struct attribute *nhmex_uncore_cbox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - NULL, -}; - -static struct attribute_group nhmex_uncore_cbox_format_group = { - .name = "format", - .attrs = nhmex_uncore_cbox_formats_attr, -}; - -/* msr offset for each instance of cbox */ -static unsigned nhmex_cbox_msr_offsets[] = { - 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0, -}; - -static struct intel_uncore_type nhmex_uncore_cbox = { - .name = "cbox", - .num_counters = 6, - .num_boxes = 10, - .perf_ctr_bits = 48, - .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, - .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, - .event_mask = NHMEX_PMON_RAW_EVENT_MASK, - .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, - .msr_offsets = nhmex_cbox_msr_offsets, - .pair_ctr_ctl = 1, - .ops = &nhmex_uncore_ops, - .format_group = &nhmex_uncore_cbox_format_group -}; - -static struct uncore_event_desc nhmex_uncore_wbox_events[] = { - INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"), - { /* end: all zeroes */ }, -}; - -static struct intel_uncore_type nhmex_uncore_wbox = { - .name = "wbox", - .num_counters = 4, - .num_boxes = 1, - .perf_ctr_bits = 48, - .event_ctl = NHMEX_W_MSR_PMON_CNT0, - .perf_ctr = NHMEX_W_MSR_PMON_EVT_SEL0, - .fixed_ctr = NHMEX_W_MSR_PMON_FIXED_CTR, - .fixed_ctl = NHMEX_W_MSR_PMON_FIXED_CTL, - .event_mask = NHMEX_PMON_RAW_EVENT_MASK, - .box_ctl = NHMEX_W_MSR_GLOBAL_CTL, - .pair_ctr_ctl = 1, - .event_descs = nhmex_uncore_wbox_events, - .ops = &nhmex_uncore_ops, - .format_group = &nhmex_uncore_cbox_format_group -}; - -static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - int ctr, ev_sel; - - ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >> - NHMEX_B_PMON_CTR_SHIFT; - ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >> - NHMEX_B_PMON_CTL_EV_SEL_SHIFT; - - /* events that do not use the match/mask registers */ - if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) || - (ctr == 2 && ev_sel != 0x4) || ctr == 3) - return 0; - - if (box->pmu->pmu_idx == 0) - reg1->reg = NHMEX_B0_MSR_MATCH; - else - reg1->reg = NHMEX_B1_MSR_MATCH; - reg1->idx = 0; - reg1->config = event->attr.config1; - reg2->config = event->attr.config2; - return 0; -} - -static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - - if (reg1->idx != EXTRA_REG_NONE) { - wrmsrl(reg1->reg, reg1->config); - wrmsrl(reg1->reg + 1, reg2->config); - } - wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | - (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK)); -} - -/* - * The Bbox has 4 counters, but each counter monitors different events. - * Use bits 6-7 in the event config to select counter. - */ -static struct event_constraint nhmex_uncore_bbox_constraints[] = { - EVENT_CONSTRAINT(0 , 1, 0xc0), - EVENT_CONSTRAINT(0x40, 2, 0xc0), - EVENT_CONSTRAINT(0x80, 4, 0xc0), - EVENT_CONSTRAINT(0xc0, 8, 0xc0), - EVENT_CONSTRAINT_END, -}; - -static struct attribute *nhmex_uncore_bbox_formats_attr[] = { - &format_attr_event5.attr, - &format_attr_counter.attr, - &format_attr_match.attr, - &format_attr_mask.attr, - NULL, -}; - -static struct attribute_group nhmex_uncore_bbox_format_group = { - .name = "format", - .attrs = nhmex_uncore_bbox_formats_attr, -}; - -static struct intel_uncore_ops nhmex_uncore_bbox_ops = { - NHMEX_UNCORE_OPS_COMMON_INIT(), - .enable_event = nhmex_bbox_msr_enable_event, - .hw_config = nhmex_bbox_hw_config, - .get_constraint = uncore_get_constraint, - .put_constraint = uncore_put_constraint, -}; - -static struct intel_uncore_type nhmex_uncore_bbox = { - .name = "bbox", - .num_counters = 4, - .num_boxes = 2, - .perf_ctr_bits = 48, - .event_ctl = NHMEX_B0_MSR_PMON_CTL0, - .perf_ctr = NHMEX_B0_MSR_PMON_CTR0, - .event_mask = NHMEX_B_PMON_RAW_EVENT_MASK, - .box_ctl = NHMEX_B0_MSR_PMON_GLOBAL_CTL, - .msr_offset = NHMEX_B_MSR_OFFSET, - .pair_ctr_ctl = 1, - .num_shared_regs = 1, - .constraints = nhmex_uncore_bbox_constraints, - .ops = &nhmex_uncore_bbox_ops, - .format_group = &nhmex_uncore_bbox_format_group -}; - -static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - - /* only TO_R_PROG_EV event uses the match/mask register */ - if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) != - NHMEX_S_EVENT_TO_R_PROG_EV) - return 0; - - if (box->pmu->pmu_idx == 0) - reg1->reg = NHMEX_S0_MSR_MM_CFG; - else - reg1->reg = NHMEX_S1_MSR_MM_CFG; - reg1->idx = 0; - reg1->config = event->attr.config1; - reg2->config = event->attr.config2; - return 0; -} - -static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - - if (reg1->idx != EXTRA_REG_NONE) { - wrmsrl(reg1->reg, 0); - wrmsrl(reg1->reg + 1, reg1->config); - wrmsrl(reg1->reg + 2, reg2->config); - wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN); - } - wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); -} - -static struct attribute *nhmex_uncore_sbox_formats_attr[] = { - &format_attr_event.attr, - &format_attr_umask.attr, - &format_attr_edge.attr, - &format_attr_inv.attr, - &format_attr_thresh8.attr, - &format_attr_match.attr, - &format_attr_mask.attr, - NULL, -}; - -static struct attribute_group nhmex_uncore_sbox_format_group = { - .name = "format", - .attrs = nhmex_uncore_sbox_formats_attr, -}; - -static struct intel_uncore_ops nhmex_uncore_sbox_ops = { - NHMEX_UNCORE_OPS_COMMON_INIT(), - .enable_event = nhmex_sbox_msr_enable_event, - .hw_config = nhmex_sbox_hw_config, - .get_constraint = uncore_get_constraint, - .put_constraint = uncore_put_constraint, -}; - -static struct intel_uncore_type nhmex_uncore_sbox = { - .name = "sbox", - .num_counters = 4, - .num_boxes = 2, - .perf_ctr_bits = 48, - .event_ctl = NHMEX_S0_MSR_PMON_CTL0, - .perf_ctr = NHMEX_S0_MSR_PMON_CTR0, - .event_mask = NHMEX_PMON_RAW_EVENT_MASK, - .box_ctl = NHMEX_S0_MSR_PMON_GLOBAL_CTL, - .msr_offset = NHMEX_S_MSR_OFFSET, - .pair_ctr_ctl = 1, - .num_shared_regs = 1, - .ops = &nhmex_uncore_sbox_ops, - .format_group = &nhmex_uncore_sbox_format_group -}; - -enum { - EXTRA_REG_NHMEX_M_FILTER, - EXTRA_REG_NHMEX_M_DSP, - EXTRA_REG_NHMEX_M_ISS, - EXTRA_REG_NHMEX_M_MAP, - EXTRA_REG_NHMEX_M_MSC_THR, - EXTRA_REG_NHMEX_M_PGT, - EXTRA_REG_NHMEX_M_PLD, - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC, -}; - -static struct extra_reg nhmex_uncore_mbox_extra_regs[] = { - MBOX_INC_SEL_EXTAR_REG(0x0, DSP), - MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR), - MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR), - MBOX_INC_SEL_EXTAR_REG(0x9, ISS), - /* event 0xa uses two extra registers */ - MBOX_INC_SEL_EXTAR_REG(0xa, ISS), - MBOX_INC_SEL_EXTAR_REG(0xa, PLD), - MBOX_INC_SEL_EXTAR_REG(0xb, PLD), - /* events 0xd ~ 0x10 use the same extra register */ - MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC), - MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC), - MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC), - MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC), - MBOX_INC_SEL_EXTAR_REG(0x16, PGT), - MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP), - MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS), - MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT), - MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP), - EVENT_EXTRA_END -}; - -/* Nehalem-EX or Westmere-EX ? */ -static bool uncore_nhmex; - -static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) -{ - struct intel_uncore_extra_reg *er; - unsigned long flags; - bool ret = false; - u64 mask; - - if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { - er = &box->shared_regs[idx]; - raw_spin_lock_irqsave(&er->lock, flags); - if (!atomic_read(&er->ref) || er->config == config) { - atomic_inc(&er->ref); - er->config = config; - ret = true; - } - raw_spin_unlock_irqrestore(&er->lock, flags); - - return ret; - } - /* - * The ZDP_CTL_FVC MSR has 4 fields which are used to control - * events 0xd ~ 0x10. Besides these 4 fields, there are additional - * fields which are shared. - */ - idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; - if (WARN_ON_ONCE(idx >= 4)) - return false; - - /* mask of the shared fields */ - if (uncore_nhmex) - mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; - else - mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK; - er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; - - raw_spin_lock_irqsave(&er->lock, flags); - /* add mask of the non-shared field if it's in use */ - if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) { - if (uncore_nhmex) - mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); - else - mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); - } - - if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { - atomic_add(1 << (idx * 8), &er->ref); - if (uncore_nhmex) - mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | - NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); - else - mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK | - WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); - er->config &= ~mask; - er->config |= (config & mask); - ret = true; - } - raw_spin_unlock_irqrestore(&er->lock, flags); - - return ret; -} - -static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx) -{ - struct intel_uncore_extra_reg *er; - - if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { - er = &box->shared_regs[idx]; - atomic_dec(&er->ref); - return; - } - - idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; - er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; - atomic_sub(1 << (idx * 8), &er->ref); -} - -static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8); - u64 config = reg1->config; - - /* get the non-shared control bits and shift them */ - idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; - if (uncore_nhmex) - config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); - else - config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); - if (new_idx > orig_idx) { - idx = new_idx - orig_idx; - config <<= 3 * idx; - } else { - idx = orig_idx - new_idx; - config >>= 3 * idx; - } - - /* add the shared control bits back */ - if (uncore_nhmex) - config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; - else - config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; - config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; - if (modify) { - /* adjust the main event selector */ - if (new_idx > orig_idx) - hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT; - else - hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT; - reg1->config = config; - reg1->idx = ~0xff | new_idx; - } - return config; -} - -static struct event_constraint * -nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; - int i, idx[2], alloc = 0; - u64 config1 = reg1->config; - - idx[0] = __BITS_VALUE(reg1->idx, 0, 8); - idx[1] = __BITS_VALUE(reg1->idx, 1, 8); -again: - for (i = 0; i < 2; i++) { - if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i))) - idx[i] = 0xff; - - if (idx[i] == 0xff) - continue; - - if (!nhmex_mbox_get_shared_reg(box, idx[i], - __BITS_VALUE(config1, i, 32))) - goto fail; - alloc |= (0x1 << i); - } - - /* for the match/mask registers */ - if (reg2->idx != EXTRA_REG_NONE && - (uncore_box_is_fake(box) || !reg2->alloc) && - !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config)) - goto fail; - - /* - * If it's a fake box -- as per validate_{group,event}() we - * shouldn't touch event state and we can avoid doing so - * since both will only call get_event_constraints() once - * on each event, this avoids the need for reg->alloc. - */ - if (!uncore_box_is_fake(box)) { - if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) - nhmex_mbox_alter_er(event, idx[0], true); - reg1->alloc |= alloc; - if (reg2->idx != EXTRA_REG_NONE) - reg2->alloc = 1; - } - return NULL; -fail: - if (idx[0] != 0xff && !(alloc & 0x1) && - idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { - /* - * events 0xd ~ 0x10 are functional identical, but are - * controlled by different fields in the ZDP_CTL_FVC - * register. If we failed to take one field, try the - * rest 3 choices. - */ - BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff); - idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; - idx[0] = (idx[0] + 1) % 4; - idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; - if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) { - config1 = nhmex_mbox_alter_er(event, idx[0], false); - goto again; - } - } - - if (alloc & 0x1) - nhmex_mbox_put_shared_reg(box, idx[0]); - if (alloc & 0x2) - nhmex_mbox_put_shared_reg(box, idx[1]); - return &uncore_constraint_empty; -} - -static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; - - if (uncore_box_is_fake(box)) - return; - - if (reg1->alloc & 0x1) - nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8)); - if (reg1->alloc & 0x2) - nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8)); - reg1->alloc = 0; - - if (reg2->alloc) { - nhmex_mbox_put_shared_reg(box, reg2->idx); - reg2->alloc = 0; - } -} - -static int nhmex_mbox_extra_reg_idx(struct extra_reg *er) -{ - if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) - return er->idx; - return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd; -} - -static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - struct intel_uncore_type *type = box->pmu->type; - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; - struct extra_reg *er; - unsigned msr; - int reg_idx = 0; - /* - * The mbox events may require 2 extra MSRs at the most. But only - * the lower 32 bits in these MSRs are significant, so we can use - * config1 to pass two MSRs' config. - */ - for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) { - if (er->event != (event->hw.config & er->config_mask)) - continue; - if (event->attr.config1 & ~er->valid_mask) - return -EINVAL; - - msr = er->msr + type->msr_offset * box->pmu->pmu_idx; - if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff)) - return -EINVAL; - - /* always use the 32~63 bits to pass the PLD config */ - if (er->idx == EXTRA_REG_NHMEX_M_PLD) - reg_idx = 1; - else if (WARN_ON_ONCE(reg_idx > 0)) - return -EINVAL; - - reg1->idx &= ~(0xff << (reg_idx * 8)); - reg1->reg &= ~(0xffff << (reg_idx * 16)); - reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8); - reg1->reg |= msr << (reg_idx * 16); - reg1->config = event->attr.config1; - reg_idx++; - } - /* - * The mbox only provides ability to perform address matching - * for the PLD events. - */ - if (reg_idx == 2) { - reg2->idx = EXTRA_REG_NHMEX_M_FILTER; - if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN) - reg2->config = event->attr.config2; - else - reg2->config = ~0ULL; - if (box->pmu->pmu_idx == 0) - reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG; - else - reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG; - } - return 0; -} - -static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx) -{ - struct intel_uncore_extra_reg *er; - unsigned long flags; - u64 config; - - if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) - return box->shared_regs[idx].config; - - er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; - raw_spin_lock_irqsave(&er->lock, flags); - config = er->config; - raw_spin_unlock_irqrestore(&er->lock, flags); - return config; -} - -static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - int idx; - - idx = __BITS_VALUE(reg1->idx, 0, 8); - if (idx != 0xff) - wrmsrl(__BITS_VALUE(reg1->reg, 0, 16), - nhmex_mbox_shared_reg_config(box, idx)); - idx = __BITS_VALUE(reg1->idx, 1, 8); - if (idx != 0xff) - wrmsrl(__BITS_VALUE(reg1->reg, 1, 16), - nhmex_mbox_shared_reg_config(box, idx)); - - if (reg2->idx != EXTRA_REG_NONE) { - wrmsrl(reg2->reg, 0); - if (reg2->config != ~0ULL) { - wrmsrl(reg2->reg + 1, - reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK); - wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK & - (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT)); - wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN); - } - } - - wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); -} - -DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3"); -DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5"); -DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6"); -DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7"); -DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13"); -DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21"); -DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en, filter_cfg_en, "config2:63"); -DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33"); -DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61"); -DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31"); -DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31"); -DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31"); -DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31"); -DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31"); -DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31"); -DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63"); - -static struct attribute *nhmex_uncore_mbox_formats_attr[] = { - &format_attr_count_mode.attr, - &format_attr_storage_mode.attr, - &format_attr_wrap_mode.attr, - &format_attr_flag_mode.attr, - &format_attr_inc_sel.attr, - &format_attr_set_flag_sel.attr, - &format_attr_filter_cfg_en.attr, - &format_attr_filter_match.attr, - &format_attr_filter_mask.attr, - &format_attr_dsp.attr, - &format_attr_thr.attr, - &format_attr_fvc.attr, - &format_attr_pgt.attr, - &format_attr_map.attr, - &format_attr_iss.attr, - &format_attr_pld.attr, - NULL, -}; - -static struct attribute_group nhmex_uncore_mbox_format_group = { - .name = "format", - .attrs = nhmex_uncore_mbox_formats_attr, -}; - -static struct uncore_event_desc nhmex_uncore_mbox_events[] = { - INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"), - INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"), - { /* end: all zeroes */ }, -}; - -static struct uncore_event_desc wsmex_uncore_mbox_events[] = { - INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"), - INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"), - { /* end: all zeroes */ }, -}; - -static struct intel_uncore_ops nhmex_uncore_mbox_ops = { - NHMEX_UNCORE_OPS_COMMON_INIT(), - .enable_event = nhmex_mbox_msr_enable_event, - .hw_config = nhmex_mbox_hw_config, - .get_constraint = nhmex_mbox_get_constraint, - .put_constraint = nhmex_mbox_put_constraint, -}; - -static struct intel_uncore_type nhmex_uncore_mbox = { - .name = "mbox", - .num_counters = 6, - .num_boxes = 2, - .perf_ctr_bits = 48, - .event_ctl = NHMEX_M0_MSR_PMU_CTL0, - .perf_ctr = NHMEX_M0_MSR_PMU_CNT0, - .event_mask = NHMEX_M_PMON_RAW_EVENT_MASK, - .box_ctl = NHMEX_M0_MSR_GLOBAL_CTL, - .msr_offset = NHMEX_M_MSR_OFFSET, - .pair_ctr_ctl = 1, - .num_shared_regs = 8, - .event_descs = nhmex_uncore_mbox_events, - .ops = &nhmex_uncore_mbox_ops, - .format_group = &nhmex_uncore_mbox_format_group, -}; - -static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - - /* adjust the main event selector and extra register index */ - if (reg1->idx % 2) { - reg1->idx--; - hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; - } else { - reg1->idx++; - hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; - } - - /* adjust extra register config */ - switch (reg1->idx % 6) { - case 2: - /* shift the 8~15 bits to the 0~7 bits */ - reg1->config >>= 8; - break; - case 3: - /* shift the 0~7 bits to the 8~15 bits */ - reg1->config <<= 8; - break; - }; -} - -/* - * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7. - * An event set consists of 6 events, the 3rd and 4th events in - * an event set use the same extra register. So an event set uses - * 5 extra registers. - */ -static struct event_constraint * -nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - struct intel_uncore_extra_reg *er; - unsigned long flags; - int idx, er_idx; - u64 config1; - bool ok = false; - - if (!uncore_box_is_fake(box) && reg1->alloc) - return NULL; - - idx = reg1->idx % 6; - config1 = reg1->config; -again: - er_idx = idx; - /* the 3rd and 4th events use the same extra register */ - if (er_idx > 2) - er_idx--; - er_idx += (reg1->idx / 6) * 5; - - er = &box->shared_regs[er_idx]; - raw_spin_lock_irqsave(&er->lock, flags); - if (idx < 2) { - if (!atomic_read(&er->ref) || er->config == reg1->config) { - atomic_inc(&er->ref); - er->config = reg1->config; - ok = true; - } - } else if (idx == 2 || idx == 3) { - /* - * these two events use different fields in a extra register, - * the 0~7 bits and the 8~15 bits respectively. - */ - u64 mask = 0xff << ((idx - 2) * 8); - if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) || - !((er->config ^ config1) & mask)) { - atomic_add(1 << ((idx - 2) * 8), &er->ref); - er->config &= ~mask; - er->config |= config1 & mask; - ok = true; - } - } else { - if (!atomic_read(&er->ref) || - (er->config == (hwc->config >> 32) && - er->config1 == reg1->config && - er->config2 == reg2->config)) { - atomic_inc(&er->ref); - er->config = (hwc->config >> 32); - er->config1 = reg1->config; - er->config2 = reg2->config; - ok = true; - } - } - raw_spin_unlock_irqrestore(&er->lock, flags); - - if (!ok) { - /* - * The Rbox events are always in pairs. The paired - * events are functional identical, but use different - * extra registers. If we failed to take an extra - * register, try the alternative. - */ - idx ^= 1; - if (idx != reg1->idx % 6) { - if (idx == 2) - config1 >>= 8; - else if (idx == 3) - config1 <<= 8; - goto again; - } - } else { - if (!uncore_box_is_fake(box)) { - if (idx != reg1->idx % 6) - nhmex_rbox_alter_er(box, event); - reg1->alloc = 1; - } - return NULL; - } - return &uncore_constraint_empty; -} - -static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) -{ - struct intel_uncore_extra_reg *er; - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - int idx, er_idx; - - if (uncore_box_is_fake(box) || !reg1->alloc) - return; - - idx = reg1->idx % 6; - er_idx = idx; - if (er_idx > 2) - er_idx--; - er_idx += (reg1->idx / 6) * 5; - - er = &box->shared_regs[er_idx]; - if (idx == 2 || idx == 3) - atomic_sub(1 << ((idx - 2) * 8), &er->ref); - else - atomic_dec(&er->ref); - - reg1->alloc = 0; -} - -static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; - struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; - int idx; - - idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >> - NHMEX_R_PMON_CTL_EV_SEL_SHIFT; - if (idx >= 0x18) - return -EINVAL; - - reg1->idx = idx; - reg1->config = event->attr.config1; - - switch (idx % 6) { - case 4: - case 5: - hwc->config |= event->attr.config & (~0ULL << 32); - reg2->config = event->attr.config2; - break; - }; - return 0; -} - -static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) -{ - struct hw_perf_event *hwc = &event->hw; - struct hw_perf_event_extra *reg1 = &hwc->extra_reg; - struct hw_perf_event_extra *reg2 = &hwc->branch_reg; - int idx, port; - - idx = reg1->idx; - port = idx / 6 + box->pmu->pmu_idx * 4; - - switch (idx % 6) { - case 0: - wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config); - break; - case 1: - wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config); - break; - case 2: - case 3: - wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port), - uncore_shared_reg_config(box, 2 + (idx / 6) * 5)); - break; - case 4: - wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port), - hwc->config >> 32); - wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config); - wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config); - break; - case 5: - wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port), - hwc->config >> 32); - wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config); - wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config); - break; - }; - - wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | - (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); -} - -DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63"); -DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63"); -DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63"); -DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15"); -DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31"); - -static struct attribute *nhmex_uncore_rbox_formats_attr[] = { - &format_attr_event5.attr, - &format_attr_xbr_mm_cfg.attr, - &format_attr_xbr_match.attr, - &format_attr_xbr_mask.attr, - &format_attr_qlx_cfg.attr, - &format_attr_iperf_cfg.attr, - NULL, -}; - -static struct attribute_group nhmex_uncore_rbox_format_group = { - .name = "format", - .attrs = nhmex_uncore_rbox_formats_attr, -}; - -static struct uncore_event_desc nhmex_uncore_rbox_events[] = { - INTEL_UNCORE_EVENT_DESC(qpi0_flit_send, "event=0x0,iperf_cfg=0x80000000"), - INTEL_UNCORE_EVENT_DESC(qpi1_filt_send, "event=0x6,iperf_cfg=0x80000000"), - INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt, "event=0x0,iperf_cfg=0x40000000"), - INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt, "event=0x6,iperf_cfg=0x40000000"), - INTEL_UNCORE_EVENT_DESC(qpi0_date_response, "event=0x0,iperf_cfg=0xc4"), - INTEL_UNCORE_EVENT_DESC(qpi1_date_response, "event=0x6,iperf_cfg=0xc4"), - { /* end: all zeroes */ }, -}; - -static struct intel_uncore_ops nhmex_uncore_rbox_ops = { - NHMEX_UNCORE_OPS_COMMON_INIT(), - .enable_event = nhmex_rbox_msr_enable_event, - .hw_config = nhmex_rbox_hw_config, - .get_constraint = nhmex_rbox_get_constraint, - .put_constraint = nhmex_rbox_put_constraint, -}; - -static struct intel_uncore_type nhmex_uncore_rbox = { - .name = "rbox", - .num_counters = 8, - .num_boxes = 2, - .perf_ctr_bits = 48, - .event_ctl = NHMEX_R_MSR_PMON_CTL0, - .perf_ctr = NHMEX_R_MSR_PMON_CNT0, - .event_mask = NHMEX_R_PMON_RAW_EVENT_MASK, - .box_ctl = NHMEX_R_MSR_GLOBAL_CTL, - .msr_offset = NHMEX_R_MSR_OFFSET, - .pair_ctr_ctl = 1, - .num_shared_regs = 20, - .event_descs = nhmex_uncore_rbox_events, - .ops = &nhmex_uncore_rbox_ops, - .format_group = &nhmex_uncore_rbox_format_group -}; - -static struct intel_uncore_type *nhmex_msr_uncores[] = { - &nhmex_uncore_ubox, - &nhmex_uncore_cbox, - &nhmex_uncore_bbox, - &nhmex_uncore_sbox, - &nhmex_uncore_mbox, - &nhmex_uncore_rbox, - &nhmex_uncore_wbox, - NULL, -}; -/* end of Nehalem-EX uncore support */ - static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx) { struct hw_perf_event *hwc = &event->hw; @@ -2195,9 +1167,8 @@ static void __init uncore_cpu_setup(void *dummy) static int __init uncore_cpu_init(void) { - int ret, max_cores; + int ret; - max_cores = boot_cpu_data.x86_max_cores; switch (boot_cpu_data.x86_model) { case 26: /* Nehalem */ case 30: @@ -2213,13 +1184,8 @@ static int __init uncore_cpu_init(void) snbep_uncore_cpu_init(); break; case 46: /* Nehalem-EX */ - uncore_nhmex = true; case 47: /* Westmere-EX aka. Xeon E7 */ - if (!uncore_nhmex) - nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events; - if (nhmex_uncore_cbox.num_boxes > max_cores) - nhmex_uncore_cbox.num_boxes = max_cores; - uncore_msr_uncores = nhmex_msr_uncores; + nhmex_uncore_cpu_init(); break; case 62: /* IvyTown */ ivt_uncore_cpu_init(); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index 538be93b5f19..b91559936d49 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -24,188 +24,6 @@ #define UNCORE_EVENT_CONSTRAINT(c, n) EVENT_CONSTRAINT(c, n, 0xff) -/* NHM-EX event control */ -#define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff -#define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00 -#define NHMEX_PMON_CTL_EN_BIT0 (1 << 0) -#define NHMEX_PMON_CTL_EDGE_DET (1 << 18) -#define NHMEX_PMON_CTL_PMI_EN (1 << 20) -#define NHMEX_PMON_CTL_EN_BIT22 (1 << 22) -#define NHMEX_PMON_CTL_INVERT (1 << 23) -#define NHMEX_PMON_CTL_TRESH_MASK 0xff000000 -#define NHMEX_PMON_RAW_EVENT_MASK (NHMEX_PMON_CTL_EV_SEL_MASK | \ - NHMEX_PMON_CTL_UMASK_MASK | \ - NHMEX_PMON_CTL_EDGE_DET | \ - NHMEX_PMON_CTL_INVERT | \ - NHMEX_PMON_CTL_TRESH_MASK) - -/* NHM-EX Ubox */ -#define NHMEX_U_MSR_PMON_GLOBAL_CTL 0xc00 -#define NHMEX_U_MSR_PMON_CTR 0xc11 -#define NHMEX_U_MSR_PMON_EV_SEL 0xc10 - -#define NHMEX_U_PMON_GLOBAL_EN (1 << 0) -#define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL 0x0000001e -#define NHMEX_U_PMON_GLOBAL_EN_ALL (1 << 28) -#define NHMEX_U_PMON_GLOBAL_RST_ALL (1 << 29) -#define NHMEX_U_PMON_GLOBAL_FRZ_ALL (1 << 31) - -#define NHMEX_U_PMON_RAW_EVENT_MASK \ - (NHMEX_PMON_CTL_EV_SEL_MASK | \ - NHMEX_PMON_CTL_EDGE_DET) - -/* NHM-EX Cbox */ -#define NHMEX_C0_MSR_PMON_GLOBAL_CTL 0xd00 -#define NHMEX_C0_MSR_PMON_CTR0 0xd11 -#define NHMEX_C0_MSR_PMON_EV_SEL0 0xd10 -#define NHMEX_C_MSR_OFFSET 0x20 - -/* NHM-EX Bbox */ -#define NHMEX_B0_MSR_PMON_GLOBAL_CTL 0xc20 -#define NHMEX_B0_MSR_PMON_CTR0 0xc31 -#define NHMEX_B0_MSR_PMON_CTL0 0xc30 -#define NHMEX_B_MSR_OFFSET 0x40 -#define NHMEX_B0_MSR_MATCH 0xe45 -#define NHMEX_B0_MSR_MASK 0xe46 -#define NHMEX_B1_MSR_MATCH 0xe4d -#define NHMEX_B1_MSR_MASK 0xe4e - -#define NHMEX_B_PMON_CTL_EN (1 << 0) -#define NHMEX_B_PMON_CTL_EV_SEL_SHIFT 1 -#define NHMEX_B_PMON_CTL_EV_SEL_MASK \ - (0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT) -#define NHMEX_B_PMON_CTR_SHIFT 6 -#define NHMEX_B_PMON_CTR_MASK \ - (0x3 << NHMEX_B_PMON_CTR_SHIFT) -#define NHMEX_B_PMON_RAW_EVENT_MASK \ - (NHMEX_B_PMON_CTL_EV_SEL_MASK | \ - NHMEX_B_PMON_CTR_MASK) - -/* NHM-EX Sbox */ -#define NHMEX_S0_MSR_PMON_GLOBAL_CTL 0xc40 -#define NHMEX_S0_MSR_PMON_CTR0 0xc51 -#define NHMEX_S0_MSR_PMON_CTL0 0xc50 -#define NHMEX_S_MSR_OFFSET 0x80 -#define NHMEX_S0_MSR_MM_CFG 0xe48 -#define NHMEX_S0_MSR_MATCH 0xe49 -#define NHMEX_S0_MSR_MASK 0xe4a -#define NHMEX_S1_MSR_MM_CFG 0xe58 -#define NHMEX_S1_MSR_MATCH 0xe59 -#define NHMEX_S1_MSR_MASK 0xe5a - -#define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63) -#define NHMEX_S_EVENT_TO_R_PROG_EV 0 - -/* NHM-EX Mbox */ -#define NHMEX_M0_MSR_GLOBAL_CTL 0xca0 -#define NHMEX_M0_MSR_PMU_DSP 0xca5 -#define NHMEX_M0_MSR_PMU_ISS 0xca6 -#define NHMEX_M0_MSR_PMU_MAP 0xca7 -#define NHMEX_M0_MSR_PMU_MSC_THR 0xca8 -#define NHMEX_M0_MSR_PMU_PGT 0xca9 -#define NHMEX_M0_MSR_PMU_PLD 0xcaa -#define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC 0xcab -#define NHMEX_M0_MSR_PMU_CTL0 0xcb0 -#define NHMEX_M0_MSR_PMU_CNT0 0xcb1 -#define NHMEX_M_MSR_OFFSET 0x40 -#define NHMEX_M0_MSR_PMU_MM_CFG 0xe54 -#define NHMEX_M1_MSR_PMU_MM_CFG 0xe5c - -#define NHMEX_M_PMON_MM_CFG_EN (1ULL << 63) -#define NHMEX_M_PMON_ADDR_MATCH_MASK 0x3ffffffffULL -#define NHMEX_M_PMON_ADDR_MASK_MASK 0x7ffffffULL -#define NHMEX_M_PMON_ADDR_MASK_SHIFT 34 - -#define NHMEX_M_PMON_CTL_EN (1 << 0) -#define NHMEX_M_PMON_CTL_PMI_EN (1 << 1) -#define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT 2 -#define NHMEX_M_PMON_CTL_COUNT_MODE_MASK \ - (0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT) -#define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT 4 -#define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK \ - (0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT) -#define NHMEX_M_PMON_CTL_WRAP_MODE (1 << 6) -#define NHMEX_M_PMON_CTL_FLAG_MODE (1 << 7) -#define NHMEX_M_PMON_CTL_INC_SEL_SHIFT 9 -#define NHMEX_M_PMON_CTL_INC_SEL_MASK \ - (0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT) -#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT 19 -#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK \ - (0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) -#define NHMEX_M_PMON_RAW_EVENT_MASK \ - (NHMEX_M_PMON_CTL_COUNT_MODE_MASK | \ - NHMEX_M_PMON_CTL_STORAGE_MODE_MASK | \ - NHMEX_M_PMON_CTL_WRAP_MODE | \ - NHMEX_M_PMON_CTL_FLAG_MODE | \ - NHMEX_M_PMON_CTL_INC_SEL_MASK | \ - NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) - -#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 11) - 1) | (1 << 23)) -#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (11 + 3 * (n))) - -#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 12) - 1) | (1 << 24)) -#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (12 + 3 * (n))) - -/* - * use the 9~13 bits to select event If the 7th bit is not set, - * otherwise use the 19~21 bits to select event. - */ -#define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT) -#define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \ - NHMEX_M_PMON_CTL_FLAG_MODE) -#define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \ - NHMEX_M_PMON_CTL_FLAG_MODE) -#define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \ - NHMEX_M_PMON_CTL_FLAG_MODE) -#define MBOX_INC_SEL_EXTAR_REG(c, r) \ - EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \ - MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r) -#define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \ - EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \ - MBOX_SET_FLAG_SEL_MASK, \ - (u64)-1, NHMEX_M_##r) - -/* NHM-EX Rbox */ -#define NHMEX_R_MSR_GLOBAL_CTL 0xe00 -#define NHMEX_R_MSR_PMON_CTL0 0xe10 -#define NHMEX_R_MSR_PMON_CNT0 0xe11 -#define NHMEX_R_MSR_OFFSET 0x20 - -#define NHMEX_R_MSR_PORTN_QLX_CFG(n) \ - ((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4)) -#define NHMEX_R_MSR_PORTN_IPERF_CFG0(n) (0xe04 + (n)) -#define NHMEX_R_MSR_PORTN_IPERF_CFG1(n) (0xe24 + (n)) -#define NHMEX_R_MSR_PORTN_XBR_OFFSET(n) \ - (((n) < 4 ? 0 : 0x10) + (n) * 4) -#define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) \ - (0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n)) -#define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n) \ - (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1) -#define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n) \ - (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2) -#define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) \ - (0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n)) -#define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n) \ - (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1) -#define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n) \ - (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2) - -#define NHMEX_R_PMON_CTL_EN (1 << 0) -#define NHMEX_R_PMON_CTL_EV_SEL_SHIFT 1 -#define NHMEX_R_PMON_CTL_EV_SEL_MASK \ - (0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT) -#define NHMEX_R_PMON_CTL_PMI_EN (1 << 6) -#define NHMEX_R_PMON_RAW_EVENT_MASK NHMEX_R_PMON_CTL_EV_SEL_MASK - -/* NHM-EX Wbox */ -#define NHMEX_W_MSR_GLOBAL_CTL 0xc80 -#define NHMEX_W_MSR_PMON_CNT0 0xc90 -#define NHMEX_W_MSR_PMON_EVT_SEL0 0xc91 -#define NHMEX_W_MSR_PMON_FIXED_CTR 0x394 -#define NHMEX_W_MSR_PMON_FIXED_CTL 0x395 - -#define NHMEX_W_PMON_GLOBAL_FIXED_EN (1ULL << 31) - struct intel_uncore_ops; struct intel_uncore_pmu; struct intel_uncore_box; @@ -514,3 +332,6 @@ int snbep_uncore_pci_init(void); void snbep_uncore_cpu_init(void); int ivt_uncore_pci_init(void); void ivt_uncore_cpu_init(void); + +/* perf_event_intel_uncore_nhmex.c */ +void nhmex_uncore_cpu_init(void); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c new file mode 100644 index 000000000000..93b11a8f110d --- /dev/null +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c @@ -0,0 +1,1221 @@ +/* Nehalem-EX/Westmere-EX uncore support */ +#include "perf_event_intel_uncore.h" + +/* NHM-EX event control */ +#define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff +#define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00 +#define NHMEX_PMON_CTL_EN_BIT0 (1 << 0) +#define NHMEX_PMON_CTL_EDGE_DET (1 << 18) +#define NHMEX_PMON_CTL_PMI_EN (1 << 20) +#define NHMEX_PMON_CTL_EN_BIT22 (1 << 22) +#define NHMEX_PMON_CTL_INVERT (1 << 23) +#define NHMEX_PMON_CTL_TRESH_MASK 0xff000000 +#define NHMEX_PMON_RAW_EVENT_MASK (NHMEX_PMON_CTL_EV_SEL_MASK | \ + NHMEX_PMON_CTL_UMASK_MASK | \ + NHMEX_PMON_CTL_EDGE_DET | \ + NHMEX_PMON_CTL_INVERT | \ + NHMEX_PMON_CTL_TRESH_MASK) + +/* NHM-EX Ubox */ +#define NHMEX_U_MSR_PMON_GLOBAL_CTL 0xc00 +#define NHMEX_U_MSR_PMON_CTR 0xc11 +#define NHMEX_U_MSR_PMON_EV_SEL 0xc10 + +#define NHMEX_U_PMON_GLOBAL_EN (1 << 0) +#define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL 0x0000001e +#define NHMEX_U_PMON_GLOBAL_EN_ALL (1 << 28) +#define NHMEX_U_PMON_GLOBAL_RST_ALL (1 << 29) +#define NHMEX_U_PMON_GLOBAL_FRZ_ALL (1 << 31) + +#define NHMEX_U_PMON_RAW_EVENT_MASK \ + (NHMEX_PMON_CTL_EV_SEL_MASK | \ + NHMEX_PMON_CTL_EDGE_DET) + +/* NHM-EX Cbox */ +#define NHMEX_C0_MSR_PMON_GLOBAL_CTL 0xd00 +#define NHMEX_C0_MSR_PMON_CTR0 0xd11 +#define NHMEX_C0_MSR_PMON_EV_SEL0 0xd10 +#define NHMEX_C_MSR_OFFSET 0x20 + +/* NHM-EX Bbox */ +#define NHMEX_B0_MSR_PMON_GLOBAL_CTL 0xc20 +#define NHMEX_B0_MSR_PMON_CTR0 0xc31 +#define NHMEX_B0_MSR_PMON_CTL0 0xc30 +#define NHMEX_B_MSR_OFFSET 0x40 +#define NHMEX_B0_MSR_MATCH 0xe45 +#define NHMEX_B0_MSR_MASK 0xe46 +#define NHMEX_B1_MSR_MATCH 0xe4d +#define NHMEX_B1_MSR_MASK 0xe4e + +#define NHMEX_B_PMON_CTL_EN (1 << 0) +#define NHMEX_B_PMON_CTL_EV_SEL_SHIFT 1 +#define NHMEX_B_PMON_CTL_EV_SEL_MASK \ + (0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT) +#define NHMEX_B_PMON_CTR_SHIFT 6 +#define NHMEX_B_PMON_CTR_MASK \ + (0x3 << NHMEX_B_PMON_CTR_SHIFT) +#define NHMEX_B_PMON_RAW_EVENT_MASK \ + (NHMEX_B_PMON_CTL_EV_SEL_MASK | \ + NHMEX_B_PMON_CTR_MASK) + +/* NHM-EX Sbox */ +#define NHMEX_S0_MSR_PMON_GLOBAL_CTL 0xc40 +#define NHMEX_S0_MSR_PMON_CTR0 0xc51 +#define NHMEX_S0_MSR_PMON_CTL0 0xc50 +#define NHMEX_S_MSR_OFFSET 0x80 +#define NHMEX_S0_MSR_MM_CFG 0xe48 +#define NHMEX_S0_MSR_MATCH 0xe49 +#define NHMEX_S0_MSR_MASK 0xe4a +#define NHMEX_S1_MSR_MM_CFG 0xe58 +#define NHMEX_S1_MSR_MATCH 0xe59 +#define NHMEX_S1_MSR_MASK 0xe5a + +#define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63) +#define NHMEX_S_EVENT_TO_R_PROG_EV 0 + +/* NHM-EX Mbox */ +#define NHMEX_M0_MSR_GLOBAL_CTL 0xca0 +#define NHMEX_M0_MSR_PMU_DSP 0xca5 +#define NHMEX_M0_MSR_PMU_ISS 0xca6 +#define NHMEX_M0_MSR_PMU_MAP 0xca7 +#define NHMEX_M0_MSR_PMU_MSC_THR 0xca8 +#define NHMEX_M0_MSR_PMU_PGT 0xca9 +#define NHMEX_M0_MSR_PMU_PLD 0xcaa +#define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC 0xcab +#define NHMEX_M0_MSR_PMU_CTL0 0xcb0 +#define NHMEX_M0_MSR_PMU_CNT0 0xcb1 +#define NHMEX_M_MSR_OFFSET 0x40 +#define NHMEX_M0_MSR_PMU_MM_CFG 0xe54 +#define NHMEX_M1_MSR_PMU_MM_CFG 0xe5c + +#define NHMEX_M_PMON_MM_CFG_EN (1ULL << 63) +#define NHMEX_M_PMON_ADDR_MATCH_MASK 0x3ffffffffULL +#define NHMEX_M_PMON_ADDR_MASK_MASK 0x7ffffffULL +#define NHMEX_M_PMON_ADDR_MASK_SHIFT 34 + +#define NHMEX_M_PMON_CTL_EN (1 << 0) +#define NHMEX_M_PMON_CTL_PMI_EN (1 << 1) +#define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT 2 +#define NHMEX_M_PMON_CTL_COUNT_MODE_MASK \ + (0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT) +#define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT 4 +#define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK \ + (0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT) +#define NHMEX_M_PMON_CTL_WRAP_MODE (1 << 6) +#define NHMEX_M_PMON_CTL_FLAG_MODE (1 << 7) +#define NHMEX_M_PMON_CTL_INC_SEL_SHIFT 9 +#define NHMEX_M_PMON_CTL_INC_SEL_MASK \ + (0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT) +#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT 19 +#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK \ + (0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) +#define NHMEX_M_PMON_RAW_EVENT_MASK \ + (NHMEX_M_PMON_CTL_COUNT_MODE_MASK | \ + NHMEX_M_PMON_CTL_STORAGE_MODE_MASK | \ + NHMEX_M_PMON_CTL_WRAP_MODE | \ + NHMEX_M_PMON_CTL_FLAG_MODE | \ + NHMEX_M_PMON_CTL_INC_SEL_MASK | \ + NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) + +#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 11) - 1) | (1 << 23)) +#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (11 + 3 * (n))) + +#define WSMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 12) - 1) | (1 << 24)) +#define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7ULL << (12 + 3 * (n))) + +/* + * use the 9~13 bits to select event If the 7th bit is not set, + * otherwise use the 19~21 bits to select event. + */ +#define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT) +#define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \ + NHMEX_M_PMON_CTL_FLAG_MODE) +#define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \ + NHMEX_M_PMON_CTL_FLAG_MODE) +#define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \ + NHMEX_M_PMON_CTL_FLAG_MODE) +#define MBOX_INC_SEL_EXTAR_REG(c, r) \ + EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \ + MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r) +#define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \ + EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \ + MBOX_SET_FLAG_SEL_MASK, \ + (u64)-1, NHMEX_M_##r) + +/* NHM-EX Rbox */ +#define NHMEX_R_MSR_GLOBAL_CTL 0xe00 +#define NHMEX_R_MSR_PMON_CTL0 0xe10 +#define NHMEX_R_MSR_PMON_CNT0 0xe11 +#define NHMEX_R_MSR_OFFSET 0x20 + +#define NHMEX_R_MSR_PORTN_QLX_CFG(n) \ + ((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4)) +#define NHMEX_R_MSR_PORTN_IPERF_CFG0(n) (0xe04 + (n)) +#define NHMEX_R_MSR_PORTN_IPERF_CFG1(n) (0xe24 + (n)) +#define NHMEX_R_MSR_PORTN_XBR_OFFSET(n) \ + (((n) < 4 ? 0 : 0x10) + (n) * 4) +#define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) \ + (0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n)) +#define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n) \ + (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1) +#define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n) \ + (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2) +#define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) \ + (0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n)) +#define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n) \ + (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1) +#define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n) \ + (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2) + +#define NHMEX_R_PMON_CTL_EN (1 << 0) +#define NHMEX_R_PMON_CTL_EV_SEL_SHIFT 1 +#define NHMEX_R_PMON_CTL_EV_SEL_MASK \ + (0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT) +#define NHMEX_R_PMON_CTL_PMI_EN (1 << 6) +#define NHMEX_R_PMON_RAW_EVENT_MASK NHMEX_R_PMON_CTL_EV_SEL_MASK + +/* NHM-EX Wbox */ +#define NHMEX_W_MSR_GLOBAL_CTL 0xc80 +#define NHMEX_W_MSR_PMON_CNT0 0xc90 +#define NHMEX_W_MSR_PMON_EVT_SEL0 0xc91 +#define NHMEX_W_MSR_PMON_FIXED_CTR 0x394 +#define NHMEX_W_MSR_PMON_FIXED_CTL 0x395 + +#define NHMEX_W_PMON_GLOBAL_FIXED_EN (1ULL << 31) + +#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ + ((1ULL << (n)) - 1))) + +DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7"); +DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); +DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15"); +DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18"); +DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23"); +DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31"); +DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); +DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); +DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63"); + +static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box) +{ + wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL); +} + +static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box) +{ + unsigned msr = uncore_msr_box_ctl(box); + u64 config; + + if (msr) { + rdmsrl(msr, config); + config &= ~((1ULL << uncore_num_counters(box)) - 1); + /* WBox has a fixed counter */ + if (uncore_msr_fixed_ctl(box)) + config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN; + wrmsrl(msr, config); + } +} + +static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box) +{ + unsigned msr = uncore_msr_box_ctl(box); + u64 config; + + if (msr) { + rdmsrl(msr, config); + config |= (1ULL << uncore_num_counters(box)) - 1; + /* WBox has a fixed counter */ + if (uncore_msr_fixed_ctl(box)) + config |= NHMEX_W_PMON_GLOBAL_FIXED_EN; + wrmsrl(msr, config); + } +} + +static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + wrmsrl(event->hw.config_base, 0); +} + +static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + + if (hwc->idx >= UNCORE_PMC_IDX_FIXED) + wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0); + else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0) + wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); + else + wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); +} + +#define NHMEX_UNCORE_OPS_COMMON_INIT() \ + .init_box = nhmex_uncore_msr_init_box, \ + .disable_box = nhmex_uncore_msr_disable_box, \ + .enable_box = nhmex_uncore_msr_enable_box, \ + .disable_event = nhmex_uncore_msr_disable_event, \ + .read_counter = uncore_msr_read_counter + +static struct intel_uncore_ops nhmex_uncore_ops = { + NHMEX_UNCORE_OPS_COMMON_INIT(), + .enable_event = nhmex_uncore_msr_enable_event, +}; + +static struct attribute *nhmex_uncore_ubox_formats_attr[] = { + &format_attr_event.attr, + &format_attr_edge.attr, + NULL, +}; + +static struct attribute_group nhmex_uncore_ubox_format_group = { + .name = "format", + .attrs = nhmex_uncore_ubox_formats_attr, +}; + +static struct intel_uncore_type nhmex_uncore_ubox = { + .name = "ubox", + .num_counters = 1, + .num_boxes = 1, + .perf_ctr_bits = 48, + .event_ctl = NHMEX_U_MSR_PMON_EV_SEL, + .perf_ctr = NHMEX_U_MSR_PMON_CTR, + .event_mask = NHMEX_U_PMON_RAW_EVENT_MASK, + .box_ctl = NHMEX_U_MSR_PMON_GLOBAL_CTL, + .ops = &nhmex_uncore_ops, + .format_group = &nhmex_uncore_ubox_format_group +}; + +static struct attribute *nhmex_uncore_cbox_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh8.attr, + NULL, +}; + +static struct attribute_group nhmex_uncore_cbox_format_group = { + .name = "format", + .attrs = nhmex_uncore_cbox_formats_attr, +}; + +/* msr offset for each instance of cbox */ +static unsigned nhmex_cbox_msr_offsets[] = { + 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0, +}; + +static struct intel_uncore_type nhmex_uncore_cbox = { + .name = "cbox", + .num_counters = 6, + .num_boxes = 10, + .perf_ctr_bits = 48, + .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, + .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, + .event_mask = NHMEX_PMON_RAW_EVENT_MASK, + .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, + .msr_offsets = nhmex_cbox_msr_offsets, + .pair_ctr_ctl = 1, + .ops = &nhmex_uncore_ops, + .format_group = &nhmex_uncore_cbox_format_group +}; + +static struct uncore_event_desc nhmex_uncore_wbox_events[] = { + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"), + { /* end: all zeroes */ }, +}; + +static struct intel_uncore_type nhmex_uncore_wbox = { + .name = "wbox", + .num_counters = 4, + .num_boxes = 1, + .perf_ctr_bits = 48, + .event_ctl = NHMEX_W_MSR_PMON_CNT0, + .perf_ctr = NHMEX_W_MSR_PMON_EVT_SEL0, + .fixed_ctr = NHMEX_W_MSR_PMON_FIXED_CTR, + .fixed_ctl = NHMEX_W_MSR_PMON_FIXED_CTL, + .event_mask = NHMEX_PMON_RAW_EVENT_MASK, + .box_ctl = NHMEX_W_MSR_GLOBAL_CTL, + .pair_ctr_ctl = 1, + .event_descs = nhmex_uncore_wbox_events, + .ops = &nhmex_uncore_ops, + .format_group = &nhmex_uncore_cbox_format_group +}; + +static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + int ctr, ev_sel; + + ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >> + NHMEX_B_PMON_CTR_SHIFT; + ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >> + NHMEX_B_PMON_CTL_EV_SEL_SHIFT; + + /* events that do not use the match/mask registers */ + if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) || + (ctr == 2 && ev_sel != 0x4) || ctr == 3) + return 0; + + if (box->pmu->pmu_idx == 0) + reg1->reg = NHMEX_B0_MSR_MATCH; + else + reg1->reg = NHMEX_B1_MSR_MATCH; + reg1->idx = 0; + reg1->config = event->attr.config1; + reg2->config = event->attr.config2; + return 0; +} + +static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + + if (reg1->idx != EXTRA_REG_NONE) { + wrmsrl(reg1->reg, reg1->config); + wrmsrl(reg1->reg + 1, reg2->config); + } + wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | + (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK)); +} + +/* + * The Bbox has 4 counters, but each counter monitors different events. + * Use bits 6-7 in the event config to select counter. + */ +static struct event_constraint nhmex_uncore_bbox_constraints[] = { + EVENT_CONSTRAINT(0 , 1, 0xc0), + EVENT_CONSTRAINT(0x40, 2, 0xc0), + EVENT_CONSTRAINT(0x80, 4, 0xc0), + EVENT_CONSTRAINT(0xc0, 8, 0xc0), + EVENT_CONSTRAINT_END, +}; + +static struct attribute *nhmex_uncore_bbox_formats_attr[] = { + &format_attr_event5.attr, + &format_attr_counter.attr, + &format_attr_match.attr, + &format_attr_mask.attr, + NULL, +}; + +static struct attribute_group nhmex_uncore_bbox_format_group = { + .name = "format", + .attrs = nhmex_uncore_bbox_formats_attr, +}; + +static struct intel_uncore_ops nhmex_uncore_bbox_ops = { + NHMEX_UNCORE_OPS_COMMON_INIT(), + .enable_event = nhmex_bbox_msr_enable_event, + .hw_config = nhmex_bbox_hw_config, + .get_constraint = uncore_get_constraint, + .put_constraint = uncore_put_constraint, +}; + +static struct intel_uncore_type nhmex_uncore_bbox = { + .name = "bbox", + .num_counters = 4, + .num_boxes = 2, + .perf_ctr_bits = 48, + .event_ctl = NHMEX_B0_MSR_PMON_CTL0, + .perf_ctr = NHMEX_B0_MSR_PMON_CTR0, + .event_mask = NHMEX_B_PMON_RAW_EVENT_MASK, + .box_ctl = NHMEX_B0_MSR_PMON_GLOBAL_CTL, + .msr_offset = NHMEX_B_MSR_OFFSET, + .pair_ctr_ctl = 1, + .num_shared_regs = 1, + .constraints = nhmex_uncore_bbox_constraints, + .ops = &nhmex_uncore_bbox_ops, + .format_group = &nhmex_uncore_bbox_format_group +}; + +static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + + /* only TO_R_PROG_EV event uses the match/mask register */ + if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) != + NHMEX_S_EVENT_TO_R_PROG_EV) + return 0; + + if (box->pmu->pmu_idx == 0) + reg1->reg = NHMEX_S0_MSR_MM_CFG; + else + reg1->reg = NHMEX_S1_MSR_MM_CFG; + reg1->idx = 0; + reg1->config = event->attr.config1; + reg2->config = event->attr.config2; + return 0; +} + +static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + + if (reg1->idx != EXTRA_REG_NONE) { + wrmsrl(reg1->reg, 0); + wrmsrl(reg1->reg + 1, reg1->config); + wrmsrl(reg1->reg + 2, reg2->config); + wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN); + } + wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22); +} + +static struct attribute *nhmex_uncore_sbox_formats_attr[] = { + &format_attr_event.attr, + &format_attr_umask.attr, + &format_attr_edge.attr, + &format_attr_inv.attr, + &format_attr_thresh8.attr, + &format_attr_match.attr, + &format_attr_mask.attr, + NULL, +}; + +static struct attribute_group nhmex_uncore_sbox_format_group = { + .name = "format", + .attrs = nhmex_uncore_sbox_formats_attr, +}; + +static struct intel_uncore_ops nhmex_uncore_sbox_ops = { + NHMEX_UNCORE_OPS_COMMON_INIT(), + .enable_event = nhmex_sbox_msr_enable_event, + .hw_config = nhmex_sbox_hw_config, + .get_constraint = uncore_get_constraint, + .put_constraint = uncore_put_constraint, +}; + +static struct intel_uncore_type nhmex_uncore_sbox = { + .name = "sbox", + .num_counters = 4, + .num_boxes = 2, + .perf_ctr_bits = 48, + .event_ctl = NHMEX_S0_MSR_PMON_CTL0, + .perf_ctr = NHMEX_S0_MSR_PMON_CTR0, + .event_mask = NHMEX_PMON_RAW_EVENT_MASK, + .box_ctl = NHMEX_S0_MSR_PMON_GLOBAL_CTL, + .msr_offset = NHMEX_S_MSR_OFFSET, + .pair_ctr_ctl = 1, + .num_shared_regs = 1, + .ops = &nhmex_uncore_sbox_ops, + .format_group = &nhmex_uncore_sbox_format_group +}; + +enum { + EXTRA_REG_NHMEX_M_FILTER, + EXTRA_REG_NHMEX_M_DSP, + EXTRA_REG_NHMEX_M_ISS, + EXTRA_REG_NHMEX_M_MAP, + EXTRA_REG_NHMEX_M_MSC_THR, + EXTRA_REG_NHMEX_M_PGT, + EXTRA_REG_NHMEX_M_PLD, + EXTRA_REG_NHMEX_M_ZDP_CTL_FVC, +}; + +static struct extra_reg nhmex_uncore_mbox_extra_regs[] = { + MBOX_INC_SEL_EXTAR_REG(0x0, DSP), + MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR), + MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR), + MBOX_INC_SEL_EXTAR_REG(0x9, ISS), + /* event 0xa uses two extra registers */ + MBOX_INC_SEL_EXTAR_REG(0xa, ISS), + MBOX_INC_SEL_EXTAR_REG(0xa, PLD), + MBOX_INC_SEL_EXTAR_REG(0xb, PLD), + /* events 0xd ~ 0x10 use the same extra register */ + MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC), + MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC), + MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC), + MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC), + MBOX_INC_SEL_EXTAR_REG(0x16, PGT), + MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP), + MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS), + MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT), + MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP), + EVENT_EXTRA_END +}; + +/* Nehalem-EX or Westmere-EX ? */ +static bool uncore_nhmex; + +static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) +{ + struct intel_uncore_extra_reg *er; + unsigned long flags; + bool ret = false; + u64 mask; + + if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { + er = &box->shared_regs[idx]; + raw_spin_lock_irqsave(&er->lock, flags); + if (!atomic_read(&er->ref) || er->config == config) { + atomic_inc(&er->ref); + er->config = config; + ret = true; + } + raw_spin_unlock_irqrestore(&er->lock, flags); + + return ret; + } + /* + * The ZDP_CTL_FVC MSR has 4 fields which are used to control + * events 0xd ~ 0x10. Besides these 4 fields, there are additional + * fields which are shared. + */ + idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; + if (WARN_ON_ONCE(idx >= 4)) + return false; + + /* mask of the shared fields */ + if (uncore_nhmex) + mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; + else + mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK; + er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; + + raw_spin_lock_irqsave(&er->lock, flags); + /* add mask of the non-shared field if it's in use */ + if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) { + if (uncore_nhmex) + mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); + else + mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); + } + + if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { + atomic_add(1 << (idx * 8), &er->ref); + if (uncore_nhmex) + mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | + NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); + else + mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK | + WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); + er->config &= ~mask; + er->config |= (config & mask); + ret = true; + } + raw_spin_unlock_irqrestore(&er->lock, flags); + + return ret; +} + +static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx) +{ + struct intel_uncore_extra_reg *er; + + if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { + er = &box->shared_regs[idx]; + atomic_dec(&er->ref); + return; + } + + idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; + er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; + atomic_sub(1 << (idx * 8), &er->ref); +} + +static u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + u64 idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8); + u64 config = reg1->config; + + /* get the non-shared control bits and shift them */ + idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; + if (uncore_nhmex) + config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); + else + config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); + if (new_idx > orig_idx) { + idx = new_idx - orig_idx; + config <<= 3 * idx; + } else { + idx = orig_idx - new_idx; + config >>= 3 * idx; + } + + /* add the shared control bits back */ + if (uncore_nhmex) + config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; + else + config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; + config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; + if (modify) { + /* adjust the main event selector */ + if (new_idx > orig_idx) + hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT; + else + hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT; + reg1->config = config; + reg1->idx = ~0xff | new_idx; + } + return config; +} + +static struct event_constraint * +nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; + int i, idx[2], alloc = 0; + u64 config1 = reg1->config; + + idx[0] = __BITS_VALUE(reg1->idx, 0, 8); + idx[1] = __BITS_VALUE(reg1->idx, 1, 8); +again: + for (i = 0; i < 2; i++) { + if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i))) + idx[i] = 0xff; + + if (idx[i] == 0xff) + continue; + + if (!nhmex_mbox_get_shared_reg(box, idx[i], + __BITS_VALUE(config1, i, 32))) + goto fail; + alloc |= (0x1 << i); + } + + /* for the match/mask registers */ + if (reg2->idx != EXTRA_REG_NONE && + (uncore_box_is_fake(box) || !reg2->alloc) && + !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config)) + goto fail; + + /* + * If it's a fake box -- as per validate_{group,event}() we + * shouldn't touch event state and we can avoid doing so + * since both will only call get_event_constraints() once + * on each event, this avoids the need for reg->alloc. + */ + if (!uncore_box_is_fake(box)) { + if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) + nhmex_mbox_alter_er(event, idx[0], true); + reg1->alloc |= alloc; + if (reg2->idx != EXTRA_REG_NONE) + reg2->alloc = 1; + } + return NULL; +fail: + if (idx[0] != 0xff && !(alloc & 0x1) && + idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) { + /* + * events 0xd ~ 0x10 are functional identical, but are + * controlled by different fields in the ZDP_CTL_FVC + * register. If we failed to take one field, try the + * rest 3 choices. + */ + BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff); + idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; + idx[0] = (idx[0] + 1) % 4; + idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; + if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) { + config1 = nhmex_mbox_alter_er(event, idx[0], false); + goto again; + } + } + + if (alloc & 0x1) + nhmex_mbox_put_shared_reg(box, idx[0]); + if (alloc & 0x2) + nhmex_mbox_put_shared_reg(box, idx[1]); + return &uncore_constraint_empty; +} + +static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; + + if (uncore_box_is_fake(box)) + return; + + if (reg1->alloc & 0x1) + nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8)); + if (reg1->alloc & 0x2) + nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8)); + reg1->alloc = 0; + + if (reg2->alloc) { + nhmex_mbox_put_shared_reg(box, reg2->idx); + reg2->alloc = 0; + } +} + +static int nhmex_mbox_extra_reg_idx(struct extra_reg *er) +{ + if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) + return er->idx; + return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd; +} + +static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct intel_uncore_type *type = box->pmu->type; + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; + struct extra_reg *er; + unsigned msr; + int reg_idx = 0; + /* + * The mbox events may require 2 extra MSRs at the most. But only + * the lower 32 bits in these MSRs are significant, so we can use + * config1 to pass two MSRs' config. + */ + for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) { + if (er->event != (event->hw.config & er->config_mask)) + continue; + if (event->attr.config1 & ~er->valid_mask) + return -EINVAL; + + msr = er->msr + type->msr_offset * box->pmu->pmu_idx; + if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff)) + return -EINVAL; + + /* always use the 32~63 bits to pass the PLD config */ + if (er->idx == EXTRA_REG_NHMEX_M_PLD) + reg_idx = 1; + else if (WARN_ON_ONCE(reg_idx > 0)) + return -EINVAL; + + reg1->idx &= ~(0xff << (reg_idx * 8)); + reg1->reg &= ~(0xffff << (reg_idx * 16)); + reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8); + reg1->reg |= msr << (reg_idx * 16); + reg1->config = event->attr.config1; + reg_idx++; + } + /* + * The mbox only provides ability to perform address matching + * for the PLD events. + */ + if (reg_idx == 2) { + reg2->idx = EXTRA_REG_NHMEX_M_FILTER; + if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN) + reg2->config = event->attr.config2; + else + reg2->config = ~0ULL; + if (box->pmu->pmu_idx == 0) + reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG; + else + reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG; + } + return 0; +} + +static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx) +{ + struct intel_uncore_extra_reg *er; + unsigned long flags; + u64 config; + + if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) + return box->shared_regs[idx].config; + + er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; + raw_spin_lock_irqsave(&er->lock, flags); + config = er->config; + raw_spin_unlock_irqrestore(&er->lock, flags); + return config; +} + +static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + int idx; + + idx = __BITS_VALUE(reg1->idx, 0, 8); + if (idx != 0xff) + wrmsrl(__BITS_VALUE(reg1->reg, 0, 16), + nhmex_mbox_shared_reg_config(box, idx)); + idx = __BITS_VALUE(reg1->idx, 1, 8); + if (idx != 0xff) + wrmsrl(__BITS_VALUE(reg1->reg, 1, 16), + nhmex_mbox_shared_reg_config(box, idx)); + + if (reg2->idx != EXTRA_REG_NONE) { + wrmsrl(reg2->reg, 0); + if (reg2->config != ~0ULL) { + wrmsrl(reg2->reg + 1, + reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK); + wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK & + (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT)); + wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN); + } + } + + wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); +} + +DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3"); +DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5"); +DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6"); +DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7"); +DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13"); +DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21"); +DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en, filter_cfg_en, "config2:63"); +DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33"); +DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61"); +DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31"); +DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31"); +DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31"); +DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31"); +DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31"); +DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31"); +DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63"); + +static struct attribute *nhmex_uncore_mbox_formats_attr[] = { + &format_attr_count_mode.attr, + &format_attr_storage_mode.attr, + &format_attr_wrap_mode.attr, + &format_attr_flag_mode.attr, + &format_attr_inc_sel.attr, + &format_attr_set_flag_sel.attr, + &format_attr_filter_cfg_en.attr, + &format_attr_filter_match.attr, + &format_attr_filter_mask.attr, + &format_attr_dsp.attr, + &format_attr_thr.attr, + &format_attr_fvc.attr, + &format_attr_pgt.attr, + &format_attr_map.attr, + &format_attr_iss.attr, + &format_attr_pld.attr, + NULL, +}; + +static struct attribute_group nhmex_uncore_mbox_format_group = { + .name = "format", + .attrs = nhmex_uncore_mbox_formats_attr, +}; + +static struct uncore_event_desc nhmex_uncore_mbox_events[] = { + INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"), + INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"), + { /* end: all zeroes */ }, +}; + +static struct uncore_event_desc wsmex_uncore_mbox_events[] = { + INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"), + INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"), + { /* end: all zeroes */ }, +}; + +static struct intel_uncore_ops nhmex_uncore_mbox_ops = { + NHMEX_UNCORE_OPS_COMMON_INIT(), + .enable_event = nhmex_mbox_msr_enable_event, + .hw_config = nhmex_mbox_hw_config, + .get_constraint = nhmex_mbox_get_constraint, + .put_constraint = nhmex_mbox_put_constraint, +}; + +static struct intel_uncore_type nhmex_uncore_mbox = { + .name = "mbox", + .num_counters = 6, + .num_boxes = 2, + .perf_ctr_bits = 48, + .event_ctl = NHMEX_M0_MSR_PMU_CTL0, + .perf_ctr = NHMEX_M0_MSR_PMU_CNT0, + .event_mask = NHMEX_M_PMON_RAW_EVENT_MASK, + .box_ctl = NHMEX_M0_MSR_GLOBAL_CTL, + .msr_offset = NHMEX_M_MSR_OFFSET, + .pair_ctr_ctl = 1, + .num_shared_regs = 8, + .event_descs = nhmex_uncore_mbox_events, + .ops = &nhmex_uncore_mbox_ops, + .format_group = &nhmex_uncore_mbox_format_group, +}; + +static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + + /* adjust the main event selector and extra register index */ + if (reg1->idx % 2) { + reg1->idx--; + hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; + } else { + reg1->idx++; + hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; + } + + /* adjust extra register config */ + switch (reg1->idx % 6) { + case 2: + /* shift the 8~15 bits to the 0~7 bits */ + reg1->config >>= 8; + break; + case 3: + /* shift the 0~7 bits to the 8~15 bits */ + reg1->config <<= 8; + break; + }; +} + +/* + * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7. + * An event set consists of 6 events, the 3rd and 4th events in + * an event set use the same extra register. So an event set uses + * 5 extra registers. + */ +static struct event_constraint * +nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + struct intel_uncore_extra_reg *er; + unsigned long flags; + int idx, er_idx; + u64 config1; + bool ok = false; + + if (!uncore_box_is_fake(box) && reg1->alloc) + return NULL; + + idx = reg1->idx % 6; + config1 = reg1->config; +again: + er_idx = idx; + /* the 3rd and 4th events use the same extra register */ + if (er_idx > 2) + er_idx--; + er_idx += (reg1->idx / 6) * 5; + + er = &box->shared_regs[er_idx]; + raw_spin_lock_irqsave(&er->lock, flags); + if (idx < 2) { + if (!atomic_read(&er->ref) || er->config == reg1->config) { + atomic_inc(&er->ref); + er->config = reg1->config; + ok = true; + } + } else if (idx == 2 || idx == 3) { + /* + * these two events use different fields in a extra register, + * the 0~7 bits and the 8~15 bits respectively. + */ + u64 mask = 0xff << ((idx - 2) * 8); + if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) || + !((er->config ^ config1) & mask)) { + atomic_add(1 << ((idx - 2) * 8), &er->ref); + er->config &= ~mask; + er->config |= config1 & mask; + ok = true; + } + } else { + if (!atomic_read(&er->ref) || + (er->config == (hwc->config >> 32) && + er->config1 == reg1->config && + er->config2 == reg2->config)) { + atomic_inc(&er->ref); + er->config = (hwc->config >> 32); + er->config1 = reg1->config; + er->config2 = reg2->config; + ok = true; + } + } + raw_spin_unlock_irqrestore(&er->lock, flags); + + if (!ok) { + /* + * The Rbox events are always in pairs. The paired + * events are functional identical, but use different + * extra registers. If we failed to take an extra + * register, try the alternative. + */ + idx ^= 1; + if (idx != reg1->idx % 6) { + if (idx == 2) + config1 >>= 8; + else if (idx == 3) + config1 <<= 8; + goto again; + } + } else { + if (!uncore_box_is_fake(box)) { + if (idx != reg1->idx % 6) + nhmex_rbox_alter_er(box, event); + reg1->alloc = 1; + } + return NULL; + } + return &uncore_constraint_empty; +} + +static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event) +{ + struct intel_uncore_extra_reg *er; + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + int idx, er_idx; + + if (uncore_box_is_fake(box) || !reg1->alloc) + return; + + idx = reg1->idx % 6; + er_idx = idx; + if (er_idx > 2) + er_idx--; + er_idx += (reg1->idx / 6) * 5; + + er = &box->shared_regs[er_idx]; + if (idx == 2 || idx == 3) + atomic_sub(1 << ((idx - 2) * 8), &er->ref); + else + atomic_dec(&er->ref); + + reg1->alloc = 0; +} + +static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; + struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; + int idx; + + idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >> + NHMEX_R_PMON_CTL_EV_SEL_SHIFT; + if (idx >= 0x18) + return -EINVAL; + + reg1->idx = idx; + reg1->config = event->attr.config1; + + switch (idx % 6) { + case 4: + case 5: + hwc->config |= event->attr.config & (~0ULL << 32); + reg2->config = event->attr.config2; + break; + }; + return 0; +} + +static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event) +{ + struct hw_perf_event *hwc = &event->hw; + struct hw_perf_event_extra *reg1 = &hwc->extra_reg; + struct hw_perf_event_extra *reg2 = &hwc->branch_reg; + int idx, port; + + idx = reg1->idx; + port = idx / 6 + box->pmu->pmu_idx * 4; + + switch (idx % 6) { + case 0: + wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config); + break; + case 1: + wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config); + break; + case 2: + case 3: + wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port), + uncore_shared_reg_config(box, 2 + (idx / 6) * 5)); + break; + case 4: + wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port), + hwc->config >> 32); + wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config); + wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config); + break; + case 5: + wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port), + hwc->config >> 32); + wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config); + wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config); + break; + }; + + wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | + (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); +} + +DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63"); +DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63"); +DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63"); +DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15"); +DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31"); + +static struct attribute *nhmex_uncore_rbox_formats_attr[] = { + &format_attr_event5.attr, + &format_attr_xbr_mm_cfg.attr, + &format_attr_xbr_match.attr, + &format_attr_xbr_mask.attr, + &format_attr_qlx_cfg.attr, + &format_attr_iperf_cfg.attr, + NULL, +}; + +static struct attribute_group nhmex_uncore_rbox_format_group = { + .name = "format", + .attrs = nhmex_uncore_rbox_formats_attr, +}; + +static struct uncore_event_desc nhmex_uncore_rbox_events[] = { + INTEL_UNCORE_EVENT_DESC(qpi0_flit_send, "event=0x0,iperf_cfg=0x80000000"), + INTEL_UNCORE_EVENT_DESC(qpi1_filt_send, "event=0x6,iperf_cfg=0x80000000"), + INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt, "event=0x0,iperf_cfg=0x40000000"), + INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt, "event=0x6,iperf_cfg=0x40000000"), + INTEL_UNCORE_EVENT_DESC(qpi0_date_response, "event=0x0,iperf_cfg=0xc4"), + INTEL_UNCORE_EVENT_DESC(qpi1_date_response, "event=0x6,iperf_cfg=0xc4"), + { /* end: all zeroes */ }, +}; + +static struct intel_uncore_ops nhmex_uncore_rbox_ops = { + NHMEX_UNCORE_OPS_COMMON_INIT(), + .enable_event = nhmex_rbox_msr_enable_event, + .hw_config = nhmex_rbox_hw_config, + .get_constraint = nhmex_rbox_get_constraint, + .put_constraint = nhmex_rbox_put_constraint, +}; + +static struct intel_uncore_type nhmex_uncore_rbox = { + .name = "rbox", + .num_counters = 8, + .num_boxes = 2, + .perf_ctr_bits = 48, + .event_ctl = NHMEX_R_MSR_PMON_CTL0, + .perf_ctr = NHMEX_R_MSR_PMON_CNT0, + .event_mask = NHMEX_R_PMON_RAW_EVENT_MASK, + .box_ctl = NHMEX_R_MSR_GLOBAL_CTL, + .msr_offset = NHMEX_R_MSR_OFFSET, + .pair_ctr_ctl = 1, + .num_shared_regs = 20, + .event_descs = nhmex_uncore_rbox_events, + .ops = &nhmex_uncore_rbox_ops, + .format_group = &nhmex_uncore_rbox_format_group +}; + +static struct intel_uncore_type *nhmex_msr_uncores[] = { + &nhmex_uncore_ubox, + &nhmex_uncore_cbox, + &nhmex_uncore_bbox, + &nhmex_uncore_sbox, + &nhmex_uncore_mbox, + &nhmex_uncore_rbox, + &nhmex_uncore_wbox, + NULL, +}; + +void nhmex_uncore_cpu_init(void) +{ + if (boot_cpu_data.x86_model == 46) + uncore_nhmex = true; + else + nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events; + if (nhmex_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) + nhmex_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; + uncore_msr_uncores = nhmex_msr_uncores; +} +/* end of Nehalem-EX uncore support */ -- GitLab From 17a6034555c601331311d31beb395f6665056b3e Mon Sep 17 00:00:00 2001 From: Fengguang Wu Date: Mon, 4 Aug 2014 13:29:11 +0200 Subject: [PATCH 0270/9167] perf/x86/uncore: Fix coccinelle warnings arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c:961:2-3: Unneeded semicolon arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c:1100:2-3: Unneeded semicolon arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c:1138:2-3: Unneeded semicolon Remove unneeded semicolon. Generated by: scripts/coccinelle/misc/semicolon.cocci Signed-off-by: Fengguang Wu Signed-off-by: Peter Zijlstra Cc: Yan, Zheng Cc: Arnaldo Carvalho de Melo Link: http://lkml.kernel.org/n/tip-ovfvr4nbqjo7nzc16y2lpjy9@git.kernel.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c index 93b11a8f110d..2749965afed0 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c @@ -958,7 +958,7 @@ static void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event /* shift the 0~7 bits to the 8~15 bits */ reg1->config <<= 8; break; - }; + } } /* @@ -1097,7 +1097,7 @@ static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event hwc->config |= event->attr.config & (~0ULL << 32); reg2->config = event->attr.config2; break; - }; + } return 0; } @@ -1135,7 +1135,7 @@ static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct per wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config); wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config); break; - }; + } wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 | (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); -- GitLab From 36bbb2f2988a29cdc3f8e0c93478795934553454 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 31 Jul 2014 14:05:22 -0700 Subject: [PATCH 0271/9167] perf/x86: Use extended offcore mask on Haswell HSW-EP has a larger offcore mask than the client Haswell CPUs. It is the same mask as on Sandy/IvyBridge-EP. All of Haswell was using the client mask, so some bits were missing. On the client parts some bits were also missing compared to Sandy/IvyBridge, in particular the bits to match on a L4 cache hit. The Haswell core in both client and server incarnations accepts the same bits (but some are nops), so we can use the same mask. So use the snbep extended mask, which is a superset of the client and the server, for all of Haswell. This allows specifying a number of extra offcore events, like for example for HSW-EP. % perf stat -e cpu/event=0xb7,umask=0x1,offcore_rsp=0x3fffc00100,name=offcore_response_pf_l3_rfo_l3_miss_any_response/ true which were before. Signed-off-by: Andi Kleen Reviewed-by: eranian@google.com Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Link: http://lkml.kernel.org/r/1406840722-25416-1-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 38d1f6d024ff..89bc750efccb 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -2553,7 +2553,7 @@ __init int intel_pmu_init(void) x86_pmu.event_constraints = intel_hsw_event_constraints; x86_pmu.pebs_constraints = intel_hsw_pebs_event_constraints; - x86_pmu.extra_regs = intel_snb_extra_regs; + x86_pmu.extra_regs = intel_snbep_extra_regs; x86_pmu.pebs_aliases = intel_pebs_aliases_snb; /* all extra regs are per-cpu when HT is on */ x86_pmu.er_flags |= ERF_HAS_RSP_1; -- GitLab From e708d7ad80737496870fd0b6794704d063fb0cdc Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 4 Aug 2014 15:31:08 +0200 Subject: [PATCH 0272/9167] perf: Do poll_wait() before checking condition in perf_poll() One should first enqueue to the waitqueue and then check for the condition. If the condition gets true after mutex_unlock() but before poll_wait() then we lose it and would have wait for another wakeup. This has been like this since v2.6.31-rc1 commit c7138f37f9 ("perf_counter: fix perf_poll()"). Before that it was slightly worse. I guess we get enough wakeups so if we miss here one it doesn't really matter. It is still a bad example. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1407159068-1478-1-git-send-email-bigeasy@linutronix.de Cc: Arnaldo Carvalho de Melo Cc: Linus Torvalds Signed-off-by: Ingo Molnar --- kernel/events/core.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index a25460559b4f..2d7363adf678 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -3629,6 +3629,7 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) struct ring_buffer *rb; unsigned int events = POLL_HUP; + poll_wait(file, &event->waitq, wait); /* * Pin the event->rb by taking event->mmap_mutex; otherwise * perf_event_set_output() can swizzle our rb and make us miss wakeups. @@ -3638,9 +3639,6 @@ static unsigned int perf_poll(struct file *file, poll_table *wait) if (rb) events = atomic_xchg(&rb->poll, 0); mutex_unlock(&event->mmap_mutex); - - poll_wait(file, &event->waitq, wait); - return events; } -- GitLab From 03de874aa76ac0adcf6f56ebf3de623d09a5dde3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Aug 2014 17:08:54 -0700 Subject: [PATCH 0273/9167] perf/x86: Fix :pp without LBR This fixes a side effect of Kan's earlier patch to probe the LBRs at boot time. Normally when the LBRs are disabled cycles:pp is disabled too. So for example cycles:pp doesn't work. However this is not needed with PEBSv2 and later (Haswell) because it does not need LBRs to correct the IP-off-by-one. So add an extra check for PEBSv2 that also allows :pp Signed-off-by: Andi Kleen Signed-off-by: Peter Zijlstra Cc: kan.liang@intel.com Cc: Arnaldo Carvalho de Melo Link: http://lkml.kernel.org/r/1407456534-15747-1-git-send-email-andi@firstfloor.org Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 2879ecdaac43..0646d3b63b9d 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c @@ -387,7 +387,7 @@ int x86_pmu_hw_config(struct perf_event *event) precise++; /* Support for IP fixup */ - if (x86_pmu.lbr_nr) + if (x86_pmu.lbr_nr || x86_pmu.intel_cap.pebs_format >= 2) precise++; } -- GitLab From 86a04461a99fb857bd7d7f87b234cae27df07f8a Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 11 Aug 2014 21:27:10 +0200 Subject: [PATCH 0274/9167] perf/x86: Revamp PEBS event selection The basic idea is that it does not make sense to list all PEBS events individually. The list is very long, sometimes outdated and the hardware doesn't need it. If an event does not support PEBS it will just not count, there is no security issue. We need to only list events that something special, like supporting load or store addresses. This vastly simplifies the PEBS event selection. It also speeds up the scheduling because the scheduler doesn't have to walk as many constraints. Bugs fixed: - We do not allow setting forbidden flags with PEBS anymore (SDM 18.9.4), except for the special cycle event. This is done using a new constraint macro that also matches on the event flags. - Correct DataLA and load/store/na flags reporting on Haswell [Requires a followon patch] - We did not allow all PEBS events on Haswell: We were missing some valid subevents in d1-d2 (MEM_LOAD_UOPS_RETIRED.*, MEM_LOAD_UOPS_RETIRED_L3_HIT_RETIRED.*) This includes the changes proposed by Stephane earlier and obsoletes his patchkit (except for some changes on pre Sandy Bridge/Silvermont CPUs) I only did Sandy Bridge and Silvermont and later so far, mostly because these are the parts I could directly confirm the hardware behavior with hardware architects. Also I do not believe the older CPUs have any missing events in their PEBS list, so there's no pressing need to change them. I did not implement the flag proposed by Peter to allow setting forbidden flags. If really needed this could be implemented on to of this patch. v2: Fix broken store events on SNB/IVB (Stephane Eranian) v3: More fixes. Rename some arguments (Stephane Eranian) v4: List most Haswell events individually again to report memory operation type correctly. Add new flags to describe load/store/na for datala. Update description. Signed-off-by: Andi Kleen Reviewed-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1407785233-32193-2-git-send-email-eranian@google.com Cc: Arnaldo Carvalho de Melo Cc: Kan Liang Cc: Linus Torvalds Cc: Maria Dimakopoulou Cc: Mark Davies Cc: Paul Mackerras Cc: Stephane Eranian Cc: Yan, Zheng Signed-off-by: Ingo Molnar --- arch/x86/include/asm/perf_event.h | 8 ++ arch/x86/kernel/cpu/perf_event.h | 48 ++++++++-- arch/x86/kernel/cpu/perf_event_intel_ds.c | 107 +++++++--------------- 3 files changed, 85 insertions(+), 78 deletions(-) diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index 8249df45d2f2..8dfc9fd094a3 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h @@ -51,6 +51,14 @@ ARCH_PERFMON_EVENTSEL_EDGE | \ ARCH_PERFMON_EVENTSEL_INV | \ ARCH_PERFMON_EVENTSEL_CMASK) +#define X86_ALL_EVENT_FLAGS \ + (ARCH_PERFMON_EVENTSEL_EDGE | \ + ARCH_PERFMON_EVENTSEL_INV | \ + ARCH_PERFMON_EVENTSEL_CMASK | \ + ARCH_PERFMON_EVENTSEL_ANY | \ + ARCH_PERFMON_EVENTSEL_PIN_CONTROL | \ + HSW_IN_TX | \ + HSW_IN_TX_CHECKPOINTED) #define AMD64_RAW_EVENT_MASK \ (X86_RAW_EVENT_MASK | \ AMD64_EVENTSEL_EVENT) diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 8ade93111e03..fc5eb390b368 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h @@ -67,8 +67,10 @@ struct event_constraint { */ #define PERF_X86_EVENT_PEBS_LDLAT 0x1 /* ld+ldlat data address sampling */ #define PERF_X86_EVENT_PEBS_ST 0x2 /* st data address sampling */ -#define PERF_X86_EVENT_PEBS_ST_HSW 0x4 /* haswell style st data sampling */ +#define PERF_X86_EVENT_PEBS_ST_HSW 0x4 /* haswell style datala, store */ #define PERF_X86_EVENT_COMMITTED 0x8 /* event passed commit_txn */ +#define PERF_X86_EVENT_PEBS_LD_HSW 0x10 /* haswell style datala, load */ +#define PERF_X86_EVENT_PEBS_NA_HSW 0x20 /* haswell style datala, unknown */ struct amd_nb { int nb_id; /* NorthBridge id */ @@ -252,18 +254,52 @@ struct cpu_hw_events { EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK) #define INTEL_PLD_CONSTRAINT(c, n) \ - __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \ + __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LDLAT) #define INTEL_PST_CONSTRAINT(c, n) \ - __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \ + __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST) -/* DataLA version of store sampling without extra enable bit. */ -#define INTEL_PST_HSW_CONSTRAINT(c, n) \ - __EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK, \ +/* Event constraint, but match on all event flags too. */ +#define INTEL_FLAGS_EVENT_CONSTRAINT(c, n) \ + EVENT_CONSTRAINT(c, n, INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS) + +/* Check only flags, but allow all event/umask */ +#define INTEL_ALL_EVENT_CONSTRAINT(code, n) \ + EVENT_CONSTRAINT(code, n, X86_ALL_EVENT_FLAGS) + +/* Check flags and event code, and set the HSW store flag */ +#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_ST(code, n) \ + __EVENT_CONSTRAINT(code, n, \ + ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \ + HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW) + +/* Check flags and event code, and set the HSW load flag */ +#define INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(code, n) \ + __EVENT_CONSTRAINT(code, n, \ + ARCH_PERFMON_EVENTSEL_EVENT|X86_ALL_EVENT_FLAGS, \ + HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW) + +/* Check flags and event code/umask, and set the HSW store flag */ +#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(code, n) \ + __EVENT_CONSTRAINT(code, n, \ + INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \ HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_ST_HSW) +/* Check flags and event code/umask, and set the HSW load flag */ +#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(code, n) \ + __EVENT_CONSTRAINT(code, n, \ + INTEL_ARCH_EVENT_MASK|X86_ALL_EVENT_FLAGS, \ + HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_LD_HSW) + +/* Check flags and event code/umask, and set the HSW N/A flag */ +#define INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(code, n) \ + __EVENT_CONSTRAINT(code, n, \ + INTEL_ARCH_EVENT_MASK|INTEL_ARCH_EVENT_MASK, \ + HWEIGHT(n), 0, PERF_X86_EVENT_PEBS_NA_HSW) + + /* * We define the end marker as having a weight of -1 * to enable blacklisting of events using a counter bitmask diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 696ade311ded..aca77e99e676 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -569,28 +569,10 @@ struct event_constraint intel_atom_pebs_event_constraints[] = { }; struct event_constraint intel_slm_pebs_event_constraints[] = { - INTEL_UEVENT_CONSTRAINT(0x0103, 0x1), /* REHABQ.LD_BLOCK_ST_FORWARD_PS */ - INTEL_UEVENT_CONSTRAINT(0x0803, 0x1), /* REHABQ.LD_SPLITS_PS */ - INTEL_UEVENT_CONSTRAINT(0x0204, 0x1), /* MEM_UOPS_RETIRED.L2_HIT_LOADS_PS */ - INTEL_UEVENT_CONSTRAINT(0x0404, 0x1), /* MEM_UOPS_RETIRED.L2_MISS_LOADS_PS */ - INTEL_UEVENT_CONSTRAINT(0x0804, 0x1), /* MEM_UOPS_RETIRED.DTLB_MISS_LOADS_PS */ - INTEL_UEVENT_CONSTRAINT(0x2004, 0x1), /* MEM_UOPS_RETIRED.HITM_PS */ - INTEL_UEVENT_CONSTRAINT(0x00c0, 0x1), /* INST_RETIRED.ANY_PS */ - INTEL_UEVENT_CONSTRAINT(0x00c4, 0x1), /* BR_INST_RETIRED.ALL_BRANCHES_PS */ - INTEL_UEVENT_CONSTRAINT(0x7ec4, 0x1), /* BR_INST_RETIRED.JCC_PS */ - INTEL_UEVENT_CONSTRAINT(0xbfc4, 0x1), /* BR_INST_RETIRED.FAR_BRANCH_PS */ - INTEL_UEVENT_CONSTRAINT(0xebc4, 0x1), /* BR_INST_RETIRED.NON_RETURN_IND_PS */ - INTEL_UEVENT_CONSTRAINT(0xf7c4, 0x1), /* BR_INST_RETIRED.RETURN_PS */ - INTEL_UEVENT_CONSTRAINT(0xf9c4, 0x1), /* BR_INST_RETIRED.CALL_PS */ - INTEL_UEVENT_CONSTRAINT(0xfbc4, 0x1), /* BR_INST_RETIRED.IND_CALL_PS */ - INTEL_UEVENT_CONSTRAINT(0xfdc4, 0x1), /* BR_INST_RETIRED.REL_CALL_PS */ - INTEL_UEVENT_CONSTRAINT(0xfec4, 0x1), /* BR_INST_RETIRED.TAKEN_JCC_PS */ - INTEL_UEVENT_CONSTRAINT(0x00c5, 0x1), /* BR_INST_MISP_RETIRED.ALL_BRANCHES_PS */ - INTEL_UEVENT_CONSTRAINT(0x7ec5, 0x1), /* BR_INST_MISP_RETIRED.JCC_PS */ - INTEL_UEVENT_CONSTRAINT(0xebc5, 0x1), /* BR_INST_MISP_RETIRED.NON_RETURN_IND_PS */ - INTEL_UEVENT_CONSTRAINT(0xf7c5, 0x1), /* BR_INST_MISP_RETIRED.RETURN_PS */ - INTEL_UEVENT_CONSTRAINT(0xfbc5, 0x1), /* BR_INST_MISP_RETIRED.IND_CALL_PS */ - INTEL_UEVENT_CONSTRAINT(0xfec5, 0x1), /* BR_INST_MISP_RETIRED.TAKEN_JCC_PS */ + /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */ + INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf), + /* Allow all events as PEBS with no flags */ + INTEL_ALL_EVENT_CONSTRAINT(0, 0x1), EVENT_CONSTRAINT_END }; @@ -626,68 +608,44 @@ struct event_constraint intel_westmere_pebs_event_constraints[] = { struct event_constraint intel_snb_pebs_event_constraints[] = { INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */ - INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */ - INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */ - INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */ INTEL_PST_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORES */ - INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */ - INTEL_UEVENT_CONSTRAINT(0x02d4, 0xf), /* MEM_LOAD_UOPS_MISC_RETIRED.LLC_MISS */ + /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */ + INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf), + /* Allow all events as PEBS with no flags */ + INTEL_ALL_EVENT_CONSTRAINT(0, 0xf), EVENT_CONSTRAINT_END }; struct event_constraint intel_ivb_pebs_event_constraints[] = { INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */ - INTEL_UEVENT_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */ - INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */ - INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xc5, 0xf), /* BR_MISP_RETIRED.* */ INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.LAT_ABOVE_THR */ INTEL_PST_CONSTRAINT(0x02cd, 0x8), /* MEM_TRANS_RETIRED.PRECISE_STORES */ - INTEL_EVENT_CONSTRAINT(0xd0, 0xf), /* MEM_UOP_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xd2, 0xf), /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.* */ - INTEL_EVENT_CONSTRAINT(0xd3, 0xf), /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.* */ + /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */ + INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf), + /* Allow all events as PEBS with no flags */ + INTEL_ALL_EVENT_CONSTRAINT(0, 0xf), EVENT_CONSTRAINT_END }; struct event_constraint intel_hsw_pebs_event_constraints[] = { INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PRECDIST */ - INTEL_PST_HSW_CONSTRAINT(0x01c2, 0xf), /* UOPS_RETIRED.ALL */ - INTEL_UEVENT_CONSTRAINT(0x02c2, 0xf), /* UOPS_RETIRED.RETIRE_SLOTS */ - INTEL_EVENT_CONSTRAINT(0xc4, 0xf), /* BR_INST_RETIRED.* */ - INTEL_UEVENT_CONSTRAINT(0x01c5, 0xf), /* BR_MISP_RETIRED.CONDITIONAL */ - INTEL_UEVENT_CONSTRAINT(0x04c5, 0xf), /* BR_MISP_RETIRED.ALL_BRANCHES */ - INTEL_UEVENT_CONSTRAINT(0x20c5, 0xf), /* BR_MISP_RETIRED.NEAR_TAKEN */ - INTEL_PLD_CONSTRAINT(0x01cd, 0x8), /* MEM_TRANS_RETIRED.* */ - /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */ - INTEL_UEVENT_CONSTRAINT(0x11d0, 0xf), - /* MEM_UOPS_RETIRED.STLB_MISS_STORES */ - INTEL_UEVENT_CONSTRAINT(0x12d0, 0xf), - INTEL_UEVENT_CONSTRAINT(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */ - INTEL_UEVENT_CONSTRAINT(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */ - /* MEM_UOPS_RETIRED.SPLIT_STORES */ - INTEL_UEVENT_CONSTRAINT(0x42d0, 0xf), - INTEL_UEVENT_CONSTRAINT(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */ - INTEL_PST_HSW_CONSTRAINT(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */ - INTEL_UEVENT_CONSTRAINT(0x01d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L1_HIT */ - INTEL_UEVENT_CONSTRAINT(0x02d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L2_HIT */ - INTEL_UEVENT_CONSTRAINT(0x04d1, 0xf), /* MEM_LOAD_UOPS_RETIRED.L3_HIT */ - /* MEM_LOAD_UOPS_RETIRED.HIT_LFB */ - INTEL_UEVENT_CONSTRAINT(0x40d1, 0xf), - /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_MISS */ - INTEL_UEVENT_CONSTRAINT(0x01d2, 0xf), - /* MEM_LOAD_UOPS_LLC_HIT_RETIRED.XSNP_HIT */ - INTEL_UEVENT_CONSTRAINT(0x02d2, 0xf), - /* MEM_LOAD_UOPS_LLC_MISS_RETIRED.LOCAL_DRAM */ - INTEL_UEVENT_CONSTRAINT(0x01d3, 0xf), - INTEL_UEVENT_CONSTRAINT(0x04c8, 0xf), /* HLE_RETIRED.Abort */ - INTEL_UEVENT_CONSTRAINT(0x04c9, 0xf), /* RTM_RETIRED.Abort */ - + INTEL_PLD_CONSTRAINT(0x01cd, 0xf), /* MEM_TRANS_RETIRED.* */ + /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */ + INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf), + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_NA(0x01c2, 0xf), /* UOPS_RETIRED.ALL */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x11d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x21d0, 0xf), /* MEM_UOPS_RETIRED.LOCK_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x41d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_LD(0x81d0, 0xf), /* MEM_UOPS_RETIRED.ALL_LOADS */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x12d0, 0xf), /* MEM_UOPS_RETIRED.STLB_MISS_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x42d0, 0xf), /* MEM_UOPS_RETIRED.SPLIT_STORES */ + INTEL_FLAGS_UEVENT_CONSTRAINT_DATALA_ST(0x82d0, 0xf), /* MEM_UOPS_RETIRED.ALL_STORES */ + INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd1, 0xf), /* MEM_LOAD_UOPS_RETIRED.* */ + INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd2, 0xf), /* MEM_LOAD_UOPS_L3_HIT_RETIRED.* */ + INTEL_FLAGS_EVENT_CONSTRAINT_DATALA_LD(0xd3, 0xf), /* MEM_LOAD_UOPS_L3_MISS_RETIRED.* */ + /* Allow all events as PEBS with no flags */ + INTEL_ALL_EVENT_CONSTRAINT(0, 0xf), EVENT_CONSTRAINT_END }; @@ -880,7 +838,9 @@ static void __intel_pmu_pebs_event(struct perf_event *event, fll = event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT; fst = event->hw.flags & (PERF_X86_EVENT_PEBS_ST | - PERF_X86_EVENT_PEBS_ST_HSW); + PERF_X86_EVENT_PEBS_ST_HSW | + PERF_X86_EVENT_PEBS_LD_HSW | + PERF_X86_EVENT_PEBS_NA_HSW); perf_sample_data_init(&data, 0, event->hw.last_period); @@ -903,7 +863,10 @@ static void __intel_pmu_pebs_event(struct perf_event *event, if (sample_type & PERF_SAMPLE_DATA_SRC) { if (fll) data.data_src.val = load_latency_data(pebs->dse); - else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) + else if (event->hw.flags & + (PERF_X86_EVENT_PEBS_ST_HSW| + PERF_X86_EVENT_PEBS_LD_HSW| + PERF_X86_EVENT_PEBS_NA_HSW)) data.data_src.val = precise_store_data_hsw(event, pebs->dse); else -- GitLab From f3908b8cfb65ab6e78ac84df3b864eb22d5b6d9e Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 11 Aug 2014 21:27:11 +0200 Subject: [PATCH 0275/9167] perf/x86: Don't mark DataLA addresses as store Haswell supports reporting the data address for a range of PEBS events, including: UOPS_RETIRED.ALL MEM_UOPS_RETIRED.STLB_MISS_LOADS MEM_UOPS_RETIRED.STLB_MISS_STORES MEM_UOPS_RETIRED.LOCK_LOADS MEM_UOPS_RETIRED.SPLIT_LOADS MEM_UOPS_RETIRED.SPLIT_STORES MEM_UOPS_RETIRED.ALL_LOADS MEM_UOPS_RETIRED.ALL_STORES MEM_LOAD_UOPS_RETIRED.L1_HIT MEM_LOAD_UOPS_RETIRED.L2_HIT MEM_LOAD_UOPS_RETIRED.L3_HIT MEM_LOAD_UOPS_RETIRED.L1_MISS MEM_LOAD_UOPS_RETIRED.L2_MISS MEM_LOAD_UOPS_RETIRED.L3_MISS MEM_LOAD_UOPS_RETIRED.HIT_LFB MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_MISS MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HIT MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_HITM MEM_LOAD_UOPS_L3_HIT_RETIRED.XSNP_NONE MEM_LOAD_UOPS_L3_MISS_RETIRED.LOCAL_DRAM This facility was already enabled earlier with the original Haswell perf changes. However these addresses were always reports as stores by perf, which is wrong, as they could be loads too. The hardware does not distinguish loads and stores for these instructions, so there's no (cheap) way for the profiler to find out. Change the type to PERF_MEM_OP_NA instead. Signed-off-by: Andi Kleen Reviewed-by: Stephane Eranian Signed-off-by: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Link: http://lkml.kernel.org/r/1407785233-32193-3-git-send-email-eranian@google.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index aca77e99e676..a9b60f32064f 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -114,7 +114,7 @@ static u64 precise_store_data_hsw(struct perf_event *event, u64 status) u64 cfg = event->hw.config & INTEL_ARCH_EVENT_MASK; dse.val = 0; - dse.mem_op = PERF_MEM_OP_STORE; + dse.mem_op = PERF_MEM_OP_NA; dse.mem_lvl = PERF_MEM_LVL_NA; /* -- GitLab From 770eee1fd38c70a009b321f5dbe64358f42511fd Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Mon, 11 Aug 2014 21:27:12 +0200 Subject: [PATCH 0276/9167] perf/x86: Fix data source encoding issues for load latency/precise store This patch fixes issues introuduce by Andi's previous patch 'Revamp PEBS' series. This patch fixes the following: - precise_store_data_hsw() encode the mem op type whenever we can - precise_store_data_hsw set the default data source correctly - 0 is not a valid init value for data source. Define PERF_MEM_NA as the default value This bug was actually introduced by commit 722e76e60f2775c21b087ff12c5e678cf0ebcaaf Author: Stephane Eranian Date: Thu May 15 17:56:44 2014 +0200 fix Haswell precise store data source encoding Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1407785233-32193-4-git-send-email-eranian@google.com Cc: Arnaldo Carvalho de Melo Cc: ak@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 11 +++++++---- include/linux/perf_event.h | 9 ++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index a9b60f32064f..67919ce0f76a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -113,9 +113,12 @@ static u64 precise_store_data_hsw(struct perf_event *event, u64 status) union perf_mem_data_src dse; u64 cfg = event->hw.config & INTEL_ARCH_EVENT_MASK; - dse.val = 0; - dse.mem_op = PERF_MEM_OP_NA; - dse.mem_lvl = PERF_MEM_LVL_NA; + dse.val = PERF_MEM_NA; + + if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) + dse.mem_op = PERF_MEM_OP_STORE; + else if (event->hw.flags & PERF_X86_EVENT_PEBS_LD_HSW) + dse.mem_op = PERF_MEM_OP_LOAD; /* * L1 info only valid for following events: @@ -126,7 +129,7 @@ static u64 precise_store_data_hsw(struct perf_event *event, u64 status) * MEM_UOPS_RETIRED.ALL_STORES */ if (cfg != 0x12d0 && cfg != 0x22d0 && cfg != 0x42d0 && cfg != 0x82d0) - return dse.mem_lvl; + return dse.val; if (status & 1) dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT; diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index ef5b62bdb103..f0a1036b1911 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h @@ -608,6 +608,13 @@ struct perf_sample_data { u64 txn; }; +/* default value for data source */ +#define PERF_MEM_NA (PERF_MEM_S(OP, NA) |\ + PERF_MEM_S(LVL, NA) |\ + PERF_MEM_S(SNOOP, NA) |\ + PERF_MEM_S(LOCK, NA) |\ + PERF_MEM_S(TLB, NA)) + static inline void perf_sample_data_init(struct perf_sample_data *data, u64 addr, u64 period) { @@ -620,7 +627,7 @@ static inline void perf_sample_data_init(struct perf_sample_data *data, data->regs_user.regs = NULL; data->stack_user_size = 0; data->weight = 0; - data->data_src.val = 0; + data->data_src.val = PERF_MEM_NA; data->txn = 0; } -- GitLab From c8aab2e04ac9f442a07abeaf49ddd1703c608f47 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Mon, 11 Aug 2014 21:27:13 +0200 Subject: [PATCH 0277/9167] perf/x86: Clean up __intel_pmu_pebs_event() code This patch makes the code more readable. It also renames precise_store_data_hsw() to precise_datala_hsw() because the function is called for both loads and stores on HSW. The patch also gets rid of the hardcoded store events codes in that same function. Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/1407785233-32193-5-git-send-email-eranian@google.com Cc: ak@linux.intel.com Cc: Arnaldo Carvalho de Melo Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_ds.c | 81 +++++++++++------------ 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 67919ce0f76a..9dc419991772 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c @@ -108,10 +108,9 @@ static u64 precise_store_data(u64 status) return val; } -static u64 precise_store_data_hsw(struct perf_event *event, u64 status) +static u64 precise_datala_hsw(struct perf_event *event, u64 status) { union perf_mem_data_src dse; - u64 cfg = event->hw.config & INTEL_ARCH_EVENT_MASK; dse.val = PERF_MEM_NA; @@ -128,15 +127,12 @@ static u64 precise_store_data_hsw(struct perf_event *event, u64 status) * MEM_UOPS_RETIRED.SPLIT_STORES * MEM_UOPS_RETIRED.ALL_STORES */ - if (cfg != 0x12d0 && cfg != 0x22d0 && cfg != 0x42d0 && cfg != 0x82d0) - return dse.val; - - if (status & 1) - dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT; - else - dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_MISS; - - /* Nothing else supported. Sorry. */ + if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) { + if (status & 1) + dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT; + else + dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_MISS; + } return dse.val; } @@ -825,6 +821,10 @@ static inline u64 intel_hsw_transaction(struct pebs_record_hsw *pebs) static void __intel_pmu_pebs_event(struct perf_event *event, struct pt_regs *iregs, void *__pebs) { +#define PERF_X86_EVENT_PEBS_HSW_PREC \ + (PERF_X86_EVENT_PEBS_ST_HSW | \ + PERF_X86_EVENT_PEBS_LD_HSW | \ + PERF_X86_EVENT_PEBS_NA_HSW) /* * We cast to the biggest pebs_record but are careful not to * unconditionally access the 'extra' entries. @@ -834,47 +834,40 @@ static void __intel_pmu_pebs_event(struct perf_event *event, struct perf_sample_data data; struct pt_regs regs; u64 sample_type; - int fll, fst; + int fll, fst, dsrc; + int fl = event->hw.flags; if (!intel_pmu_save_and_restart(event)) return; - fll = event->hw.flags & PERF_X86_EVENT_PEBS_LDLAT; - fst = event->hw.flags & (PERF_X86_EVENT_PEBS_ST | - PERF_X86_EVENT_PEBS_ST_HSW | - PERF_X86_EVENT_PEBS_LD_HSW | - PERF_X86_EVENT_PEBS_NA_HSW); + sample_type = event->attr.sample_type; + dsrc = sample_type & PERF_SAMPLE_DATA_SRC; + + fll = fl & PERF_X86_EVENT_PEBS_LDLAT; + fst = fl & (PERF_X86_EVENT_PEBS_ST | PERF_X86_EVENT_PEBS_HSW_PREC); perf_sample_data_init(&data, 0, event->hw.last_period); data.period = event->hw.last_period; - sample_type = event->attr.sample_type; /* - * if PEBS-LL or PreciseStore + * Use latency for weight (only avail with PEBS-LL) */ - if (fll || fst) { - /* - * Use latency for weight (only avail with PEBS-LL) - */ - if (fll && (sample_type & PERF_SAMPLE_WEIGHT)) - data.weight = pebs->lat; - - /* - * data.data_src encodes the data source - */ - if (sample_type & PERF_SAMPLE_DATA_SRC) { - if (fll) - data.data_src.val = load_latency_data(pebs->dse); - else if (event->hw.flags & - (PERF_X86_EVENT_PEBS_ST_HSW| - PERF_X86_EVENT_PEBS_LD_HSW| - PERF_X86_EVENT_PEBS_NA_HSW)) - data.data_src.val = - precise_store_data_hsw(event, pebs->dse); - else - data.data_src.val = precise_store_data(pebs->dse); - } + if (fll && (sample_type & PERF_SAMPLE_WEIGHT)) + data.weight = pebs->lat; + + /* + * data.data_src encodes the data source + */ + if (dsrc) { + u64 val = PERF_MEM_NA; + if (fll) + val = load_latency_data(pebs->dse); + else if (fst && (fl & PERF_X86_EVENT_PEBS_HSW_PREC)) + val = precise_datala_hsw(event, pebs->dse); + else if (fst) + val = precise_store_data(pebs->dse); + data.data_src.val = val; } /* @@ -901,16 +894,16 @@ static void __intel_pmu_pebs_event(struct perf_event *event, else regs.flags &= ~PERF_EFLAGS_EXACT; - if ((event->attr.sample_type & PERF_SAMPLE_ADDR) && + if ((sample_type & PERF_SAMPLE_ADDR) && x86_pmu.intel_cap.pebs_format >= 1) data.addr = pebs->dla; if (x86_pmu.intel_cap.pebs_format >= 2) { /* Only set the TSX weight when no memory weight. */ - if ((event->attr.sample_type & PERF_SAMPLE_WEIGHT) && !fll) + if ((sample_type & PERF_SAMPLE_WEIGHT) && !fll) data.weight = intel_hsw_weight(pebs); - if (event->attr.sample_type & PERF_SAMPLE_TRANSACTION) + if (sample_type & PERF_SAMPLE_TRANSACTION) data.txn = intel_hsw_transaction(pebs); } -- GitLab From 85a16ef66cc8a053de80aadf13722a2c1254d346 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Tue, 12 Aug 2014 08:00:31 +0200 Subject: [PATCH 0278/9167] perf/x86/uncore: Export basic memory events for IVT IMC PMU This patch exposes two basic events for Ivytown IMC uncore PMU: - cas_count_read: number of full-cache line reads to memory controller - cas_count_write: number of full-cache line writes to memory controller Those events use the same encoding as for SNB-EP, so reuse the same event table. See specification in: http://www.intel.com/content/dam/www/public/us/en/documents/manuals/xeon-e5-2600-v2-uncore-manual.pdf By aggregating all the read and write events from all the memory controllers of each processor socket, one can determine the total memory bandwidth utilization. Signed-off-by: Stephane Eranian Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20140812060031.GA25239@quad Cc: zheng.z.yan@intel.com Cc: ak@linux.intel.com Cc: Arnaldo Carvalho de Melo Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c index 30468f434e9e..00bd0485ed13 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c @@ -1422,6 +1422,7 @@ static struct intel_uncore_type ivt_uncore_imc = { .fixed_ctr_bits = 48, .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, + .event_descs = snbep_uncore_imc_events, IVT_UNCORE_PCI_COMMON_INIT(), }; -- GitLab From ddcd0973fe02aad3d4bdc59dd0f1db90f51105a9 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 12 Aug 2014 09:15:25 +0200 Subject: [PATCH 0279/9167] perf/x86/uncore: Rename IvyTown to IvyBridge-EP Keeping track of all the various CPU names is hard enough; adding extra silly names for no reason is just not helping. If we know the base arch name (IvyBridge) then we can do the client/server parts with the well known {,EP,EX} postfixes, no need to remember endless amounts of unrelated and pointless names for this. Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/n/tip-8559jke61dsyr7d0i74iutli@git.kernel.org Cc: Arnaldo Carvalho de Melo Cc: Linus Torvalds Cc: Stephane Eranian Cc: Yan, Zheng Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/perf_event_intel_uncore.c | 8 +- arch/x86/kernel/cpu/perf_event_intel_uncore.h | 4 +- .../cpu/perf_event_intel_uncore_snbep.c | 340 +++++++++--------- 3 files changed, 176 insertions(+), 176 deletions(-) diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index b1f84d9ccc48..4785ee8ac599 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c @@ -880,8 +880,8 @@ static int __init uncore_pci_init(void) case 45: /* Sandy Bridge-EP */ ret = snbep_uncore_pci_init(); break; - case 62: /* IvyTown */ - ret = ivt_uncore_pci_init(); + case 62: /* Ivy Bridge-EP */ + ret = ivbep_uncore_pci_init(); break; case 42: /* Sandy Bridge */ ret = snb_uncore_pci_init(); @@ -1187,8 +1187,8 @@ static int __init uncore_cpu_init(void) case 47: /* Westmere-EX aka. Xeon E7 */ nhmex_uncore_cpu_init(); break; - case 62: /* IvyTown */ - ivt_uncore_cpu_init(); + case 62: /* Ivy Bridge-EP */ + ivbep_uncore_cpu_init(); break; default: diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index b91559936d49..1d7e89416018 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h @@ -330,8 +330,8 @@ void nhm_uncore_cpu_init(void); /* perf_event_intel_uncore_snbep.c */ int snbep_uncore_pci_init(void); void snbep_uncore_cpu_init(void); -int ivt_uncore_pci_init(void); -void ivt_uncore_cpu_init(void); +int ivbep_uncore_pci_init(void); +void ivbep_uncore_cpu_init(void); /* perf_event_intel_uncore_nhmex.c */ void nhmex_uncore_cpu_init(void); diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c index 00bd0485ed13..d3e9c55d984a 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c @@ -111,43 +111,43 @@ #define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc #define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd -/* IVT event control */ -#define IVT_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ +/* IVBEP event control */ +#define IVBEP_PMON_BOX_CTL_INT (SNBEP_PMON_BOX_CTL_RST_CTRL | \ SNBEP_PMON_BOX_CTL_RST_CTRS) -#define IVT_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ +#define IVBEP_PMON_RAW_EVENT_MASK (SNBEP_PMON_CTL_EV_SEL_MASK | \ SNBEP_PMON_CTL_UMASK_MASK | \ SNBEP_PMON_CTL_EDGE_DET | \ SNBEP_PMON_CTL_TRESH_MASK) -/* IVT Ubox */ -#define IVT_U_MSR_PMON_GLOBAL_CTL 0xc00 -#define IVT_U_PMON_GLOBAL_FRZ_ALL (1 << 31) -#define IVT_U_PMON_GLOBAL_UNFRZ_ALL (1 << 29) +/* IVBEP Ubox */ +#define IVBEP_U_MSR_PMON_GLOBAL_CTL 0xc00 +#define IVBEP_U_PMON_GLOBAL_FRZ_ALL (1 << 31) +#define IVBEP_U_PMON_GLOBAL_UNFRZ_ALL (1 << 29) -#define IVT_U_MSR_PMON_RAW_EVENT_MASK \ +#define IVBEP_U_MSR_PMON_RAW_EVENT_MASK \ (SNBEP_PMON_CTL_EV_SEL_MASK | \ SNBEP_PMON_CTL_UMASK_MASK | \ SNBEP_PMON_CTL_EDGE_DET | \ SNBEP_U_MSR_PMON_CTL_TRESH_MASK) -/* IVT Cbo */ -#define IVT_CBO_MSR_PMON_RAW_EVENT_MASK (IVT_PMON_RAW_EVENT_MASK | \ +/* IVBEP Cbo */ +#define IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK (IVBEP_PMON_RAW_EVENT_MASK | \ SNBEP_CBO_PMON_CTL_TID_EN) -#define IVT_CB0_MSR_PMON_BOX_FILTER_TID (0x1fULL << 0) -#define IVT_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 5) -#define IVT_CB0_MSR_PMON_BOX_FILTER_STATE (0x3fULL << 17) -#define IVT_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32) -#define IVT_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52) -#define IVT_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61) -#define IVT_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62) -#define IVT_CB0_MSR_PMON_BOX_FILTER_IOSC (0x1ULL << 63) - -/* IVT home agent */ -#define IVT_HA_PCI_PMON_CTL_Q_OCC_RST (1 << 16) -#define IVT_HA_PCI_PMON_RAW_EVENT_MASK \ - (IVT_PMON_RAW_EVENT_MASK | \ - IVT_HA_PCI_PMON_CTL_Q_OCC_RST) -/* IVT PCU */ -#define IVT_PCU_MSR_PMON_RAW_EVENT_MASK \ +#define IVBEP_CB0_MSR_PMON_BOX_FILTER_TID (0x1fULL << 0) +#define IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK (0xfULL << 5) +#define IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE (0x3fULL << 17) +#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NID (0xffffULL << 32) +#define IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC (0x1ffULL << 52) +#define IVBEP_CB0_MSR_PMON_BOX_FILTER_C6 (0x1ULL << 61) +#define IVBEP_CB0_MSR_PMON_BOX_FILTER_NC (0x1ULL << 62) +#define IVBEP_CB0_MSR_PMON_BOX_FILTER_IOSC (0x1ULL << 63) + +/* IVBEP home agent */ +#define IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST (1 << 16) +#define IVBEP_HA_PCI_PMON_RAW_EVENT_MASK \ + (IVBEP_PMON_RAW_EVENT_MASK | \ + IVBEP_HA_PCI_PMON_CTL_Q_OCC_RST) +/* IVBEP PCU */ +#define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ (SNBEP_PMON_CTL_EV_SEL_MASK | \ SNBEP_PMON_CTL_EV_SEL_EXT | \ SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ @@ -155,9 +155,9 @@ SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET) -/* IVT QPI */ -#define IVT_QPI_PCI_PMON_RAW_EVENT_MASK \ - (IVT_PMON_RAW_EVENT_MASK | \ +/* IVBEP QPI */ +#define IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK \ + (IVBEP_PMON_RAW_EVENT_MASK | \ SNBEP_PMON_CTL_EV_SEL_EXT) #define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \ @@ -1088,34 +1088,34 @@ int snbep_uncore_pci_init(void) /* end of Sandy Bridge-EP uncore support */ /* IvyTown uncore support */ -static void ivt_uncore_msr_init_box(struct intel_uncore_box *box) +static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box) { unsigned msr = uncore_msr_box_ctl(box); if (msr) - wrmsrl(msr, IVT_PMON_BOX_CTL_INT); + wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT); } -static void ivt_uncore_pci_init_box(struct intel_uncore_box *box) +static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box) { struct pci_dev *pdev = box->pci_dev; - pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVT_PMON_BOX_CTL_INT); + pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT); } -#define IVT_UNCORE_MSR_OPS_COMMON_INIT() \ - .init_box = ivt_uncore_msr_init_box, \ +#define IVBEP_UNCORE_MSR_OPS_COMMON_INIT() \ + .init_box = ivbep_uncore_msr_init_box, \ .disable_box = snbep_uncore_msr_disable_box, \ .enable_box = snbep_uncore_msr_enable_box, \ .disable_event = snbep_uncore_msr_disable_event, \ .enable_event = snbep_uncore_msr_enable_event, \ .read_counter = uncore_msr_read_counter -static struct intel_uncore_ops ivt_uncore_msr_ops = { - IVT_UNCORE_MSR_OPS_COMMON_INIT(), +static struct intel_uncore_ops ivbep_uncore_msr_ops = { + IVBEP_UNCORE_MSR_OPS_COMMON_INIT(), }; -static struct intel_uncore_ops ivt_uncore_pci_ops = { - .init_box = ivt_uncore_pci_init_box, +static struct intel_uncore_ops ivbep_uncore_pci_ops = { + .init_box = ivbep_uncore_pci_init_box, .disable_box = snbep_uncore_pci_disable_box, .enable_box = snbep_uncore_pci_enable_box, .disable_event = snbep_uncore_pci_disable_event, @@ -1123,15 +1123,15 @@ static struct intel_uncore_ops ivt_uncore_pci_ops = { .read_counter = snbep_uncore_pci_read_counter, }; -#define IVT_UNCORE_PCI_COMMON_INIT() \ +#define IVBEP_UNCORE_PCI_COMMON_INIT() \ .perf_ctr = SNBEP_PCI_PMON_CTR0, \ .event_ctl = SNBEP_PCI_PMON_CTL0, \ - .event_mask = IVT_PMON_RAW_EVENT_MASK, \ + .event_mask = IVBEP_PMON_RAW_EVENT_MASK, \ .box_ctl = SNBEP_PCI_PMON_BOX_CTL, \ - .ops = &ivt_uncore_pci_ops, \ - .format_group = &ivt_uncore_format_group + .ops = &ivbep_uncore_pci_ops, \ + .format_group = &ivbep_uncore_format_group -static struct attribute *ivt_uncore_formats_attr[] = { +static struct attribute *ivbep_uncore_formats_attr[] = { &format_attr_event.attr, &format_attr_umask.attr, &format_attr_edge.attr, @@ -1140,7 +1140,7 @@ static struct attribute *ivt_uncore_formats_attr[] = { NULL, }; -static struct attribute *ivt_uncore_ubox_formats_attr[] = { +static struct attribute *ivbep_uncore_ubox_formats_attr[] = { &format_attr_event.attr, &format_attr_umask.attr, &format_attr_edge.attr, @@ -1149,7 +1149,7 @@ static struct attribute *ivt_uncore_ubox_formats_attr[] = { NULL, }; -static struct attribute *ivt_uncore_cbox_formats_attr[] = { +static struct attribute *ivbep_uncore_cbox_formats_attr[] = { &format_attr_event.attr, &format_attr_umask.attr, &format_attr_edge.attr, @@ -1163,7 +1163,7 @@ static struct attribute *ivt_uncore_cbox_formats_attr[] = { NULL, }; -static struct attribute *ivt_uncore_pcu_formats_attr[] = { +static struct attribute *ivbep_uncore_pcu_formats_attr[] = { &format_attr_event_ext.attr, &format_attr_occ_sel.attr, &format_attr_edge.attr, @@ -1177,7 +1177,7 @@ static struct attribute *ivt_uncore_pcu_formats_attr[] = { NULL, }; -static struct attribute *ivt_uncore_qpi_formats_attr[] = { +static struct attribute *ivbep_uncore_qpi_formats_attr[] = { &format_attr_event_ext.attr, &format_attr_umask.attr, &format_attr_edge.attr, @@ -1203,32 +1203,32 @@ static struct attribute *ivt_uncore_qpi_formats_attr[] = { NULL, }; -static struct attribute_group ivt_uncore_format_group = { +static struct attribute_group ivbep_uncore_format_group = { .name = "format", - .attrs = ivt_uncore_formats_attr, + .attrs = ivbep_uncore_formats_attr, }; -static struct attribute_group ivt_uncore_ubox_format_group = { +static struct attribute_group ivbep_uncore_ubox_format_group = { .name = "format", - .attrs = ivt_uncore_ubox_formats_attr, + .attrs = ivbep_uncore_ubox_formats_attr, }; -static struct attribute_group ivt_uncore_cbox_format_group = { +static struct attribute_group ivbep_uncore_cbox_format_group = { .name = "format", - .attrs = ivt_uncore_cbox_formats_attr, + .attrs = ivbep_uncore_cbox_formats_attr, }; -static struct attribute_group ivt_uncore_pcu_format_group = { +static struct attribute_group ivbep_uncore_pcu_format_group = { .name = "format", - .attrs = ivt_uncore_pcu_formats_attr, + .attrs = ivbep_uncore_pcu_formats_attr, }; -static struct attribute_group ivt_uncore_qpi_format_group = { +static struct attribute_group ivbep_uncore_qpi_format_group = { .name = "format", - .attrs = ivt_uncore_qpi_formats_attr, + .attrs = ivbep_uncore_qpi_formats_attr, }; -static struct intel_uncore_type ivt_uncore_ubox = { +static struct intel_uncore_type ivbep_uncore_ubox = { .name = "ubox", .num_counters = 2, .num_boxes = 1, @@ -1236,14 +1236,14 @@ static struct intel_uncore_type ivt_uncore_ubox = { .fixed_ctr_bits = 48, .perf_ctr = SNBEP_U_MSR_PMON_CTR0, .event_ctl = SNBEP_U_MSR_PMON_CTL0, - .event_mask = IVT_U_MSR_PMON_RAW_EVENT_MASK, + .event_mask = IVBEP_U_MSR_PMON_RAW_EVENT_MASK, .fixed_ctr = SNBEP_U_MSR_PMON_UCLK_FIXED_CTR, .fixed_ctl = SNBEP_U_MSR_PMON_UCLK_FIXED_CTL, - .ops = &ivt_uncore_msr_ops, - .format_group = &ivt_uncore_ubox_format_group, + .ops = &ivbep_uncore_msr_ops, + .format_group = &ivbep_uncore_ubox_format_group, }; -static struct extra_reg ivt_uncore_cbox_extra_regs[] = { +static struct extra_reg ivbep_uncore_cbox_extra_regs[] = { SNBEP_CBO_EVENT_EXTRA_REG(SNBEP_CBO_PMON_CTL_TID_EN, SNBEP_CBO_PMON_CTL_TID_EN, 0x1), SNBEP_CBO_EVENT_EXTRA_REG(0x1031, 0x10ff, 0x2), @@ -1284,37 +1284,37 @@ static struct extra_reg ivt_uncore_cbox_extra_regs[] = { EVENT_EXTRA_END }; -static u64 ivt_cbox_filter_mask(int fields) +static u64 ivbep_cbox_filter_mask(int fields) { u64 mask = 0; if (fields & 0x1) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_TID; + mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_TID; if (fields & 0x2) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_LINK; + mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_LINK; if (fields & 0x4) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_STATE; + mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_STATE; if (fields & 0x8) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_NID; + mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_NID; if (fields & 0x10) - mask |= IVT_CB0_MSR_PMON_BOX_FILTER_OPC; + mask |= IVBEP_CB0_MSR_PMON_BOX_FILTER_OPC; return mask; } static struct event_constraint * -ivt_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) +ivbep_cbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event) { - return __snbep_cbox_get_constraint(box, event, ivt_cbox_filter_mask); + return __snbep_cbox_get_constraint(box, event, ivbep_cbox_filter_mask); } -static int ivt_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) +static int ivbep_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) { struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; struct extra_reg *er; int idx = 0; - for (er = ivt_uncore_cbox_extra_regs; er->msr; er++) { + for (er = ivbep_uncore_cbox_extra_regs; er->msr; er++) { if (er->event != (event->hw.config & er->config_mask)) continue; idx |= er->idx; @@ -1323,13 +1323,13 @@ static int ivt_cbox_hw_config(struct intel_uncore_box *box, struct perf_event *e if (idx) { reg1->reg = SNBEP_C0_MSR_PMON_BOX_FILTER + SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx; - reg1->config = event->attr.config1 & ivt_cbox_filter_mask(idx); + reg1->config = event->attr.config1 & ivbep_cbox_filter_mask(idx); reg1->idx = idx; } return 0; } -static void ivt_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event) +static void ivbep_cbox_enable_event(struct intel_uncore_box *box, struct perf_event *event) { struct hw_perf_event *hwc = &event->hw; struct hw_perf_event_extra *reg1 = &hwc->extra_reg; @@ -1343,78 +1343,78 @@ static void ivt_cbox_enable_event(struct intel_uncore_box *box, struct perf_even wrmsrl(hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN); } -static struct intel_uncore_ops ivt_uncore_cbox_ops = { - .init_box = ivt_uncore_msr_init_box, +static struct intel_uncore_ops ivbep_uncore_cbox_ops = { + .init_box = ivbep_uncore_msr_init_box, .disable_box = snbep_uncore_msr_disable_box, .enable_box = snbep_uncore_msr_enable_box, .disable_event = snbep_uncore_msr_disable_event, - .enable_event = ivt_cbox_enable_event, + .enable_event = ivbep_cbox_enable_event, .read_counter = uncore_msr_read_counter, - .hw_config = ivt_cbox_hw_config, - .get_constraint = ivt_cbox_get_constraint, + .hw_config = ivbep_cbox_hw_config, + .get_constraint = ivbep_cbox_get_constraint, .put_constraint = snbep_cbox_put_constraint, }; -static struct intel_uncore_type ivt_uncore_cbox = { +static struct intel_uncore_type ivbep_uncore_cbox = { .name = "cbox", .num_counters = 4, .num_boxes = 15, .perf_ctr_bits = 44, .event_ctl = SNBEP_C0_MSR_PMON_CTL0, .perf_ctr = SNBEP_C0_MSR_PMON_CTR0, - .event_mask = IVT_CBO_MSR_PMON_RAW_EVENT_MASK, + .event_mask = IVBEP_CBO_MSR_PMON_RAW_EVENT_MASK, .box_ctl = SNBEP_C0_MSR_PMON_BOX_CTL, .msr_offset = SNBEP_CBO_MSR_OFFSET, .num_shared_regs = 1, .constraints = snbep_uncore_cbox_constraints, - .ops = &ivt_uncore_cbox_ops, - .format_group = &ivt_uncore_cbox_format_group, + .ops = &ivbep_uncore_cbox_ops, + .format_group = &ivbep_uncore_cbox_format_group, }; -static struct intel_uncore_ops ivt_uncore_pcu_ops = { - IVT_UNCORE_MSR_OPS_COMMON_INIT(), +static struct intel_uncore_ops ivbep_uncore_pcu_ops = { + IVBEP_UNCORE_MSR_OPS_COMMON_INIT(), .hw_config = snbep_pcu_hw_config, .get_constraint = snbep_pcu_get_constraint, .put_constraint = snbep_pcu_put_constraint, }; -static struct intel_uncore_type ivt_uncore_pcu = { +static struct intel_uncore_type ivbep_uncore_pcu = { .name = "pcu", .num_counters = 4, .num_boxes = 1, .perf_ctr_bits = 48, .perf_ctr = SNBEP_PCU_MSR_PMON_CTR0, .event_ctl = SNBEP_PCU_MSR_PMON_CTL0, - .event_mask = IVT_PCU_MSR_PMON_RAW_EVENT_MASK, + .event_mask = IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK, .box_ctl = SNBEP_PCU_MSR_PMON_BOX_CTL, .num_shared_regs = 1, - .ops = &ivt_uncore_pcu_ops, - .format_group = &ivt_uncore_pcu_format_group, + .ops = &ivbep_uncore_pcu_ops, + .format_group = &ivbep_uncore_pcu_format_group, }; -static struct intel_uncore_type *ivt_msr_uncores[] = { - &ivt_uncore_ubox, - &ivt_uncore_cbox, - &ivt_uncore_pcu, +static struct intel_uncore_type *ivbep_msr_uncores[] = { + &ivbep_uncore_ubox, + &ivbep_uncore_cbox, + &ivbep_uncore_pcu, NULL, }; -void ivt_uncore_cpu_init(void) +void ivbep_uncore_cpu_init(void) { - if (ivt_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) - ivt_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; - uncore_msr_uncores = ivt_msr_uncores; + if (ivbep_uncore_cbox.num_boxes > boot_cpu_data.x86_max_cores) + ivbep_uncore_cbox.num_boxes = boot_cpu_data.x86_max_cores; + uncore_msr_uncores = ivbep_msr_uncores; } -static struct intel_uncore_type ivt_uncore_ha = { +static struct intel_uncore_type ivbep_uncore_ha = { .name = "ha", .num_counters = 4, .num_boxes = 2, .perf_ctr_bits = 48, - IVT_UNCORE_PCI_COMMON_INIT(), + IVBEP_UNCORE_PCI_COMMON_INIT(), }; -static struct intel_uncore_type ivt_uncore_imc = { +static struct intel_uncore_type ivbep_uncore_imc = { .name = "imc", .num_counters = 4, .num_boxes = 8, @@ -1423,64 +1423,64 @@ static struct intel_uncore_type ivt_uncore_imc = { .fixed_ctr = SNBEP_MC_CHy_PCI_PMON_FIXED_CTR, .fixed_ctl = SNBEP_MC_CHy_PCI_PMON_FIXED_CTL, .event_descs = snbep_uncore_imc_events, - IVT_UNCORE_PCI_COMMON_INIT(), + IVBEP_UNCORE_PCI_COMMON_INIT(), }; /* registers in IRP boxes are not properly aligned */ -static unsigned ivt_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4}; -static unsigned ivt_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0}; +static unsigned ivbep_uncore_irp_ctls[] = {0xd8, 0xdc, 0xe0, 0xe4}; +static unsigned ivbep_uncore_irp_ctrs[] = {0xa0, 0xb0, 0xb8, 0xc0}; -static void ivt_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event) +static void ivbep_uncore_irp_enable_event(struct intel_uncore_box *box, struct perf_event *event) { struct pci_dev *pdev = box->pci_dev; struct hw_perf_event *hwc = &event->hw; - pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], + pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config | SNBEP_PMON_CTL_EN); } -static void ivt_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event) +static void ivbep_uncore_irp_disable_event(struct intel_uncore_box *box, struct perf_event *event) { struct pci_dev *pdev = box->pci_dev; struct hw_perf_event *hwc = &event->hw; - pci_write_config_dword(pdev, ivt_uncore_irp_ctls[hwc->idx], hwc->config); + pci_write_config_dword(pdev, ivbep_uncore_irp_ctls[hwc->idx], hwc->config); } -static u64 ivt_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event) +static u64 ivbep_uncore_irp_read_counter(struct intel_uncore_box *box, struct perf_event *event) { struct pci_dev *pdev = box->pci_dev; struct hw_perf_event *hwc = &event->hw; u64 count = 0; - pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx], (u32 *)&count); - pci_read_config_dword(pdev, ivt_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1); + pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx], (u32 *)&count); + pci_read_config_dword(pdev, ivbep_uncore_irp_ctrs[hwc->idx] + 4, (u32 *)&count + 1); return count; } -static struct intel_uncore_ops ivt_uncore_irp_ops = { - .init_box = ivt_uncore_pci_init_box, +static struct intel_uncore_ops ivbep_uncore_irp_ops = { + .init_box = ivbep_uncore_pci_init_box, .disable_box = snbep_uncore_pci_disable_box, .enable_box = snbep_uncore_pci_enable_box, - .disable_event = ivt_uncore_irp_disable_event, - .enable_event = ivt_uncore_irp_enable_event, - .read_counter = ivt_uncore_irp_read_counter, + .disable_event = ivbep_uncore_irp_disable_event, + .enable_event = ivbep_uncore_irp_enable_event, + .read_counter = ivbep_uncore_irp_read_counter, }; -static struct intel_uncore_type ivt_uncore_irp = { +static struct intel_uncore_type ivbep_uncore_irp = { .name = "irp", .num_counters = 4, .num_boxes = 1, .perf_ctr_bits = 48, - .event_mask = IVT_PMON_RAW_EVENT_MASK, + .event_mask = IVBEP_PMON_RAW_EVENT_MASK, .box_ctl = SNBEP_PCI_PMON_BOX_CTL, - .ops = &ivt_uncore_irp_ops, - .format_group = &ivt_uncore_format_group, + .ops = &ivbep_uncore_irp_ops, + .format_group = &ivbep_uncore_format_group, }; -static struct intel_uncore_ops ivt_uncore_qpi_ops = { - .init_box = ivt_uncore_pci_init_box, +static struct intel_uncore_ops ivbep_uncore_qpi_ops = { + .init_box = ivbep_uncore_pci_init_box, .disable_box = snbep_uncore_pci_disable_box, .enable_box = snbep_uncore_pci_enable_box, .disable_event = snbep_uncore_pci_disable_event, @@ -1491,129 +1491,129 @@ static struct intel_uncore_ops ivt_uncore_qpi_ops = { .put_constraint = uncore_put_constraint, }; -static struct intel_uncore_type ivt_uncore_qpi = { +static struct intel_uncore_type ivbep_uncore_qpi = { .name = "qpi", .num_counters = 4, .num_boxes = 3, .perf_ctr_bits = 48, .perf_ctr = SNBEP_PCI_PMON_CTR0, .event_ctl = SNBEP_PCI_PMON_CTL0, - .event_mask = IVT_QPI_PCI_PMON_RAW_EVENT_MASK, + .event_mask = IVBEP_QPI_PCI_PMON_RAW_EVENT_MASK, .box_ctl = SNBEP_PCI_PMON_BOX_CTL, .num_shared_regs = 1, - .ops = &ivt_uncore_qpi_ops, - .format_group = &ivt_uncore_qpi_format_group, + .ops = &ivbep_uncore_qpi_ops, + .format_group = &ivbep_uncore_qpi_format_group, }; -static struct intel_uncore_type ivt_uncore_r2pcie = { +static struct intel_uncore_type ivbep_uncore_r2pcie = { .name = "r2pcie", .num_counters = 4, .num_boxes = 1, .perf_ctr_bits = 44, .constraints = snbep_uncore_r2pcie_constraints, - IVT_UNCORE_PCI_COMMON_INIT(), + IVBEP_UNCORE_PCI_COMMON_INIT(), }; -static struct intel_uncore_type ivt_uncore_r3qpi = { +static struct intel_uncore_type ivbep_uncore_r3qpi = { .name = "r3qpi", .num_counters = 3, .num_boxes = 2, .perf_ctr_bits = 44, .constraints = snbep_uncore_r3qpi_constraints, - IVT_UNCORE_PCI_COMMON_INIT(), + IVBEP_UNCORE_PCI_COMMON_INIT(), }; enum { - IVT_PCI_UNCORE_HA, - IVT_PCI_UNCORE_IMC, - IVT_PCI_UNCORE_IRP, - IVT_PCI_UNCORE_QPI, - IVT_PCI_UNCORE_R2PCIE, - IVT_PCI_UNCORE_R3QPI, -}; - -static struct intel_uncore_type *ivt_pci_uncores[] = { - [IVT_PCI_UNCORE_HA] = &ivt_uncore_ha, - [IVT_PCI_UNCORE_IMC] = &ivt_uncore_imc, - [IVT_PCI_UNCORE_IRP] = &ivt_uncore_irp, - [IVT_PCI_UNCORE_QPI] = &ivt_uncore_qpi, - [IVT_PCI_UNCORE_R2PCIE] = &ivt_uncore_r2pcie, - [IVT_PCI_UNCORE_R3QPI] = &ivt_uncore_r3qpi, + IVBEP_PCI_UNCORE_HA, + IVBEP_PCI_UNCORE_IMC, + IVBEP_PCI_UNCORE_IRP, + IVBEP_PCI_UNCORE_QPI, + IVBEP_PCI_UNCORE_R2PCIE, + IVBEP_PCI_UNCORE_R3QPI, +}; + +static struct intel_uncore_type *ivbep_pci_uncores[] = { + [IVBEP_PCI_UNCORE_HA] = &ivbep_uncore_ha, + [IVBEP_PCI_UNCORE_IMC] = &ivbep_uncore_imc, + [IVBEP_PCI_UNCORE_IRP] = &ivbep_uncore_irp, + [IVBEP_PCI_UNCORE_QPI] = &ivbep_uncore_qpi, + [IVBEP_PCI_UNCORE_R2PCIE] = &ivbep_uncore_r2pcie, + [IVBEP_PCI_UNCORE_R3QPI] = &ivbep_uncore_r3qpi, NULL, }; -static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { +static DEFINE_PCI_DEVICE_TABLE(ivbep_uncore_pci_ids) = { { /* Home Agent 0 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe30), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 0), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 0), }, { /* Home Agent 1 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe38), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_HA, 1), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_HA, 1), }, { /* MC0 Channel 0 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb4), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 0), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 0), }, { /* MC0 Channel 1 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb5), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 1), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 1), }, { /* MC0 Channel 3 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb0), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 2), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 2), }, { /* MC0 Channel 4 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xeb1), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 3), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 3), }, { /* MC1 Channel 0 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef4), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 4), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 4), }, { /* MC1 Channel 1 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef5), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 5), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 5), }, { /* MC1 Channel 3 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef0), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 6), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 6), }, { /* MC1 Channel 4 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xef1), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IMC, 7), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IMC, 7), }, { /* IRP */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe39), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_IRP, 0), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_IRP, 0), }, { /* QPI0 Port 0 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe32), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 0), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 0), }, { /* QPI0 Port 1 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe33), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 1), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 1), }, { /* QPI1 Port 2 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3a), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_QPI, 2), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_QPI, 2), }, { /* R2PCIe */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe34), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R2PCIE, 0), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R2PCIE, 0), }, { /* R3QPI0 Link 0 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe36), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 0), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 0), }, { /* R3QPI0 Link 1 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe37), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 1), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 1), }, { /* R3QPI1 Link 2 */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe3e), - .driver_data = UNCORE_PCI_DEV_DATA(IVT_PCI_UNCORE_R3QPI, 2), + .driver_data = UNCORE_PCI_DEV_DATA(IVBEP_PCI_UNCORE_R3QPI, 2), }, { /* QPI Port 0 filter */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe86), @@ -1628,18 +1628,18 @@ static DEFINE_PCI_DEVICE_TABLE(ivt_uncore_pci_ids) = { { /* end: all zeroes */ } }; -static struct pci_driver ivt_uncore_pci_driver = { - .name = "ivt_uncore", - .id_table = ivt_uncore_pci_ids, +static struct pci_driver ivbep_uncore_pci_driver = { + .name = "ivbep_uncore", + .id_table = ivbep_uncore_pci_ids, }; -int ivt_uncore_pci_init(void) +int ivbep_uncore_pci_init(void) { int ret = snbep_pci2phy_map_init(0x0e1e); if (ret) return ret; - uncore_pci_uncores = ivt_pci_uncores; - uncore_pci_driver = &ivt_uncore_pci_driver; + uncore_pci_uncores = ivbep_pci_uncores; + uncore_pci_driver = &ivbep_uncore_pci_driver; return 0; } /* end of IvyTown uncore support */ -- GitLab From 2e39465abc4b7856a0ea6fcf4f6b4668bb5db877 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Mon, 4 Aug 2014 12:07:15 +0200 Subject: [PATCH 0280/9167] locking: Remove deprecated smp_mb__() barriers Its been a while and there are no in-tree users left, so remove the deprecated barriers. Signed-off-by: Peter Zijlstra Cc: Chen, Gong Cc: Jacob Pan Cc: Joe Perches Cc: John Sullivan Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Srinivas Pandruvada Cc: Theodore Ts'o Signed-off-by: Ingo Molnar --- include/linux/atomic.h | 36 ------------------------------------ include/linux/bitops.h | 20 -------------------- kernel/sched/core.c | 16 ---------------- 3 files changed, 72 deletions(-) diff --git a/include/linux/atomic.h b/include/linux/atomic.h index fef3a809e7cf..5b08a8540ecf 100644 --- a/include/linux/atomic.h +++ b/include/linux/atomic.h @@ -3,42 +3,6 @@ #define _LINUX_ATOMIC_H #include -/* - * Provide __deprecated wrappers for the new interface, avoid flag day changes. - * We need the ugly external functions to break header recursion hell. - */ -#ifndef smp_mb__before_atomic_inc -static inline void __deprecated smp_mb__before_atomic_inc(void) -{ - extern void __smp_mb__before_atomic(void); - __smp_mb__before_atomic(); -} -#endif - -#ifndef smp_mb__after_atomic_inc -static inline void __deprecated smp_mb__after_atomic_inc(void) -{ - extern void __smp_mb__after_atomic(void); - __smp_mb__after_atomic(); -} -#endif - -#ifndef smp_mb__before_atomic_dec -static inline void __deprecated smp_mb__before_atomic_dec(void) -{ - extern void __smp_mb__before_atomic(void); - __smp_mb__before_atomic(); -} -#endif - -#ifndef smp_mb__after_atomic_dec -static inline void __deprecated smp_mb__after_atomic_dec(void) -{ - extern void __smp_mb__after_atomic(void); - __smp_mb__after_atomic(); -} -#endif - /** * atomic_add_unless - add unless the number is already a given value * @v: pointer of type atomic_t diff --git a/include/linux/bitops.h b/include/linux/bitops.h index cbc5833fb221..be5fd38bd5a0 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h @@ -32,26 +32,6 @@ extern unsigned long __sw_hweight64(__u64 w); */ #include -/* - * Provide __deprecated wrappers for the new interface, avoid flag day changes. - * We need the ugly external functions to break header recursion hell. - */ -#ifndef smp_mb__before_clear_bit -static inline void __deprecated smp_mb__before_clear_bit(void) -{ - extern void __smp_mb__before_atomic(void); - __smp_mb__before_atomic(); -} -#endif - -#ifndef smp_mb__after_clear_bit -static inline void __deprecated smp_mb__after_clear_bit(void) -{ - extern void __smp_mb__after_atomic(void); - __smp_mb__after_atomic(); -} -#endif - #define for_each_set_bit(bit, addr, size) \ for ((bit) = find_first_bit((addr), (size)); \ (bit) < (size); \ diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1211575a2208..76c518c9b3a7 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -90,22 +90,6 @@ #define CREATE_TRACE_POINTS #include -#ifdef smp_mb__before_atomic -void __smp_mb__before_atomic(void) -{ - smp_mb__before_atomic(); -} -EXPORT_SYMBOL(__smp_mb__before_atomic); -#endif - -#ifdef smp_mb__after_atomic -void __smp_mb__after_atomic(void) -{ - smp_mb__after_atomic(); -} -EXPORT_SYMBOL(__smp_mb__after_atomic); -#endif - void start_bandwidth_timer(struct hrtimer *period_timer, ktime_t period) { unsigned long delta; -- GitLab From 242489cfe97d44290e7f88b12591fab6c0819045 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 30 Jul 2014 13:41:50 -0700 Subject: [PATCH 0281/9167] locking/mutexes: Standardize arguments in lock/unlock slowpaths Just how the locking-end behaves, when unlocking, go ahead and obtain the proper data structure immediately after the previous (asm-end) call exits and there are (probably) pending waiters. This simplifies a bit some of the layering. Signed-off-by: Davidlohr Bueso Signed-off-by: Peter Zijlstra Cc: jason.low2@hp.com Cc: aswin@hp.com Cc: mingo@kernel.org Cc: Linus Torvalds Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/1406752916-3341-1-git-send-email-davidlohr@hp.com Signed-off-by: Ingo Molnar --- kernel/locking/mutex.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index ae712b25e492..ad0e3335c481 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -679,9 +679,8 @@ EXPORT_SYMBOL_GPL(__ww_mutex_lock_interruptible); * Release the lock, slowpath: */ static inline void -__mutex_unlock_common_slowpath(atomic_t *lock_count, int nested) +__mutex_unlock_common_slowpath(struct mutex *lock, int nested) { - struct mutex *lock = container_of(lock_count, struct mutex, count); unsigned long flags; /* @@ -716,7 +715,9 @@ __mutex_unlock_common_slowpath(atomic_t *lock_count, int nested) __visible void __mutex_unlock_slowpath(atomic_t *lock_count) { - __mutex_unlock_common_slowpath(lock_count, 1); + struct mutex *lock = container_of(lock_count, struct mutex, count); + + __mutex_unlock_common_slowpath(lock, 1); } #ifndef CONFIG_DEBUG_LOCK_ALLOC -- GitLab From 42fa566bd74aa7b95413fb00611ec983b488222d Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 30 Jul 2014 13:41:51 -0700 Subject: [PATCH 0282/9167] locking/mutexes: Document quick lock release when unlocking When unlocking, we always want to reach the slowpath with the lock's counter indicating it is unlocked. -- as returned by the asm fastpath call or by explicitly setting it. While doing so, at least in theory, we can optimize and allow faster lock stealing. When unlocking, we always want to reach the slowpath with the lock's counter indicating it is unlocked. -- as returned by the asm fastpath call or by explicitly setting it. While doing so, at least in theory, we can optimize and allow faster lock stealing. Signed-off-by: Davidlohr Bueso Signed-off-by: Peter Zijlstra Cc: jason.low2@hp.com Cc: aswin@hp.com Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1406752916-3341-2-git-send-email-davidlohr@hp.com Signed-off-by: Ingo Molnar --- kernel/locking/mutex.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index ad0e3335c481..93bec48f09ed 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -684,9 +684,16 @@ __mutex_unlock_common_slowpath(struct mutex *lock, int nested) unsigned long flags; /* - * some architectures leave the lock unlocked in the fastpath failure + * As a performance measurement, release the lock before doing other + * wakeup related duties to follow. This allows other tasks to acquire + * the lock sooner, while still handling cleanups in past unlock calls. + * This can be done as we do not enforce strict equivalence between the + * mutex counter and wait_list. + * + * + * Some architectures leave the lock unlocked in the fastpath failure * case, others need to leave it locked. In the later case we have to - * unlock it here + * unlock it here - as the lock counter is currently 0 or negative. */ if (__mutex_slowpath_needs_to_unlock()) atomic_set(&lock->count, 1); -- GitLab From aa9fc0c19bee0cbc152e0e06488095fb69229236 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 30 Jul 2014 13:41:52 -0700 Subject: [PATCH 0283/9167] locking/mcs: Remove obsolete comment ... as we clearly inline mcs_spin_lock() now. Signed-off-by: Davidlohr Bueso Acked-by: Jason Low Signed-off-by: Peter Zijlstra Cc: aswin@hp.com Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1406752916-3341-3-git-send-email-davidlohr@hp.com Signed-off-by: Ingo Molnar --- kernel/locking/mcs_spinlock.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/kernel/locking/mcs_spinlock.h b/kernel/locking/mcs_spinlock.h index 23e89c5930e9..4d60986fcbee 100644 --- a/kernel/locking/mcs_spinlock.h +++ b/kernel/locking/mcs_spinlock.h @@ -56,9 +56,6 @@ do { \ * If the lock has already been acquired, then this will proceed to spin * on this node->locked until the previous lock holder sets the node->locked * in mcs_spin_unlock(). - * - * We don't inline mcs_spin_lock() so that perf can correctly account for the - * time spent in this lock function. */ static inline void mcs_spin_lock(struct mcs_spinlock **lock, struct mcs_spinlock *node) -- GitLab From 76916515d9d84e6552ee5e218e0ed566ad75e600 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 30 Jul 2014 13:41:53 -0700 Subject: [PATCH 0284/9167] locking/mutexes: Refactor optimistic spinning code When we fail to acquire the mutex in the fastpath, we end up calling __mutex_lock_common(). A *lot* goes on in this function. Move out the optimistic spinning code into mutex_optimistic_spin() and simplify the former a bit. Furthermore, this is similar to what we have in rwsems. No logical changes. Signed-off-by: Davidlohr Bueso Acked-by: Jason Low Signed-off-by: Peter Zijlstra Cc: aswin@hp.com Cc: mingo@kernel.org Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1406752916-3341-4-git-send-email-davidlohr@hp.com Signed-off-by: Ingo Molnar --- kernel/locking/mutex.c | 396 ++++++++++++++++++++++------------------- 1 file changed, 214 insertions(+), 182 deletions(-) diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 93bec48f09ed..0d8b6ed93874 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -106,6 +106,92 @@ void __sched mutex_lock(struct mutex *lock) EXPORT_SYMBOL(mutex_lock); #endif +static __always_inline void ww_mutex_lock_acquired(struct ww_mutex *ww, + struct ww_acquire_ctx *ww_ctx) +{ +#ifdef CONFIG_DEBUG_MUTEXES + /* + * If this WARN_ON triggers, you used ww_mutex_lock to acquire, + * but released with a normal mutex_unlock in this call. + * + * This should never happen, always use ww_mutex_unlock. + */ + DEBUG_LOCKS_WARN_ON(ww->ctx); + + /* + * Not quite done after calling ww_acquire_done() ? + */ + DEBUG_LOCKS_WARN_ON(ww_ctx->done_acquire); + + if (ww_ctx->contending_lock) { + /* + * After -EDEADLK you tried to + * acquire a different ww_mutex? Bad! + */ + DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock != ww); + + /* + * You called ww_mutex_lock after receiving -EDEADLK, + * but 'forgot' to unlock everything else first? + */ + DEBUG_LOCKS_WARN_ON(ww_ctx->acquired > 0); + ww_ctx->contending_lock = NULL; + } + + /* + * Naughty, using a different class will lead to undefined behavior! + */ + DEBUG_LOCKS_WARN_ON(ww_ctx->ww_class != ww->ww_class); +#endif + ww_ctx->acquired++; +} + +/* + * after acquiring lock with fastpath or when we lost out in contested + * slowpath, set ctx and wake up any waiters so they can recheck. + * + * This function is never called when CONFIG_DEBUG_LOCK_ALLOC is set, + * as the fastpath and opportunistic spinning are disabled in that case. + */ +static __always_inline void +ww_mutex_set_context_fastpath(struct ww_mutex *lock, + struct ww_acquire_ctx *ctx) +{ + unsigned long flags; + struct mutex_waiter *cur; + + ww_mutex_lock_acquired(lock, ctx); + + lock->ctx = ctx; + + /* + * The lock->ctx update should be visible on all cores before + * the atomic read is done, otherwise contended waiters might be + * missed. The contended waiters will either see ww_ctx == NULL + * and keep spinning, or it will acquire wait_lock, add itself + * to waiter list and sleep. + */ + smp_mb(); /* ^^^ */ + + /* + * Check if lock is contended, if not there is nobody to wake up + */ + if (likely(atomic_read(&lock->base.count) == 0)) + return; + + /* + * Uh oh, we raced in fastpath, wake up everyone in this case, + * so they can see the new lock->ctx. + */ + spin_lock_mutex(&lock->base.wait_lock, flags); + list_for_each_entry(cur, &lock->base.wait_list, list) { + debug_mutex_wake_waiter(&lock->base, cur); + wake_up_process(cur->task); + } + spin_unlock_mutex(&lock->base.wait_lock, flags); +} + + #ifdef CONFIG_MUTEX_SPIN_ON_OWNER /* * In order to avoid a stampede of mutex spinners from acquiring the mutex @@ -180,6 +266,129 @@ static inline int mutex_can_spin_on_owner(struct mutex *lock) */ return retval; } + +/* + * Atomically try to take the lock when it is available + */ +static inline bool mutex_try_to_acquire(struct mutex *lock) +{ + return !mutex_is_locked(lock) && + (atomic_cmpxchg(&lock->count, 1, 0) == 1); +} + +/* + * Optimistic spinning. + * + * We try to spin for acquisition when we find that the lock owner + * is currently running on a (different) CPU and while we don't + * need to reschedule. The rationale is that if the lock owner is + * running, it is likely to release the lock soon. + * + * Since this needs the lock owner, and this mutex implementation + * doesn't track the owner atomically in the lock field, we need to + * track it non-atomically. + * + * We can't do this for DEBUG_MUTEXES because that relies on wait_lock + * to serialize everything. + * + * The mutex spinners are queued up using MCS lock so that only one + * spinner can compete for the mutex. However, if mutex spinning isn't + * going to happen, there is no point in going through the lock/unlock + * overhead. + * + * Returns true when the lock was taken, otherwise false, indicating + * that we need to jump to the slowpath and sleep. + */ +static bool mutex_optimistic_spin(struct mutex *lock, + struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx) +{ + struct task_struct *task = current; + + if (!mutex_can_spin_on_owner(lock)) + goto done; + + if (!osq_lock(&lock->osq)) + goto done; + + while (true) { + struct task_struct *owner; + + if (use_ww_ctx && ww_ctx->acquired > 0) { + struct ww_mutex *ww; + + ww = container_of(lock, struct ww_mutex, base); + /* + * If ww->ctx is set the contents are undefined, only + * by acquiring wait_lock there is a guarantee that + * they are not invalid when reading. + * + * As such, when deadlock detection needs to be + * performed the optimistic spinning cannot be done. + */ + if (ACCESS_ONCE(ww->ctx)) + break; + } + + /* + * If there's an owner, wait for it to either + * release the lock or go to sleep. + */ + owner = ACCESS_ONCE(lock->owner); + if (owner && !mutex_spin_on_owner(lock, owner)) + break; + + /* Try to acquire the mutex if it is unlocked. */ + if (mutex_try_to_acquire(lock)) { + lock_acquired(&lock->dep_map, ip); + + if (use_ww_ctx) { + struct ww_mutex *ww; + ww = container_of(lock, struct ww_mutex, base); + + ww_mutex_set_context_fastpath(ww, ww_ctx); + } + + mutex_set_owner(lock); + osq_unlock(&lock->osq); + return true; + } + + /* + * When there's no owner, we might have preempted between the + * owner acquiring the lock and setting the owner field. If + * we're an RT task that will live-lock because we won't let + * the owner complete. + */ + if (!owner && (need_resched() || rt_task(task))) + break; + + /* + * The cpu_relax() call is a compiler barrier which forces + * everything in this loop to be re-loaded. We don't need + * memory barriers as we'll eventually observe the right + * values at the cost of a few extra spins. + */ + cpu_relax_lowlatency(); + } + + osq_unlock(&lock->osq); +done: + /* + * If we fell out of the spin path because of need_resched(), + * reschedule now, before we try-lock the mutex. This avoids getting + * scheduled out right after we obtained the mutex. + */ + if (need_resched()) + schedule_preempt_disabled(); + + return false; +} +#else +static bool mutex_optimistic_spin(struct mutex *lock, + struct ww_acquire_ctx *ww_ctx, const bool use_ww_ctx) +{ + return false; +} #endif __visible __used noinline @@ -277,91 +486,6 @@ __mutex_lock_check_stamp(struct mutex *lock, struct ww_acquire_ctx *ctx) return 0; } -static __always_inline void ww_mutex_lock_acquired(struct ww_mutex *ww, - struct ww_acquire_ctx *ww_ctx) -{ -#ifdef CONFIG_DEBUG_MUTEXES - /* - * If this WARN_ON triggers, you used ww_mutex_lock to acquire, - * but released with a normal mutex_unlock in this call. - * - * This should never happen, always use ww_mutex_unlock. - */ - DEBUG_LOCKS_WARN_ON(ww->ctx); - - /* - * Not quite done after calling ww_acquire_done() ? - */ - DEBUG_LOCKS_WARN_ON(ww_ctx->done_acquire); - - if (ww_ctx->contending_lock) { - /* - * After -EDEADLK you tried to - * acquire a different ww_mutex? Bad! - */ - DEBUG_LOCKS_WARN_ON(ww_ctx->contending_lock != ww); - - /* - * You called ww_mutex_lock after receiving -EDEADLK, - * but 'forgot' to unlock everything else first? - */ - DEBUG_LOCKS_WARN_ON(ww_ctx->acquired > 0); - ww_ctx->contending_lock = NULL; - } - - /* - * Naughty, using a different class will lead to undefined behavior! - */ - DEBUG_LOCKS_WARN_ON(ww_ctx->ww_class != ww->ww_class); -#endif - ww_ctx->acquired++; -} - -/* - * after acquiring lock with fastpath or when we lost out in contested - * slowpath, set ctx and wake up any waiters so they can recheck. - * - * This function is never called when CONFIG_DEBUG_LOCK_ALLOC is set, - * as the fastpath and opportunistic spinning are disabled in that case. - */ -static __always_inline void -ww_mutex_set_context_fastpath(struct ww_mutex *lock, - struct ww_acquire_ctx *ctx) -{ - unsigned long flags; - struct mutex_waiter *cur; - - ww_mutex_lock_acquired(lock, ctx); - - lock->ctx = ctx; - - /* - * The lock->ctx update should be visible on all cores before - * the atomic read is done, otherwise contended waiters might be - * missed. The contended waiters will either see ww_ctx == NULL - * and keep spinning, or it will acquire wait_lock, add itself - * to waiter list and sleep. - */ - smp_mb(); /* ^^^ */ - - /* - * Check if lock is contended, if not there is nobody to wake up - */ - if (likely(atomic_read(&lock->base.count) == 0)) - return; - - /* - * Uh oh, we raced in fastpath, wake up everyone in this case, - * so they can see the new lock->ctx. - */ - spin_lock_mutex(&lock->base.wait_lock, flags); - list_for_each_entry(cur, &lock->base.wait_list, list) { - debug_mutex_wake_waiter(&lock->base, cur); - wake_up_process(cur->task); - } - spin_unlock_mutex(&lock->base.wait_lock, flags); -} - /* * Lock a mutex (possibly interruptible), slowpath: */ @@ -378,104 +502,12 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, preempt_disable(); mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip); -#ifdef CONFIG_MUTEX_SPIN_ON_OWNER - /* - * Optimistic spinning. - * - * We try to spin for acquisition when we find that the lock owner - * is currently running on a (different) CPU and while we don't - * need to reschedule. The rationale is that if the lock owner is - * running, it is likely to release the lock soon. - * - * Since this needs the lock owner, and this mutex implementation - * doesn't track the owner atomically in the lock field, we need to - * track it non-atomically. - * - * We can't do this for DEBUG_MUTEXES because that relies on wait_lock - * to serialize everything. - * - * The mutex spinners are queued up using MCS lock so that only one - * spinner can compete for the mutex. However, if mutex spinning isn't - * going to happen, there is no point in going through the lock/unlock - * overhead. - */ - if (!mutex_can_spin_on_owner(lock)) - goto slowpath; - - if (!osq_lock(&lock->osq)) - goto slowpath; - - for (;;) { - struct task_struct *owner; - - if (use_ww_ctx && ww_ctx->acquired > 0) { - struct ww_mutex *ww; - - ww = container_of(lock, struct ww_mutex, base); - /* - * If ww->ctx is set the contents are undefined, only - * by acquiring wait_lock there is a guarantee that - * they are not invalid when reading. - * - * As such, when deadlock detection needs to be - * performed the optimistic spinning cannot be done. - */ - if (ACCESS_ONCE(ww->ctx)) - break; - } - - /* - * If there's an owner, wait for it to either - * release the lock or go to sleep. - */ - owner = ACCESS_ONCE(lock->owner); - if (owner && !mutex_spin_on_owner(lock, owner)) - break; - - /* Try to acquire the mutex if it is unlocked. */ - if (!mutex_is_locked(lock) && - (atomic_cmpxchg(&lock->count, 1, 0) == 1)) { - lock_acquired(&lock->dep_map, ip); - if (use_ww_ctx) { - struct ww_mutex *ww; - ww = container_of(lock, struct ww_mutex, base); - - ww_mutex_set_context_fastpath(ww, ww_ctx); - } - - mutex_set_owner(lock); - osq_unlock(&lock->osq); - preempt_enable(); - return 0; - } - - /* - * When there's no owner, we might have preempted between the - * owner acquiring the lock and setting the owner field. If - * we're an RT task that will live-lock because we won't let - * the owner complete. - */ - if (!owner && (need_resched() || rt_task(task))) - break; - - /* - * The cpu_relax() call is a compiler barrier which forces - * everything in this loop to be re-loaded. We don't need - * memory barriers as we'll eventually observe the right - * values at the cost of a few extra spins. - */ - cpu_relax_lowlatency(); + if (mutex_optimistic_spin(lock, ww_ctx, use_ww_ctx)) { + /* got the lock, yay! */ + preempt_enable(); + return 0; } - osq_unlock(&lock->osq); -slowpath: - /* - * If we fell out of the spin path because of need_resched(), - * reschedule now, before we try-lock the mutex. This avoids getting - * scheduled out right after we obtained the mutex. - */ - if (need_resched()) - schedule_preempt_disabled(); -#endif + spin_lock_mutex(&lock->wait_lock, flags); /* -- GitLab From 7608a43d8f2e02f8b532f8e11481d7ecf8b5d3f9 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 30 Jul 2014 13:41:54 -0700 Subject: [PATCH 0285/9167] locking/mutexes: Use MUTEX_SPIN_ON_OWNER when appropriate 4badad35 ("locking/mutex: Disable optimistic spinning on some architectures") added a ARCH_SUPPORTS_ATOMIC_RMW flag to disable the mutex optimistic feature on specific archs. Because CONFIG_MUTEX_SPIN_ON_OWNER only depended on DEBUG and SMP, it was ok to have the ->owner field conditional a bit flexible. However by adding a new variable to the matter, we can waste space with the unused field, ie: CONFIG_SMP && (!CONFIG_MUTEX_SPIN_ON_OWNER && !CONFIG_DEBUG_MUTEX). Signed-off-by: Davidlohr Bueso Acked-by: Jason Low Signed-off-by: Peter Zijlstra Cc: aswin@hp.com Cc: Davidlohr Bueso Cc: Heiko Carstens Cc: Jason Low Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Tim Chen Link: http://lkml.kernel.org/r/1406752916-3341-5-git-send-email-davidlohr@hp.com Signed-off-by: Ingo Molnar --- include/linux/mutex.h | 2 +- kernel/locking/mutex.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/mutex.h b/include/linux/mutex.h index 8d5535c58cc2..e4c29418f407 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -52,7 +52,7 @@ struct mutex { atomic_t count; spinlock_t wait_lock; struct list_head wait_list; -#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) +#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER) struct task_struct *owner; #endif #ifdef CONFIG_MUTEX_SPIN_ON_OWNER diff --git a/kernel/locking/mutex.h b/kernel/locking/mutex.h index 4115fbf83b12..5cda397607f2 100644 --- a/kernel/locking/mutex.h +++ b/kernel/locking/mutex.h @@ -16,7 +16,7 @@ #define mutex_remove_waiter(lock, waiter, ti) \ __list_del((waiter)->list.prev, (waiter)->list.next) -#ifdef CONFIG_SMP +#ifdef CONFIG_MUTEX_SPIN_ON_OWNER static inline void mutex_set_owner(struct mutex *lock) { lock->owner = current; -- GitLab From 214e0aed639ef40987bf6159fad303171a6de31e Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 30 Jul 2014 13:41:55 -0700 Subject: [PATCH 0286/9167] locking/Documentation: Move locking related docs into Documentation/locking/ Specifically: Documentation/locking/lockdep-design.txt Documentation/locking/lockstat.txt Documentation/locking/mutex-design.txt Documentation/locking/rt-mutex-design.txt Documentation/locking/rt-mutex.txt Documentation/locking/spinlocks.txt Documentation/locking/ww-mutex-design.txt Signed-off-by: Davidlohr Bueso Acked-by: Randy Dunlap Signed-off-by: Peter Zijlstra Cc: jason.low2@hp.com Cc: aswin@hp.com Cc: Alexei Starovoitov Cc: Al Viro Cc: Andrew Morton Cc: Chris Mason Cc: Dan Streetman Cc: David Airlie Cc: Davidlohr Bueso Cc: David S. Miller Cc: Greg Kroah-Hartman Cc: Heiko Carstens Cc: Jason Low Cc: Josef Bacik Cc: Kees Cook Cc: Linus Torvalds Cc: Lubomir Rintel Cc: Masanari Iida Cc: Paul E. McKenney Cc: Randy Dunlap Cc: Tim Chen Cc: Vineet Gupta Cc: fengguang.wu@intel.com Link: http://lkml.kernel.org/r/1406752916-3341-6-git-send-email-davidlohr@hp.com Signed-off-by: Ingo Molnar --- Documentation/00-INDEX | 2 ++ Documentation/DocBook/kernel-locking.tmpl | 2 +- Documentation/{ => locking}/lockdep-design.txt | 0 Documentation/{ => locking}/lockstat.txt | 2 +- Documentation/{ => locking}/mutex-design.txt | 0 Documentation/{ => locking}/rt-mutex-design.txt | 0 Documentation/{ => locking}/rt-mutex.txt | 0 Documentation/{ => locking}/spinlocks.txt | 14 +++++++------- Documentation/{ => locking}/ww-mutex-design.txt | 0 MAINTAINERS | 4 ++-- drivers/gpu/drm/drm_modeset_lock.c | 2 +- include/linux/lockdep.h | 2 +- include/linux/mutex.h | 2 +- include/linux/rwsem.h | 2 +- kernel/locking/mutex.c | 2 +- kernel/locking/rtmutex.c | 2 +- lib/Kconfig.debug | 4 ++-- 17 files changed, 21 insertions(+), 19 deletions(-) rename Documentation/{ => locking}/lockdep-design.txt (100%) rename Documentation/{ => locking}/lockstat.txt (99%) rename Documentation/{ => locking}/mutex-design.txt (100%) rename Documentation/{ => locking}/rt-mutex-design.txt (100%) rename Documentation/{ => locking}/rt-mutex.txt (100%) rename Documentation/{ => locking}/spinlocks.txt (98%) rename Documentation/{ => locking}/ww-mutex-design.txt (100%) diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 27e67a98b7be..1750fcef1ab4 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -287,6 +287,8 @@ local_ops.txt - semantics and behavior of local atomic operations. lockdep-design.txt - documentation on the runtime locking correctness validator. +locking/ + - directory with info about kernel locking primitives lockstat.txt - info on collecting statistics on locks (and contention). lockup-watchdogs.txt diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl index e584ee12a1e7..7c9cc4846cb6 100644 --- a/Documentation/DocBook/kernel-locking.tmpl +++ b/Documentation/DocBook/kernel-locking.tmpl @@ -1972,7 +1972,7 @@ machines due to caching. - Documentation/spinlocks.txt: + Documentation/locking/spinlocks.txt: Linus Torvalds' spinlocking tutorial in the kernel sources. diff --git a/Documentation/lockdep-design.txt b/Documentation/locking/lockdep-design.txt similarity index 100% rename from Documentation/lockdep-design.txt rename to Documentation/locking/lockdep-design.txt diff --git a/Documentation/lockstat.txt b/Documentation/locking/lockstat.txt similarity index 99% rename from Documentation/lockstat.txt rename to Documentation/locking/lockstat.txt index 72d010689751..7428773a1e69 100644 --- a/Documentation/lockstat.txt +++ b/Documentation/locking/lockstat.txt @@ -12,7 +12,7 @@ Because things like lock contention can severely impact performance. - HOW Lockdep already has hooks in the lock functions and maps lock instances to -lock classes. We build on that (see Documentation/lockdep-design.txt). +lock classes. We build on that (see Documentation/lokcing/lockdep-design.txt). The graph below shows the relation between the lock functions and the various hooks therein. diff --git a/Documentation/mutex-design.txt b/Documentation/locking/mutex-design.txt similarity index 100% rename from Documentation/mutex-design.txt rename to Documentation/locking/mutex-design.txt diff --git a/Documentation/rt-mutex-design.txt b/Documentation/locking/rt-mutex-design.txt similarity index 100% rename from Documentation/rt-mutex-design.txt rename to Documentation/locking/rt-mutex-design.txt diff --git a/Documentation/rt-mutex.txt b/Documentation/locking/rt-mutex.txt similarity index 100% rename from Documentation/rt-mutex.txt rename to Documentation/locking/rt-mutex.txt diff --git a/Documentation/spinlocks.txt b/Documentation/locking/spinlocks.txt similarity index 98% rename from Documentation/spinlocks.txt rename to Documentation/locking/spinlocks.txt index 97eaf5727178..ff35e40bdf5b 100644 --- a/Documentation/spinlocks.txt +++ b/Documentation/locking/spinlocks.txt @@ -105,9 +105,9 @@ never used in interrupt handlers, you can use the non-irq versions: spin_unlock(&lock); (and the equivalent read-write versions too, of course). The spinlock will -guarantee the same kind of exclusive access, and it will be much faster. +guarantee the same kind of exclusive access, and it will be much faster. This is useful if you know that the data in question is only ever -manipulated from a "process context", ie no interrupts involved. +manipulated from a "process context", ie no interrupts involved. The reasons you mustn't use these versions if you have interrupts that play with the spinlock is that you can get deadlocks: @@ -122,21 +122,21 @@ the other interrupt happens on another CPU, but it is _not_ ok if the interrupt happens on the same CPU that already holds the lock, because the lock will obviously never be released (because the interrupt is waiting for the lock, and the lock-holder is interrupted by the interrupt and will -not continue until the interrupt has been processed). +not continue until the interrupt has been processed). (This is also the reason why the irq-versions of the spinlocks only need to disable the _local_ interrupts - it's ok to use spinlocks in interrupts on other CPU's, because an interrupt on another CPU doesn't interrupt the CPU that holds the lock, so the lock-holder can continue and eventually -releases the lock). +releases the lock). Note that you can be clever with read-write locks and interrupts. For example, if you know that the interrupt only ever gets a read-lock, then you can use a non-irq version of read locks everywhere - because they -don't block on each other (and thus there is no dead-lock wrt interrupts. -But when you do the write-lock, you have to use the irq-safe version. +don't block on each other (and thus there is no dead-lock wrt interrupts. +But when you do the write-lock, you have to use the irq-safe version. -For an example of being clever with rw-locks, see the "waitqueue_lock" +For an example of being clever with rw-locks, see the "waitqueue_lock" handling in kernel/sched/core.c - nothing ever _changes_ a wait-queue from within an interrupt, they only read the queue in order to know whom to wake up. So read-locks are safe (which is good: they are very common diff --git a/Documentation/ww-mutex-design.txt b/Documentation/locking/ww-mutex-design.txt similarity index 100% rename from Documentation/ww-mutex-design.txt rename to Documentation/locking/ww-mutex-design.txt diff --git a/MAINTAINERS b/MAINTAINERS index 1acc624ecfd7..aac481fcbf5c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5523,8 +5523,8 @@ M: Ingo Molnar L: linux-kernel@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core/locking S: Maintained -F: Documentation/lockdep*.txt -F: Documentation/lockstat.txt +F: Documentation/locking/lockdep*.txt +F: Documentation/locking/lockstat.txt F: include/linux/lockdep.h F: kernel/locking/ diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 0dc57d5ecd10..3a02e5e3e9f3 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -35,7 +35,7 @@ * of extra utility/tracking out of our acquire-ctx. This is provided * by drm_modeset_lock / drm_modeset_acquire_ctx. * - * For basic principles of ww_mutex, see: Documentation/ww-mutex-design.txt + * For basic principles of ww_mutex, see: Documentation/locking/ww-mutex-design.txt * * The basic usage pattern is to: * diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 008388f920d7..f388481201cd 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -4,7 +4,7 @@ * Copyright (C) 2006,2007 Red Hat, Inc., Ingo Molnar * Copyright (C) 2007 Red Hat, Inc., Peter Zijlstra * - * see Documentation/lockdep-design.txt for more details. + * see Documentation/locking/lockdep-design.txt for more details. */ #ifndef __LINUX_LOCKDEP_H #define __LINUX_LOCKDEP_H diff --git a/include/linux/mutex.h b/include/linux/mutex.h index e4c29418f407..cc31498fc526 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -133,7 +133,7 @@ static inline int mutex_is_locked(struct mutex *lock) /* * See kernel/locking/mutex.c for detailed documentation of these APIs. - * Also see Documentation/mutex-design.txt. + * Also see Documentation/locking/mutex-design.txt. */ #ifdef CONFIG_DEBUG_LOCK_ALLOC extern void mutex_lock_nested(struct mutex *lock, unsigned int subclass); diff --git a/include/linux/rwsem.h b/include/linux/rwsem.h index 035d3c57fc8a..8f498cdde280 100644 --- a/include/linux/rwsem.h +++ b/include/linux/rwsem.h @@ -149,7 +149,7 @@ extern void downgrade_write(struct rw_semaphore *sem); * static then another method for expressing nested locking is * the explicit definition of lock class keys and the use of * lockdep_set_class() at lock initialization time. - * See Documentation/lockdep-design.txt for more details.) + * See Documentation/locking/lockdep-design.txt for more details.) */ extern void down_read_nested(struct rw_semaphore *sem, int subclass); extern void down_write_nested(struct rw_semaphore *sem, int subclass); diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index 0d8b6ed93874..dadbf88c22c4 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c @@ -15,7 +15,7 @@ * by Steven Rostedt, based on work by Gregory Haskins, Peter Morreale * and Sven Dietrich. * - * Also see Documentation/mutex-design.txt. + * Also see Documentation/locking/mutex-design.txt. */ #include #include diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index a0ea2a141b3b..7c98873a3077 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -8,7 +8,7 @@ * Copyright (C) 2005 Kihon Technologies Inc., Steven Rostedt * Copyright (C) 2006 Esben Nielsen * - * See Documentation/rt-mutex-design.txt for details. + * See Documentation/locking/rt-mutex-design.txt for details. */ #include #include diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 901096d31c66..9b94a063e26c 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -924,7 +924,7 @@ config PROVE_LOCKING the proof of observed correctness is also maintained for an arbitrary combination of these separate locking variants. - For more details, see Documentation/lockdep-design.txt. + For more details, see Documentation/locking/lockdep-design.txt. config LOCKDEP bool @@ -945,7 +945,7 @@ config LOCK_STAT help This feature enables tracking lock contention points - For more details, see Documentation/lockstat.txt + For more details, see Documentation/locking/lockstat.txt This also enables lock events required by "perf lock", subcommand of perf. -- GitLab From 0a7cbf9abe3198461de3d3e97268db32a646ba06 Mon Sep 17 00:00:00 2001 From: Davidlohr Bueso Date: Wed, 30 Jul 2014 13:41:56 -0700 Subject: [PATCH 0287/9167] locking/Documentation: Update locking/mutex-design.txt disadvantages Fortunately Jason was able to reduce some of the overhead we had introduced in the original rwsem optimistic spinning - an it is now the same size as mutexes. Update the documentation accordingly. Signed-off-by: Davidlohr Bueso Acked-by: Jason Low Signed-off-by: Peter Zijlstra Cc: aswin@hp.com Cc: Linus Torvalds Cc: Randy Dunlap Link: http://lkml.kernel.org/r/1406752916-3341-7-git-send-email-davidlohr@hp.com Signed-off-by: Ingo Molnar --- Documentation/locking/mutex-design.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/locking/mutex-design.txt b/Documentation/locking/mutex-design.txt index ee231ed09ec6..60c482df1a38 100644 --- a/Documentation/locking/mutex-design.txt +++ b/Documentation/locking/mutex-design.txt @@ -145,9 +145,9 @@ Disadvantages Unlike its original design and purpose, 'struct mutex' is larger than most locks in the kernel. E.g: on x86-64 it is 40 bytes, almost twice -as large as 'struct semaphore' (24 bytes) and 8 bytes shy of the -'struct rw_semaphore' variant. Larger structure sizes mean more CPU -cache and memory footprint. +as large as 'struct semaphore' (24 bytes) and tied, along with rwsems, +for the largest lock in the kernel. Larger structure sizes mean more +CPU cache and memory footprint. When to use mutexes ------------------- -- GitLab From 4999201a59ef555f9105d2bb2459ed895627f7aa Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 8 Aug 2014 12:35:36 +0200 Subject: [PATCH 0288/9167] locking/spinlocks: Always evaluate the second argument of spin_lock_nested() Evaluating a macro argument only if certain configuration options have been selected is confusing and error-prone. Hence always evaluate the second argument of spin_lock_nested(). An intentional side effect of this patch is that it avoids that the following warning is reported for netif_addr_lock_nested() when building with CONFIG_DEBUG_LOCK_ALLOC=n and with W=1: include/linux/netdevice.h: In function 'netif_addr_lock_nested': include/linux/netdevice.h:2865:6: warning: variable 'subclass' set but not used [-Wunused-but-set-variable] int subclass = SINGLE_DEPTH_NESTING; ^ Signed-off-by: Bart Van Assche Signed-off-by: Peter Zijlstra Cc: David Rientjes Cc: David S. Miller Cc: Andrew Morton Cc: Linus Torvalds Cc: Oleg Nesterov Cc: Paul E. McKenney Link: http://lkml.kernel.org/r/53E4A7F8.1040700@acm.org Signed-off-by: Ingo Molnar --- include/linux/spinlock.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 3f2867ff0ced..262ba4ef9a8e 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -197,7 +197,13 @@ static inline void do_raw_spin_unlock(raw_spinlock_t *lock) __releases(lock) _raw_spin_lock_nest_lock(lock, &(nest_lock)->dep_map); \ } while (0) #else -# define raw_spin_lock_nested(lock, subclass) _raw_spin_lock(lock) +/* + * Always evaluate the 'subclass' argument to avoid that the compiler + * warns about set-but-not-used variables when building with + * CONFIG_DEBUG_LOCK_ALLOC=n and with W=1. + */ +# define raw_spin_lock_nested(lock, subclass) \ + _raw_spin_lock(((void)(subclass), (lock))) # define raw_spin_lock_nest_lock(lock, nest_lock) _raw_spin_lock(lock) #endif -- GitLab From f0bab73cb539fb803c4d419951e8d28aa4964f8f Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Wed, 6 Aug 2014 13:22:01 -0400 Subject: [PATCH 0289/9167] locking/lockdep: Restrict the use of recursive read_lock() with qrwlock Unlike the original unfair rwlock implementation, queued rwlock will grant lock according to the chronological sequence of the lock requests except when the lock requester is in the interrupt context. Consequently, recursive read_lock calls will now hang the process if there is a write_lock call somewhere in between the read_lock calls. This patch updates the lockdep implementation to look for recursive read_lock calls. A new read state (3) is used to mark those read_lock call that cannot be recursively called except in the interrupt context. The new read state does exhaust the 2 bits available in held_lock:read bit field. The addition of any new read state in the future may require a redesign of how all those bits are squeezed together in the held_lock structure. Signed-off-by: Waiman Long Signed-off-by: Peter Zijlstra Cc: Maarten Lankhorst Cc: Rik van Riel Cc: Scott J Norton Cc: Fengguang Wu Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1407345722-61615-2-git-send-email-Waiman.Long@hp.com Signed-off-by: Ingo Molnar --- include/linux/lockdep.h | 10 +++++++++- kernel/locking/lockdep.c | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index f388481201cd..b5a84b62fb84 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -478,16 +478,24 @@ static inline void print_irqtrace_events(struct task_struct *curr) * on the per lock-class debug mode: */ +/* + * Read states in the 2-bit held_lock:read field: + * 0: Exclusive lock + * 1: Shareable lock, cannot be recursively called + * 2: Shareable lock, can be recursively called + * 3: Shareable lock, cannot be recursively called except in interrupt context + */ #define lock_acquire_exclusive(l, s, t, n, i) lock_acquire(l, s, t, 0, 1, n, i) #define lock_acquire_shared(l, s, t, n, i) lock_acquire(l, s, t, 1, 1, n, i) #define lock_acquire_shared_recursive(l, s, t, n, i) lock_acquire(l, s, t, 2, 1, n, i) +#define lock_acquire_shared_irecursive(l, s, t, n, i) lock_acquire(l, s, t, 3, 1, n, i) #define spin_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) #define spin_acquire_nest(l, s, t, n, i) lock_acquire_exclusive(l, s, t, n, i) #define spin_release(l, n, i) lock_release(l, n, i) #define rwlock_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) -#define rwlock_acquire_read(l, s, t, i) lock_acquire_shared_recursive(l, s, t, NULL, i) +#define rwlock_acquire_read(l, s, t, i) lock_acquire_shared_irecursive(l, s, t, NULL, i) #define rwlock_release(l, n, i) lock_release(l, n, i) #define seqcount_acquire(l, s, t, i) lock_acquire_exclusive(l, s, t, NULL, i) diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index 88d0d4420ad2..420ba685c4e5 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c @@ -3597,6 +3597,12 @@ void lock_acquire(struct lockdep_map *lock, unsigned int subclass, raw_local_irq_save(flags); check_flags(flags); + /* + * An interrupt recursive read in interrupt context can be considered + * to be the same as a recursive read from checking perspective. + */ + if ((read == 3) && in_interrupt()) + read = 2; current->lockdep_recursion = 1; trace_lock_acquire(lock, subclass, trylock, read, check, nest_lock, ip); __lock_acquire(lock, subclass, trylock, read, check, -- GitLab From ae17ea0ec7d8fa64fbb773a52b2df5ba4766bcb8 Mon Sep 17 00:00:00 2001 From: Waiman Long Date: Wed, 6 Aug 2014 13:22:02 -0400 Subject: [PATCH 0290/9167] locking/selftest: Support queued rwlock The queued rwlock does not support the use of recursive read-lock in the process context. With changes in the lockdep code to check and disallow recursive read-lock, it is also necessary for the locking selftest to be updated to change the process context recursive read locking results from SUCCESS to FAILURE for rwlock. Signed-off-by: Waiman Long Signed-off-by: Peter Zijlstra Cc: Maarten Lankhorst Cc: Rik van Riel Cc: Scott J Norton Cc: Fengguang Wu Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1407345722-61615-3-git-send-email-Waiman.Long@hp.com Signed-off-by: Ingo Molnar --- lib/locking-selftest.c | 56 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c index 872a15a2a637..62af709b2083 100644 --- a/lib/locking-selftest.c +++ b/lib/locking-selftest.c @@ -267,19 +267,46 @@ GENERATE_TESTCASE(AA_rsem) #undef E /* - * Special-case for read-locking, they are - * allowed to recurse on the same lock class: + * Special-case for read-locking, they are not allowed to + * recurse on the same lock class except under interrupt context: */ static void rlock_AA1(void) { RL(X1); - RL(X1); // this one should NOT fail + RL(X1); // this one should fail } static void rlock_AA1B(void) { RL(X1); - RL(X2); // this one should NOT fail + RL(X2); // this one should fail +} + +static void rlock_AHA1(void) +{ + RL(X1); + HARDIRQ_ENTER(); + RL(X1); // this one should NOT fail + HARDIRQ_EXIT(); +} + +static void rlock_AHA1B(void) +{ + RL(X1); + HARDIRQ_ENTER(); + RL(X2); // this one should NOT fail + HARDIRQ_EXIT(); +} + +static void rlock_ASAHA1(void) +{ + RL(X1); + SOFTIRQ_ENTER(); + RL(X1); // this one should NOT fail + HARDIRQ_ENTER(); + RL(X1); // this one should NOT fail + HARDIRQ_EXIT(); + SOFTIRQ_EXIT(); } static void rsem_AA1(void) @@ -1069,7 +1096,7 @@ static inline void print_testname(const char *testname) print_testname(desc); \ dotest(name##_spin, FAILURE, LOCKTYPE_SPIN); \ dotest(name##_wlock, FAILURE, LOCKTYPE_RWLOCK); \ - dotest(name##_rlock, SUCCESS, LOCKTYPE_RWLOCK); \ + dotest(name##_rlock, FAILURE, LOCKTYPE_RWLOCK); \ dotest(name##_mutex, FAILURE, LOCKTYPE_MUTEX); \ dotest(name##_wsem, FAILURE, LOCKTYPE_RWSEM); \ dotest(name##_rsem, FAILURE, LOCKTYPE_RWSEM); \ @@ -1830,14 +1857,14 @@ void locking_selftest(void) printk(" --------------------------------------------------------------------------\n"); print_testname("recursive read-lock"); printk(" |"); - dotest(rlock_AA1, SUCCESS, LOCKTYPE_RWLOCK); + dotest(rlock_AA1, FAILURE, LOCKTYPE_RWLOCK); printk(" |"); dotest(rsem_AA1, FAILURE, LOCKTYPE_RWSEM); printk("\n"); print_testname("recursive read-lock #2"); printk(" |"); - dotest(rlock_AA1B, SUCCESS, LOCKTYPE_RWLOCK); + dotest(rlock_AA1B, FAILURE, LOCKTYPE_RWLOCK); printk(" |"); dotest(rsem_AA1B, FAILURE, LOCKTYPE_RWSEM); printk("\n"); @@ -1856,6 +1883,21 @@ void locking_selftest(void) dotest(rsem_AA3, FAILURE, LOCKTYPE_RWSEM); printk("\n"); + print_testname("recursive rlock with interrupt"); + printk(" |"); + dotest(rlock_AHA1, SUCCESS, LOCKTYPE_RWLOCK); + printk("\n"); + + print_testname("recursive rlock with interrupt #2"); + printk(" |"); + dotest(rlock_AHA1B, SUCCESS, LOCKTYPE_RWLOCK); + printk("\n"); + + print_testname("recursive rlock with interrupt #3"); + printk(" |"); + dotest(rlock_ASAHA1, SUCCESS, LOCKTYPE_RWLOCK); + printk("\n"); + printk(" --------------------------------------------------------------------------\n"); /* -- GitLab From 4d884705dababd7d0f3f12796bc7b45e84962596 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:47 +0200 Subject: [PATCH 0291/9167] drm/i915: Track file_priv, not ctx in the ppgtt structure Hardware contexts reference a ppgtt, not the other way round. And the only user of this (in debugfs) actually only cares about which file the ppgtt is associated with. So give it what it wants. While at it give the ppgtt create function a proper name&place. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_gem_context.c | 22 +--------------------- drivers/gpu/drm/i915/i915_gem_gtt.c | 21 +++++++++++++++++++++ drivers/gpu/drm/i915/i915_gem_gtt.h | 6 +++++- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3b7decbeeed3..1c3a9943a742 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -333,7 +333,7 @@ static int per_file_stats(int id, void *ptr, void *data) } ppgtt = container_of(vma->vm, struct i915_hw_ppgtt, base); - if (ppgtt->ctx && ppgtt->ctx->file_priv != stats->file_priv) + if (ppgtt->file_priv != stats->file_priv) continue; if (obj->ring) /* XXX per-vma statistic */ diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index dc43d0263a01..90665872734d 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -184,26 +184,6 @@ i915_gem_alloc_context_obj(struct drm_device *dev, size_t size) return obj; } -static struct i915_hw_ppgtt * -create_vm_for_ctx(struct drm_device *dev, struct intel_context *ctx) -{ - struct i915_hw_ppgtt *ppgtt; - int ret; - - ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); - if (!ppgtt) - return ERR_PTR(-ENOMEM); - - ret = i915_ppgtt_init(dev, ppgtt); - if (ret) { - kfree(ppgtt); - return ERR_PTR(ret); - } - - ppgtt->ctx = ctx; - return ppgtt; -} - static struct intel_context * __create_hw_context(struct drm_device *dev, struct drm_i915_file_private *file_priv) @@ -290,7 +270,7 @@ i915_gem_create_context(struct drm_device *dev, } if (create_vm) { - struct i915_hw_ppgtt *ppgtt = create_vm_for_ctx(dev, ctx); + struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv); if (IS_ERR_OR_NULL(ppgtt)) { DRM_DEBUG_DRIVER("PPGTT setup failed (%ld)\n", diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6ffa12b72538..a5715faba65f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1211,6 +1211,27 @@ int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) return ret; } +struct i915_hw_ppgtt * +i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv) +{ + struct i915_hw_ppgtt *ppgtt; + int ret; + + ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); + if (!ppgtt) + return ERR_PTR(-ENOMEM); + + ret = i915_ppgtt_init(dev, ppgtt); + if (ret) { + kfree(ppgtt); + return ERR_PTR(ret); + } + + ppgtt->file_priv = fpriv; + + return ppgtt; +} + void i915_ppgtt_release(struct kref *kref) { struct i915_hw_ppgtt *ppgtt = diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index c6beb528f955..90ff45246b62 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -34,6 +34,8 @@ #ifndef __I915_GEM_GTT_H__ #define __I915_GEM_GTT_H__ +struct drm_i915_file_private; + typedef uint32_t gen6_gtt_pte_t; typedef uint64_t gen8_gtt_pte_t; typedef gen8_gtt_pte_t gen8_ppgtt_pde_t; @@ -258,7 +260,7 @@ struct i915_hw_ppgtt { dma_addr_t *gen8_pt_dma_addr[4]; }; - struct intel_context *ctx; + struct drm_i915_file_private *file_priv; int (*enable)(struct i915_hw_ppgtt *ppgtt); int (*switch_mm)(struct i915_hw_ppgtt *ppgtt, @@ -275,6 +277,8 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start, int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); void i915_ppgtt_release(struct kref *kref); +struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_device *dev, + struct drm_i915_file_private *fpriv); static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt) { if (ppgtt) -- GitLab From 841cd7737557785c0f215b0984c06aaaaa882302 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:48 +0200 Subject: [PATCH 0292/9167] drm/i915: Only refcount ppgtt if it actually is one This essentially unbreaks non-ppgtt operation where we'd scribble over random memory. While at it give the vm_to_ppgtt function a proper prefix and make it a bit more paranoid. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 10 +++++++++- drivers/gpu/drm/i915/i915_gem.c | 3 ++- drivers/gpu/drm/i915/i915_gem_gtt.c | 3 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 101fc637eb46..454badf31dfd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2512,6 +2512,15 @@ static inline bool i915_is_ggtt(struct i915_address_space *vm) return vm == ggtt; } +static inline struct i915_hw_ppgtt * +i915_vm_to_ppgtt(struct i915_address_space *vm) +{ + WARN_ON(i915_is_ggtt(vm)); + + return container_of(vm, struct i915_hw_ppgtt, base); +} + + static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj) { return i915_gem_obj_bound(obj, obj_to_ggtt(obj)); @@ -2547,7 +2556,6 @@ void i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj); /* i915_gem_context.c */ #define ctx_to_ppgtt(ctx) container_of((ctx)->vm, struct i915_hw_ppgtt, base) -#define vm_to_ppgtt(vm) container_of(vm, struct i915_hw_ppgtt, base) int __must_check i915_gem_context_init(struct drm_device *dev); void i915_gem_context_fini(struct drm_device *dev); void i915_gem_context_reset(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8061d45eaa80..e3e30cd474be 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4485,7 +4485,8 @@ void i915_gem_vma_destroy(struct i915_vma *vma) vm = vma->vm; - i915_ppgtt_put(vm_to_ppgtt(vm)); + if (!i915_is_ggtt(vm)) + i915_ppgtt_put(i915_vm_to_ppgtt(vm)); list_del(&vma->vma_link); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index a5715faba65f..48d8f4a21c3f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -2187,7 +2187,8 @@ i915_gem_obj_lookup_or_create_vma(struct drm_i915_gem_object *obj, if (!vma) vma = __i915_gem_vma_create(obj, vm); - i915_ppgtt_get(vm_to_ppgtt(vm)); + if (!i915_is_ggtt(vm)) + i915_ppgtt_get(i915_vm_to_ppgtt(vm)); return vma; } -- GitLab From 5dc383b05a05d05e964172d882603cd171040c5f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:49 +0200 Subject: [PATCH 0293/9167] drm/i915: Add proper prefix to obj_to_ggtt Stuff in headers really aught to have this. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 11 ++++++----- drivers/gpu/drm/i915/i915_gem.c | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 454badf31dfd..2db22732c7ae 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2503,7 +2503,7 @@ static inline bool i915_gem_obj_is_pinned(struct drm_i915_gem_object *obj) { } /* Some GGTT VM helpers */ -#define obj_to_ggtt(obj) \ +#define i915_obj_to_ggtt(obj) \ (&((struct drm_i915_private *)(obj)->base.dev->dev_private)->gtt.base) static inline bool i915_is_ggtt(struct i915_address_space *vm) { @@ -2523,19 +2523,19 @@ i915_vm_to_ppgtt(struct i915_address_space *vm) static inline bool i915_gem_obj_ggtt_bound(struct drm_i915_gem_object *obj) { - return i915_gem_obj_bound(obj, obj_to_ggtt(obj)); + return i915_gem_obj_bound(obj, i915_obj_to_ggtt(obj)); } static inline unsigned long i915_gem_obj_ggtt_offset(struct drm_i915_gem_object *obj) { - return i915_gem_obj_offset(obj, obj_to_ggtt(obj)); + return i915_gem_obj_offset(obj, i915_obj_to_ggtt(obj)); } static inline unsigned long i915_gem_obj_ggtt_size(struct drm_i915_gem_object *obj) { - return i915_gem_obj_size(obj, obj_to_ggtt(obj)); + return i915_gem_obj_size(obj, i915_obj_to_ggtt(obj)); } static inline int __must_check @@ -2543,7 +2543,8 @@ i915_gem_obj_ggtt_pin(struct drm_i915_gem_object *obj, uint32_t alignment, unsigned flags) { - return i915_gem_object_pin(obj, obj_to_ggtt(obj), alignment, flags | PIN_GLOBAL); + return i915_gem_object_pin(obj, i915_obj_to_ggtt(obj), + alignment, flags | PIN_GLOBAL); } static inline int diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e3e30cd474be..c9d1396781e2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5252,7 +5252,7 @@ struct i915_vma *i915_gem_obj_to_ggtt(struct drm_i915_gem_object *obj) struct i915_vma *vma; vma = list_first_entry(&obj->vma_list, typeof(*vma), vma_link); - if (vma->vm != obj_to_ggtt(obj)) + if (vma->vm != i915_obj_to_ggtt(obj)) return NULL; return vma; -- GitLab From 6c5566a82c6fb1da9e13a294f23d4cd85a08cb30 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:50 +0200 Subject: [PATCH 0294/9167] drm/i915: Allow i915_gem_setup_global_gtt to fail We already needs this just as a safety check in case the preallocation reservation dance fails. But we definitely need this to be able to move tha aliasing ppgtt setup back out of the context code to this place, where it belongs. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 7 ++++++- drivers/gpu/drm/i915/i915_gem_gtt.c | 16 ++++++++++------ drivers/gpu/drm/i915/i915_gem_gtt.h | 4 ++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c9d1396781e2..c8404a439502 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4754,7 +4754,12 @@ int i915_gem_init(struct drm_device *dev) dev_priv->gt.stop_ring = intel_logical_ring_stop; } - i915_gem_init_userptr(dev); + ret = i915_gem_init_userptr(dev); + if (ret) { + mutex_unlock(&dev->struct_mutex); + return ret; + } + i915_gem_init_global_gtt(dev); ret = i915_gem_context_init(dev); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 48d8f4a21c3f..d228f839ca4f 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1698,10 +1698,10 @@ static void i915_gtt_color_adjust(struct drm_mm_node *node, } } -void i915_gem_setup_global_gtt(struct drm_device *dev, - unsigned long start, - unsigned long mappable_end, - unsigned long end) +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. * @@ -1734,8 +1734,10 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, WARN_ON(i915_gem_obj_ggtt_bound(obj)); ret = drm_mm_reserve_node(&ggtt_vm->mm, &vma->node); - if (ret) - DRM_DEBUG_KMS("Reservation failed\n"); + if (ret) { + DRM_DEBUG_KMS("Reservation failed: %i\n", ret); + return ret; + } obj->has_global_gtt_mapping = 1; } @@ -1752,6 +1754,8 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, /* And finally clear the reserved guard page */ ggtt_vm->clear_range(ggtt_vm, end - PAGE_SIZE, PAGE_SIZE, true); + + return 0; } void i915_gem_init_global_gtt(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 90ff45246b62..0eb0dddff76b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -271,8 +271,8 @@ struct i915_hw_ppgtt { int i915_gem_gtt_init(struct drm_device *dev); void i915_gem_init_global_gtt(struct drm_device *dev); -void i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start, - unsigned long mappable_end, unsigned long end); +int i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start, + unsigned long mappable_end, unsigned long end); int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); -- GitLab From 896ab1a5d54269b463a24194c2e4a369103b46d8 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:51 +0200 Subject: [PATCH 0295/9167] drm/i915: Fix up checks for aliasing ppgtt A subsequent patch will no longer initialize the aliasing ppgtt if we have full ppgtt enabled, since we simply don't need that any more. Unfortunately a few places check for the aliasing ppgtt instead of checking for ppgtt in general. Fix them up. One special case are the gtt offset and size macros, which have some code to remap the aliasing ppgtt to the global gtt. The aliasing ppgtt is _not_ a logical address space, so passing that in as the vm is plain and simple a bug. So just WARN about it and carry on - we have a gracefully fall-through anyway if we can't find the vma. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_cmd_parser.c | 4 +--- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_gem.c | 8 ++------ drivers/gpu/drm/i915/intel_ringbuffer.c | 4 +--- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index dea99d92fb4a..c45856bcc8b9 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -842,8 +842,6 @@ static u32 *vmap_batch(struct drm_i915_gem_object *obj) */ bool i915_needs_cmd_parser(struct intel_engine_cs *ring) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; - if (!ring->needs_cmd_parser) return false; @@ -852,7 +850,7 @@ bool i915_needs_cmd_parser(struct intel_engine_cs *ring) * disabled. That will cause all of the parser's PPGTT checks to * fail. For now, disable parsing when PPGTT is off. */ - if (!dev_priv->mm.aliasing_ppgtt) + if (USES_PPGTT(ring->dev)) return false; return (i915.enable_cmd_parser == 1); diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1763fbf34e1d..895f9f2f35ea 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -999,7 +999,7 @@ static int i915_getparam(struct drm_device *dev, void *data, value = HAS_WT(dev); break; case I915_PARAM_HAS_ALIASING_PPGTT: - value = dev_priv->mm.aliasing_ppgtt || USES_FULL_PPGTT(dev); + value = USES_PPGTT(dev); break; case I915_PARAM_HAS_WAIT_TIMEOUT: value = 1; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c8404a439502..6a7795097017 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -5106,9 +5106,7 @@ unsigned long i915_gem_obj_offset(struct drm_i915_gem_object *o, struct drm_i915_private *dev_priv = o->base.dev->dev_private; struct i915_vma *vma; - if (!dev_priv->mm.aliasing_ppgtt || - vm == &dev_priv->mm.aliasing_ppgtt->base) - vm = &dev_priv->gtt.base; + WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base); list_for_each_entry(vma, &o->vma_list, vma_link) { if (vma->vm == vm) @@ -5149,9 +5147,7 @@ unsigned long i915_gem_obj_size(struct drm_i915_gem_object *o, struct drm_i915_private *dev_priv = o->base.dev->dev_private; struct i915_vma *vma; - if (!dev_priv->mm.aliasing_ppgtt || - vm == &dev_priv->mm.aliasing_ppgtt->base) - vm = &dev_priv->gtt.base; + WARN_ON(vm == &dev_priv->mm.aliasing_ppgtt->base); BUG_ON(list_empty(&o->vma_list)); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4236014c1cda..13543f8528c2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -2006,9 +2006,7 @@ gen8_ring_dispatch_execbuffer(struct intel_engine_cs *ring, u64 offset, u32 len, unsigned flags) { - struct drm_i915_private *dev_priv = ring->dev->dev_private; - bool ppgtt = dev_priv->mm.aliasing_ppgtt != NULL && - !(flags & I915_DISPATCH_SECURE); + bool ppgtt = USES_PPGTT(ring->dev) && !(flags & I915_DISPATCH_SECURE); int ret; ret = intel_ring_begin(ring, 4); -- GitLab From 82460d97246a993aa49e88bf9b4154cce60f8da8 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 20:19:53 +0200 Subject: [PATCH 0296/9167] drm/i915: Rework ppgtt init to no require an aliasing ppgtt Currently we abuse the aliasing ppgtt to set up the ppgtt support in general. Which is a bit backwards since with full ppgtt we don't ever need the aliasing ppgtt. So untangle this and separate the ppgtt init from the aliasing ppgtt. While at it drag it out of the context enabling (which just does a switch to the default context). Note that we still have the differentiation between synchronous and asynchronous ppgtt setup, but that will soon vanish. So also correctly wire up the return value handling to be prepared for when ->switch_mm drops the synchronous parameter and could start to fail. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 8 +++ drivers/gpu/drm/i915/i915_gem_context.c | 7 --- drivers/gpu/drm/i915/i915_gem_gtt.c | 84 ++++++++++--------------- drivers/gpu/drm/i915/i915_gem_gtt.h | 1 + 4 files changed, 42 insertions(+), 58 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6a7795097017..6c2f0b886eb0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4719,6 +4719,14 @@ i915_gem_init_hw(struct drm_device *dev) if (ret && ret != -EIO) { DRM_ERROR("Context enable failed %d\n", ret); i915_gem_cleanup_ringbuffer(dev); + + return ret; + } + + ret = i915_ppgtt_init_hw(dev); + if (ret && ret != -EIO) { + DRM_ERROR("PPGTT enable failed %d\n", ret); + i915_gem_cleanup_ringbuffer(dev); } return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 90665872734d..eece059a8447 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -436,13 +436,6 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv) struct intel_engine_cs *ring; int ret, i; - /* This is the only place the aliasing PPGTT gets enabled, which means - * it has to happen before we bail on reset */ - if (dev_priv->mm.aliasing_ppgtt) { - struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; - ppgtt->enable(ppgtt); - } - /* FIXME: We should make this work, even in reset */ if (i915_reset_in_progress(&dev_priv->gpu_error)) return 0; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d228f839ca4f..b7dcf72126f9 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -67,7 +67,6 @@ static void ppgtt_bind_vma(struct i915_vma *vma, enum i915_cache_level cache_level, u32 flags); static void ppgtt_unbind_vma(struct i915_vma *vma); -static int gen8_ppgtt_enable(struct i915_hw_ppgtt *ppgtt); static inline gen8_gtt_pte_t gen8_pte_encode(dma_addr_t addr, enum i915_cache_level level, @@ -604,7 +603,6 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) kunmap_atomic(pd_vaddr); } - ppgtt->enable = gen8_ppgtt_enable; ppgtt->switch_mm = gen8_mm_switch; ppgtt->base.clear_range = gen8_ppgtt_clear_range; ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; @@ -825,39 +823,20 @@ static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt, return 0; } -static int gen8_ppgtt_enable(struct i915_hw_ppgtt *ppgtt) +static void gen8_ppgtt_enable(struct drm_device *dev) { - struct drm_device *dev = ppgtt->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; - int j, ret; + int j; for_each_ring(ring, dev_priv, j) { I915_WRITE(RING_MODE_GEN7(ring), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); - - /* We promise to do a switch later with FULL PPGTT. If this is - * aliasing, this is the one and only switch we'll do */ - if (USES_FULL_PPGTT(dev)) - continue; - - ret = ppgtt->switch_mm(ppgtt, ring, true); - if (ret) - goto err_out; } - - return 0; - -err_out: - for_each_ring(ring, dev_priv, j) - I915_WRITE(RING_MODE_GEN7(ring), - _MASKED_BIT_DISABLE(GFX_PPGTT_ENABLE)); - return ret; } -static int gen7_ppgtt_enable(struct i915_hw_ppgtt *ppgtt) +static void gen7_ppgtt_enable(struct drm_device *dev) { - struct drm_device *dev = ppgtt->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_engine_cs *ring; uint32_t ecochk, ecobits; @@ -876,31 +855,16 @@ static int gen7_ppgtt_enable(struct i915_hw_ppgtt *ppgtt) I915_WRITE(GAM_ECOCHK, ecochk); for_each_ring(ring, dev_priv, i) { - int ret; /* GFX_MODE is per-ring on gen7+ */ I915_WRITE(RING_MODE_GEN7(ring), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); - - /* We promise to do a switch later with FULL PPGTT. If this is - * aliasing, this is the one and only switch we'll do */ - if (USES_FULL_PPGTT(dev)) - continue; - - ret = ppgtt->switch_mm(ppgtt, ring, true); - if (ret) - return ret; } - - return 0; } -static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt) +static void gen6_ppgtt_enable(struct drm_device *dev) { - struct drm_device *dev = ppgtt->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_engine_cs *ring; uint32_t ecochk, gab_ctl, ecobits; - int i; ecobits = I915_READ(GAC_ECO_BITS); I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_SNB_BIT | @@ -913,14 +877,6 @@ static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt) I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | ECOCHK_PPGTT_CACHE64B); I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); - - for_each_ring(ring, dev_priv, i) { - int ret = ppgtt->switch_mm(ppgtt, ring, true); - if (ret) - return ret; - } - - return 0; } /* PPGTT support for Sandybdrige/Gen6 and later */ @@ -1140,13 +1096,10 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ppgtt->base.pte_encode = dev_priv->gtt.base.pte_encode; if (IS_GEN6(dev)) { - ppgtt->enable = gen6_ppgtt_enable; ppgtt->switch_mm = gen6_mm_switch; } else if (IS_HASWELL(dev)) { - ppgtt->enable = gen7_ppgtt_enable; ppgtt->switch_mm = hsw_mm_switch; } else if (IS_GEN7(dev)) { - ppgtt->enable = gen7_ppgtt_enable; ppgtt->switch_mm = gen7_mm_switch; } else BUG(); @@ -1211,6 +1164,35 @@ int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) return ret; } +int i915_ppgtt_init_hw(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring; + struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; + int i, ret = 0; + + if (!USES_PPGTT(dev)) + return 0; + + if (IS_GEN6(dev)) + gen6_ppgtt_enable(dev); + else if (IS_GEN7(dev)) + gen7_ppgtt_enable(dev); + else if (INTEL_INFO(dev)->gen >= 8) + gen8_ppgtt_enable(dev); + else + WARN_ON(1); + + if (ppgtt) { + for_each_ring(ring, dev_priv, i) { + ret = ppgtt->switch_mm(ppgtt, ring, true); + if (ret != 0) + return ret; + } + } + + return ret; +} struct i915_hw_ppgtt * i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv) { diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 0eb0dddff76b..98fbb7309ea5 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -276,6 +276,7 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, unsigned long start, int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); +int i915_ppgtt_init_hw(struct drm_device *dev); void i915_ppgtt_release(struct kref *kref); struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_device *dev, struct drm_i915_file_private *fpriv); -- GitLab From fa76da3499f1789f0e37d3bbcdc320bdf47c89ca Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 20:19:54 +0200 Subject: [PATCH 0297/9167] drm/i915: Initialize the aliasing ppgtt as part of global gtt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stuffing this into the context setup code doesn't make a lot of sense. Also reusing the real ppgtt setup code makes even less sense since the aliasing ppgtt isn't a real address space. Leaving all that stuff unitialized will make sure that we catch any abusers promptly. This is also a prep work to clean up the context->ppgtt link. v2: Fix up the logic fail, I've fumbled it so badly to completely disable ppgtt on gen6. Spotted by Ville and Michel. Also move around the pde write into the gen6 init function, since otherwise it won't work at all. v3: Only initialize the aliasing ppgtt when we actually enable it. Cc: "Thierry, Michel" Cc: Ville Syrjälä Reviewed-by: Michel Thierry [danvet: Squash in fixup from Fengguang Wu.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_context.c | 13 +------- drivers/gpu/drm/i915/i915_gem_gtt.c | 42 ++++++++++++++++++------- 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index eece059a8447..7093f5df9ee7 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -279,17 +279,6 @@ i915_gem_create_context(struct drm_device *dev, goto err_unpin; } else ctx->vm = &ppgtt->base; - - /* This case is reserved for the global default context and - * should only happen once. */ - if (is_global_default_ctx) { - if (WARN_ON(dev_priv->mm.aliasing_ppgtt)) { - ret = -EEXIST; - goto err_unpin; - } - - dev_priv->mm.aliasing_ppgtt = ppgtt; - } } else if (USES_PPGTT(dev)) { /* For platforms which only have aliasing PPGTT, we fake the * address space and refcounting. */ @@ -368,7 +357,7 @@ int i915_gem_context_init(struct drm_device *dev) } } - ctx = i915_gem_create_context(dev, NULL, USES_PPGTT(dev)); + ctx = i915_gem_create_context(dev, NULL, USES_FULL_PPGTT(dev)); if (IS_ERR(ctx)) { DRM_ERROR("Failed to create default global context (error %ld)\n", PTR_ERR(ctx)); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index b7dcf72126f9..b033ff770ac4 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1130,35 +1130,38 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt) ppgtt->node.size >> 20, ppgtt->node.start / PAGE_SIZE); + gen6_write_pdes(ppgtt); + DRM_DEBUG("Adding PPGTT at offset %x\n", + ppgtt->pd_offset << 10); + return 0; } -int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) +static int __hw_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) { struct drm_i915_private *dev_priv = dev->dev_private; - int ret = 0; ppgtt->base.dev = dev; ppgtt->base.scratch = dev_priv->gtt.base.scratch; if (INTEL_INFO(dev)->gen < 8) - ret = gen6_ppgtt_init(ppgtt); + return gen6_ppgtt_init(ppgtt); else if (IS_GEN8(dev)) - ret = gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total); + return gen8_ppgtt_init(ppgtt, dev_priv->gtt.base.total); else BUG(); +} +int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int ret = 0; - if (!ret) { - struct drm_i915_private *dev_priv = dev->dev_private; + ret = __hw_ppgtt_init(dev, ppgtt); + if (ret == 0) { kref_init(&ppgtt->ref); drm_mm_init(&ppgtt->base.mm, ppgtt->base.start, ppgtt->base.total); i915_init_vm(dev_priv, &ppgtt->base); - if (INTEL_INFO(dev)->gen < 8) { - gen6_write_pdes(ppgtt); - DRM_DEBUG("Adding PPGTT at offset %x\n", - ppgtt->pd_offset << 10); - } } return ret; @@ -1699,6 +1702,7 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, struct drm_mm_node *entry; struct drm_i915_gem_object *obj; unsigned long hole_start, hole_end; + int ret; BUG_ON(mappable_end > end); @@ -1710,7 +1714,7 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, /* Mark any preallocated objects as occupied */ list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { struct i915_vma *vma = i915_gem_obj_to_vma(obj, ggtt_vm); - int ret; + DRM_DEBUG_KMS("reserving preallocated space: %lx + %zx\n", i915_gem_obj_ggtt_offset(obj), obj->base.size); @@ -1737,6 +1741,20 @@ int i915_gem_setup_global_gtt(struct drm_device *dev, /* And finally clear the reserved guard page */ ggtt_vm->clear_range(ggtt_vm, end - PAGE_SIZE, PAGE_SIZE, true); + if (USES_PPGTT(dev) && !USES_FULL_PPGTT(dev)) { + struct i915_hw_ppgtt *ppgtt; + + ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); + if (!ppgtt) + return -ENOMEM; + + ret = __hw_ppgtt_init(dev, ppgtt); + if (ret != 0) + return ret; + + dev_priv->mm.aliasing_ppgtt = ppgtt; + } + return 0; } -- GitLab From ae6c4806927b8b0781ecc187aa16b10c820fc430 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:53 +0200 Subject: [PATCH 0298/9167] drm/i915: Only track real ppgtt for a context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There's a bit a confusion since we track the global gtt, the aliasing and real ppgtt in the ctx->vm pointer. And not all callers really bother to check for the different cases and just presume that it points to a real ppgtt. Now looking closely we don't actually need ->vm to always point at an address space - the only place that cares actually has fixup code already to decide whether to look at the per-proces or the global address space. So switch to just tracking the ppgtt directly and ditch all the extraneous code. v2: Fixup the ppgtt debugfs file to not oops on a NULL ctx->ppgtt. Also drop the early exit - without aliasing ppgtt we want to dump all the ppgtts of the contexts if we have full ppgtt. v3: Actually git add the compile fix. Reviewed-by: Michel Thierry Cc: "Thierry, Michel" Cc: Ville Syrjälä OTC-Jira: VIZ-3724 [danvet: Resolve conflicts with execlist patches while applying.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 11 ++++++-- drivers/gpu/drm/i915/i915_drv.h | 3 +- drivers/gpu/drm/i915/i915_gem_context.c | 33 +++++++--------------- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 5 ++-- drivers/gpu/drm/i915/i915_gpu_error.c | 10 +++++-- drivers/gpu/drm/i915/intel_lrc.c | 2 +- 6 files changed, 30 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1c3a9943a742..d42db6bc34e0 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1821,7 +1821,13 @@ static int per_file_ctx(int id, void *ptr, void *data) { struct intel_context *ctx = ptr; struct seq_file *m = data; - struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(ctx); + struct i915_hw_ppgtt *ppgtt = ctx->ppgtt; + + if (!ppgtt) { + seq_printf(m, " no ppgtt for context %d\n", + ctx->user_handle); + return 0; + } if (i915_gem_context_is_default(ctx)) seq_puts(m, " default context:\n"); @@ -1881,8 +1887,7 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev) seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset); ppgtt->debug_dump(ppgtt, m); - } else - return; + } list_for_each_entry_reverse(file, &dev->filelist, lhead) { struct drm_i915_file_private *file_priv = file->driver_priv; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2db22732c7ae..eb99a109c0bc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -624,7 +624,7 @@ struct intel_context { uint8_t remap_slice; struct drm_i915_file_private *file_priv; struct i915_ctx_hang_stats hang_stats; - struct i915_address_space *vm; + struct i915_hw_ppgtt *ppgtt; /* Legacy ring buffer submission */ struct { @@ -2556,7 +2556,6 @@ i915_gem_object_ggtt_unbind(struct drm_i915_gem_object *obj) void i915_gem_object_ggtt_unpin(struct drm_i915_gem_object *obj); /* i915_gem_context.c */ -#define ctx_to_ppgtt(ctx) container_of((ctx)->vm, struct i915_hw_ppgtt, base) int __must_check i915_gem_context_init(struct drm_device *dev); void i915_gem_context_fini(struct drm_device *dev); void i915_gem_context_reset(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 7093f5df9ee7..206bf2d6c554 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -135,19 +135,13 @@ static int get_context_size(struct drm_device *dev) void i915_gem_context_free(struct kref *ctx_ref) { struct intel_context *ctx = container_of(ctx_ref, - typeof(*ctx), ref); - struct i915_hw_ppgtt *ppgtt = NULL; + typeof(*ctx), ref); - if (i915.enable_execlists) { - ppgtt = ctx_to_ppgtt(ctx); + if (i915.enable_execlists) intel_lr_context_free(ctx); - } else if (ctx->legacy_hw_ctx.rcs_state) { - /* We refcount even the aliasing PPGTT to keep the code symmetric */ - if (USES_PPGTT(ctx->legacy_hw_ctx.rcs_state->base.dev)) - ppgtt = ctx_to_ppgtt(ctx); - } - i915_ppgtt_put(ppgtt); + i915_ppgtt_put(ctx->ppgtt); + if (ctx->legacy_hw_ctx.rcs_state) drm_gem_object_unreference(&ctx->legacy_hw_ctx.rcs_state->base); list_del(&ctx->link); @@ -243,7 +237,6 @@ i915_gem_create_context(struct drm_device *dev, bool create_vm) { const bool is_global_default_ctx = file_priv == NULL; - struct drm_i915_private *dev_priv = dev->dev_private; struct intel_context *ctx; int ret = 0; @@ -277,15 +270,10 @@ i915_gem_create_context(struct drm_device *dev, PTR_ERR(ppgtt)); ret = PTR_ERR(ppgtt); goto err_unpin; - } else - ctx->vm = &ppgtt->base; - } else if (USES_PPGTT(dev)) { - /* For platforms which only have aliasing PPGTT, we fake the - * address space and refcounting. */ - ctx->vm = &dev_priv->mm.aliasing_ppgtt->base; - i915_ppgtt_get(dev_priv->mm.aliasing_ppgtt); - } else - ctx->vm = &dev_priv->gtt.base; + } + + ctx->ppgtt = ppgtt; + } return ctx; @@ -543,7 +531,6 @@ static int do_switch(struct intel_engine_cs *ring, { struct drm_i915_private *dev_priv = ring->dev->dev_private; struct intel_context *from = ring->last_context; - struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(to); u32 hw_flags = 0; bool uninitialized = false; int ret, i; @@ -571,8 +558,8 @@ static int do_switch(struct intel_engine_cs *ring, */ from = ring->last_context; - if (USES_FULL_PPGTT(ring->dev)) { - ret = ppgtt->switch_mm(ppgtt, ring, false); + if (to->ppgtt) { + ret = to->ppgtt->switch_mm(to->ppgtt, ring, false); if (ret) goto unpin_out; } diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 7e04a4825ed0..1a0611bb576b 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1315,8 +1315,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, i915_gem_context_reference(ctx); - vm = ctx->vm; - if (!USES_FULL_PPGTT(dev)) + if (ctx->ppgtt) + vm = &ctx->ppgtt->base; + else vm = &dev_priv->gtt.base; eb = eb_create(args); diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index eab41f9390f8..fc11ac6b0373 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -967,6 +967,12 @@ static void i915_gem_record_rings(struct drm_device *dev, request = i915_gem_find_active_request(ring); if (request) { + struct i915_address_space *vm; + + vm = request->ctx && request->ctx->ppgtt ? + &request->ctx->ppgtt->base : + &dev_priv->gtt.base; + /* We need to copy these to an anonymous buffer * as the simplest method to avoid being overwritten * by userspace. @@ -974,9 +980,7 @@ static void i915_gem_record_rings(struct drm_device *dev, error->ring[i].batchbuffer = i915_error_object_create(dev_priv, request->batch_obj, - request->ctx ? - request->ctx->vm : - &dev_priv->gtt.base); + vm); if (HAS_BROKEN_CS_TLB(dev_priv->dev) && ring->scratch.obj) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6f1b64e01a05..6b5f416b5c0d 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -904,7 +904,7 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o struct intel_engine_cs *ring, struct intel_ringbuffer *ringbuf) { struct drm_i915_gem_object *ring_obj = ringbuf->obj; - struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(ctx); + struct i915_hw_ppgtt *ppgtt = ctx->ppgtt; struct page *page; uint32_t *reg_state; int ret; -- GitLab From d624d86e1e3b69cadb2dad42588e71e9a3b6d70a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:54 +0200 Subject: [PATCH 0299/9167] drm/i915: Drop create_vm argument to i915_gem_create_context Now that all the flow is streamlined the rule is simple: We create a new ppgtt for a new context when we have full ppgtt enabled. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_context.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index 206bf2d6c554..9683e62ec61a 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c @@ -233,8 +233,7 @@ __create_hw_context(struct drm_device *dev, */ static struct intel_context * i915_gem_create_context(struct drm_device *dev, - struct drm_i915_file_private *file_priv, - bool create_vm) + struct drm_i915_file_private *file_priv) { const bool is_global_default_ctx = file_priv == NULL; struct intel_context *ctx; @@ -262,7 +261,7 @@ i915_gem_create_context(struct drm_device *dev, } } - if (create_vm) { + if (USES_FULL_PPGTT(dev)) { struct i915_hw_ppgtt *ppgtt = i915_ppgtt_create(dev, file_priv); if (IS_ERR_OR_NULL(ppgtt)) { @@ -345,7 +344,7 @@ int i915_gem_context_init(struct drm_device *dev) } } - ctx = i915_gem_create_context(dev, NULL, USES_FULL_PPGTT(dev)); + ctx = i915_gem_create_context(dev, NULL); if (IS_ERR(ctx)) { DRM_ERROR("Failed to create default global context (error %ld)\n", PTR_ERR(ctx)); @@ -444,7 +443,7 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file) idr_init(&file_priv->context_idr); mutex_lock(&dev->struct_mutex); - ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev)); + ctx = i915_gem_create_context(dev, file_priv); mutex_unlock(&dev->struct_mutex); if (IS_ERR(ctx)) { @@ -702,7 +701,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - ctx = i915_gem_create_context(dev, file_priv, USES_FULL_PPGTT(dev)); + ctx = i915_gem_create_context(dev, file_priv); mutex_unlock(&dev->struct_mutex); if (IS_ERR(ctx)) return PTR_ERR(ctx); -- GitLab From 19dd120ceee085dbac70b1b01bd09d599cf87bd0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:55 +0200 Subject: [PATCH 0300/9167] drm/i915: Extract common cleanup into i915_ppgtt_release Address space cleanup isn't really a job for the low-level cleanup callbacks. Without this change we can't reuse the low-level cleanup callback for the aliasing ppgtt cleanup. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index b033ff770ac4..c1e2d9a9f9e2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -391,9 +391,6 @@ static void gen8_ppgtt_cleanup(struct i915_address_space *vm) struct i915_hw_ppgtt *ppgtt = container_of(vm, struct i915_hw_ppgtt, base); - list_del(&vm->global_link); - drm_mm_takedown(&vm->mm); - gen8_ppgtt_unmap_pages(ppgtt); gen8_ppgtt_free(ppgtt); } @@ -974,8 +971,6 @@ static void gen6_ppgtt_cleanup(struct i915_address_space *vm) struct i915_hw_ppgtt *ppgtt = container_of(vm, struct i915_hw_ppgtt, base); - list_del(&vm->global_link); - drm_mm_takedown(&ppgtt->base.mm); drm_mm_remove_node(&ppgtt->node); gen6_ppgtt_unmap_pages(ppgtt); @@ -1226,6 +1221,9 @@ void i915_ppgtt_release(struct kref *kref) WARN_ON(!list_empty(&ppgtt->base.active_list)); WARN_ON(!list_empty(&ppgtt->base.inactive_list)); + list_del(&ppgtt->base.global_link); + drm_mm_takedown(&ppgtt->base.mm); + ppgtt->base.cleanup(&ppgtt->base); kfree(ppgtt); } -- GitLab From 90d0a0e8d0e64c92c4a6147f3c7cdc7c544d6b1a Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:56 +0200 Subject: [PATCH 0301/9167] drm/i915: Extract commmon global gtt cleanup code We want to move the aliasing ppgtt cleanup back into the global gtt cleanup code for symmetry, but first we need to create such a place. Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- drivers/gpu/drm/i915/i915_gem_gtt.c | 20 ++++++++++++-------- drivers/gpu/drm/i915/i915_gem_gtt.h | 1 + 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 895f9f2f35ea..c9af48503f76 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1821,7 +1821,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) arch_phys_wc_del(dev_priv->gtt.mtrr); io_mapping_free(dev_priv->gtt.mappable); out_gtt: - dev_priv->gtt.base.cleanup(&dev_priv->gtt.base); + i915_global_gtt_cleanup(dev); out_regs: intel_uncore_fini(dev); pci_iounmap(dev->pdev, dev_priv->regs); @@ -1920,7 +1920,7 @@ int i915_driver_unload(struct drm_device *dev) destroy_workqueue(dev_priv->wq); pm_qos_remove_request(&dev_priv->pm_qos); - dev_priv->gtt.base.cleanup(&dev_priv->gtt.base); + i915_global_gtt_cleanup(dev); intel_uncore_fini(dev); if (dev_priv->regs != NULL) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index c1e2d9a9f9e2..8d94e3582045 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1767,6 +1767,18 @@ void i915_gem_init_global_gtt(struct drm_device *dev) i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size); } +void i915_global_gtt_cleanup(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_address_space *vm = &dev_priv->gtt.base; + + if (drm_mm_initialized(&vm->mm)) { + drm_mm_takedown(&vm->mm); + list_del(&vm->global_link); + } + + vm->cleanup(vm); +} static int setup_scratch_page(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -2035,10 +2047,6 @@ static void gen6_gmch_remove(struct i915_address_space *vm) struct i915_gtt *gtt = container_of(vm, struct i915_gtt, base); - if (drm_mm_initialized(&vm->mm)) { - drm_mm_takedown(&vm->mm); - list_del(&vm->global_link); - } iounmap(gtt->gsm); teardown_scratch_page(vm->dev); } @@ -2071,10 +2079,6 @@ static int i915_gmch_probe(struct drm_device *dev, static void i915_gmch_remove(struct i915_address_space *vm) { - if (drm_mm_initialized(&vm->mm)) { - drm_mm_takedown(&vm->mm); - list_del(&vm->global_link); - } intel_gmch_remove(); } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.h b/drivers/gpu/drm/i915/i915_gem_gtt.h index 98fbb7309ea5..6280648d4805 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.h +++ b/drivers/gpu/drm/i915/i915_gem_gtt.h @@ -273,6 +273,7 @@ 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); int i915_ppgtt_init(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt); -- GitLab From 70e32544aa4027b4c27226da32eb3866e7bbbcdc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 6 Aug 2014 15:04:57 +0200 Subject: [PATCH 0302/9167] drm/i915: Cleanup aliasging ppgtt alongside the global gtt Also remove related WARN_ONs which seem to have been hit since a rather long time. But apperently no one noticed since our module reload is already WARNING-infested :( Reviewed-by: Michel Thierry Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 4 ---- drivers/gpu/drm/i915/i915_gem_gtt.c | 7 +++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index c9af48503f76..04dd6112865e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1388,7 +1388,6 @@ static int i915_load_modeset_init(struct drm_device *dev) i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); mutex_unlock(&dev->struct_mutex); - WARN_ON(dev_priv->mm.aliasing_ppgtt); cleanup_irq: drm_irq_uninstall(dev); cleanup_gem_stolen: @@ -1901,7 +1900,6 @@ int i915_driver_unload(struct drm_device *dev) mutex_lock(&dev->struct_mutex); i915_gem_cleanup_ringbuffer(dev); i915_gem_context_fini(dev); - WARN_ON(dev_priv->mm.aliasing_ppgtt); mutex_unlock(&dev->struct_mutex); i915_gem_cleanup_stolen(dev); @@ -1909,8 +1907,6 @@ int i915_driver_unload(struct drm_device *dev) i915_free_hws(dev); } - WARN_ON(!list_empty(&dev_priv->vm_list)); - drm_vblank_cleanup(dev); intel_teardown_gmbus(dev); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 8d94e3582045..d97b280861ee 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -1772,6 +1772,12 @@ void i915_global_gtt_cleanup(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct i915_address_space *vm = &dev_priv->gtt.base; + if (dev_priv->mm.aliasing_ppgtt) { + struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; + + ppgtt->base.cleanup(&ppgtt->base); + } + if (drm_mm_initialized(&vm->mm)) { drm_mm_takedown(&vm->mm); list_del(&vm->global_link); @@ -1779,6 +1785,7 @@ void i915_global_gtt_cleanup(struct drm_device *dev) vm->cleanup(vm); } + static int setup_scratch_page(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; -- GitLab From a08a42ad441e113f87308e0844049cb881f1ac1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Aug 2014 19:39:52 +0300 Subject: [PATCH 0303/9167] drm/i915: Don't try to enable cursor from setplane when crtc is disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure the cursor gets fully clipped when enabling it on a disabled crtc via setplane. This will prevent the lower level code from attempting to enable the cursor in hardware. Cc: Paulo Zanoni Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson 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 1bd1aa21a8e9..a93d5ffd3863 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11743,8 +11743,8 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, }; const struct drm_rect clip = { /* integer pixels */ - .x2 = intel_crtc->config.pipe_src_w, - .y2 = intel_crtc->config.pipe_src_h, + .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; -- GitLab From d7ce484eeec43079ad842f1d351f53998ed6bb30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Aug 2014 19:39:53 +0300 Subject: [PATCH 0304/9167] drm/i915: Move CURSIZE setup to i845_update_cursor() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CURSIZE register exists on 845/865 only, so move it to i845_update_cursor(). Changes to cursor size must be done only when the cursor is disabled, so do the write just before enabling the cursor. 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, 1 insertion(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a93d5ffd3863..cd3dc3b72798 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8070,6 +8070,7 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base) CURSOR_GAMMA_ENABLE | CURSOR_FORMAT_ARGB); if (intel_crtc->cursor_cntl != cntl) { + I915_WRITE(CURSIZE, (64 << 12) | 64); I915_WRITE(_CURACNTR, cntl); POSTING_READ(_CURACNTR); intel_crtc->cursor_cntl = cntl; @@ -8219,7 +8220,6 @@ 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 intel_crtc *intel_crtc = to_intel_crtc(crtc); enum pipe pipe = intel_crtc->pipe; unsigned old_width; @@ -8292,9 +8292,6 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, addr = obj->phys_handle->busaddr; } - if (IS_GEN2(dev)) - I915_WRITE(CURSIZE, (height << 12) | width); - finish: if (intel_crtc->cursor_bo) { if (!INTEL_INFO(dev)->cursor_needs_physical) -- GitLab From 8ac5466926daef2406f7b25e9a272567cb81adb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Tue, 12 Aug 2014 19:39:54 +0300 Subject: [PATCH 0305/9167] drm/i915: Unify ivb_update_cursor() and i9xx_update_cursor() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ever since commit 5efb3e2838536832c9b6872512e6b6daf592cee9 Author: Ville Syrjälä Date: Wed Apr 9 13:28:53 2014 +0300 drm/i915/chv: Add cursor pipe offsets the only difference between i9xx_update_cursor() and ivb_update_cursor() was the hsw+ pipe csc handling. Let's unify them and we can rid outselves of some duplicated code. Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 41 +--------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cd3dc3b72798..b3fb127131f0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8104,43 +8104,6 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) } cntl |= pipe << 28; /* Connect to correct pipe */ } - if (intel_crtc->cursor_cntl != cntl) { - I915_WRITE(CURCNTR(pipe), cntl); - POSTING_READ(CURCNTR(pipe)); - intel_crtc->cursor_cntl = cntl; - } - - /* and commit changes on next vblank */ - I915_WRITE(CURBASE(pipe), base); - POSTING_READ(CURBASE(pipe)); -} - -static void ivb_update_cursor(struct drm_crtc *crtc, u32 base) -{ - 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 pipe = intel_crtc->pipe; - uint32_t cntl; - - cntl = 0; - if (base) { - cntl = MCURSOR_GAMMA_ENABLE; - switch (intel_crtc->cursor_width) { - case 64: - cntl |= CURSOR_MODE_64_ARGB_AX; - break; - case 128: - cntl |= CURSOR_MODE_128_ARGB_AX; - break; - case 256: - cntl |= CURSOR_MODE_256_ARGB_AX; - break; - default: - WARN_ON(1); - return; - } - } if (IS_HASWELL(dev) || IS_BROADWELL(dev)) cntl |= CURSOR_PIPE_CSC_ENABLE; @@ -8199,9 +8162,7 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, I915_WRITE(CURPOS(pipe), pos); - if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev) || IS_BROADWELL(dev)) - ivb_update_cursor(crtc, base); - else if (IS_845G(dev) || IS_I865G(dev)) + if (IS_845G(dev) || IS_I865G(dev)) i845_update_cursor(crtc, base); else i9xx_update_cursor(crtc, base); -- GitLab From dc41c154ffc30afb7ee7e891140dead26fce5c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 13 Aug 2014 11:57:05 +0300 Subject: [PATCH 0306/9167] drm/i915: Add support for variable cursor size on 845/865 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 845/865 support different cursor sizes as well, albeit a bit differently than later platforms. Add the necessary code to make them work. Untested due to lack of hardware. v2: Warn but accept invalid stride (Chris) Rewrite the cursor size checks for other platforms (Chris) v3: More polish and magic to the cursor size checks (Chris) v4: Moar polish and a comment (Chris) Reviewed-by: Chris Wilson Signed-off-by: Ville Syrjälä Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 3 +- drivers/gpu/drm/i915/intel_display.c | 111 +++++++++++++++++++++------ drivers/gpu/drm/i915/intel_drv.h | 1 + 3 files changed, 91 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f79c20d49d99..203062e93452 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -4128,7 +4128,8 @@ enum punit_power_well { /* Old style CUR*CNTR flags (desktop 8xx) */ #define CURSOR_ENABLE 0x80000000 #define CURSOR_GAMMA_ENABLE 0x40000000 -#define CURSOR_STRIDE_MASK 0x30000000 +#define CURSOR_STRIDE_SHIFT 28 +#define CURSOR_STRIDE(x) ((ffs(x)-9) << CURSOR_STRIDE_SHIFT) /* 256,512,1k,2k */ #define CURSOR_PIPE_CSC_ENABLE (1<<24) #define CURSOR_FORMAT_SHIFT 24 #define CURSOR_FORMAT_MASK (0x07 << CURSOR_FORMAT_SHIFT) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b3fb127131f0..fd15601f6360 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8047,30 +8047,55 @@ static void i845_update_cursor(struct drm_crtc *crtc, u32 base) struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - uint32_t cntl; + uint32_t cntl = 0, size = 0; - if (base != intel_crtc->cursor_base) { - /* On these chipsets we can only modify the base whilst - * the cursor is disabled. - */ - if (intel_crtc->cursor_cntl) { - I915_WRITE(_CURACNTR, 0); - POSTING_READ(_CURACNTR); - intel_crtc->cursor_cntl = 0; + if (base) { + unsigned int width = intel_crtc->cursor_width; + unsigned int height = intel_crtc->cursor_height; + unsigned int stride = roundup_pow_of_two(width) * 4; + + switch (stride) { + default: + WARN_ONCE(1, "Invalid cursor width/stride, width=%u, stride=%u\n", + width, stride); + stride = 256; + /* fallthrough */ + case 256: + case 512: + case 1024: + case 2048: + break; } + cntl |= CURSOR_ENABLE | + CURSOR_GAMMA_ENABLE | + CURSOR_FORMAT_ARGB | + CURSOR_STRIDE(stride); + + size = (height << 12) | width; + } + + if (intel_crtc->cursor_cntl != 0 && + (intel_crtc->cursor_base != base || + intel_crtc->cursor_size != size || + intel_crtc->cursor_cntl != cntl)) { + /* On these chipsets we can only modify the base/size/stride + * whilst the cursor is disabled. + */ + I915_WRITE(_CURACNTR, 0); + POSTING_READ(_CURACNTR); + intel_crtc->cursor_cntl = 0; + } + + if (intel_crtc->cursor_base != base) I915_WRITE(_CURABASE, base); - POSTING_READ(_CURABASE); + + if (intel_crtc->cursor_size != size) { + I915_WRITE(CURSIZE, size); + intel_crtc->cursor_size = size; } - /* XXX width must be 64, stride 256 => 0x00 << 28 */ - cntl = 0; - if (base) - cntl = (CURSOR_ENABLE | - CURSOR_GAMMA_ENABLE | - CURSOR_FORMAT_ARGB); if (intel_crtc->cursor_cntl != cntl) { - I915_WRITE(CURSIZE, (64 << 12) | 64); I915_WRITE(_CURACNTR, cntl); POSTING_READ(_CURACNTR); intel_crtc->cursor_cntl = cntl; @@ -8169,6 +8194,43 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, intel_crtc->cursor_base = base; } +static bool cursor_size_ok(struct drm_device *dev, + uint32_t width, uint32_t height) +{ + if (width == 0 || height == 0) + return false; + + /* + * 845g/865g are special in that they are only limited by + * the width of their cursors, the height is arbitrary up to + * the precision of the register. Everything else requires + * square cursors, limited to a few power-of-two sizes. + */ + if (IS_845G(dev) || IS_I865G(dev)) { + if ((width & 63) != 0) + return false; + + if (width > (IS_845G(dev) ? 64 : 512)) + return false; + + if (height > 1023) + return false; + } else { + switch (width | height) { + case 256: + case 128: + if (IS_GEN2(dev)) + return false; + case 64: + break; + default: + return false; + } + } + + return true; +} + /* * intel_crtc_cursor_set_obj - Set cursor to specified GEM object * @@ -8183,7 +8245,7 @@ static int intel_crtc_cursor_set_obj(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; - unsigned old_width; + unsigned old_width, stride; uint32_t addr; int ret; @@ -8197,14 +8259,13 @@ static int intel_crtc_cursor_set_obj(struct drm_crtc *crtc, } /* Check for which cursor types we support */ - if (!((width == 64 && height == 64) || - (width == 128 && height == 128 && !IS_GEN2(dev)) || - (width == 256 && height == 256 && !IS_GEN2(dev)))) { + if (!cursor_size_ok(dev, width, height)) { DRM_DEBUG("Cursor dimension not supported\n"); return -EINVAL; } - if (obj->base.size < width * height * 4) { + 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; @@ -11797,6 +11858,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) intel_crtc->cursor_base = ~0; intel_crtc->cursor_cntl = ~0; + intel_crtc->cursor_size = ~0; BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); @@ -12585,7 +12647,10 @@ void intel_modeset_init(struct drm_device *dev) dev->mode_config.max_height = 8192; } - if (IS_GEN2(dev)) { + if (IS_845G(dev) || IS_I865G(dev)) { + dev->mode_config.cursor_width = IS_845G(dev) ? 64 : 512; + dev->mode_config.cursor_height = 1023; + } else if (IS_GEN2(dev)) { dev->mode_config.cursor_width = GEN2_CURSOR_WIDTH; dev->mode_config.cursor_height = GEN2_CURSOR_HEIGHT; } else { diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 666ca8a044ea..579b1d40f934 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -405,6 +405,7 @@ struct intel_crtc { uint32_t cursor_addr; int16_t cursor_width, cursor_height; uint32_t cursor_cntl; + uint32_t cursor_size; uint32_t cursor_base; struct intel_plane_config plane_config; -- GitLab From 7312e2ddec1ffe4511a85a2814df44e79ded3c1d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Aug 2014 12:14:12 +0100 Subject: [PATCH 0307/9167] drm/i915: Replace __I915__ with typesafe variant Ville pointed out the GCCism __builtin_types_compatible_p() that we could use to replace our heavily casted presumption __I915__ macro that was based on comparing struct sizes. Signed-off-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 3 --- drivers/gpu/drm/i915/i915_drv.h | 12 ++++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 04dd6112865e..db56b26a08c9 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1595,9 +1595,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!drm_core_check_feature(dev, DRIVER_MODESET) && !dev->agp) return -EINVAL; - /* For the ugly agnostic INTEL_INFO macro */ - BUILD_BUG_ON(sizeof(*dev_priv) == sizeof(*dev)); - dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); if (dev_priv == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index eb99a109c0bc..2af0071efb38 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2004,8 +2004,16 @@ struct drm_i915_cmd_table { }; /* Note that the (struct drm_i915_private *) cast is just to shut up gcc. */ -#define __I915__(p) ((sizeof(*(p)) == sizeof(struct drm_i915_private)) ? \ - (struct drm_i915_private *)(p) : to_i915(p)) +#define __I915__(p) ({ \ + struct drm_i915_private *__p; \ + if (__builtin_types_compatible_p(typeof(*p), struct drm_i915_private)) \ + __p = (struct drm_i915_private *)p; \ + else if (__builtin_types_compatible_p(typeof(*p), struct drm_device)) \ + __p = to_i915((struct drm_device *)p); \ + else \ + BUILD_BUG(); \ + __p; \ +}) #define INTEL_INFO(p) (&__I915__(p)->info) #define INTEL_DEVID(p) (INTEL_INFO(p)->device_id) -- GitLab From 82e3b8c130f046b7dd1e7898c10e40edb52fee6d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 13 Aug 2014 13:09:46 +0100 Subject: [PATCH 0308/9167] drm/i915: Localise the fbdev console lock frobbing Rather than take and release the console_lock() around a non-existent DRM_I915_FBDEV, move the lock acquisation into the callee where it will be compiled out by the config option entirely. This includes moving the deferred fb_set_suspend() dance and encapsulating it entirely within intel_fbdev.c. v2: Use an integral work item so that we can explicitly flush the work upon suspend/unload. Signed-off-by: Chris Wilson Cc: Daniel Vetter [danvet: Add the flush_work in fbdev_fini per the mailing list discussion. And s/BUG_ON/WARN_ON/ because.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 3 -- drivers/gpu/drm/i915/i915_drv.c | 28 ++----------------- drivers/gpu/drm/i915/i915_drv.h | 9 +----- drivers/gpu/drm/i915/intel_drv.h | 4 +-- drivers/gpu/drm/i915/intel_fbdev.c | 44 +++++++++++++++++++++++++++++- 5 files changed, 48 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index db56b26a08c9..3f676f904f7e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1350,8 +1350,6 @@ static int i915_load_modeset_init(struct drm_device *dev) if (ret) goto cleanup_irq; - INIT_WORK(&dev_priv->console_resume_work, intel_console_resume); - intel_modeset_gem_init(dev); /* Always safe in the mode setting case. */ @@ -1864,7 +1862,6 @@ int i915_driver_unload(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { intel_fbdev_fini(dev); intel_modeset_cleanup(dev); - cancel_work_sync(&dev_priv->console_resume_work); /* * free the memory space allocated for the child device diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ec96f9a9724c..01de97776d81 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -558,9 +558,7 @@ static int i915_drm_freeze(struct drm_device *dev) intel_uncore_forcewake_reset(dev, false); intel_opregion_fini(dev); - console_lock(); - intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED); - console_unlock(); + intel_fbdev_set_suspend(dev, FBINFO_STATE_SUSPENDED, true); dev_priv->suspend_count++; @@ -599,18 +597,6 @@ int i915_suspend(struct drm_device *dev, pm_message_t state) return 0; } -void intel_console_resume(struct work_struct *work) -{ - struct drm_i915_private *dev_priv = - container_of(work, struct drm_i915_private, - console_resume_work); - struct drm_device *dev = dev_priv->dev; - - console_lock(); - intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING); - console_unlock(); -} - static int i915_drm_thaw_early(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -681,17 +667,7 @@ static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) intel_opregion_init(dev); - /* - * The console lock can be pretty contented on resume due - * to all the printk activity. Try to keep it out of the hot - * path of resume if possible. - */ - if (console_trylock()) { - intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING); - console_unlock(); - } else { - schedule_work(&dev_priv->console_resume_work); - } + intel_fbdev_set_suspend(dev, FBINFO_STATE_RUNNING, false); mutex_lock(&dev_priv->modeset_restore_lock); dev_priv->modeset_restore = MODESET_DONE; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2af0071efb38..541fb6f295bb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1586,14 +1586,9 @@ struct drm_i915_private { #ifdef CONFIG_DRM_I915_FBDEV /* list of fbdev register on this device */ struct intel_fbdev *fbdev; + struct work_struct fbdev_suspend_work; #endif - /* - * The console may be contended at resume, but we don't - * want it to block on it. - */ - struct work_struct console_resume_work; - struct drm_property *broadcast_rgb_property; struct drm_property *force_audio_property; @@ -2225,8 +2220,6 @@ extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on); -extern void intel_console_resume(struct work_struct *work); - /* i915_irq.c */ void i915_queue_hangcheck(struct drm_device *dev); __printf(3, 4) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 579b1d40f934..4ab0d928b819 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -948,7 +948,7 @@ void intel_dvo_init(struct drm_device *dev); extern int intel_fbdev_init(struct drm_device *dev); extern void intel_fbdev_initial_config(struct drm_device *dev); extern void intel_fbdev_fini(struct drm_device *dev); -extern void intel_fbdev_set_suspend(struct drm_device *dev, int state); +extern void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous); extern void intel_fbdev_output_poll_changed(struct drm_device *dev); extern void intel_fbdev_restore_mode(struct drm_device *dev); #else @@ -965,7 +965,7 @@ static inline void intel_fbdev_fini(struct drm_device *dev) { } -static inline void intel_fbdev_set_suspend(struct drm_device *dev, int state) +static inline void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) { } diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c index f475414671d8..cf052a39558d 100644 --- a/drivers/gpu/drm/i915/intel_fbdev.c +++ b/drivers/gpu/drm/i915/intel_fbdev.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -636,6 +637,15 @@ static bool intel_fbdev_init_bios(struct drm_device *dev, return false; } +static void intel_fbdev_suspend_worker(struct work_struct *work) +{ + intel_fbdev_set_suspend(container_of(work, + struct drm_i915_private, + fbdev_suspend_work)->dev, + FBINFO_STATE_RUNNING, + true); +} + int intel_fbdev_init(struct drm_device *dev) { struct intel_fbdev *ifbdev; @@ -662,6 +672,8 @@ int intel_fbdev_init(struct drm_device *dev) } dev_priv->fbdev = ifbdev; + INIT_WORK(&dev_priv->fbdev_suspend_work, intel_fbdev_suspend_worker); + drm_fb_helper_single_add_all_connectors(&ifbdev->helper); return 0; @@ -682,12 +694,14 @@ void intel_fbdev_fini(struct drm_device *dev) if (!dev_priv->fbdev) return; + flush_work(&dev_priv->fbdev_suspend_work); + intel_fbdev_destroy(dev, dev_priv->fbdev); kfree(dev_priv->fbdev); dev_priv->fbdev = NULL; } -void intel_fbdev_set_suspend(struct drm_device *dev, int state) +void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous) { struct drm_i915_private *dev_priv = dev->dev_private; struct intel_fbdev *ifbdev = dev_priv->fbdev; @@ -698,6 +712,33 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state) info = ifbdev->helper.fbdev; + if (synchronous) { + /* Flush any pending work to turn the console on, and then + * wait to turn it off. It must be synchronous as we are + * about to suspend or unload the driver. + * + * Note that from within the work-handler, we cannot flush + * ourselves, so only flush outstanding work upon suspend! + */ + if (state != FBINFO_STATE_RUNNING) + flush_work(&dev_priv->fbdev_suspend_work); + console_lock(); + } else { + /* + * The console lock can be pretty contented on resume due + * to all the printk activity. Try to keep it out of the hot + * path of resume if possible. + */ + WARN_ON(state != FBINFO_STATE_RUNNING); + if (!console_trylock()) { + /* Don't block our own workqueue as this can + * be run in parallel with other i915.ko tasks. + */ + schedule_work(&dev_priv->fbdev_suspend_work); + return; + } + } + /* On resume from hibernation: If the object is shmemfs backed, it has * been restored from swap. If the object is stolen however, it will be * full of whatever garbage was left in there. @@ -706,6 +747,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state) memset_io(info->screen_base, 0, info->screen_size); fb_set_suspend(info, state); + console_unlock(); } void intel_fbdev_output_poll_changed(struct drm_device *dev) -- GitLab From e7110b9fb901dcc022afd358386c1be69658af7d Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 8 Aug 2014 18:00:39 -0300 Subject: [PATCH 0309/9167] perf top: Don't look for kernel idle symbols in all DSOs The 'top' tool initially supported only kernel symbols, when making it support userspace symbols we forgot to make the symbol filter first check that the DSO is the kernel one. Fix it. Cc: Adrian Hunter Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra c: Stephane Eranian Link: http://lkml.kernel.org/n/tip-54haztkeigmbump5sexxnzhv@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 4 +++- tools/perf/util/symbol.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index bde216b2071c..4fb6f726271c 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -623,10 +623,12 @@ static void *display_thread(void *arg) return NULL; } -static int symbol_filter(struct map *map __maybe_unused, struct symbol *sym) +static int symbol_filter(struct map *map, struct symbol *sym) { const char *name = sym->name; + if (!map->dso->kernel) + return 0; /* * ppc64 uses function descriptors and appends a '.' to the * start of every instruction address. Remove it. diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index f134ec138934..35a8bd56cd15 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -523,6 +523,10 @@ struct process_kallsyms_args { struct dso *dso; }; +/* + * These are symbols in the kernel image, so make sure that + * sym is from a kernel DSO. + */ bool symbol__is_idle(struct symbol *sym) { const char * const idle_symbols[] = { -- GitLab From e0336ed66f5dd974e02b1af4a81bb567a2391e45 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 8 Aug 2014 18:02:41 -0300 Subject: [PATCH 0310/9167] perf tools: Add cpu_startup_entry to the list of kernel idle symbols Cc: Adrian Hunter Cc: David Ahern Cc: Don Zickus Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-oh4lrofvrqqv1eyslh7m4rq4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 35a8bd56cd15..581c56836567 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -531,6 +531,7 @@ bool symbol__is_idle(struct symbol *sym) { const char * const idle_symbols[] = { "cpu_idle", + "cpu_startup_entry", "intel_idle", "default_idle", "native_safe_halt", -- GitLab From ae256fa27118e54b0f093f0cfe2ada28f1704ef3 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Aug 2014 10:50:05 +0200 Subject: [PATCH 0311/9167] perf top: Join the display thread on exit We create the display thread, but never join it. It gives the display thread a chance to quit and cleanup properly. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407747014-18394-12-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 4fb6f726271c..10fc7e844872 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -965,7 +965,7 @@ static int __cmd_top(struct perf_top *top) param.sched_priority = top->realtime_prio; if (sched_setscheduler(0, SCHED_FIFO, ¶m)) { ui__error("Could not set realtime priority.\n"); - goto out_delete; + goto out_join; } } @@ -979,6 +979,8 @@ static int __cmd_top(struct perf_top *top) } ret = 0; +out_join: + pthread_join(thread, NULL); out_delete: perf_session__delete(top->session); top->session = NULL; -- GitLab From 9398c484f8abc8d287cb90f5a33dd43ac26f24ef Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Aug 2014 10:50:02 +0200 Subject: [PATCH 0312/9167] perf tools: Introduce set_term_quiet_input helper function Adding set_term_quiet_input helper to set the terminal quiet, out from 'perf top', used in following patches in 'perf kvm'. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407747014-18394-9-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 10 ++-------- tools/perf/util/util.c | 13 +++++++++++++ tools/perf/util/util.h | 2 ++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 10fc7e844872..e8459e260c3b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -580,20 +580,14 @@ static void *display_thread_tui(void *arg) static void *display_thread(void *arg) { struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; - struct termios tc, save; + struct termios save; struct perf_top *top = arg; int delay_msecs, c; - tcgetattr(0, &save); - tc = save; - tc.c_lflag &= ~(ICANON | ECHO); - tc.c_cc[VMIN] = 0; - tc.c_cc[VTIME] = 0; - pthread__unblock_sigwinch(); repeat: delay_msecs = top->delay_secs * 1000; - tcsetattr(0, TCSANOW, &tc); + set_term_quiet_input(&save); /* trash return*/ getc(stdin); diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index b82a93cb1694..25822bdf7bbf 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -13,6 +13,7 @@ #include #include #include +#include /* * XXX We need to find a better place for these things... @@ -282,6 +283,18 @@ void get_term_dimensions(struct winsize *ws) ws->ws_col = 80; } +void set_term_quiet_input(struct termios *old) +{ + struct termios tc; + + tcgetattr(0, old); + tc = *old; + tc.c_lflag &= ~(ICANON | ECHO); + tc.c_cc[VMIN] = 0; + tc.c_cc[VTIME] = 0; + tcsetattr(0, TCSANOW, &tc); +} + static void set_tracing_events_path(const char *mountpoint) { snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s", diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 03a1ea2266b8..d6a79b1fb28c 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -75,6 +75,7 @@ #include #include #include +#include extern const char *graph_line; extern const char *graph_dotted_line; @@ -308,6 +309,7 @@ extern unsigned int page_size; extern int cacheline_size; void get_term_dimensions(struct winsize *ws); +void set_term_quiet_input(struct termios *old); struct parse_tag { char tag; -- GitLab From 4a1a99712a8a13d97e9de818869bf1b88583d6bc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Aug 2014 10:50:07 +0200 Subject: [PATCH 0313/9167] perf top: Setup signals for terminal output The TUI code setup standard signals handling, while the stdio display code does not. This leads to premature termination of display thread when signal is received and leaving terminal in wrong state. Also adding terminal cleanup at the end of display thread, to ensure we get the old terminal state in case of signal interruption. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407747014-18394-14-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e8459e260c3b..0ab3ea7f7525 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -577,6 +577,20 @@ static void *display_thread_tui(void *arg) return NULL; } +static void display_sig(int sig __maybe_unused) +{ + done = 1; +} + +static void display_setup_sig(void) +{ + signal(SIGSEGV, display_sig); + signal(SIGFPE, display_sig); + signal(SIGINT, display_sig); + signal(SIGQUIT, display_sig); + signal(SIGTERM, display_sig); +} + static void *display_thread(void *arg) { struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; @@ -584,6 +598,7 @@ static void *display_thread(void *arg) struct perf_top *top = arg; int delay_msecs, c; + display_setup_sig(); pthread__unblock_sigwinch(); repeat: delay_msecs = top->delay_secs * 1000; @@ -614,6 +629,7 @@ static void *display_thread(void *arg) } } + tcsetattr(0, TCSAFLUSH, &save); return NULL; } -- GitLab From d5b4130ae636e1fd0eaaea7152170198c34fbf62 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Mon, 11 Aug 2014 10:50:09 +0200 Subject: [PATCH 0314/9167] perf kvm: Fix stdin handling for 'kvm stat live' command Currently the initial ~(ICANON | ECHO) terminal mode is not set, so we dont get stdin data until we press ENTER. Fixing this by early setting of the ~(ICANON | ECHO) mode and leaving this mode for whole life of the command, because canonical mode is not needed. Signed-off-by: Jiri Olsa Cc: Adrian Hunter Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jean Pihet Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407747014-18394-16-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 7ccceadcd9f8..ff404750d744 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -885,15 +885,11 @@ static int fd_set_nonblock(int fd) return 0; } -static -int perf_kvm__handle_stdin(struct termios *tc_now, struct termios *tc_save) +static int perf_kvm__handle_stdin(void) { int c; - tcsetattr(0, TCSANOW, tc_now); c = getc(stdin); - tcsetattr(0, TCSAFLUSH, tc_save); - if (c == 'q') return 1; @@ -904,7 +900,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) { struct pollfd *pollfds = NULL; int nr_fds, nr_stdin, ret, err = -EINVAL; - struct termios tc, save; + struct termios save; /* live flag must be set first */ kvm->live = true; @@ -919,14 +915,9 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) goto out; } + set_term_quiet_input(&save); init_kvm_event_record(kvm); - tcgetattr(0, &save); - tc = save; - tc.c_lflag &= ~(ICANON | ECHO); - tc.c_cc[VMIN] = 0; - tc.c_cc[VTIME] = 0; - signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); @@ -972,7 +963,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) goto out; if (pollfds[nr_stdin].revents & POLLIN) - done = perf_kvm__handle_stdin(&tc, &save); + done = perf_kvm__handle_stdin(); if (!rc && !done) err = poll(pollfds, nr_fds, 100); @@ -989,6 +980,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) if (kvm->timerfd >= 0) close(kvm->timerfd); + tcsetattr(0, TCSAFLUSH, &save); free(pollfds); return err; } -- GitLab From d177143c3670aa57ee08c73880beb55ee9d8ab7c Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 8 Aug 2014 14:47:21 +0800 Subject: [PATCH 0315/9167] ASoC: fsl_esai: refine esai for TDM support Original driver didn't store the number of slots, just fix the slot number to 2, use this default number to calculate bclk and pins for TX/RX. In this patch, add one parameter for slots, and update the calculation of bclk and pins of TX/RX. Then driver will be compatible with slots > 2 in TDM mode. Signed-off-by: Shengjiu Wang Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 14 +++++++++++--- sound/soc/fsl/fsl_esai.h | 8 ++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 72d154e7dd03..f252370073e5 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -38,6 +38,7 @@ * @fsysclk: system clock source to derive HCK, SCK and FS * @fifo_depth: depth of tx/rx FIFO * @slot_width: width of each DAI slot + * @slots: number of slots * @hck_rate: clock rate of desired HCKx clock * @sck_rate: clock rate of desired SCKx clock * @hck_dir: the direction of HCKx pads @@ -56,6 +57,7 @@ struct fsl_esai { struct clk *fsysclk; u32 fifo_depth; u32 slot_width; + u32 slots; u32 hck_rate[2]; u32 sck_rate[2]; bool hck_dir[2]; @@ -363,6 +365,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); esai_priv->slot_width = slot_width; + esai_priv->slots = slots; return 0; } @@ -510,10 +513,11 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u32 width = snd_pcm_format_width(params_format(params)); u32 channels = params_channels(params); + u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); u32 bclk, mask, val; int ret; - bclk = params_rate(params) * esai_priv->slot_width * 2; + bclk = params_rate(params) * esai_priv->slot_width * esai_priv->slots; ret = fsl_esai_set_bclk(dai, tx, bclk); if (ret) @@ -530,7 +534,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK | (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK); val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) | - (tx ? ESAI_xFCR_TE(channels) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(channels)); + (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins)); regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val); @@ -565,6 +569,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u8 i, channels = substream->runtime->channels; + u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -579,7 +584,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, - tx ? ESAI_xCR_TE(channels) : ESAI_xCR_RE(channels)); + tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: @@ -783,6 +788,9 @@ static int fsl_esai_probe(struct platform_device *pdev) /* Set a default slot size */ esai_priv->slot_width = 32; + /* Set a default slot number */ + esai_priv->slots = 2; + /* Set a default master/slave state */ esai_priv->slave_mode = true; diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h index 75e14033e8d8..91a550f4a10d 100644 --- a/sound/soc/fsl/fsl_esai.h +++ b/sound/soc/fsl/fsl_esai.h @@ -130,8 +130,8 @@ #define ESAI_xFCR_RE_WIDTH 4 #define ESAI_xFCR_TE_MASK (((1 << ESAI_xFCR_TE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) #define ESAI_xFCR_RE_MASK (((1 << ESAI_xFCR_RE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) -#define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_TE_MASK) -#define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_RE_MASK) +#define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - x)) & ESAI_xFCR_TE_MASK) +#define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - x)) & ESAI_xFCR_RE_MASK) #define ESAI_xFCR_xFR_SHIFT 1 #define ESAI_xFCR_xFR_MASK (1 << ESAI_xFCR_xFR_SHIFT) #define ESAI_xFCR_xFR (1 << ESAI_xFCR_xFR_SHIFT) @@ -272,8 +272,8 @@ #define ESAI_xCR_RE_WIDTH 4 #define ESAI_xCR_TE_MASK (((1 << ESAI_xCR_TE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) #define ESAI_xCR_RE_MASK (((1 << ESAI_xCR_RE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) -#define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_TE_MASK) -#define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_RE_MASK) +#define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - x)) & ESAI_xCR_TE_MASK) +#define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - x)) & ESAI_xCR_RE_MASK) /* * Transmit Clock Control Register -- REG_ESAI_TCCR 0xD8 -- GitLab From 5e45187cc94814d2a5324bc18af994efc4fb4f7c Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 13 Aug 2014 16:12:48 +0000 Subject: [PATCH 0316/9167] perf probe: Fix --list option to show events only with uprobe events Current perf probe --list doesn't work if only CONFIG_UPROBE_EVENTS=y because it aborts when it fails to open kprobe_events file before checking uprobe_events file. This fixes --list option to show dynamic events if it can open either kprobe_events or uprobe_events. Only if it failed to open both of them, it shows an error message and aborts. Without this patch, if we run perf probe -l on the kernel configured with CONFIG_KPROBE_EVENTS=n and CONFIG_UPROBE_EVENTS=y, # perf probe -l /sys/kernel/debug/tracing/kprobe_events file does not exist - please rebuild ker Error: Failed to show event list. With this patch, # perf probe -l probe_perf:alloc_event (on alloc_event@lib/traceevent/event-parse.c in /home/fedora/ksrc/linux-3/tools/perf/perf) Changes in v2: - Use strerror_r instead of strerror. Reported-by: Naohiro Aota Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140813161248.26440.84370.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-event.c | 89 +++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 30 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 9a0a1839a377..50aa7f05ceb1 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1780,10 +1780,11 @@ static void clear_probe_trace_event(struct probe_trace_event *tev) memset(tev, 0, sizeof(*tev)); } -static void print_warn_msg(const char *file, bool is_kprobe) +static void print_open_warning(int err, bool is_kprobe) { + char sbuf[128]; - if (errno == ENOENT) { + if (err == -ENOENT) { const char *config; if (!is_kprobe) @@ -1791,25 +1792,26 @@ static void print_warn_msg(const char *file, bool is_kprobe) else config = "CONFIG_KPROBE_EVENTS"; - pr_warning("%s file does not exist - please rebuild kernel" - " with %s.\n", file, config); - } else - pr_warning("Failed to open %s file: %s\n", file, - strerror(errno)); + pr_warning("%cprobe_events file does not exist" + " - please rebuild kernel with %s.\n", + is_kprobe ? 'k' : 'u', config); + } else if (err == -ENOTSUP) + pr_warning("Debugfs is not mounted.\n"); + else + pr_warning("Failed to open %cprobe_events: %s\n", + is_kprobe ? 'k' : 'u', + strerror_r(-err, sbuf, sizeof(sbuf))); } -static int open_probe_events(const char *trace_file, bool readwrite, - bool is_kprobe) +static int open_probe_events(const char *trace_file, bool readwrite) { char buf[PATH_MAX]; const char *__debugfs; int ret; __debugfs = debugfs_find_mountpoint(); - if (__debugfs == NULL) { - pr_warning("Debugfs is not mounted.\n"); - return -ENOENT; - } + if (__debugfs == NULL) + return -ENOTSUP; ret = e_snprintf(buf, PATH_MAX, "%s/%s", __debugfs, trace_file); if (ret >= 0) { @@ -1820,19 +1822,19 @@ static int open_probe_events(const char *trace_file, bool readwrite, ret = open(buf, O_RDONLY, 0); if (ret < 0) - print_warn_msg(buf, is_kprobe); + ret = -errno; } return ret; } static int open_kprobe_events(bool readwrite) { - return open_probe_events("tracing/kprobe_events", readwrite, true); + return open_probe_events("tracing/kprobe_events", readwrite); } static int open_uprobe_events(bool readwrite) { - return open_probe_events("tracing/uprobe_events", readwrite, false); + return open_probe_events("tracing/uprobe_events", readwrite); } /* Get raw string list of current kprobe_events or uprobe_events */ @@ -1940,27 +1942,47 @@ static int __show_perf_probe_events(int fd, bool is_kprobe) /* List up current perf-probe events */ int show_perf_probe_events(void) { - int fd, ret; + int kp_fd, up_fd, ret; setup_pager(); - fd = open_kprobe_events(false); - - if (fd < 0) - return fd; ret = init_symbol_maps(false); if (ret < 0) return ret; - ret = __show_perf_probe_events(fd, true); - close(fd); + kp_fd = open_kprobe_events(false); + if (kp_fd >= 0) { + ret = __show_perf_probe_events(kp_fd, true); + close(kp_fd); + if (ret < 0) + goto out; + } - fd = open_uprobe_events(false); - if (fd >= 0) { - ret = __show_perf_probe_events(fd, false); - close(fd); + up_fd = open_uprobe_events(false); + if (kp_fd < 0 && up_fd < 0) { + /* Both kprobes and uprobes are disabled, warn it. */ + if (kp_fd == -ENOTSUP && up_fd == -ENOTSUP) + pr_warning("Debugfs is not mounted.\n"); + else if (kp_fd == -ENOENT && up_fd == -ENOENT) + pr_warning("Please rebuild kernel with " + "CONFIG_KPROBE_EVENTS or/and " + "CONFIG_UPROBE_EVENTS.\n"); + else { + char sbuf[128]; + pr_warning("Failed to open kprobe events: %s.\n", + strerror_r(-kp_fd, sbuf, sizeof(sbuf))); + pr_warning("Failed to open uprobe events: %s.\n", + strerror_r(-up_fd, sbuf, sizeof(sbuf))); + } + ret = kp_fd; + goto out; } + if (up_fd >= 0) { + ret = __show_perf_probe_events(up_fd, false); + close(up_fd); + } +out: exit_symbol_maps(); return ret; } @@ -2075,8 +2097,11 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, else fd = open_kprobe_events(true); - if (fd < 0) + if (fd < 0) { + print_open_warning(fd, !pev->uprobes); return fd; + } + /* Get current event names */ namelist = get_probe_trace_event_names(fd, false); if (!namelist) { @@ -2449,13 +2474,17 @@ int del_perf_probe_events(struct strlist *dellist) /* Get current event names */ kfd = open_kprobe_events(true); - if (kfd < 0) + if (kfd < 0) { + print_open_warning(kfd, true); return kfd; + } namelist = get_probe_trace_event_names(kfd, true); ufd = open_uprobe_events(true); - if (ufd >= 0) + if (ufd < 0) + print_open_warning(ufd, false); + else unamelist = get_probe_trace_event_names(ufd, true); if (namelist == NULL && unamelist == NULL) -- GitLab From 467ec08567483e3868f240b1ee03808970e06388 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 13 Aug 2014 16:12:50 +0000 Subject: [PATCH 0317/9167] perf probe: Fix --del option to delete events only with uprobe events Current perf probe --del doesn't work if only CONFIG_UPROBE_EVENTS=y because it aborts when it fails to open kprobe_events file before checking uprobe_events file. This fixes --del option to delete dynamic events if it can open either kprobe_events or uprobe_events. Only if it failed to open both of them, it shows an error message and aborts. Without this patch, if we run perf probe -d on the kernel configured with CONFIG_KPROBE_EVENTS=n and CONFIG_UPROBE_EVENTS=y, # perf probe -d \* kprobe_events file does not exist - please rebuild kernel with CONFIG_KPROBE_EVENTS. Error: Failed to delete events. With this patch, # perf probe -d \* Removed event: probe_perf:alloc_event Changes in v2: - Use strerror_r instead of strerror. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140813161250.26440.24028.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-event.c | 49 +++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 50aa7f05ceb1..443225cb62f7 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1803,6 +1803,23 @@ static void print_open_warning(int err, bool is_kprobe) strerror_r(-err, sbuf, sizeof(sbuf))); } +static void print_both_open_warning(int kerr, int uerr) +{ + /* Both kprobes and uprobes are disabled, warn it. */ + if (kerr == -ENOTSUP && uerr == -ENOTSUP) + pr_warning("Debugfs is not mounted.\n"); + else if (kerr == -ENOENT && uerr == -ENOENT) + pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS " + "or/and CONFIG_UPROBE_EVENTS.\n"); + else { + char sbuf[128]; + pr_warning("Failed to open kprobe events: %s.\n", + strerror_r(-kerr, sbuf, sizeof(sbuf))); + pr_warning("Failed to open uprobe events: %s.\n", + strerror_r(-uerr, sbuf, sizeof(sbuf))); + } +} + static int open_probe_events(const char *trace_file, bool readwrite) { char buf[PATH_MAX]; @@ -1960,20 +1977,7 @@ int show_perf_probe_events(void) up_fd = open_uprobe_events(false); if (kp_fd < 0 && up_fd < 0) { - /* Both kprobes and uprobes are disabled, warn it. */ - if (kp_fd == -ENOTSUP && up_fd == -ENOTSUP) - pr_warning("Debugfs is not mounted.\n"); - else if (kp_fd == -ENOENT && up_fd == -ENOENT) - pr_warning("Please rebuild kernel with " - "CONFIG_KPROBE_EVENTS or/and " - "CONFIG_UPROBE_EVENTS.\n"); - else { - char sbuf[128]; - pr_warning("Failed to open kprobe events: %s.\n", - strerror_r(-kp_fd, sbuf, sizeof(sbuf))); - pr_warning("Failed to open uprobe events: %s.\n", - strerror_r(-up_fd, sbuf, sizeof(sbuf))); - } + print_both_open_warning(kp_fd, up_fd); ret = kp_fd; goto out; } @@ -2474,19 +2478,18 @@ int del_perf_probe_events(struct strlist *dellist) /* Get current event names */ kfd = open_kprobe_events(true); - if (kfd < 0) { - print_open_warning(kfd, true); - return kfd; - } + if (kfd >= 0) + namelist = get_probe_trace_event_names(kfd, true); - namelist = get_probe_trace_event_names(kfd, true); ufd = open_uprobe_events(true); - - if (ufd < 0) - print_open_warning(ufd, false); - else + if (ufd >= 0) unamelist = get_probe_trace_event_names(ufd, true); + if (kfd < 0 && ufd < 0) { + print_both_open_warning(kfd, ufd); + goto error; + } + if (namelist == NULL && unamelist == NULL) goto error; -- GitLab From 86998dda5d244f4b1b994dfe34a677f3b70cfdd3 Mon Sep 17 00:00:00 2001 From: Alex Snast Date: Wed, 13 Aug 2014 18:42:40 +0300 Subject: [PATCH 0318/9167] perf trace: Add beautifier for mremap flags param MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ~/devel/kernel/tools/perf(branch:master*) » sudo ./perf trace ~/mremap_test 0.543 ( 0.003 ms): mprotect(start: 0x600000, len: 4096, prot: READ ) = 0 0.550 ( 0.003 ms): mprotect(start: 0x7f441260d000, len: 4096, prot: READ) = 0 0.561 ( 0.010 ms): munmap(addr: 0x7f44125e2000, len: 165572 ) = 0 0.595 ( 0.012 ms): mmap(len: 12288, prot: READ|WRITE, flags: SHARED|ANONYMOUS|LOCKED, fd: -1) = 0x12608000 0.603 ( 0.006 ms): mremap(addr: 0x7f4412608000, old_len: 4096, new_len: 4096, flags: MAYMOVE|FIXED, new_addr: 0x7f16da295000) = 0xda295000 0.608 ( 0.003 ms): mremap(addr: 0x7f441260a000, old_len: 4096, new_len: 4096, flags: MAYMOVE|FIXED, new_addr: 0x7f16da297000) = 0xda297000 0.612 ( 0.003 ms): mremap(addr: 0x7f4412609000, old_len: 4096, new_len: 4096, flags: MAYMOVE|FIXED, new_addr: 0x7f16da296000) = 0xda296000 0.619 ( 0.000 ms): exit_group( Signed-off-by: Alex Snast Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407944560-26924-1-git-send-email-asnast@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 36ae51d61be2..20fac5083771 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -402,6 +402,31 @@ static size_t syscall_arg__scnprintf_mmap_flags(char *bf, size_t size, #define SCA_MMAP_FLAGS syscall_arg__scnprintf_mmap_flags +static size_t syscall_arg__scnprintf_mremap_flags(char *bf, size_t size, + struct syscall_arg *arg) +{ + int printed = 0, flags = arg->val; + +#define P_MREMAP_FLAG(n) \ + if (flags & MREMAP_##n) { \ + printed += scnprintf(bf + printed, size - printed, "%s%s", printed ? "|" : "", #n); \ + flags &= ~MREMAP_##n; \ + } + + P_MREMAP_FLAG(MAYMOVE); +#ifdef MREMAP_FIXED + P_MREMAP_FLAG(FIXED); +#endif +#undef P_MREMAP_FLAG + + if (flags) + printed += scnprintf(bf + printed, size - printed, "%s%#x", printed ? "|" : "", flags); + + return printed; +} + +#define SCA_MREMAP_FLAGS syscall_arg__scnprintf_mremap_flags + static size_t syscall_arg__scnprintf_madvise_behavior(char *bf, size_t size, struct syscall_arg *arg) { @@ -1004,6 +1029,7 @@ static struct syscall_fmt { [2] = SCA_MMAP_PROT, /* prot */ }, }, { .name = "mremap", .hexret = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ + [3] = SCA_MREMAP_FLAGS, /* flags */ [4] = SCA_HEX, /* new_addr */ }, }, { .name = "munlock", .errmsg = true, .arg_scnprintf = { [0] = SCA_HEX, /* addr */ }, }, -- GitLab From a5b0153c880c2775bf5bdd78306f0a47e860ea04 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 12 Aug 2014 18:04:28 +0300 Subject: [PATCH 0319/9167] perf tools: Fix CLOEXEC probe for perf_event_paranoid == 2 With /proc/sys/kernel/perf_event_paranoid set to 2, the probe of PERF_FLAG_FD_CLOEXEC would fail. Fix by excluding kernel profiling from the probe event. Signed-off-by: Adrian Hunter Acked-by: Jiri Olsa Acked-by: Namhyung Kim Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1407855871-15024-2-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cloexec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index 5073c01af618..000047cb3fee 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -11,6 +11,7 @@ static int perf_flag_probe(void) struct perf_event_attr attr = { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_CLOCK, + .exclude_kernel = 1, }; int fd; int err; -- GitLab From c6fa35659c5fae5f9aeb6874b177baeb2adbc02e Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 12 Aug 2014 18:04:29 +0300 Subject: [PATCH 0320/9167] perf tools: Fix one of the probe events to exclude kernel When probing the kernel API the kernel should be excluded otherwise the probe will fail for users with insufficient privilege to profile the kernel. Signed-off-by: Adrian Hunter Acked-by: Jiri Olsa Acked-by: Namhyung Kim Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1407855871-15024-3-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/record.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index fe8079edbdc1..58267a85705f 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -47,7 +47,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) static bool perf_probe_api(setup_probe_fn_t fn) { - const char *try[] = {"cycles:u", "instructions:u", "cpu-clock", NULL}; + const char *try[] = {"cycles:u", "instructions:u", "cpu-clock:u", NULL}; struct cpu_map *cpus; int cpu, ret, i = 0; -- GitLab From 46ec69add5df60310147ce3ce01a662053d82a1e Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 12 Aug 2014 18:04:30 +0300 Subject: [PATCH 0321/9167] perf tools: Fix probing the kernel API with cpu-wide events Fall back to probing with the current pid if cpu-wide probing fails. This primarily affects the setting of comm_exec flag when the user is un-privileged and /proc/sys/kernel/perf_event_paranoid > 0. The change to comm_exec can be observed by using -vv with perf record and a kernel that supports comm_exec. Signed-off-by: Adrian Hunter Acked-by: Jiri Olsa Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1407855871-15024-4-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/record.c | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index 58267a85705f..e778afda0fb9 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -14,6 +14,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) struct perf_evsel *evsel; unsigned long flags = perf_event_open_cloexec_flag(); int err = -EAGAIN, fd; + static pid_t pid = -1; evlist = perf_evlist__new(); if (!evlist) @@ -24,14 +25,22 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str) evsel = perf_evlist__first(evlist); - fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags); - if (fd < 0) - goto out_delete; + while (1) { + fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags); + if (fd < 0) { + if (pid == -1 && errno == EACCES) { + pid = 0; + continue; + } + goto out_delete; + } + break; + } close(fd); fn(evsel); - fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags); + fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags); if (fd < 0) { if (errno == EINVAL) err = -EINVAL; @@ -201,6 +210,7 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) struct perf_evsel *evsel; int err, fd, cpu; bool ret = false; + pid_t pid = -1; temp_evlist = perf_evlist__new(); if (!temp_evlist) @@ -221,12 +231,20 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str) cpu = evlist->cpus->map[0]; } - fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, - perf_event_open_cloexec_flag()); - if (fd >= 0) { - close(fd); - ret = true; + while (1) { + fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, + perf_event_open_cloexec_flag()); + if (fd < 0) { + if (pid == -1 && errno == EACCES) { + pid = 0; + continue; + } + goto out_delete; + } + break; } + close(fd); + ret = true; out_delete: perf_evlist__delete(temp_evlist); -- GitLab From f6edb53c4993ffe92ce521fb449d1c146cea6ec2 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 12 Aug 2014 18:04:31 +0300 Subject: [PATCH 0322/9167] perf tools: Prefer to use a cpu-wide event for probing CLOEXEC When doing a system-wide trace with Intel PT, the jump label set up as a result of probing CLOEXEC gets reset while the trace is running. That causes an Intel PT decoding error because the object code (obtained from /proc/kcore) does not match the running code at that point. While we can't expect there never to be jump label changes, we can avoid cases that the perf tool itself creates. The problem is avoided by first trying a cpu-wide event (pid = -1) for probing the PERF_FLAG_FD_CLOEXEC flag and falling back to an event for the current process (pid = 0). Signed-off-by: Adrian Hunter Acked-by: Jiri Olsa Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1407855871-15024-5-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cloexec.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index 000047cb3fee..4945aa56a017 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -1,3 +1,4 @@ +#include #include "util.h" #include "../perf.h" #include "cloexec.h" @@ -15,10 +16,23 @@ static int perf_flag_probe(void) }; int fd; int err; + int cpu; + pid_t pid = -1; - /* check cloexec flag */ - fd = sys_perf_event_open(&attr, 0, -1, -1, - PERF_FLAG_FD_CLOEXEC); + cpu = sched_getcpu(); + if (cpu < 0) + cpu = 0; + + while (1) { + /* check cloexec flag */ + fd = sys_perf_event_open(&attr, pid, cpu, -1, + PERF_FLAG_FD_CLOEXEC); + if (fd < 0 && pid == -1 && errno == EACCES) { + pid = 0; + continue; + } + break; + } err = errno; if (fd >= 0) { @@ -31,7 +45,7 @@ static int perf_flag_probe(void) err, strerror(err)); /* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */ - fd = sys_perf_event_open(&attr, 0, -1, -1, 0); + fd = sys_perf_event_open(&attr, pid, cpu, -1, 0); err = errno; if (WARN_ONCE(fd < 0 && err != EBUSY, -- GitLab From 6cc870f09da4d50722bc1caa27cad51733ce36f6 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:33 +0900 Subject: [PATCH 0323/9167] perf script: Fix possible memory leaks Some paths in perf script don't call perf_session__delete() after creating a new session. Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-2-git-send-email-namhyung@kernel.org [ Saved errno value before calling perror(), as pointed out by Adrian Hunter ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 868c17d09762..c84d723e0484 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1471,12 +1471,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) bool show_full_info = false; bool header = false; bool header_only = false; + bool script_started = false; char *rec_script_path = NULL; char *rep_script_path = NULL; struct perf_session *session; char *script_path = NULL; const char **__argv; - int i, j, err; + int i, j, err = 0; struct perf_script script = { .tool = { .sample = process_sample_event, @@ -1730,14 +1731,15 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) if (header || header_only) { perf_session__fprintf_info(session, stdout, show_full_info); if (header_only) - return 0; + goto out_delete; } script.session = session; if (cpu_list) { - if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) - return -1; + err = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); + if (err < 0) + goto out_delete; } if (!no_callchain) @@ -1752,53 +1754,60 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) if (output_set_by_user()) { fprintf(stderr, "custom fields not supported for generated scripts"); - return -1; + err = -EINVAL; + goto out_delete; } input = open(file.path, O_RDONLY); /* input_name */ if (input < 0) { + err = -errno; perror("failed to open file"); - return -1; + goto out_delete; } err = fstat(input, &perf_stat); if (err < 0) { perror("failed to stat file"); - return -1; + goto out_delete; } if (!perf_stat.st_size) { fprintf(stderr, "zero-sized file, nothing to do!\n"); - return 0; + goto out_delete; } scripting_ops = script_spec__lookup(generate_script_lang); if (!scripting_ops) { fprintf(stderr, "invalid language specifier"); - return -1; + err = -ENOENT; + goto out_delete; } err = scripting_ops->generate_script(session->tevent.pevent, "perf-script"); - goto out; + goto out_delete; } if (script_name) { err = scripting_ops->start_script(script_name, argc, argv); if (err) - goto out; + goto out_delete; pr_debug("perf script started with script %s\n\n", script_name); + script_started = true; } err = perf_session__check_output_opt(session); if (err < 0) - goto out; + goto out_delete; err = __cmd_script(&script); +out_delete: perf_session__delete(session); - cleanup_scripting(); + + if (script_started) + cleanup_scripting(); out: return err; } -- GitLab From e96c674fe2c228fd5c16fd7a7607c60dea4cdaa2 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:34 +0900 Subject: [PATCH 0324/9167] perf symbols: Fix a memory leak in vmlinux_path__init() When uname() failed, it should free vmlinux_path. Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 581c56836567..009a9d064f11 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1772,7 +1772,7 @@ static int vmlinux_path__init(void) return 0; if (uname(&uts) < 0) - return -1; + goto out_fail; snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release); vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); -- GitLab From fa10f316d59f39020d19d3f4a323598d05afa65c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:35 +0900 Subject: [PATCH 0325/9167] perf annotate: Move session handling out of __cmd_annotate() This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 75 +++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 952b5ece6740..c0464dc38057 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -36,7 +36,8 @@ struct perf_annotate { struct perf_tool tool; - bool force, use_tui, use_stdio, use_gtk; + struct perf_session *session; + bool use_tui, use_stdio, use_gtk; bool full_paths; bool print_line; bool skip_missing; @@ -188,18 +189,9 @@ static void hists__find_annotations(struct hists *hists, static int __cmd_annotate(struct perf_annotate *ann) { int ret; - struct perf_session *session; + struct perf_session *session = ann->session; struct perf_evsel *pos; u64 total_nr_samples; - struct perf_data_file file = { - .path = input_name, - .mode = PERF_DATA_MODE_READ, - .force = ann->force, - }; - - session = perf_session__new(&file, false, &ann->tool); - if (session == NULL) - return -ENOMEM; machines__set_symbol_filter(&session->machines, symbol__annotate_init); @@ -207,22 +199,22 @@ static int __cmd_annotate(struct perf_annotate *ann) ret = perf_session__cpu_bitmap(session, ann->cpu_list, ann->cpu_bitmap); if (ret) - goto out_delete; + goto out; } if (!objdump_path) { ret = perf_session_env__lookup_objdump(&session->header.env); if (ret) - goto out_delete; + goto out; } ret = perf_session__process_events(session, &ann->tool); if (ret) - goto out_delete; + goto out; if (dump_trace) { perf_session__fprintf_nr_events(session, stdout); - goto out_delete; + goto out; } if (verbose > 3) @@ -250,8 +242,8 @@ static int __cmd_annotate(struct perf_annotate *ann) } if (total_nr_samples == 0) { - ui__error("The %s file has no samples!\n", file.path); - goto out_delete; + ui__error("The %s file has no samples!\n", session->file->path); + goto out; } if (use_browser == 2) { @@ -261,24 +253,12 @@ static int __cmd_annotate(struct perf_annotate *ann) "perf_gtk__show_annotations"); if (show_annotations == NULL) { ui__error("GTK browser not found!\n"); - goto out_delete; + goto out; } show_annotations(); } -out_delete: - /* - * Speed up the exit process, for large files this can - * take quite a while. - * - * XXX Enable this when using valgrind or if we ever - * librarize this command. - * - * Also experiment with obstacks to see how much speed - * up we'll get here. - * - * perf_session__delete(session); - */ +out: return ret; } @@ -301,6 +281,10 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) .ordering_requires_timestamps = true, }, }; + struct perf_data_file file = { + .path = input_name, + .mode = PERF_DATA_MODE_READ, + }; const struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), @@ -308,7 +292,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) "only consider symbols in these dsos"), OPT_STRING('s', "symbol", &annotate.sym_hist_filter, "symbol", "symbol to annotate"), - OPT_BOOLEAN('f', "force", &annotate.force, "don't complain, do it"), + OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"), OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, @@ -341,6 +325,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) "Show event group information together"), OPT_END() }; + int ret; argc = parse_options(argc, argv, options, annotate_usage, 0); @@ -353,11 +338,16 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) setup_browser(true); + annotate.session = perf_session__new(&file, false, &annotate.tool); + if (annotate.session == NULL) + return -ENOMEM; + symbol_conf.priv_size = sizeof(struct annotation); symbol_conf.try_vmlinux_path = true; - if (symbol__init() < 0) - return -1; + ret = symbol__init(); + if (ret < 0) + goto out_delete; if (setup_sorting() < 0) usage_with_options(annotate_usage, options); @@ -373,5 +363,20 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) annotate.sym_hist_filter = argv[0]; } - return __cmd_annotate(&annotate); + ret = __cmd_annotate(&annotate); + +out_delete: + /* + * Speed up the exit process, for large files this can + * take quite a while. + * + * XXX Enable this when using valgrind or if we ever + * librarize this command. + * + * Also experiment with obstacks to see how much speed + * up we'll get here. + * + * perf_session__delete(session); + */ + return ret; } -- GitLab From e3ed75bb537a860a375ca1e09ad1b87c707f1636 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:36 +0900 Subject: [PATCH 0326/9167] perf buildid-cache: Move session handling into cmd_buildid_cache() This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Acked-by: Jiri Olsa Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-buildid-cache.c | 35 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index 2a2c78f80876..d91bfa6632e8 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -246,20 +246,9 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused) return true; } -static int build_id_cache__fprintf_missing(const char *filename, bool force, FILE *fp) +static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *fp) { - struct perf_data_file file = { - .path = filename, - .mode = PERF_DATA_MODE_READ, - .force = force, - }; - struct perf_session *session = perf_session__new(&file, false, NULL); - if (session == NULL) - return -1; - perf_session__fprintf_dsos_buildid(session, fp, dso__missing_buildid_cache, 0); - perf_session__delete(session); - return 0; } @@ -303,6 +292,11 @@ int cmd_buildid_cache(int argc, const char **argv, *update_name_list_str = NULL, *kcore_filename; + struct perf_data_file file = { + .mode = PERF_DATA_MODE_READ, + }; + struct perf_session *session = NULL; + const struct option buildid_cache_options[] = { OPT_STRING('a', "add", &add_name_list_str, "file list", "file(s) to add"), @@ -326,8 +320,17 @@ int cmd_buildid_cache(int argc, const char **argv, argc = parse_options(argc, argv, buildid_cache_options, buildid_cache_usage, 0); + if (missing_filename) { + file.path = missing_filename; + file.force = force; + + session = perf_session__new(&file, false, NULL); + if (session == NULL) + return -1; + } + if (symbol__init() < 0) - return -1; + goto out; setup_pager(); @@ -370,7 +373,7 @@ int cmd_buildid_cache(int argc, const char **argv, } if (missing_filename) - ret = build_id_cache__fprintf_missing(missing_filename, force, stdout); + ret = build_id_cache__fprintf_missing(session, stdout); if (update_name_list_str) { list = strlist__new(true, update_name_list_str); @@ -394,5 +397,9 @@ int cmd_buildid_cache(int argc, const char **argv, build_id_cache__add_kcore(kcore_filename, debugdir, force)) pr_warning("Couldn't add %s\n", kcore_filename); +out: + if (session) + perf_session__delete(session); + return ret; } -- GitLab From 1cb8bdcca0e2f738a492c3857568cf34ba4a4373 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:37 +0900 Subject: [PATCH 0327/9167] perf inject: Move session handling out of __cmd_inject() This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-6-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-inject.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index ee875cca13b1..18eaefd3cd0c 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -23,6 +23,7 @@ struct perf_inject { struct perf_tool tool; + struct perf_session *session; bool build_ids; bool sched_stat; const char *input_name; @@ -340,12 +341,8 @@ static int perf_evsel__check_stype(struct perf_evsel *evsel, static int __cmd_inject(struct perf_inject *inject) { - struct perf_session *session; int ret = -EINVAL; - struct perf_data_file file = { - .path = inject->input_name, - .mode = PERF_DATA_MODE_READ, - }; + struct perf_session *session = inject->session; struct perf_data_file *file_out = &inject->output; signal(SIGINT, sig_handler); @@ -357,10 +354,6 @@ static int __cmd_inject(struct perf_inject *inject) inject->tool.tracing_data = perf_event__repipe_tracing_data; } - session = perf_session__new(&file, true, &inject->tool); - if (session == NULL) - return -ENOMEM; - if (inject->build_ids) { inject->tool.sample = perf_event__inject_buildid; } else if (inject->sched_stat) { @@ -396,8 +389,6 @@ static int __cmd_inject(struct perf_inject *inject) perf_session__write_header(session, session->evlist, file_out->fd, true); } - perf_session__delete(session); - return ret; } @@ -427,6 +418,11 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) .mode = PERF_DATA_MODE_WRITE, }, }; + struct perf_data_file file = { + .mode = PERF_DATA_MODE_READ, + }; + int ret; + const struct option options[] = { OPT_BOOLEAN('b', "build-ids", &inject.build_ids, "Inject build-ids into the output stream"), @@ -461,8 +457,17 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) return -1; } + file.path = inject.input_name; + inject.session = perf_session__new(&file, true, &inject.tool); + if (inject.session == NULL) + return -ENOMEM; + if (symbol__init() < 0) return -1; - return __cmd_inject(&inject); + ret = __cmd_inject(&inject); + + perf_session__delete(inject.session); + + return ret; } -- GitLab From 2b2b2c68c64fb9db392940b42355944064f2a4ca Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:38 +0900 Subject: [PATCH 0328/9167] perf kmem: Move session handling out of __cmd_kmem() This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-7-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kmem.c | 49 ++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 84b82397a28e..349d9b46098e 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -405,10 +405,9 @@ static void sort_result(void) __sort_result(&root_caller_stat, &root_caller_sorted, &caller_sort); } -static int __cmd_kmem(void) +static int __cmd_kmem(struct perf_session *session) { int err = -EINVAL; - struct perf_session *session; const struct perf_evsel_str_handler kmem_tracepoints[] = { { "kmem:kmalloc", perf_evsel__process_alloc_event, }, { "kmem:kmem_cache_alloc", perf_evsel__process_alloc_event, }, @@ -417,31 +416,22 @@ static int __cmd_kmem(void) { "kmem:kfree", perf_evsel__process_free_event, }, { "kmem:kmem_cache_free", perf_evsel__process_free_event, }, }; - struct perf_data_file file = { - .path = input_name, - .mode = PERF_DATA_MODE_READ, - }; - - session = perf_session__new(&file, false, &perf_kmem); - if (session == NULL) - return -ENOMEM; if (!perf_session__has_traces(session, "kmem record")) - goto out_delete; + goto out; if (perf_session__set_tracepoints_handlers(session, kmem_tracepoints)) { pr_err("Initializing perf session tracepoint handlers failed\n"); - return -1; + goto out; } setup_pager(); err = perf_session__process_events(session, &perf_kmem); if (err != 0) - goto out_delete; + goto out; sort_result(); print_result(session); -out_delete: - perf_session__delete(session); +out: return err; } @@ -688,29 +678,46 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) NULL, NULL }; + struct perf_session *session; + struct perf_data_file file = { + .path = input_name, + .mode = PERF_DATA_MODE_READ, + }; + int ret = -1; + argc = parse_options_subcommand(argc, argv, kmem_options, kmem_subcommands, kmem_usage, 0); if (!argc) usage_with_options(kmem_usage, kmem_options); - symbol__init(); - if (!strncmp(argv[0], "rec", 3)) { + symbol__init(); return __cmd_record(argc, argv); - } else if (!strcmp(argv[0], "stat")) { + } + + session = perf_session__new(&file, false, &perf_kmem); + if (session == NULL) + return -ENOMEM; + + symbol__init(); + + if (!strcmp(argv[0], "stat")) { if (cpu__setup_cpunode_map()) - return -1; + goto out_delete; if (list_empty(&caller_sort)) setup_sorting(&caller_sort, default_sort_order); if (list_empty(&alloc_sort)) setup_sorting(&alloc_sort, default_sort_order); - return __cmd_kmem(); + ret = __cmd_kmem(session); } else usage_with_options(kmem_usage, kmem_options); - return 0; +out_delete: + perf_session__delete(session); + + return ret; } -- GitLab From 14d37f38e956ba0dd4f2206f68534eb418ecd905 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:39 +0900 Subject: [PATCH 0329/9167] perf kvm: Move call to symbol__init() after creating session This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-8-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index ff404750d744..7f2b55513863 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1064,6 +1064,8 @@ static int read_events(struct perf_kvm_stat *kvm) return -EINVAL; } + symbol__init(); + if (!perf_session__has_traces(kvm->session, "kvm record")) return -EINVAL; @@ -1193,8 +1195,6 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv) NULL }; - symbol__init(); - if (argc) { argc = parse_options(argc, argv, kvm_events_report_options, -- GitLab From 6fd6c6b462c55f33c20f38051f1116dc52054d67 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:40 +0900 Subject: [PATCH 0330/9167] perf lock: Move call to symbol__init() after creating session This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-9-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-lock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index c8122d323621..d73580b39908 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -865,6 +865,8 @@ static int __cmd_report(bool display_info) return -ENOMEM; } + symbol__init(); + if (!perf_session__has_traces(session, "lock record")) goto out_delete; @@ -974,7 +976,6 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused) unsigned int i; int rc = 0; - symbol__init(); for (i = 0; i < LOCKHASH_SIZE; i++) INIT_LIST_HEAD(lockhash_table + i); -- GitLab From 0493410612486cadaa4e076caf4df3fa9cd20fde Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:41 +0900 Subject: [PATCH 0331/9167] perf sched: Move call to symbol__init() after creating session This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-10-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index 7c16aeb6b675..dcd9ebf5a7df 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1462,6 +1462,8 @@ static int perf_sched__read_events(struct perf_sched *sched, return -1; } + symbol__init(); + if (perf_session__set_tracepoints_handlers(session, handlers)) goto out_delete; @@ -1747,7 +1749,6 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused) if (!strcmp(argv[0], "script")) return cmd_script(argc, argv, prefix); - symbol__init(); if (!strncmp(argv[0], "rec", 3)) { return __cmd_record(argc, argv); } else if (!strncmp(argv[0], "lat", 3)) { -- GitLab From 38520dc31206bae1dc811ddd59ccea3a6536784d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:42 +0900 Subject: [PATCH 0332/9167] perf script: Move call to symbol__init() after creating session This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-11-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index c84d723e0484..9ca7a2d03f17 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1719,8 +1719,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) exit(-1); } - if (symbol__init() < 0) - return -1; if (!script_name) setup_pager(); @@ -1734,6 +1732,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) goto out_delete; } + if (symbol__init() < 0) + goto out_delete; + script.session = session; if (cpu_list) { -- GitLab From dc5c8190b800dc59eff6bb2aa47ea749712197df Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:43 +0900 Subject: [PATCH 0333/9167] perf timechart: Move call to symbol__init() after creating session This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Acked-by: Jiri Olsa Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-12-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-timechart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 912e3b5bb22b..df3b1c5ae7b9 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1607,6 +1607,8 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) if (session == NULL) return -ENOMEM; + symbol__init(); + (void)perf_header__process_sections(&session->header, perf_data_file__fd(session->file), tchart, @@ -1982,8 +1984,6 @@ int cmd_timechart(int argc, const char **argv, return -1; } - symbol__init(); - if (argc && !strncmp(argv[0], "rec", 3)) { argc = parse_options(argc, argv, record_options, record_usage, PARSE_OPT_STOP_AT_NON_OPTION); -- GitLab From cb2ffae241cfdd6d90acb7ec5f52ad8401885dd2 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:44 +0900 Subject: [PATCH 0334/9167] perf trace: Move call to symbol__init() after creating session This is a preparation of fixing dso__load_kernel_sym(). It needs a session info before calling symbol__init(). Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1407825645-24586-13-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 20fac5083771..8a83bd835327 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2241,13 +2241,13 @@ static int trace__replay(struct trace *trace) /* add tid to output */ trace->multiple_threads = true; - if (symbol__init() < 0) - return -1; - session = perf_session__new(&file, false, &trace->tool); if (session == NULL) return -ENOMEM; + if (symbol__init() < 0) + goto out; + trace->host = &session->machines.host; err = perf_session__set_tracepoints_handlers(session, handlers); -- GitLab From 0a7e6d1b6844bec2d6817615a693c7fce447b80d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 15:40:45 +0900 Subject: [PATCH 0335/9167] perf tools: Check recorded kernel version when finding vmlinux Currently vmlinux_path__init() only tries to find vmlinux file from current directory, /boot and some canonical directories with version number of the running kernel. This can be a problem when reporting old data recorded on a kernel version not running currently. We can use --symfs option for this but it's annoying for user to do it always. As we already have the info in the perf.data file, it can be changed to use it for the search automatically. Before: $ perf report ... # Samples: 4K of event 'cpu-clock' # Event count (approx.): 1067250000 # # Overhead Command Shared Object Symbol # ........ .......... ................. .............................. 71.87% swapper [kernel.kallsyms] [k] recover_probed_instruction After: # Overhead Command Shared Object Symbol # ........ .......... ................. .................... 71.87% swapper [kernel.kallsyms] [k] native_safe_halt This requires to change signature of symbol__init() to receive struct perf_session_env *. Reported-by: Minchan Kim Signed-off-by: Namhyung Kim Cc: Adrian Hunter Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Masami Hiramatsu Cc: Minchan Kim Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1407825645-24586-14-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-buildid-cache.c | 2 +- tools/perf/builtin-diff.c | 2 +- tools/perf/builtin-inject.c | 2 +- tools/perf/builtin-kmem.c | 4 ++-- tools/perf/builtin-kvm.c | 4 ++-- tools/perf/builtin-lock.c | 2 +- tools/perf/builtin-mem.c | 2 +- tools/perf/builtin-record.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-sched.c | 2 +- tools/perf/builtin-script.c | 2 +- tools/perf/builtin-timechart.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/builtin-trace.c | 4 ++-- tools/perf/tests/builtin-test.c | 2 +- tools/perf/util/probe-event.c | 2 +- tools/perf/util/symbol.c | 26 +++++++++++++++++--------- tools/perf/util/symbol.h | 3 ++- 19 files changed, 39 insertions(+), 30 deletions(-) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index c0464dc38057..d4da6929597f 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -345,7 +345,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) symbol_conf.priv_size = sizeof(struct annotation); symbol_conf.try_vmlinux_path = true; - ret = symbol__init(); + ret = symbol__init(&annotate.session->header.env); if (ret < 0) goto out_delete; diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index d91bfa6632e8..ac5838e0b1bd 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -329,7 +329,7 @@ int cmd_buildid_cache(int argc, const char **argv, return -1; } - if (symbol__init() < 0) + if (symbol__init(session ? &session->header.env : NULL) < 0) goto out; setup_pager(); diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index c10cc44bae19..190d0b6b28cc 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -1143,7 +1143,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused) argc = parse_options(argc, argv, options, diff_usage, 0); - if (symbol__init() < 0) + if (symbol__init(NULL) < 0) return -1; if (data_init(argc, argv) < 0) diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 18eaefd3cd0c..3a62b6b3c8fd 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -462,7 +462,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused) if (inject.session == NULL) return -ENOMEM; - if (symbol__init() < 0) + if (symbol__init(&inject.session->header.env) < 0) return -1; ret = __cmd_inject(&inject); diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index 349d9b46098e..23762187a219 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c @@ -692,7 +692,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) usage_with_options(kmem_usage, kmem_options); if (!strncmp(argv[0], "rec", 3)) { - symbol__init(); + symbol__init(NULL); return __cmd_record(argc, argv); } @@ -700,7 +700,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused) if (session == NULL) return -ENOMEM; - symbol__init(); + symbol__init(&session->header.env); if (!strcmp(argv[0], "stat")) { if (cpu__setup_cpunode_map()) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 7f2b55513863..14d03edc81c2 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -1064,7 +1064,7 @@ static int read_events(struct perf_kvm_stat *kvm) return -EINVAL; } - symbol__init(); + symbol__init(&kvm->session->header.env); if (!perf_session__has_traces(kvm->session, "kvm record")) return -EINVAL; @@ -1314,7 +1314,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, kvm->opts.target.uid_str = NULL; kvm->opts.target.uid = UINT_MAX; - symbol__init(); + symbol__init(NULL); disable_buildid_cache(); use_browser = 0; diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index d73580b39908..92790ed7af45 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -865,7 +865,7 @@ static int __cmd_report(bool display_info) return -ENOMEM; } - symbol__init(); + symbol__init(&session->header.env); if (!perf_session__has_traces(session, "lock record")) goto out_delete; diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c index 80e57c84adef..8b4a87fe3858 100644 --- a/tools/perf/builtin-mem.c +++ b/tools/perf/builtin-mem.c @@ -133,7 +133,7 @@ static int report_raw_events(struct perf_mem *mem) goto out_delete; } - if (symbol__init() < 0) + if (symbol__init(&session->header.env) < 0) return -1; printf("# PID, TID, IP, ADDR, LOCAL WEIGHT, DSRC, SYMBOL\n"); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index ca0251e8470d..4db670d4b8da 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -908,7 +908,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused) usage_with_options(record_usage, record_options); } - symbol__init(); + symbol__init(NULL); if (symbol_conf.kptr_restrict) pr_warning( diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 041e93da13e4..b9e0fcac4d71 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -798,7 +798,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) } } - if (symbol__init() < 0) + if (symbol__init(&session->header.env) < 0) goto error; if (argc) { diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index dcd9ebf5a7df..f5874a27b346 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -1462,7 +1462,7 @@ static int perf_sched__read_events(struct perf_sched *sched, return -1; } - symbol__init(); + symbol__init(&session->header.env); if (perf_session__set_tracepoints_handlers(session, handlers)) goto out_delete; diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 9ca7a2d03f17..37d2b608d388 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1732,7 +1732,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) goto out_delete; } - if (symbol__init() < 0) + if (symbol__init(&session->header.env) < 0) goto out_delete; script.session = session; diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index df3b1c5ae7b9..48eea6cd2f5b 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -1607,7 +1607,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) if (session == NULL) return -ENOMEM; - symbol__init(); + symbol__init(&session->header.env); (void)perf_header__process_sections(&session->header, perf_data_file__fd(session->file), diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0ab3ea7f7525..4b0e15c2b2a8 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1234,7 +1234,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) symbol_conf.priv_size = sizeof(struct annotation); symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); - if (symbol__init() < 0) + if (symbol__init(NULL) < 0) return -1; sort__setup_elide(stdout); diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 8a83bd835327..d080b9cf0354 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1411,7 +1411,7 @@ static int trace__tool_process(struct perf_tool *tool, static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) { - int err = symbol__init(); + int err = symbol__init(NULL); if (err) return err; @@ -2245,7 +2245,7 @@ static int trace__replay(struct trace *trace) if (session == NULL) return -ENOMEM; - if (symbol__init() < 0) + if (symbol__init(&session->header.env) < 0) goto out; trace->host = &session->machines.host; diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 6f8b01bc6033..c6796d22423a 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -297,7 +297,7 @@ int cmd_test(int argc, const char **argv, const char *prefix __maybe_unused) symbol_conf.sort_by_name = true; symbol_conf.try_vmlinux_path = true; - if (symbol__init() < 0) + if (symbol__init(NULL) < 0) return -1; if (skip != NULL) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 443225cb62f7..784ea42ad8cb 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -79,7 +79,7 @@ static int init_symbol_maps(bool user_only) int ret; symbol_conf.sort_by_name = true; - ret = symbol__init(); + ret = symbol__init(NULL); if (ret < 0) { pr_debug("Failed to init symbol map.\n"); goto out; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 009a9d064f11..ac098a3c2a31 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -15,6 +15,7 @@ #include "machine.h" #include "symbol.h" #include "strlist.h" +#include "header.h" #include #include @@ -1749,10 +1750,11 @@ static void vmlinux_path__exit(void) zfree(&vmlinux_path); } -static int vmlinux_path__init(void) +static int vmlinux_path__init(struct perf_session_env *env) { struct utsname uts; char bf[PATH_MAX]; + char *kernel_version; vmlinux_path = malloc(sizeof(char *) * 5); if (vmlinux_path == NULL) @@ -1767,25 +1769,31 @@ static int vmlinux_path__init(void) goto out_fail; ++vmlinux_path__nr_entries; - /* only try running kernel version if no symfs was given */ + /* only try kernel version if no symfs was given */ if (symbol_conf.symfs[0] != 0) return 0; - if (uname(&uts) < 0) - goto out_fail; + if (env) { + kernel_version = env->os_release; + } else { + if (uname(&uts) < 0) + goto out_fail; + + kernel_version = uts.release; + } - snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release); + snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", kernel_version); vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); if (vmlinux_path[vmlinux_path__nr_entries] == NULL) goto out_fail; ++vmlinux_path__nr_entries; - snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release); + snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", kernel_version); vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); if (vmlinux_path[vmlinux_path__nr_entries] == NULL) goto out_fail; ++vmlinux_path__nr_entries; snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux", - uts.release); + kernel_version); vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); if (vmlinux_path[vmlinux_path__nr_entries] == NULL) goto out_fail; @@ -1831,7 +1839,7 @@ static bool symbol__read_kptr_restrict(void) return value; } -int symbol__init(void) +int symbol__init(struct perf_session_env *env) { const char *symfs; @@ -1846,7 +1854,7 @@ int symbol__init(void) symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - sizeof(struct symbol)); - if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0) + if (symbol_conf.try_vmlinux_path && vmlinux_path__init(env) < 0) return -1; if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') { diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 196b29104276..b95e3a36d654 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -262,7 +262,8 @@ int modules__parse(const char *filename, void *arg, int filename__read_debuglink(const char *filename, char *debuglink, size_t size); -int symbol__init(void); +struct perf_session_env; +int symbol__init(struct perf_session_env *env); void symbol__exit(void); void symbol__elf_init(void); struct symbol *symbol__new(u64 start, u64 len, u8 binding, const char *name); -- GitLab From 82162b5ae3d152fd7d887b36213f5b6785fe1294 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 13 Aug 2014 15:02:41 +0900 Subject: [PATCH 0336/9167] perf hists browser: Fix a small callchain display bug The currently when perf TUI report shows callchain, the first level chains have bogus '+' sign even though only the last one has children. Since they are on a single line of the chain, toggling intermediate entries has no effect. Fix it to show '+' sign at the last entry only. Note that non-first level callchain entries don't have this problem. Before: --------------------------------------------------------------------------- Children Self Command Shared Object Symbols - 40.70% 0.00% swapper [kernel.kallsyms] [k] cpuidle_wrap_enter + cpuidle_wrap_enter + cpuidle_enter_tk + cpuidle_idle_call + cpu_idle After: --------------------------------------------------------------------------- Children Self Command Shared Object Symbols - 40.70% 0.00% swapper [kernel.kallsyms] [k] cpuidle_wrap_enter cpuidle_wrap_enter cpuidle_enter_tk cpuidle_idle_call + cpu_idle Signed-off-by: Namhyung Kim Acked-by: Ingo Molnar Cc: Andi Kleen Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Frederic Weisbecker Link: http://lkml.kernel.org/r/1407909761-10822-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 045c1e16ac59..1818d1275d02 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -228,8 +228,10 @@ static void callchain_node__init_have_children(struct callchain_node *node) { struct callchain_list *chain; - list_for_each_entry(chain, &node->val, list) + if (!list_empty(&node->val)) { + chain = list_entry(node->val.prev, struct callchain_list, list); chain->ms.has_children = !RB_EMPTY_ROOT(&node->rb_root); + } callchain_node__init_have_children_rb_tree(node); } -- GitLab From edd114e213751c3274891f692be66eb65771f278 Mon Sep 17 00:00:00 2001 From: "naota@elisp.net" Date: Thu, 7 Aug 2014 00:04:49 +0900 Subject: [PATCH 0337/9167] perf report: Set proper sort__mode for the branch option When you specify "--branch-stack"("-b" for short) or "--no-branch-stack", "branch_mode" variable is set to 1 or 0 respectively. However, the code is just checking if the variable is -1 or not, ignoring "branch_mode == 1" case. Thus "perf report -b" dose not show its result with the branch sorted mode. This patch fix the problem. Signed-off-by: Naohiro Aota Acked-by: Namhyung Kim Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/87y4v1fylq.fsf@elisp.net Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-report.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index b9e0fcac4d71..3da59a87ec7c 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -730,7 +730,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused) has_br_stack = perf_header__has_feat(&session->header, HEADER_BRANCH_STACK); - if (branch_mode == -1 && has_br_stack) { + if ((branch_mode == -1 && has_br_stack) || branch_mode == 1) { sort__mode = SORT_MODE__BRANCH; symbol_conf.cumulate_callchain = false; } -- GitLab From 701937bd59cc94b6913086feb62f05ae565ff2de Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 17:16:05 +0900 Subject: [PATCH 0338/9167] perf top: Fix -z option behavior The current -z option does almost nothing. It doesn't zero the existing samples so that we can see profiles of exited process after last refresh. It seems it only affects annotation. This patch clears existing entries before processing if -z option is given. For this original decaying logic also moved before processing. Reported-by: Stephane Eranian Tested-by: Stephane Eranian Signed-off-by: Namhyung Kim Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1407831366-28892-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 23 +++++++++++++++++------ tools/perf/util/hist.c | 22 ++++++++++++++++++++++ tools/perf/util/hist.h | 1 + 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 4b0e15c2b2a8..87a6615a40fa 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -276,11 +276,17 @@ static void perf_top__print_sym_table(struct perf_top *top) return; } + if (top->zero) { + hists__delete_entries(&top->sym_evsel->hists); + } else { + hists__decay_entries(&top->sym_evsel->hists, + top->hide_user_symbols, + top->hide_kernel_symbols); + } + hists__collapse_resort(&top->sym_evsel->hists, NULL); hists__output_resort(&top->sym_evsel->hists); - hists__decay_entries(&top->sym_evsel->hists, - top->hide_user_symbols, - top->hide_kernel_symbols); + hists__output_recalc_col_len(&top->sym_evsel->hists, top->print_entries - printed); putchar('\n'); @@ -542,11 +548,16 @@ static void perf_top__sort_new_samples(void *arg) if (t->evlist->selected != NULL) t->sym_evsel = t->evlist->selected; + if (t->zero) { + hists__delete_entries(&t->sym_evsel->hists); + } else { + hists__decay_entries(&t->sym_evsel->hists, + t->hide_user_symbols, + t->hide_kernel_symbols); + } + hists__collapse_resort(&t->sym_evsel->hists, NULL); hists__output_resort(&t->sym_evsel->hists); - hists__decay_entries(&t->sym_evsel->hists, - t->hide_user_symbols, - t->hide_kernel_symbols); } static void *display_thread_tui(void *arg) diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 30df6187ee02..86569fa3651d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -277,6 +277,28 @@ void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel) } } +void hists__delete_entries(struct hists *hists) +{ + struct rb_node *next = rb_first(&hists->entries); + struct hist_entry *n; + + while (next) { + n = rb_entry(next, struct hist_entry, rb_node); + next = rb_next(&n->rb_node); + + rb_erase(&n->rb_node, &hists->entries); + + if (sort__need_collapse) + rb_erase(&n->rb_node_in, &hists->entries_collapsed); + + --hists->nr_entries; + if (!n->filtered) + --hists->nr_non_filtered_entries; + + hist_entry__free(n); + } +} + /* * histogram, sorted on item, collects periods */ diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 95405a8fbd95..8c9c70e18cbb 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h @@ -152,6 +152,7 @@ void hists__output_resort(struct hists *hists); void hists__collapse_resort(struct hists *hists, struct ui_progress *prog); void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); +void hists__delete_entries(struct hists *hists); void hists__output_recalc_col_len(struct hists *hists, int max_rows); u64 hists__total_period(struct hists *hists); -- GitLab From 42337a222c93cd22864f20ef9b157765ab1086a0 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Tue, 12 Aug 2014 17:16:06 +0900 Subject: [PATCH 0339/9167] perf top: Handle 'z' key for toggle zeroing samples in TUI The perf top TUI lacks 'z' key support to toggle sample zeroing. Add it. Reported-by: Stephane Eranian Tested-by: Stephane Eranian Signed-off-by: Namhyung Kim Cc: David Ahern Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1407831366-28892-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 1818d1275d02..4892480e8298 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -10,6 +10,7 @@ #include "../../util/pstack.h" #include "../../util/sort.h" #include "../../util/util.h" +#include "../../util/top.h" #include "../../arch/common.h" #include "../browser.h" @@ -1532,6 +1533,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, "P Print histograms to perf.hist.N\n" "t Zoom into current Thread\n" "V Verbose (DSO names in callchains, etc)\n" + "z Toggle zeroing of samples\n" "/ Filter symbol by name"; if (browser == NULL) @@ -1632,6 +1634,13 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, case 'F': symbol_conf.filter_relative ^= 1; continue; + case 'z': + if (!is_report_browser(hbt)) { + struct perf_top *top = hbt->arg; + + top->zero = !top->zero; + } + continue; case K_F1: case 'h': case '?': -- GitLab From e71e79457b79a52827039d9d7f253321bfd342bd Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 31 Jul 2014 14:47:42 +0900 Subject: [PATCH 0340/9167] perf symbols: Don't demangle parameters and such by default Some C++ symbols have very long name and they make column length longer. Most of them are about parameters including templates and we can ignore such info most of time IMHO. This patch passes DMGL_NO_OPTS by default when calling bfd_demangle(). One can still see full symbols with -v/--verbose option. before: JS_CallFunctionValue(JSContext*, JSObject*, JS::Value, unsigned int, JS::Value*, JS::Value*) after: JS_CallFunctionValue Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1406785662-5534-9-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol-elf.c | 7 +++++-- tools/perf/util/symbol.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index d75349979e65..ec5ec1c9d9b5 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -939,8 +939,11 @@ int dso__load_sym(struct dso *dso, struct map *map, * to it... */ if (symbol_conf.demangle) { - demangled = bfd_demangle(NULL, elf_name, - DMGL_PARAMS | DMGL_ANSI); + int demangle_flags = DMGL_NO_OPTS; + if (verbose) + demangle_flags = DMGL_PARAMS | DMGL_ANSI; + + demangled = bfd_demangle(NULL, elf_name, demangle_flags); if (demangled != NULL) elf_name = demangled; } diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index b95e3a36d654..3f95ea0357e3 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -60,6 +60,7 @@ extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, #endif #ifndef DMGL_PARAMS +#define DMGL_NO_OPTS 0 /* For readability... */ #define DMGL_PARAMS (1 << 0) /* Include function args */ #define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ #endif -- GitLab From f247fb8191aa7f10d3f6c987e8ef0853ae789a02 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:00:46 +0300 Subject: [PATCH 0341/9167] perf symbols: Fix missing label symbols Label symbols are missing because elf_sec__is_a() fails to find the section because the section strings do not match the section headers because the sections headers are from the 'runtime' object and the sections strings are from the 'symbol source' object. Fix by getting the section strings from the 'runtime' object so that they match the section headers. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-4-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol-elf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index ec5ec1c9d9b5..9fb5e9e9f161 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -736,7 +736,7 @@ int dso__load_sym(struct dso *dso, struct map *map, if (symstrs == NULL) goto out_elf_end; - sec_strndx = elf_getscn(elf, ehdr.e_shstrndx); + sec_strndx = elf_getscn(runtime_ss->elf, runtime_ss->ehdr.e_shstrndx); if (sec_strndx == NULL) goto out_elf_end; -- GitLab From bf8e8f4b832972c76d64ab2e2837a48397144887 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:00:51 +0300 Subject: [PATCH 0342/9167] perf evlist: Add 'system_wide' option Add an option to cause a selected event to be opened always without a pid when configured by perf_evsel__config(). This is needed when using the sched_switch tracepoint to follow object code execution. sched_switch occurs before the task switch and so it cannot record it in a context limited to that task. Note that also means that sched_switch is useless when capturing data per-thread, as is the 'context-switches' software event for the same reason. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-9-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 45 +++++++++++++++++++++++++++++++++------- tools/perf/util/evsel.c | 31 ++++++++++++++++++++++----- tools/perf/util/evsel.h | 1 + 3 files changed, 64 insertions(+), 13 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3b366c085021..c74d8ecc9c70 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -265,17 +265,27 @@ int perf_evlist__add_newtp(struct perf_evlist *evlist, return 0; } +static int perf_evlist__nr_threads(struct perf_evlist *evlist, + struct perf_evsel *evsel) +{ + if (evsel->system_wide) + return 1; + else + return thread_map__nr(evlist->threads); +} + void perf_evlist__disable(struct perf_evlist *evlist) { int cpu, thread; struct perf_evsel *pos; int nr_cpus = cpu_map__nr(evlist->cpus); - int nr_threads = thread_map__nr(evlist->threads); + int nr_threads; for (cpu = 0; cpu < nr_cpus; cpu++) { evlist__for_each(evlist, pos) { if (!perf_evsel__is_group_leader(pos) || !pos->fd) continue; + nr_threads = perf_evlist__nr_threads(evlist, pos); for (thread = 0; thread < nr_threads; thread++) ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_DISABLE, 0); @@ -288,12 +298,13 @@ void perf_evlist__enable(struct perf_evlist *evlist) int cpu, thread; struct perf_evsel *pos; int nr_cpus = cpu_map__nr(evlist->cpus); - int nr_threads = thread_map__nr(evlist->threads); + int nr_threads; for (cpu = 0; cpu < nr_cpus; cpu++) { evlist__for_each(evlist, pos) { if (!perf_evsel__is_group_leader(pos) || !pos->fd) continue; + nr_threads = perf_evlist__nr_threads(evlist, pos); for (thread = 0; thread < nr_threads; thread++) ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); @@ -305,12 +316,14 @@ int perf_evlist__disable_event(struct perf_evlist *evlist, struct perf_evsel *evsel) { int cpu, thread, err; + int nr_cpus = cpu_map__nr(evlist->cpus); + int nr_threads = perf_evlist__nr_threads(evlist, evsel); if (!evsel->fd) return 0; - for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { - for (thread = 0; thread < evlist->threads->nr; thread++) { + for (cpu = 0; cpu < nr_cpus; cpu++) { + for (thread = 0; thread < nr_threads; thread++) { err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_DISABLE, 0); if (err) @@ -324,12 +337,14 @@ int perf_evlist__enable_event(struct perf_evlist *evlist, struct perf_evsel *evsel) { int cpu, thread, err; + int nr_cpus = cpu_map__nr(evlist->cpus); + int nr_threads = perf_evlist__nr_threads(evlist, evsel); if (!evsel->fd) return -EINVAL; - for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { - for (thread = 0; thread < evlist->threads->nr; thread++) { + for (cpu = 0; cpu < nr_cpus; cpu++) { + for (thread = 0; thread < nr_threads; thread++) { err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); if (err) @@ -343,7 +358,16 @@ static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) { int nr_cpus = cpu_map__nr(evlist->cpus); int nr_threads = thread_map__nr(evlist->threads); - int nfds = nr_cpus * nr_threads * evlist->nr_entries; + int nfds = 0; + struct perf_evsel *evsel; + + list_for_each_entry(evsel, &evlist->entries, node) { + if (evsel->system_wide) + nfds += nr_cpus; + else + nfds += nr_cpus * nr_threads; + } + evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); return evlist->pollfd != NULL ? 0 : -ENOMEM; } @@ -636,7 +660,12 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx, struct perf_evsel *evsel; evlist__for_each(evlist, evsel) { - int fd = FD(evsel, cpu, thread); + int fd; + + if (evsel->system_wide && thread) + continue; + + fd = FD(evsel, cpu, thread); if (*output == -1) { *output = fd; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0c8919decac8..66de9a708163 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -695,6 +695,10 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) { int cpu, thread; + + if (evsel->system_wide) + nthreads = 1; + evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int)); if (evsel->fd) { @@ -713,6 +717,9 @@ static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthrea { int cpu, thread; + if (evsel->system_wide) + nthreads = 1; + for (cpu = 0; cpu < ncpus; cpu++) { for (thread = 0; thread < nthreads; thread++) { int fd = FD(evsel, cpu, thread), @@ -743,6 +750,9 @@ int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads) int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads) { + if (evsel->system_wide) + nthreads = 1; + evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id)); if (evsel->sample_id == NULL) return -ENOMEM; @@ -787,6 +797,9 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads) { int cpu, thread; + if (evsel->system_wide) + nthreads = 1; + for (cpu = 0; cpu < ncpus; cpu++) for (thread = 0; thread < nthreads; ++thread) { close(FD(evsel, cpu, thread)); @@ -875,6 +888,9 @@ int __perf_evsel__read(struct perf_evsel *evsel, int cpu, thread; struct perf_counts_values *aggr = &evsel->counts->aggr, count; + if (evsel->system_wide) + nthreads = 1; + aggr->val = aggr->ena = aggr->run = 0; for (cpu = 0; cpu < ncpus; cpu++) { @@ -997,13 +1013,18 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp) static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, struct thread_map *threads) { - int cpu, thread; + int cpu, thread, nthreads; unsigned long flags = PERF_FLAG_FD_CLOEXEC; int pid = -1, err; enum { NO_CHANGE, SET_TO_MAX, INCREASED_MAX } set_rlimit = NO_CHANGE; + if (evsel->system_wide) + nthreads = 1; + else + nthreads = threads->nr; + if (evsel->fd == NULL && - perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0) + perf_evsel__alloc_fd(evsel, cpus->nr, nthreads) < 0) return -ENOMEM; if (evsel->cgrp) { @@ -1027,10 +1048,10 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, for (cpu = 0; cpu < cpus->nr; cpu++) { - for (thread = 0; thread < threads->nr; thread++) { + for (thread = 0; thread < nthreads; thread++) { int group_fd; - if (!evsel->cgrp) + if (!evsel->cgrp && !evsel->system_wide) pid = threads->map[thread]; group_fd = get_group_fd(evsel, cpu, thread); @@ -1103,7 +1124,7 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, close(FD(evsel, cpu, thread)); FD(evsel, cpu, thread) = -1; } - thread = threads->nr; + thread = nthreads; } while (--cpu >= 0); return err; } diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d7f93ce0ebc1..dbb2a0d20907 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -85,6 +85,7 @@ struct perf_evsel { bool needs_swap; bool no_aux_samples; bool immediate; + bool system_wide; /* parse modifier helper */ int exclude_GH; int nr_members; -- GitLab From 60b0896cc35243f515eda2085f9897e296177e45 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:00:52 +0300 Subject: [PATCH 0343/9167] perf evlist: Add perf_evlist__set_tracking_event() Add a function to change which event is used to track mmap, comm and task events. This is needed with Instruction Tracing because the Instruction Tracing event must come first but cannot be used for tracking because it will be disabled under some circumstances. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-10-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 17 +++++++++++++++++ tools/perf/util/evlist.h | 3 +++ tools/perf/util/evsel.c | 3 ++- tools/perf/util/evsel.h | 1 + tools/perf/util/record.c | 2 +- 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index c74d8ecc9c70..9d863db3f4b2 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -122,6 +122,7 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) { list_add_tail(&entry->node, &evlist->entries); entry->idx = evlist->nr_entries; + entry->tracking = !entry->idx; if (!evlist->nr_entries++) perf_evlist__set_id_pos(evlist); @@ -1295,3 +1296,19 @@ void perf_evlist__to_front(struct perf_evlist *evlist, list_splice(&move, &evlist->entries); } + +void perf_evlist__set_tracking_event(struct perf_evlist *evlist, + struct perf_evsel *tracking_evsel) +{ + struct perf_evsel *evsel; + + if (tracking_evsel->tracking) + return; + + evlist__for_each(evlist, evsel) { + if (evsel != tracking_evsel) + evsel->tracking = false; + } + + tracking_evsel->tracking = true; +} diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index f5173cd63693..e0084f90c271 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -262,4 +262,7 @@ void perf_evlist__to_front(struct perf_evlist *evlist, #define evlist__for_each_safe(evlist, tmp, evsel) \ __evlist__for_each_safe(&(evlist)->entries, tmp, evsel) +void perf_evlist__set_tracking_event(struct perf_evlist *evlist, + struct perf_evsel *tracking_evsel); + #endif /* __PERF_EVLIST_H */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 66de9a708163..01ce14c3575e 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -162,6 +162,7 @@ void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr, int idx) { evsel->idx = idx; + evsel->tracking = !idx; evsel->attr = *attr; evsel->leader = evsel; evsel->unit = ""; @@ -561,7 +562,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) { struct perf_evsel *leader = evsel->leader; struct perf_event_attr *attr = &evsel->attr; - int track = !evsel->idx; /* only the first counter needs these */ + int track = evsel->tracking; bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread; attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index dbb2a0d20907..7bc314be6a7b 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -86,6 +86,7 @@ struct perf_evsel { bool no_aux_samples; bool immediate; bool system_wide; + bool tracking; /* parse modifier helper */ int exclude_GH; int nr_members; diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c index e778afda0fb9..cf69325b985f 100644 --- a/tools/perf/util/record.c +++ b/tools/perf/util/record.c @@ -115,7 +115,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts) evlist__for_each(evlist, evsel) { perf_evsel__config(evsel, opts); - if (!evsel->idx && use_comm_exec) + if (evsel->tracking && use_comm_exec) evsel->attr.comm_exec = 1; } -- GitLab From 5a52f33adf02a3e5eafdc1e597a3fe172e620bec Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:00:57 +0300 Subject: [PATCH 0344/9167] perf session: Add perf_session__peek_event() Add a function to peek at other events in the event stream. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-15-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/session.c | 55 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/session.h | 5 ++++ 2 files changed, 60 insertions(+) diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 7e27f1eb260c..1b383bd93af6 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -897,6 +897,61 @@ static void event_swap(union perf_event *event, bool sample_id_all) swap(event, sample_id_all); } +int perf_session__peek_event(struct perf_session *session, off_t file_offset, + void *buf, size_t buf_sz, + union perf_event **event_ptr, + struct perf_sample *sample) +{ + union perf_event *event; + size_t hdr_sz, rest; + int fd; + + if (session->one_mmap && !session->header.needs_swap) { + event = file_offset - session->one_mmap_offset + + session->one_mmap_addr; + goto out_parse_sample; + } + + if (perf_data_file__is_pipe(session->file)) + return -1; + + fd = perf_data_file__fd(session->file); + hdr_sz = sizeof(struct perf_event_header); + + if (buf_sz < hdr_sz) + return -1; + + if (lseek(fd, file_offset, SEEK_SET) == (off_t)-1 || + readn(fd, &buf, hdr_sz) != (ssize_t)hdr_sz) + return -1; + + event = (union perf_event *)buf; + + if (session->header.needs_swap) + perf_event_header__bswap(&event->header); + + if (event->header.size < hdr_sz) + return -1; + + rest = event->header.size - hdr_sz; + + if (readn(fd, &buf, rest) != (ssize_t)rest) + return -1; + + if (session->header.needs_swap) + event_swap(event, perf_evlist__sample_id_all(session->evlist)); + +out_parse_sample: + + if (sample && event->header.type < PERF_RECORD_USER_TYPE_START && + perf_evlist__parse_sample(session->evlist, event, sample)) + return -1; + + *event_ptr = event; + + return 0; +} + static s64 perf_session__process_event(struct perf_session *session, union perf_event *event, struct perf_tool *tool, diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 0630e658f8be..8dd41cad2d59 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -45,6 +45,11 @@ void perf_session__delete(struct perf_session *session); void perf_event_header__bswap(struct perf_event_header *hdr); +int perf_session__peek_event(struct perf_session *session, off_t file_offset, + void *buf, size_t buf_sz, + union perf_event **event_ptr, + struct perf_sample *sample); + int __perf_session__process_events(struct perf_session *session, u64 data_offset, u64 data_size, u64 size, struct perf_tool *tool); -- GitLab From 98526ee7229be8537373aebe037b74cac112d84b Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:00:59 +0300 Subject: [PATCH 0345/9167] perf script: Allow callchains if any event samples them perf script was not displaying callchains if any selected event did not have PERF_SAMPLE_CALLCHAIN. Change this to disable callchains only if all selected events do not have PERF_SAMPLE_CALLCHAIN. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-17-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 37d2b608d388..c1b7029884b1 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -184,10 +184,6 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, if (perf_evsel__check_stype(evsel, PERF_SAMPLE_IP, "IP", PERF_OUTPUT_IP)) return -EINVAL; - - if (!no_callchain && - !(attr->sample_type & PERF_SAMPLE_CALLCHAIN)) - symbol_conf.use_callchain = false; } if (PRINT_FIELD(ADDR) && @@ -290,6 +286,19 @@ static int perf_session__check_output_opt(struct perf_session *session) set_print_ip_opts(&evsel->attr); } + if (!no_callchain) { + bool use_callchain = false; + + evlist__for_each(session->evlist, evsel) { + if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) { + use_callchain = true; + break; + } + } + if (!use_callchain) + symbol_conf.use_callchain = false; + } + /* * set default for tracepoints to print symbols only * if callchains are present -- GitLab From a5563edfa1bd25d052d81f5ad7fe74ba71c3d44e Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:01:01 +0300 Subject: [PATCH 0346/9167] perf script python: Add helpers for calling Python objects The Python script API repeatedly uses the same lines of code to get and call objects. Make that into helper functions instead. A side-effect is that some reference counting bugs disappear because the new call_object() function always decrements the reference count of 'retval'. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-19-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- .../scripting-engines/trace-event-python.c | 114 ++++++++---------- 1 file changed, 47 insertions(+), 67 deletions(-) diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index cbce2545da45..26e5f14239ed 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -73,6 +73,35 @@ static void pydict_set_item_string_decref(PyObject *dict, const char *key, PyObj Py_DECREF(val); } +static PyObject *get_handler(const char *handler_name) +{ + PyObject *handler; + + handler = PyDict_GetItemString(main_dict, handler_name); + if (handler && !PyCallable_Check(handler)) + return NULL; + return handler; +} + +static void call_object(PyObject *handler, PyObject *args, const char *die_msg) +{ + PyObject *retval; + + retval = PyObject_CallObject(handler, args); + if (retval == NULL) + handler_call_die(die_msg); + Py_DECREF(retval); +} + +static void try_call_object(const char *handler_name, PyObject *args) +{ + PyObject *handler; + + handler = get_handler(handler_name); + if (handler) + call_object(handler, args, handler_name); +} + static void define_value(enum print_arg_type field_type, const char *ev_name, const char *field_name, @@ -80,7 +109,7 @@ static void define_value(enum print_arg_type field_type, const char *field_str) { const char *handler_name = "define_flag_value"; - PyObject *handler, *t, *retval; + PyObject *t; unsigned long long value; unsigned n = 0; @@ -98,13 +127,7 @@ static void define_value(enum print_arg_type field_type, PyTuple_SetItem(t, n++, PyInt_FromLong(value)); PyTuple_SetItem(t, n++, PyString_FromString(field_str)); - handler = PyDict_GetItemString(main_dict, handler_name); - if (handler && PyCallable_Check(handler)) { - retval = PyObject_CallObject(handler, t); - if (retval == NULL) - handler_call_die(handler_name); - Py_DECREF(retval); - } + try_call_object(handler_name, t); Py_DECREF(t); } @@ -127,7 +150,7 @@ static void define_field(enum print_arg_type field_type, const char *delim) { const char *handler_name = "define_flag_field"; - PyObject *handler, *t, *retval; + PyObject *t; unsigned n = 0; if (field_type == PRINT_SYMBOL) @@ -145,13 +168,7 @@ static void define_field(enum print_arg_type field_type, if (field_type == PRINT_FLAGS) PyTuple_SetItem(t, n++, PyString_FromString(delim)); - handler = PyDict_GetItemString(main_dict, handler_name); - if (handler && PyCallable_Check(handler)) { - retval = PyObject_CallObject(handler, t); - if (retval == NULL) - handler_call_die(handler_name); - Py_DECREF(retval); - } + try_call_object(handler_name, t); Py_DECREF(t); } @@ -362,7 +379,7 @@ static void python_process_tracepoint(struct perf_sample *sample, struct thread *thread, struct addr_location *al) { - PyObject *handler, *retval, *context, *t, *obj, *callchain; + PyObject *handler, *context, *t, *obj, *callchain; PyObject *dict = NULL; static char handler_name[256]; struct format_field *field; @@ -387,9 +404,7 @@ static void python_process_tracepoint(struct perf_sample *sample, sprintf(handler_name, "%s__%s", event->system, event->name); - handler = PyDict_GetItemString(main_dict, handler_name); - if (handler && !PyCallable_Check(handler)) - handler = NULL; + handler = get_handler(handler_name); if (!handler) { dict = PyDict_New(); if (!dict) @@ -450,19 +465,9 @@ static void python_process_tracepoint(struct perf_sample *sample, Py_FatalError("error resizing Python tuple"); if (handler) { - retval = PyObject_CallObject(handler, t); - if (retval == NULL) - handler_call_die(handler_name); - Py_DECREF(retval); + call_object(handler, t, handler_name); } else { - handler = PyDict_GetItemString(main_dict, "trace_unhandled"); - if (handler && PyCallable_Check(handler)) { - - retval = PyObject_CallObject(handler, t); - if (retval == NULL) - handler_call_die("trace_unhandled"); - Py_DECREF(retval); - } + try_call_object("trace_unhandled", t); Py_DECREF(dict); } @@ -474,7 +479,7 @@ static void python_process_general_event(struct perf_sample *sample, struct thread *thread, struct addr_location *al) { - PyObject *handler, *retval, *t, *dict, *callchain, *dict_sample; + PyObject *handler, *t, *dict, *callchain, *dict_sample; static char handler_name[64]; unsigned n = 0; @@ -496,8 +501,8 @@ static void python_process_general_event(struct perf_sample *sample, snprintf(handler_name, sizeof(handler_name), "%s", "process_event"); - handler = PyDict_GetItemString(main_dict, handler_name); - if (!handler || !PyCallable_Check(handler)) + handler = get_handler(handler_name); + if (!handler) goto exit; pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel))); @@ -539,10 +544,7 @@ static void python_process_general_event(struct perf_sample *sample, if (_PyTuple_Resize(&t, n) == -1) Py_FatalError("error resizing Python tuple"); - retval = PyObject_CallObject(handler, t); - if (retval == NULL) - handler_call_die(handler_name); - Py_DECREF(retval); + call_object(handler, t, handler_name); exit: Py_DECREF(dict); Py_DECREF(t); @@ -566,36 +568,24 @@ static void python_process_event(union perf_event *event __maybe_unused, static int run_start_sub(void) { - PyObject *handler, *retval; - int err = 0; - main_module = PyImport_AddModule("__main__"); if (main_module == NULL) return -1; Py_INCREF(main_module); main_dict = PyModule_GetDict(main_module); - if (main_dict == NULL) { - err = -1; + if (main_dict == NULL) goto error; - } Py_INCREF(main_dict); - handler = PyDict_GetItemString(main_dict, "trace_begin"); - if (handler == NULL || !PyCallable_Check(handler)) - goto out; + try_call_object("trace_begin", NULL); - retval = PyObject_CallObject(handler, NULL); - if (retval == NULL) - handler_call_die("trace_begin"); + return 0; - Py_DECREF(retval); - return err; error: Py_XDECREF(main_dict); Py_XDECREF(main_module); -out: - return err; + return -1; } /* @@ -654,23 +644,13 @@ static int python_start_script(const char *script, int argc, const char **argv) */ static int python_stop_script(void) { - PyObject *handler, *retval; - int err = 0; + try_call_object("trace_end", NULL); - handler = PyDict_GetItemString(main_dict, "trace_end"); - if (handler == NULL || !PyCallable_Check(handler)) - goto out; - - retval = PyObject_CallObject(handler, NULL); - if (retval == NULL) - handler_call_die("trace_end"); - Py_DECREF(retval); -out: Py_XDECREF(main_dict); Py_XDECREF(main_module); Py_Finalize(); - return err; + return 0; } static int python_generate_script(struct pevent *pevent, const char *outfile) -- GitLab From 65de51f93ebf9305ec011da59c0b5fe29429d1b9 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:00:44 +0300 Subject: [PATCH 0347/9167] perf tools: Identify which comms are from exec For grouping together all the data from a single execution, which is needed for pairing calls and returns e.g. any outstanding calls when a process exec's will never return. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-2-git-send-email-adrian.hunter@intel.com [ Remove testing if comm->exec is false before setting it to true ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/comm.c | 7 +++++-- tools/perf/util/comm.h | 6 ++++-- tools/perf/util/machine.c | 4 +++- tools/perf/util/thread.c | 24 +++++++++++++++++++----- tools/perf/util/thread.h | 10 +++++++++- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/tools/perf/util/comm.c b/tools/perf/util/comm.c index f9e777629e21..b2bb59df65e1 100644 --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c @@ -74,7 +74,7 @@ static struct comm_str *comm_str__findnew(const char *str, struct rb_root *root) return new; } -struct comm *comm__new(const char *str, u64 timestamp) +struct comm *comm__new(const char *str, u64 timestamp, bool exec) { struct comm *comm = zalloc(sizeof(*comm)); @@ -82,6 +82,7 @@ struct comm *comm__new(const char *str, u64 timestamp) return NULL; comm->start = timestamp; + comm->exec = exec; comm->comm_str = comm_str__findnew(str, &comm_str_root); if (!comm->comm_str) { @@ -94,7 +95,7 @@ struct comm *comm__new(const char *str, u64 timestamp) return comm; } -int comm__override(struct comm *comm, const char *str, u64 timestamp) +int comm__override(struct comm *comm, const char *str, u64 timestamp, bool exec) { struct comm_str *new, *old = comm->comm_str; @@ -106,6 +107,8 @@ int comm__override(struct comm *comm, const char *str, u64 timestamp) comm_str__put(old); comm->comm_str = new; comm->start = timestamp; + if (exec) + comm->exec = true; return 0; } diff --git a/tools/perf/util/comm.h b/tools/perf/util/comm.h index fac5bd51befc..51c10ab257f8 100644 --- a/tools/perf/util/comm.h +++ b/tools/perf/util/comm.h @@ -11,11 +11,13 @@ struct comm { struct comm_str *comm_str; u64 start; struct list_head list; + bool exec; }; void comm__free(struct comm *comm); -struct comm *comm__new(const char *str, u64 timestamp); +struct comm *comm__new(const char *str, u64 timestamp, bool exec); const char *comm__str(const struct comm *comm); -int comm__override(struct comm *comm, const char *str, u64 timestamp); +int comm__override(struct comm *comm, const char *str, u64 timestamp, + bool exec); #endif /* __PERF_COMM_H */ diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 16bba9fff2c8..ea3e09f6a9c6 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -404,11 +404,13 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event struct thread *thread = machine__findnew_thread(machine, event->comm.pid, event->comm.tid); + bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC; if (dump_trace) perf_event__fprintf_comm(event, stdout); - if (thread == NULL || thread__set_comm(thread, event->comm.comm, sample->time)) { + if (thread == NULL || + __thread__set_comm(thread, event->comm.comm, sample->time, exec)) { dump_printf("problem processing PERF_RECORD_COMM, skipping event.\n"); return -1; } diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index 12c7a253a63c..a9df7f2c6dc9 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -42,7 +42,7 @@ struct thread *thread__new(pid_t pid, pid_t tid) goto err_thread; snprintf(comm_str, 32, ":%d", tid); - comm = comm__new(comm_str, 0); + comm = comm__new(comm_str, 0, false); free(comm_str); if (!comm) goto err_thread; @@ -81,19 +81,33 @@ struct comm *thread__comm(const struct thread *thread) return list_first_entry(&thread->comm_list, struct comm, list); } +struct comm *thread__exec_comm(const struct thread *thread) +{ + struct comm *comm, *last = NULL; + + list_for_each_entry(comm, &thread->comm_list, list) { + if (comm->exec) + return comm; + last = comm; + } + + return last; +} + /* CHECKME: time should always be 0 if event aren't ordered */ -int thread__set_comm(struct thread *thread, const char *str, u64 timestamp) +int __thread__set_comm(struct thread *thread, const char *str, u64 timestamp, + bool exec) { struct comm *new, *curr = thread__comm(thread); int err; /* Override latest entry if it had no specific time coverage */ - if (!curr->start) { - err = comm__override(curr, str, timestamp); + if (!curr->start && !curr->exec) { + err = comm__override(curr, str, timestamp, exec); if (err) return err; } else { - new = comm__new(str, timestamp); + new = comm__new(str, timestamp, exec); if (!new) return -ENOMEM; list_add(&new->list, &thread->comm_list); diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 716b7723cce2..8c75fa774706 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -38,9 +38,17 @@ static inline void thread__exited(struct thread *thread) thread->dead = true; } -int thread__set_comm(struct thread *thread, const char *comm, u64 timestamp); +int __thread__set_comm(struct thread *thread, const char *comm, u64 timestamp, + bool exec); +static inline int thread__set_comm(struct thread *thread, const char *comm, + u64 timestamp) +{ + return __thread__set_comm(thread, comm, timestamp, false); +} + int thread__comm_len(struct thread *thread); struct comm *thread__comm(const struct thread *thread); +struct comm *thread__exec_comm(const struct thread *thread); const char *thread__comm_str(const struct thread *thread); void thread__insert_map(struct thread *thread, struct map *map); int thread__fork(struct thread *thread, struct thread *parent, u64 timestamp); -- GitLab From cfe1c41405fe9a559f8b3c24c904b2bb42d4a6e8 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:00:45 +0300 Subject: [PATCH 0348/9167] perf machine: Add machine__thread_exec_comm() Add machine__thread_exec_comm() to return the comm that matches the last exec, if the comm_exec flag is present, or the last comm otherwise. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-3-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/machine.c | 26 ++++++++++++++++++++++++++ tools/perf/util/machine.h | 4 ++++ tools/perf/util/session.c | 24 +++++++++++++++++++++++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index ea3e09f6a9c6..b093b93607fb 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -31,6 +31,7 @@ int machine__init(struct machine *machine, const char *root_dir, pid_t pid) machine->symbol_filter = NULL; machine->id_hdr_size = 0; + machine->comm_exec = false; machine->root_dir = strdup(root_dir); if (machine->root_dir == NULL) @@ -179,6 +180,19 @@ void machines__set_symbol_filter(struct machines *machines, } } +void machines__set_comm_exec(struct machines *machines, bool comm_exec) +{ + struct rb_node *nd; + + machines->host.comm_exec = comm_exec; + + for (nd = rb_first(&machines->guests); nd; nd = rb_next(nd)) { + struct machine *machine = rb_entry(nd, struct machine, rb_node); + + machine->comm_exec = comm_exec; + } +} + struct machine *machines__find(struct machines *machines, pid_t pid) { struct rb_node **p = &machines->guests.rb_node; @@ -398,6 +412,15 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid, return __machine__findnew_thread(machine, pid, tid, false); } +struct comm *machine__thread_exec_comm(struct machine *machine, + struct thread *thread) +{ + if (machine->comm_exec) + return thread__exec_comm(thread); + else + return thread__comm(thread); +} + int machine__process_comm_event(struct machine *machine, union perf_event *event, struct perf_sample *sample) { @@ -406,6 +429,9 @@ int machine__process_comm_event(struct machine *machine, union perf_event *event event->comm.tid); bool exec = event->header.misc & PERF_RECORD_MISC_COMM_EXEC; + if (exec) + machine->comm_exec = true; + if (dump_trace) perf_event__fprintf_comm(event, stdout); diff --git a/tools/perf/util/machine.h b/tools/perf/util/machine.h index b972824e6294..61216e028319 100644 --- a/tools/perf/util/machine.h +++ b/tools/perf/util/machine.h @@ -26,6 +26,7 @@ struct machine { struct rb_node rb_node; pid_t pid; u16 id_hdr_size; + bool comm_exec; char *root_dir; struct rb_root threads; struct list_head dead_threads; @@ -47,6 +48,8 @@ struct map *machine__kernel_map(struct machine *machine, enum map_type type) struct thread *machine__find_thread(struct machine *machine, pid_t pid, pid_t tid); +struct comm *machine__thread_exec_comm(struct machine *machine, + struct thread *thread); int machine__process_comm_event(struct machine *machine, union perf_event *event, struct perf_sample *sample); @@ -88,6 +91,7 @@ char *machine__mmap_name(struct machine *machine, char *bf, size_t size); void machines__set_symbol_filter(struct machines *machines, symbol_filter_t symbol_filter); +void machines__set_comm_exec(struct machines *machines, bool comm_exec); struct machine *machine__new_host(void); int machine__init(struct machine *machine, const char *root_dir, pid_t pid); diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 1b383bd93af6..6d2d50dea1d8 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -67,6 +67,25 @@ static void perf_session__destroy_kernel_maps(struct perf_session *session) machines__destroy_kernel_maps(&session->machines); } +static bool perf_session__has_comm_exec(struct perf_session *session) +{ + struct perf_evsel *evsel; + + evlist__for_each(session->evlist, evsel) { + if (evsel->attr.comm_exec) + return true; + } + + return false; +} + +static void perf_session__set_comm_exec(struct perf_session *session) +{ + bool comm_exec = perf_session__has_comm_exec(session); + + machines__set_comm_exec(&session->machines, comm_exec); +} + struct perf_session *perf_session__new(struct perf_data_file *file, bool repipe, struct perf_tool *tool) { @@ -90,6 +109,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file, goto out_close; perf_session__set_id_hdr_size(session); + perf_session__set_comm_exec(session); } } @@ -866,8 +886,10 @@ static s64 perf_session__process_user_event(struct perf_session *session, switch (event->header.type) { case PERF_RECORD_HEADER_ATTR: err = tool->attr(tool, event, &session->evlist); - if (err == 0) + if (err == 0) { perf_session__set_id_hdr_size(session); + perf_session__set_comm_exec(session); + } return err; case PERF_RECORD_HEADER_EVENT_TYPE: /* -- GitLab From bf4939027decde7aaaf8b5dbeee70126d2822eb6 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:01:04 +0300 Subject: [PATCH 0349/9167] perf tools: Add flags and insn_len to struct sample The flags will be used to export branch type and transaction status. insn_len is preparation for pairing calls and returns because the return address equals the call address plus the instruction length (insn_len). Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-22-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/event.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 94d6976180da..7eb7107731ec 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -156,6 +156,8 @@ struct perf_sample { u32 cpu; u32 raw_size; u64 data_src; + u32 flags; + u16 insn_len; void *raw_data; struct ip_callchain *callchain; struct branch_stack *branch_stack; -- GitLab From 1c65056c547141a0cb52fb8e6056f63524d2bbf2 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Thu, 31 Jul 2014 09:00:56 +0300 Subject: [PATCH 0350/9167] perf evlist: Add perf_evlist__enable_event_idx() Add a function to enable a specific event within a specific perf event buffer. Signed-off-by: Adrian Hunter Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1406786474-9306-14-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/evlist.c | 47 ++++++++++++++++++++++++++++++++++++++++ tools/perf/util/evlist.h | 2 ++ 2 files changed, 49 insertions(+) diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 9d863db3f4b2..5dcd28c79c6e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -355,6 +355,53 @@ int perf_evlist__enable_event(struct perf_evlist *evlist, return 0; } +static int perf_evlist__enable_event_cpu(struct perf_evlist *evlist, + struct perf_evsel *evsel, int cpu) +{ + int thread, err; + int nr_threads = perf_evlist__nr_threads(evlist, evsel); + + if (!evsel->fd) + return -EINVAL; + + for (thread = 0; thread < nr_threads; thread++) { + err = ioctl(FD(evsel, cpu, thread), + PERF_EVENT_IOC_ENABLE, 0); + if (err) + return err; + } + return 0; +} + +static int perf_evlist__enable_event_thread(struct perf_evlist *evlist, + struct perf_evsel *evsel, + int thread) +{ + int cpu, err; + int nr_cpus = cpu_map__nr(evlist->cpus); + + if (!evsel->fd) + return -EINVAL; + + for (cpu = 0; cpu < nr_cpus; cpu++) { + err = ioctl(FD(evsel, cpu, thread), PERF_EVENT_IOC_ENABLE, 0); + if (err) + return err; + } + return 0; +} + +int perf_evlist__enable_event_idx(struct perf_evlist *evlist, + struct perf_evsel *evsel, int idx) +{ + bool per_cpu_mmaps = !cpu_map__empty(evlist->cpus); + + if (per_cpu_mmaps) + return perf_evlist__enable_event_cpu(evlist, evsel, idx); + else + return perf_evlist__enable_event_thread(evlist, evsel, idx); +} + static int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) { int nr_cpus = cpu_map__nr(evlist->cpus); diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index e0084f90c271..106de53a6a74 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -122,6 +122,8 @@ int perf_evlist__disable_event(struct perf_evlist *evlist, struct perf_evsel *evsel); int perf_evlist__enable_event(struct perf_evlist *evlist, struct perf_evsel *evsel); +int perf_evlist__enable_event_idx(struct perf_evlist *evlist, + struct perf_evsel *evsel, int idx); void perf_evlist__set_selected(struct perf_evlist *evlist, struct perf_evsel *evsel); -- GitLab From 84c61d92bb6e9048eecc0738a83f1bf66f053026 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 1 Aug 2014 11:13:30 +0300 Subject: [PATCH 0351/9167] Bluetooth: Add convenience function to check for pending power off There are several situations where we're interested in knowing whether we're currently in the process of powering off an adapter. This patch adds a convenience function for the purpose and makes it public since we'll soon need to access it from hci_event.c as well. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/mgmt.c | 52 +++++++++++++++++--------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b5d5af3aa469..8394abc4fd87 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -1351,6 +1351,7 @@ void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, s8 rssi, u8 *name, u8 name_len); void mgmt_discovering(struct hci_dev *hdev, u8 discovering); +bool mgmt_powering_down(struct hci_dev *hdev); void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent); void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk); void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index b8554d429d88..c9de0d9945f5 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -6281,25 +6281,35 @@ static void unpair_device_rsp(struct pending_cmd *cmd, void *data) mgmt_pending_remove(cmd); } +bool mgmt_powering_down(struct hci_dev *hdev) +{ + struct pending_cmd *cmd; + struct mgmt_mode *cp; + + cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); + if (!cmd) + return false; + + cp = cmd->param; + if (!cp->val) + return true; + + return false; +} + void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 reason, bool mgmt_connected) { struct mgmt_ev_device_disconnected ev; - struct pending_cmd *power_off; struct sock *sk = NULL; - power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); - if (power_off) { - struct mgmt_mode *cp = power_off->param; - - /* The connection is still in hci_conn_hash so test for 1 - * instead of 0 to know if this is the last one. - */ - if (!cp->val && hci_conn_count(hdev) == 1) { - cancel_delayed_work(&hdev->power_off); - queue_work(hdev->req_workqueue, &hdev->power_off.work); - } + /* The connection is still in hci_conn_hash so test for 1 + * instead of 0 to know if this is the last one. + */ + if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) { + cancel_delayed_work(&hdev->power_off); + queue_work(hdev->req_workqueue, &hdev->power_off.work); } if (!mgmt_connected) @@ -6359,19 +6369,13 @@ void mgmt_connect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status) { struct mgmt_ev_connect_failed ev; - struct pending_cmd *power_off; - - power_off = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); - if (power_off) { - struct mgmt_mode *cp = power_off->param; - /* The connection is still in hci_conn_hash so test for 1 - * instead of 0 to know if this is the last one. - */ - if (!cp->val && hci_conn_count(hdev) == 1) { - cancel_delayed_work(&hdev->power_off); - queue_work(hdev->req_workqueue, &hdev->power_off.work); - } + /* The connection is still in hci_conn_hash so test for 1 + * instead of 0 to know if this is the last one. + */ + if (mgmt_powering_down(hdev) && hci_conn_count(hdev) == 1) { + cancel_delayed_work(&hdev->power_off); + queue_work(hdev->req_workqueue, &hdev->power_off.work); } bacpy(&ev.addr.bdaddr, bdaddr); -- GitLab From 432df05eb1e57adfc46df08abbedca6c3b8862f7 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 1 Aug 2014 11:13:31 +0300 Subject: [PATCH 0352/9167] Bluetooth: Create unified helper function for updating page scan Similar to our hci_update_background_scan() function we can simplify a lot of code by creating a unified helper function for doing page scan updates. This patch adds such a function to hci_core.c and updates all the relevant places to use it. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 5 +++ net/bluetooth/hci_core.c | 31 ++++++++++++++ net/bluetooth/mgmt.c | 72 ++++++-------------------------- 3 files changed, 48 insertions(+), 60 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 8394abc4fd87..cc2eb7730fbc 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -968,6 +968,9 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE)) #define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR)) +#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ + !test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) + /* ----- HCI protocols ----- */ #define HCI_PROTO_DEFER 0x01 @@ -1256,6 +1259,8 @@ bool hci_req_pending(struct hci_dev *hdev); void hci_req_add_le_scan_disable(struct hci_request *req); void hci_req_add_le_passive_scan(struct hci_request *req); +void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req); + struct sk_buff *__hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, const void *param, u32 timeout); struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen, diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index c32d361c0cf7..a031589598b2 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -5680,3 +5680,34 @@ void hci_update_background_scan(struct hci_dev *hdev) if (err) BT_ERR("Failed to run HCI request: err %d", err); } + +void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req) +{ + u8 scan; + + if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) + return; + + if (!hdev_is_powered(hdev)) + return; + + if (mgmt_powering_down(hdev)) + return; + + if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || + !list_empty(&hdev->whitelist)) + scan = SCAN_PAGE; + else + scan = SCAN_DISABLED; + + if (test_bit(HCI_PSCAN, &hdev->flags) == !!(scan & SCAN_PAGE)) + return; + + if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) + scan |= SCAN_INQUIRY; + + if (req) + hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); + else + hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); +} diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index c9de0d9945f5..c2457435a670 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -129,9 +129,6 @@ static const u16 mgmt_events[] = { #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) -#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ - !test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) - struct pending_cmd { struct list_head list; u16 opcode; @@ -1536,9 +1533,11 @@ static void set_discoverable_complete(struct hci_dev *hdev, u8 status) /* When the discoverable mode gets changed, make sure * that class of device has the limited discoverable - * bit correctly set. + * bit correctly set. Also update page scan based on whitelist + * entries. */ hci_req_init(&req, hdev); + hci_update_page_scan(hdev, &req); update_class(&req); hci_req_run(&req, NULL); @@ -1785,6 +1784,7 @@ static void set_connectable_complete(struct hci_dev *hdev, u8 status) if (conn_changed || discov_changed) { new_settings(hdev, cmd->sk); + hci_update_page_scan(hdev, NULL); if (discov_changed) mgmt_update_adv_data(hdev); hci_update_background_scan(hdev); @@ -1818,6 +1818,7 @@ static int set_connectable_update_settings(struct hci_dev *hdev, return err; if (changed) { + hci_update_page_scan(hdev, NULL); hci_update_background_scan(hdev); return new_settings(hdev, sk); } @@ -4381,27 +4382,6 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, return err; } -static void set_bredr_scan(struct hci_request *req) -{ - struct hci_dev *hdev = req->hdev; - u8 scan = 0; - - /* Ensure that fast connectable is disabled. This function will - * not do anything if the page scan parameters are already what - * they should be. - */ - write_fast_connectable(req, false); - - if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || - !list_empty(&hdev->whitelist)) - scan |= SCAN_PAGE; - if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) - scan |= SCAN_INQUIRY; - - if (scan) - hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); -} - static void set_bredr_complete(struct hci_dev *hdev, u8 status) { struct pending_cmd *cmd; @@ -4507,9 +4487,8 @@ static int set_bredr(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) hci_req_init(&req, hdev); - if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || - !list_empty(&hdev->whitelist)) - set_bredr_scan(&req); + write_fast_connectable(&req, false); + hci_update_page_scan(hdev, &req); /* Since only the advertising data flags will change, there * is no need to update the scan response data. @@ -5235,27 +5214,6 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data, return err; } -/* Helper for Add/Remove Device commands */ -static void update_page_scan(struct hci_dev *hdev, u8 scan) -{ - if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) - return; - - if (!hdev_is_powered(hdev)) - return; - - /* If HCI_CONNECTABLE is set then Add/Remove Device should not - * make any changes to page scanning. - */ - if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) - return; - - if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) - scan |= SCAN_INQUIRY; - - hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); -} - static void device_added(struct sock *sk, struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type, u8 action) { @@ -5291,8 +5249,6 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, hci_dev_lock(hdev); if (cp->addr.type == BDADDR_BREDR) { - bool update_scan; - /* Only incoming connections action is supported for now */ if (cp->action != 0x01) { err = cmd_complete(sk, hdev->id, MGMT_OP_ADD_DEVICE, @@ -5301,15 +5257,12 @@ static int add_device(struct sock *sk, struct hci_dev *hdev, goto unlock; } - update_scan = list_empty(&hdev->whitelist); - err = hci_bdaddr_list_add(&hdev->whitelist, &cp->addr.bdaddr, cp->addr.type); if (err) goto unlock; - if (update_scan) - update_page_scan(hdev, SCAN_PAGE); + hci_update_page_scan(hdev, NULL); goto added; } @@ -5392,8 +5345,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, goto unlock; } - if (list_empty(&hdev->whitelist)) - update_page_scan(hdev, SCAN_DISABLED); + hci_update_page_scan(hdev, NULL); device_removed(sk, hdev, &cp->addr.bdaddr, cp->addr.type); @@ -5444,7 +5396,7 @@ static int remove_device(struct sock *sk, struct hci_dev *hdev, kfree(b); } - update_page_scan(hdev, SCAN_DISABLED); + hci_update_page_scan(hdev, NULL); list_for_each_entry_safe(p, tmp, &hdev->le_conn_params, list) { if (p->auto_connect == HCI_AUTO_CONN_DISABLED) @@ -5969,8 +5921,8 @@ static int powered_update_hci(struct hci_dev *hdev) sizeof(link_sec), &link_sec); if (lmp_bredr_capable(hdev)) { - if (test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) - set_bredr_scan(&req); + write_fast_connectable(&req, false); + hci_update_page_scan(hdev, &req); update_class(&req); update_name(&req); update_eir(&req); -- GitLab From 22f433dcf7c71cf075e4c42b5f36ea4352978a6d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 1 Aug 2014 11:13:32 +0300 Subject: [PATCH 0353/9167] Bluetooth: Disable page scan if all whitelisted devices are connected When we're not connectable and all whitelisted (BR/EDR) devices are connected it doesn't make sense to keep page scan enabled. This patch adds code to check for any disconnected whitelist devices and if there are none take the appropriate action in the hci_update_page_scan() function to disable page scan. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 20 +++++++++++++++++++- net/bluetooth/hci_event.c | 11 ++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index a031589598b2..217ef83fb541 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -5681,6 +5681,24 @@ void hci_update_background_scan(struct hci_dev *hdev) BT_ERR("Failed to run HCI request: err %d", err); } +static bool disconnected_whitelist_entries(struct hci_dev *hdev) +{ + struct bdaddr_list *b; + + list_for_each_entry(b, &hdev->whitelist, list) { + struct hci_conn *conn; + + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &b->bdaddr); + if (!conn) + return true; + + if (conn->state != BT_CONNECTED && conn->state != BT_CONFIG) + return true; + } + + return false; +} + void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req) { u8 scan; @@ -5695,7 +5713,7 @@ void hci_update_page_scan(struct hci_dev *hdev, struct hci_request *req) return; if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags) || - !list_empty(&hdev->whitelist)) + disconnected_whitelist_entries(hdev)) scan = SCAN_PAGE; else scan = SCAN_DISABLED; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index be35598984d9..da7ab6b9bb69 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -2071,6 +2071,8 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) cp.handle = ev->handle; hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp); + + hci_update_page_scan(hdev, NULL); } /* Set packet type for incoming connection */ @@ -2247,9 +2249,12 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type, reason, mgmt_connected); - if (conn->type == ACL_LINK && - test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) - hci_remove_link_key(hdev, &conn->dst); + if (conn->type == ACL_LINK) { + if (test_bit(HCI_CONN_FLUSH_KEY, &conn->flags)) + hci_remove_link_key(hdev, &conn->dst); + + hci_update_page_scan(hdev, NULL); + } params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); if (params) { -- GitLab From 5fcb93475697911eb239f68241903eb5540803ac Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 10:03:31 +0300 Subject: [PATCH 0354/9167] Bluetooth: Remove redundant check for remote_key_dist In the smp_cmd_sign_info() function the SMP_DIST_SIGN bit is explicitly cleared early on in the function. This means that there's no need to check for it again before calling smp_distribute_keys(). Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index fd3294300803..40db728f044b 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1168,8 +1168,7 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); } smp->csrk = csrk; - if (!(smp->remote_key_dist & SMP_DIST_SIGN)) - smp_distribute_keys(conn); + smp_distribute_keys(conn); hci_dev_unlock(hdev); return 0; -- GitLab From 2b29349044cc2cf74d4c6e23e26cd27977d91353 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 10:03:32 +0300 Subject: [PATCH 0355/9167] Bluetooth: Fix confusion between parent and child channel for 6lowpan The new_connection L2CAP channel callback creates a new channel based on the provided parent channel. The 6lowpan code was confusingly naming the child channel "pchan" and the parent channel "chan". This patch swaps the names. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/6lowpan.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 206b65ccd5b8..35ebe79c87b0 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -772,16 +772,16 @@ static inline void chan_ready_cb(struct l2cap_chan *chan) ifup(dev->netdev); } -static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *chan) +static inline struct l2cap_chan *chan_new_conn_cb(struct l2cap_chan *pchan) { - struct l2cap_chan *pchan; + struct l2cap_chan *chan; - pchan = chan_open(chan); - pchan->ops = chan->ops; + chan = chan_open(pchan); + chan->ops = pchan->ops; BT_DBG("chan %p pchan %p", chan, pchan); - return pchan; + return chan; } static void delete_netdev(struct work_struct *work) -- GitLab From a24cce144b9814a17f46006dbad6056f1f5f481e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:42 +0300 Subject: [PATCH 0356/9167] Bluetooth: Fix reference counting of global L2CAP channels When looking up entries from the global L2CAP channel list there needs to be a guarantee that other code doesn't go and remove the entry after a channel has been returned by the lookup function. This patch makes sure that the channel reference is incremented before the read lock is released in the global channel lookup functions. The patch also adds the corresponding l2cap_chan_put() calls once the channels pointers are no-longer needed. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 46547b920f88..a47a14efd5aa 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1440,6 +1440,7 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, src_match = !bacmp(&c->src, src); dst_match = !bacmp(&c->dst, dst); if (src_match && dst_match) { + l2cap_chan_hold(c); read_unlock(&chan_list_lock); return c; } @@ -1453,6 +1454,9 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, } } + if (c1) + l2cap_chan_hold(c1); + read_unlock(&chan_list_lock); return c1; @@ -1475,13 +1479,13 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) /* Client ATT sockets should override the server one */ if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT)) - return; + goto put; dst_type = bdaddr_type(hcon, hcon->dst_type); /* If device is blocked, do not create a channel for it */ if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type)) - return; + goto put; /* For LE slave connections, make sure the connection interval * is in the range of the minium and maximum interval that has @@ -1517,6 +1521,8 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) clean: l2cap_chan_unlock(pchan); +put: + l2cap_chan_put(pchan); } static void l2cap_conn_ready(struct l2cap_conn *conn) @@ -1794,6 +1800,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, src_match = !bacmp(&c->src, src); dst_match = !bacmp(&c->dst, dst); if (src_match && dst_match) { + l2cap_chan_hold(c); read_unlock(&chan_list_lock); return c; } @@ -1807,6 +1814,9 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, } } + if (c1) + l2cap_chan_hold(c1); + read_unlock(&chan_list_lock); return c1; @@ -3884,6 +3894,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, response: l2cap_chan_unlock(pchan); mutex_unlock(&conn->chan_lock); + l2cap_chan_put(pchan); sendresp: rsp.scid = cpu_to_le16(scid); @@ -5497,6 +5508,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, response_unlock: l2cap_chan_unlock(pchan); mutex_unlock(&conn->chan_lock); + l2cap_chan_put(pchan); if (result == L2CAP_CR_PEND) return 0; @@ -6845,12 +6857,12 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct l2cap_chan *chan; if (hcon->type != ACL_LINK) - goto drop; + goto free_skb; chan = l2cap_global_chan_by_psm(0, psm, &hcon->src, &hcon->dst, ACL_LINK); if (!chan) - goto drop; + goto free_skb; BT_DBG("chan %p, len %d", chan, skb->len); @@ -6864,10 +6876,14 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, bacpy(&bt_cb(skb)->bdaddr, &hcon->dst); bt_cb(skb)->psm = psm; - if (!chan->ops->recv(chan, skb)) + if (!chan->ops->recv(chan, skb)) { + l2cap_chan_put(chan); return; + } drop: + l2cap_chan_put(chan); +free_skb: kfree_skb(skb); } @@ -6878,22 +6894,26 @@ static void l2cap_att_channel(struct l2cap_conn *conn, struct l2cap_chan *chan; if (hcon->type != LE_LINK) - goto drop; + goto free_skb; chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, &hcon->src, &hcon->dst); if (!chan) - goto drop; + goto free_skb; BT_DBG("chan %p, len %d", chan, skb->len); if (chan->imtu < skb->len) goto drop; - if (!chan->ops->recv(chan, skb)) + if (!chan->ops->recv(chan, skb)) { + l2cap_chan_put(chan); return; + } drop: + l2cap_chan_put(chan); +free_skb: kfree_skb(skb); } -- GitLab From 5ff6f34d4260c542df3712e29ead87cf071ad472 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:43 +0300 Subject: [PATCH 0357/9167] Bluetooth: Fix __l2cap_no_conn_pending() usage with all channels The __l2cap_no_conn_pending() function would previously only return a meaningful value for connection oriented channels and was therefore not useful for anything else. As preparation of making the L2CAP code more generic allow the function to be called for other channel types as well by returning a meaningful value for them. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a47a14efd5aa..a0a910eb897b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1082,6 +1082,9 @@ static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll) static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) { + if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) + return true; + return !test_bit(CONF_CONNECT_PEND, &chan->conf_state); } -- GitLab From d52deb17489b8155e031fb1a9f116c602d719e11 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:44 +0300 Subject: [PATCH 0358/9167] Bluetooth: Resume BT_CONNECTED state after LE security elevation The LE ATT socket uses a special trick where it temporarily sets BT_CONFIG state for the duration of a security level elevation. In order to not require special hacks for going back to BT_CONNECTED state in the l2cap_core.c code the most reasonable place to resume the state is the resume callback. This patch adds a new flag to track the pending security level change and ensures that the state is set back to BT_CONNECTED in the resume callback in case the flag is set. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 + net/bluetooth/l2cap_sock.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 8df15ad0d43f..4a51e7596608 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -708,6 +708,7 @@ enum { FLAG_EFS_ENABLE, FLAG_DEFER_SETUP, FLAG_LE_CONN_REQ_SENT, + FLAG_PENDING_SECURITY, }; enum { diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 1884f72083c2..5a42f6a818c0 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -790,6 +790,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, if (chan->scid == L2CAP_CID_ATT) { if (smp_conn_security(conn->hcon, sec.level)) break; + set_bit(FLAG_PENDING_SECURITY, &chan->flags); sk->sk_state = BT_CONFIG; chan->state = BT_CONFIG; @@ -1359,6 +1360,11 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan) { struct sock *sk = chan->data; + if (test_and_clear_bit(FLAG_PENDING_SECURITY, &chan->flags)) { + sk->sk_state = BT_CONNECTED; + chan->state = BT_CONNECTED; + } + clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags); sk->sk_state_change(sk); } -- GitLab From 191eb398c677444bc08cb4497467ca9e2b8696bc Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:45 +0300 Subject: [PATCH 0359/9167] Bluetooth: Remove special handling of ATT in l2cap_security_cfm() With the update to sk->resume() and __l2cap_no_conn_pending() we no-longer need to have special handling of ATT channels in the l2cap_security_cfm() function. The chan->sec_level update when encryption has been enabled is safe to do for any kind of channel, and the loop takes later care of calling chan->ready() or chan->resume() if necessary. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a0a910eb897b..54cbfcd4da44 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -7341,15 +7341,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) continue; } - if (chan->scid == L2CAP_CID_ATT) { - if (!status && encrypt) { - chan->sec_level = hcon->sec_level; - l2cap_chan_ready(chan); - } - - l2cap_chan_unlock(chan); - continue; - } + if (!status && encrypt) + chan->sec_level = hcon->sec_level; if (!__l2cap_no_conn_pending(chan)) { l2cap_chan_unlock(chan); -- GitLab From dc0f5088182b2e48ae47629a55bdf35ad5d6ed44 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:46 +0300 Subject: [PATCH 0360/9167] Bluetooth: Refactor l2cap_connect_cfm This patch is a simple refactoring of l2cap_connect_cfm to allow easier extension of the function. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 54cbfcd4da44..7a5cff89b792 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -7268,13 +7268,16 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); - if (!status) { - conn = l2cap_conn_add(hcon); - if (conn) - l2cap_conn_ready(conn); - } else { + if (status) { l2cap_conn_del(hcon, bt_to_errno(status)); + return; } + + conn = l2cap_conn_add(hcon); + if (!conn) + return; + + l2cap_conn_ready(conn); } int l2cap_disconn_ind(struct hci_conn *hcon) -- GitLab From e760ec12134d5736065c4e88b0e783cc1fe0d20a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:47 +0300 Subject: [PATCH 0361/9167] Bluetooth: Move L2CAP fixed channel creation into l2cap_conn_cfm In order to remove special handling of fixed L2CAP channels we need to start creating them in a single place instead of having per-channel exceptions. The most natural place is the l2cap_conn_cfm() function which is called whenever there is a new baseband link. The only really special case so far has been the ATT socket, so in order not to break the code in between this patch removes the ATT special handling at the same time as it adds the generic fixed channel handling from l2cap_le_conn_ready() into the hci_conn_cfm() function. As a related change the channel locking in l2cap_conn_ready() becomes simpler and we can thereby move the smp_conn_security() call into the l2cap_le_conn_ready() function. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 124 ++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 44 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 7a5cff89b792..8c4767f91a23 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1469,26 +1469,14 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) { struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; - struct l2cap_chan *chan, *pchan; - u8 dst_type; - BT_DBG(""); - - /* Check if we have socket listening on cid */ - pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT, - &hcon->src, &hcon->dst); - if (!pchan) - return; + BT_DBG("%s conn %p", hdev->name, conn); - /* Client ATT sockets should override the server one */ - if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT)) - goto put; - - dst_type = bdaddr_type(hcon, hcon->dst_type); - - /* If device is blocked, do not create a channel for it */ - if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type)) - goto put; + /* For outgoing pairing which doesn't necessarily have an + * associated socket (e.g. mgmt_pair_device). + */ + if (hcon->out) + smp_conn_security(hcon, hcon->pending_sec_level); /* For LE slave connections, make sure the connection interval * is in the range of the minium and maximum interval that has @@ -1508,24 +1496,6 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONN_PARAM_UPDATE_REQ, sizeof(req), &req); } - - l2cap_chan_lock(pchan); - - chan = pchan->ops->new_connection(pchan); - if (!chan) - goto clean; - - bacpy(&chan->src, &hcon->src); - bacpy(&chan->dst, &hcon->dst); - chan->src_type = bdaddr_type(hcon, hcon->src_type); - chan->dst_type = dst_type; - - __l2cap_chan_add(conn, chan); - -clean: - l2cap_chan_unlock(pchan); -put: - l2cap_chan_put(pchan); } static void l2cap_conn_ready(struct l2cap_conn *conn) @@ -1535,17 +1505,11 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) BT_DBG("conn %p", conn); - /* For outgoing pairing which doesn't necessarily have an - * associated socket (e.g. mgmt_pair_device). - */ - if (hcon->out && hcon->type == LE_LINK) - smp_conn_security(hcon, hcon->pending_sec_level); - - mutex_lock(&conn->chan_lock); - if (hcon->type == LE_LINK) l2cap_le_conn_ready(conn); + mutex_lock(&conn->chan_lock); + list_for_each_entry(chan, &conn->chan_l, list) { l2cap_chan_lock(chan); @@ -7262,9 +7226,44 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) return exact ? lm1 : lm2; } +/* Find the next fixed channel in BT_LISTEN state, continue iteration + * from an existing channel in the list or from the beginning of the + * global list (by passing NULL as first parameter). + */ +static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c, + bdaddr_t *src) +{ + read_lock(&chan_list_lock); + + if (c) + c = list_next_entry(c, global_l); + else + c = list_entry(chan_list.next, typeof(*c), global_l); + + list_for_each_entry_from(c, &chan_list, global_l) { + if (c->chan_type != L2CAP_CHAN_FIXED) + continue; + if (c->state != BT_LISTEN) + continue; + if (bacmp(&c->src, src) && bacmp(&c->src, BDADDR_ANY)) + continue; + + l2cap_chan_hold(c); + read_unlock(&chan_list_lock); + return c; + } + + read_unlock(&chan_list_lock); + + return NULL; +} + void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) { + struct hci_dev *hdev = hcon->hdev; struct l2cap_conn *conn; + struct l2cap_chan *pchan; + u8 dst_type; BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status); @@ -7277,6 +7276,43 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) if (!conn) return; + dst_type = bdaddr_type(hcon, hcon->dst_type); + + /* If device is blocked, do not create channels for it */ + if (hci_bdaddr_list_lookup(&hdev->blacklist, &hcon->dst, dst_type)) + return; + + /* Find fixed channels and notify them of the new connection. We + * use multiple individual lookups, continuing each time where + * we left off, because the list lock would prevent calling the + * potentially sleeping l2cap_chan_lock() function. + */ + pchan = l2cap_global_fixed_chan(NULL, &hdev->bdaddr); + while (pchan) { + struct l2cap_chan *chan, *next; + + /* Client fixed channels should override server ones */ + if (__l2cap_get_chan_by_dcid(conn, pchan->scid)) + goto next; + + l2cap_chan_lock(pchan); + chan = pchan->ops->new_connection(pchan); + if (chan) { + bacpy(&chan->src, &hcon->src); + bacpy(&chan->dst, &hcon->dst); + chan->src_type = bdaddr_type(hcon, hcon->src_type); + chan->dst_type = dst_type; + + __l2cap_chan_add(conn, chan); + } + + l2cap_chan_unlock(pchan); +next: + next = l2cap_global_fixed_chan(pchan, &hdev->bdaddr); + l2cap_chan_put(pchan); + pchan = next; + } + l2cap_conn_ready(conn); } -- GitLab From 54a1b626c96039f172dd2ea15b2671053b3c5a68 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:48 +0300 Subject: [PATCH 0362/9167] Bluetooth: Improve fixed channel lookup based on link type When notifying global fixed channels of new connections it doesn't make sense to consider channels meant for a different link type than the one available. This patch adds an extra parameter to the l2cap_global_fixed_chan() lookup function and ensures that only channels matching the current hci_conn type are looked up. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8c4767f91a23..191b58f48245 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -7231,7 +7231,7 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) * global list (by passing NULL as first parameter). */ static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c, - bdaddr_t *src) + bdaddr_t *src, u8 link_type) { read_lock(&chan_list_lock); @@ -7247,6 +7247,10 @@ static struct l2cap_chan *l2cap_global_fixed_chan(struct l2cap_chan *c, continue; if (bacmp(&c->src, src) && bacmp(&c->src, BDADDR_ANY)) continue; + if (link_type == ACL_LINK && c->src_type != BDADDR_BREDR) + continue; + if (link_type == LE_LINK && c->src_type == BDADDR_BREDR) + continue; l2cap_chan_hold(c); read_unlock(&chan_list_lock); @@ -7287,7 +7291,7 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) * we left off, because the list lock would prevent calling the * potentially sleeping l2cap_chan_lock() function. */ - pchan = l2cap_global_fixed_chan(NULL, &hdev->bdaddr); + pchan = l2cap_global_fixed_chan(NULL, &hdev->bdaddr, hcon->type); while (pchan) { struct l2cap_chan *chan, *next; @@ -7308,7 +7312,8 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) l2cap_chan_unlock(pchan); next: - next = l2cap_global_fixed_chan(pchan, &hdev->bdaddr); + next = l2cap_global_fixed_chan(pchan, &hdev->bdaddr, + hcon->type); l2cap_chan_put(pchan); pchan = next; } -- GitLab From 06171e0546434b006a3857ea745b4258ad5d677c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:49 +0300 Subject: [PATCH 0363/9167] Bluetooth: Remove special ATT data channel handling Now that we've got the fixed channel infrastructure cleaned up in a generic way there's no longer a need to have a dedicated function for handling data on the ATT channel. Instead the generic l2cap_data_channel() handler will be able to do the exact same thing. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 79 -------------------------------------- 1 file changed, 79 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 191b58f48245..09eb4e3e8ab2 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1420,51 +1420,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn) mutex_unlock(&conn->chan_lock); } -/* Find socket with cid and source/destination bdaddr. - * Returns closest match, locked. - */ -static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, - bdaddr_t *src, - bdaddr_t *dst) -{ - struct l2cap_chan *c, *c1 = NULL; - - read_lock(&chan_list_lock); - - list_for_each_entry(c, &chan_list, global_l) { - if (state && c->state != state) - continue; - - if (c->scid == cid) { - int src_match, dst_match; - int src_any, dst_any; - - /* Exact match. */ - src_match = !bacmp(&c->src, src); - dst_match = !bacmp(&c->dst, dst); - if (src_match && dst_match) { - l2cap_chan_hold(c); - read_unlock(&chan_list_lock); - return c; - } - - /* Closest match */ - src_any = !bacmp(&c->src, BDADDR_ANY); - dst_any = !bacmp(&c->dst, BDADDR_ANY); - if ((src_match && dst_any) || (src_any && dst_match) || - (src_any && dst_any)) - c1 = c; - } - } - - if (c1) - l2cap_chan_hold(c1); - - read_unlock(&chan_list_lock); - - return c1; -} - static void l2cap_le_conn_ready(struct l2cap_conn *conn) { struct hci_conn *hcon = conn->hcon; @@ -6854,36 +6809,6 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, kfree_skb(skb); } -static void l2cap_att_channel(struct l2cap_conn *conn, - struct sk_buff *skb) -{ - struct hci_conn *hcon = conn->hcon; - struct l2cap_chan *chan; - - if (hcon->type != LE_LINK) - goto free_skb; - - chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, - &hcon->src, &hcon->dst); - if (!chan) - goto free_skb; - - BT_DBG("chan %p, len %d", chan, skb->len); - - if (chan->imtu < skb->len) - goto drop; - - if (!chan->ops->recv(chan, skb)) { - l2cap_chan_put(chan); - return; - } - -drop: - l2cap_chan_put(chan); -free_skb: - kfree_skb(skb); -} - static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) { struct l2cap_hdr *lh = (void *) skb->data; @@ -6929,10 +6854,6 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) l2cap_conless_channel(conn, psm, skb); break; - case L2CAP_CID_ATT: - l2cap_att_channel(conn, skb); - break; - case L2CAP_CID_LE_SIGNALING: l2cap_le_sig_channel(conn, skb); break; -- GitLab From 148243087b3a5d95a32825da26858dc9d893b141 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 7 Aug 2014 22:56:50 +0300 Subject: [PATCH 0364/9167] Bluetooth: Move parts of fixed channel initialization to l2cap_add_scid The l2cap_add_scid function is used for registering a fixed L2CAP channel. Instead of having separate initialization of the channel type and outgoing MTU in l2cap_sock.c it's more intuitive to do these things in the l2cap_add_scid function itself (and thereby make the functionality available to other users besides l2cap_sock.c). Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 4 ++++ net/bluetooth/l2cap_sock.c | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 09eb4e3e8ab2..344a29c53227 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -210,6 +210,10 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid) { write_lock(&chan_list_lock); + /* Override the defaults (which are for conn-oriented) */ + chan->omtu = L2CAP_DEFAULT_MTU; + chan->chan_type = L2CAP_CHAN_FIXED; + chan->scid = scid; write_unlock(&chan_list_lock); diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 5a42f6a818c0..ed06f88e6f10 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -99,15 +99,6 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) if (!bdaddr_type_is_valid(la.l2_bdaddr_type)) return -EINVAL; - if (la.l2_cid) { - /* When the socket gets created it defaults to - * CHAN_CONN_ORIENTED, so we need to overwrite the - * default here. - */ - chan->chan_type = L2CAP_CHAN_FIXED; - chan->omtu = L2CAP_DEFAULT_MTU; - } - if (bdaddr_type_is_le(la.l2_bdaddr_type)) { /* We only allow ATT user space socket */ if (la.l2_cid && -- GitLab From 72847ce02180e8a0be1b23ba53ffe437cdb25d6a Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:28:03 +0300 Subject: [PATCH 0365/9167] Bluetooth: Call L2CAP teardown callback before clearing chan->conn L2CAP channel implementations may want to still access the chan->conn pointer. This will particularly be the case for SMP that will want to clear a reference to the SMP channel in the l2cap_conn structure. The only user of the teardown callback so far is l2cap_sock.c and for the code there it makes no difference whether the callback is called before or after clearing the chan->conn pointer. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 344a29c53227..c6419f40cfba 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -566,6 +566,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) BT_DBG("chan %p, conn %p, err %d", chan, conn, err); + chan->ops->teardown(chan, err); + if (conn) { struct amp_mgr *mgr = conn->hcon->amp_mgr; /* Delete from channel list */ @@ -589,8 +591,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) amp_disconnect_logical_link(hs_hchan); } - chan->ops->teardown(chan, err); - if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) return; -- GitLab From 79a0572736ad4b9cac7be72d4402f9c79db8ebaf Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:28:04 +0300 Subject: [PATCH 0366/9167] Bluetooth: Call l2cap_le_conn_ready after notifying channels For most cases it makes no difference whether l2cap_le_conn_ready() is called before or after calling the channel ready() callbacks, however for upcoming SMP code we need this as the ready() callback initializes certain structures that a call to smp_conn_security() from l2cap_le_conn_ready() depends on. Therefore, move the call to l2cap_le_conn_ready() after iterating through and notifying channels. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index c6419f40cfba..8acfe6f57b5e 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1464,9 +1464,6 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) BT_DBG("conn %p", conn); - if (hcon->type == LE_LINK) - l2cap_le_conn_ready(conn); - mutex_lock(&conn->chan_lock); list_for_each_entry(chan, &conn->chan_l, list) { @@ -1492,6 +1489,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) mutex_unlock(&conn->chan_lock); + if (hcon->type == LE_LINK) + l2cap_le_conn_ready(conn); + queue_work(hcon->hdev->workqueue, &conn->pending_rx_work); } -- GitLab From d3368605591b88cd8af522adadb1c460a8f8e7bb Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:28:05 +0300 Subject: [PATCH 0367/9167] Bluetooth: Fix using HCI_CONN_LE_SMP_PEND to check for SMP context The code is consistently using the HCI_CONN_LE_SMP_PEND flag check for the existence of the SMP context, with the exception of this one place in smp_sig_channel(). This patch converts the place to use the flag just like all other instances. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 40db728f044b..33016ec9b247 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1206,7 +1206,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) * returns an error). */ if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && - !conn->smp_chan) { + !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); kfree_skb(skb); return -EOPNOTSUPP; -- GitLab From fabed38fcf456cc5d3e6946fab78855aa65bd40b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:32:48 +0300 Subject: [PATCH 0368/9167] Bluetooth: Fix hci_update_random_address() error return for no crypto If the AES crypto context is not available we cannot generate new RPAs. We should therefore cleanly return an error from the function responsible for updating the random address. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 217ef83fb541..860477090d78 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3882,6 +3882,12 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, !bacmp(&hdev->random_addr, &hdev->rpa)) return 0; + if (!hdev->tfm_aes) { + BT_ERR("%s crypto not available to generate RPA", + hdev->name); + return -EOPNOTSUPP; + } + err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa); if (err < 0) { BT_ERR("%s failed to generate new RPA", hdev->name); -- GitLab From 893ededeb189aa48c308116a7acd793efae5c830 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:32:49 +0300 Subject: [PATCH 0369/9167] Bluetooth: Fix IRK lookup when tfm_aes is not available If the AES crypto has not been initialized properly we should cleanly return from the hci_find_irk_by_rpa() function. Right now this will not happen in practice, but once (in subsequent patches) SMP init is moved to after the HCI init procedure it is possible that the pointer is NULL. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 860477090d78..4a1ec259099e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3232,6 +3232,9 @@ struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) return irk; } + if (!hdev->tfm_aes) + return NULL; + list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { bacpy(&irk->rpa, rpa); -- GitLab From 222916e3e509f04678d0b6f13f7b17bbc8dd14b6 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:32:50 +0300 Subject: [PATCH 0370/9167] Bluetooth: Refactor SMP (de)initialization into separate functions As preparation for converting SMP to use the l2cap_chan infrastructure refactor the (de)initialization into separate functions. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 46 +++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 4a1ec259099e..1f691c50abbc 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1764,6 +1764,34 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt) } } +static int hci_register_smp(struct hci_dev *hdev) +{ + int err; + + BT_DBG("%s", hdev->name); + + hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(hdev->tfm_aes)) { + BT_ERR("Unable to create crypto context"); + err = PTR_ERR(hdev->tfm_aes); + hdev->tfm_aes = NULL; + return err; + } + + return 0; +} + +static void hci_unregister_smp(struct hci_dev *hdev) +{ + BT_DBG("%s", hdev->name); + + if (hdev->tfm_aes) { + crypto_free_blkcipher(hdev->tfm_aes); + hdev->tfm_aes = NULL; + } +} + static int __hci_init(struct hci_dev *hdev) { int err; @@ -4099,18 +4127,13 @@ int hci_register_dev(struct hci_dev *hdev) dev_set_name(&hdev->dev, "%s", hdev->name); - hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(hdev->tfm_aes)) { - BT_ERR("Unable to create crypto context"); - error = PTR_ERR(hdev->tfm_aes); - hdev->tfm_aes = NULL; + error = hci_register_smp(hdev); + if (error) goto err_wqueue; - } error = device_add(&hdev->dev); if (error < 0) - goto err_tfm; + goto err_smp; hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, @@ -4152,8 +4175,8 @@ int hci_register_dev(struct hci_dev *hdev) return id; -err_tfm: - crypto_free_blkcipher(hdev->tfm_aes); +err_smp: + hci_unregister_smp(hdev); err_wqueue: destroy_workqueue(hdev->workqueue); destroy_workqueue(hdev->req_workqueue); @@ -4205,8 +4228,7 @@ void hci_unregister_dev(struct hci_dev *hdev) rfkill_destroy(hdev->rfkill); } - if (hdev->tfm_aes) - crypto_free_blkcipher(hdev->tfm_aes); + hci_unregister_smp(hdev); device_del(&hdev->dev); -- GitLab From 54506918059a5bdbf396f34f2e0a2735803024db Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:32:51 +0300 Subject: [PATCH 0371/9167] Bluetooth: Move SMP initialization after HCI init First of all, it's wasteful to initialize SMP if it's never going to be used (e.g. on non-LE controllers). Second of all, when we move to use l2cap_chan we need to know the real local address, meaning we must have completed at least part of the HCI init. This patch moves the SMP initialization to after the HCI init procedure and makes it depend on whether the controller actually supports LE. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 1f691c50abbc..9eb2869b183b 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1926,6 +1926,8 @@ static int __hci_init(struct hci_dev *hdev) debugfs_create_u16("discov_interleaved_timeout", 0644, hdev->debugfs, &hdev->discov_interleaved_timeout); + + hci_register_smp(hdev); } return 0; @@ -4127,13 +4129,9 @@ int hci_register_dev(struct hci_dev *hdev) dev_set_name(&hdev->dev, "%s", hdev->name); - error = hci_register_smp(hdev); - if (error) - goto err_wqueue; - error = device_add(&hdev->dev); if (error < 0) - goto err_smp; + goto err_wqueue; hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, @@ -4175,8 +4173,6 @@ int hci_register_dev(struct hci_dev *hdev) return id; -err_smp: - hci_unregister_smp(hdev); err_wqueue: destroy_workqueue(hdev->workqueue); destroy_workqueue(hdev->req_workqueue); -- GitLab From 711eafe345d993cf4831e890fa989d02c06cad62 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:32:52 +0300 Subject: [PATCH 0372/9167] Bluetooth: Move SMP (de)initialization to smp.c As preparation for moving SMP to use l2cap_chan infrastructure we need to move the (de)initialization functions to smp.c (where they'll eventually need access to the local L2CAP channel callbacks). Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/hci_core.c | 32 ++------------------------------ net/bluetooth/smp.c | 26 ++++++++++++++++++++++++++ net/bluetooth/smp.h | 3 +++ 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 9eb2869b183b..88575a633601 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1764,34 +1764,6 @@ static void hci_init4_req(struct hci_request *req, unsigned long opt) } } -static int hci_register_smp(struct hci_dev *hdev) -{ - int err; - - BT_DBG("%s", hdev->name); - - hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(hdev->tfm_aes)) { - BT_ERR("Unable to create crypto context"); - err = PTR_ERR(hdev->tfm_aes); - hdev->tfm_aes = NULL; - return err; - } - - return 0; -} - -static void hci_unregister_smp(struct hci_dev *hdev) -{ - BT_DBG("%s", hdev->name); - - if (hdev->tfm_aes) { - crypto_free_blkcipher(hdev->tfm_aes); - hdev->tfm_aes = NULL; - } -} - static int __hci_init(struct hci_dev *hdev) { int err; @@ -1927,7 +1899,7 @@ static int __hci_init(struct hci_dev *hdev) hdev->debugfs, &hdev->discov_interleaved_timeout); - hci_register_smp(hdev); + smp_register(hdev); } return 0; @@ -4224,7 +4196,7 @@ void hci_unregister_dev(struct hci_dev *hdev) rfkill_destroy(hdev->rfkill); } - hci_unregister_smp(hdev); + smp_unregister(hdev); device_del(&hdev->dev); diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 33016ec9b247..ab07649ecc77 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1455,3 +1455,29 @@ int smp_distribute_keys(struct l2cap_conn *conn) return 0; } + +int smp_register(struct hci_dev *hdev) +{ + BT_DBG("%s", hdev->name); + + hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(hdev->tfm_aes)) { + int err = PTR_ERR(hdev->tfm_aes); + BT_ERR("Unable to create crypto context"); + hdev->tfm_aes = NULL; + return err; + } + + return 0; +} + +void smp_unregister(struct hci_dev *hdev) +{ + BT_DBG("%s", hdev->name); + + if (hdev->tfm_aes) { + crypto_free_blkcipher(hdev->tfm_aes); + hdev->tfm_aes = NULL; + } +} diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 796f4f45f92f..6e29359f60a3 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -136,4 +136,7 @@ bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *bdaddr); int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa); +int smp_register(struct hci_dev *hdev); +void smp_unregister(struct hci_dev *hdev); + #endif /* __SMP_H */ -- GitLab From f193844c51e88ea3d2137bb0c1d38d27d37691a2 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:37:15 +0300 Subject: [PATCH 0373/9167] Bluetooth: Add more L2CAP convenience callbacks In preparation for converting SMP to use l2cap_chan it's useful to add a few more callback helpers so that smp.c won't need to define all of its own. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 4a51e7596608..a72965f6bc2f 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -838,18 +838,43 @@ static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan return NULL; } +static inline int l2cap_chan_no_recv(struct l2cap_chan *chan, struct sk_buff *skb) +{ + return -ENOSYS; +} + +static inline struct sk_buff *l2cap_chan_no_alloc_skb(struct l2cap_chan *chan, + unsigned long hdr_len, + unsigned long len, int nb) +{ + return ERR_PTR(-ENOSYS); +} + static inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err) { } +static inline void l2cap_chan_no_close(struct l2cap_chan *chan) +{ +} + static inline void l2cap_chan_no_ready(struct l2cap_chan *chan) { } +static inline void l2cap_chan_no_state_change(struct l2cap_chan *chan, + int state, int err) +{ +} + static inline void l2cap_chan_no_defer(struct l2cap_chan *chan) { } +static inline void l2cap_chan_no_suspend(struct l2cap_chan *chan) +{ +} + static inline void l2cap_chan_no_resume(struct l2cap_chan *chan) { } -- GitLab From 70db83c4bcdc1447bbcb318389561c90d7056b18 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:37:16 +0300 Subject: [PATCH 0374/9167] Bluetooth: Add SMP L2CAP channel skeleton This patch creates the initial SMP L2CAP channels and a skeleton for their callbacks. There is one per-adapter channel created upon adapter registration, and then one channel per-connection created through the new_connection callback. The channels are registered with the reserved CID 0x1f for now in order to not conflict with existing SMP functionality. Once everything is in place the value can be changed to what it should be, i.e. L2CAP_CID_SMP. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 + include/net/bluetooth/l2cap.h | 1 + net/bluetooth/smp.c | 131 ++++++++++++++++++++++++++++++- 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index cc2eb7730fbc..2571fc1cb1c5 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -303,6 +303,7 @@ struct hci_dev { __u32 req_result; struct crypto_blkcipher *tfm_aes; + void *smp_data; struct discovery_state discovery; struct hci_conn_hash conn_hash; diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index a72965f6bc2f..1a037ba4b6f4 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -637,6 +637,7 @@ struct l2cap_conn { struct delayed_work security_timer; struct smp_chan *smp_chan; + struct l2cap_chan *smp; struct list_head chan_l; struct mutex chan_lock; diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index ab07649ecc77..2362ae35a4d5 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1456,8 +1456,106 @@ int smp_distribute_keys(struct l2cap_conn *conn) return 0; } +static void smp_teardown_cb(struct l2cap_chan *chan, int err) +{ + struct l2cap_conn *conn = chan->conn; + + BT_DBG("chan %p", chan); + + conn->smp = NULL; + l2cap_chan_put(chan); +} + +static void smp_ready_cb(struct l2cap_chan *chan) +{ + struct l2cap_conn *conn = chan->conn; + + BT_DBG("chan %p", chan); + + conn->smp = chan; + l2cap_chan_hold(chan); +} + +static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, + unsigned long hdr_len, + unsigned long len, int nb) +{ + struct sk_buff *skb; + + skb = bt_skb_alloc(hdr_len + len, GFP_KERNEL); + if (!skb) + return ERR_PTR(-ENOMEM); + + skb->priority = HCI_PRIO_MAX; + bt_cb(skb)->chan = chan; + + return skb; +} + +static const struct l2cap_ops smp_chan_ops = { + .name = "Security Manager", + .ready = smp_ready_cb, + .alloc_skb = smp_alloc_skb_cb, + .teardown = smp_teardown_cb, + + .new_connection = l2cap_chan_no_new_connection, + .recv = l2cap_chan_no_recv, + .state_change = l2cap_chan_no_state_change, + .close = l2cap_chan_no_close, + .defer = l2cap_chan_no_defer, + .suspend = l2cap_chan_no_suspend, + .resume = l2cap_chan_no_resume, + .set_shutdown = l2cap_chan_no_set_shutdown, + .get_sndtimeo = l2cap_chan_no_get_sndtimeo, + .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, +}; + +static inline struct l2cap_chan *smp_new_conn_cb(struct l2cap_chan *pchan) +{ + struct l2cap_chan *chan; + + BT_DBG("pchan %p", pchan); + + chan = l2cap_chan_create(); + if (!chan) + return NULL; + + chan->chan_type = pchan->chan_type; + chan->ops = &smp_chan_ops; + chan->scid = pchan->scid; + chan->dcid = chan->scid; + chan->imtu = pchan->imtu; + chan->omtu = pchan->omtu; + chan->mode = pchan->mode; + + BT_DBG("created chan %p", chan); + + return chan; +} + +static const struct l2cap_ops smp_root_chan_ops = { + .name = "Security Manager Root", + .new_connection = smp_new_conn_cb, + + /* None of these are implemented for the root channel */ + .close = l2cap_chan_no_close, + .alloc_skb = l2cap_chan_no_alloc_skb, + .recv = l2cap_chan_no_recv, + .state_change = l2cap_chan_no_state_change, + .teardown = l2cap_chan_no_teardown, + .ready = l2cap_chan_no_ready, + .defer = l2cap_chan_no_defer, + .suspend = l2cap_chan_no_suspend, + .resume = l2cap_chan_no_resume, + .set_shutdown = l2cap_chan_no_set_shutdown, + .get_sndtimeo = l2cap_chan_no_get_sndtimeo, + .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, +}; + int smp_register(struct hci_dev *hdev) { + struct l2cap_chan *chan; + BT_DBG("%s", hdev->name); hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, @@ -1469,15 +1567,46 @@ int smp_register(struct hci_dev *hdev) return err; } + chan = l2cap_chan_create(); + if (!chan) { + crypto_free_blkcipher(hdev->tfm_aes); + hdev->tfm_aes = NULL; + return -ENOMEM; + } + + /* FIXME: Using reserved 0x1f value for now - to be changed to + * L2CAP_CID_SMP once all functionality is in place. + */ + l2cap_add_scid(chan, 0x1f); + + l2cap_chan_set_defaults(chan); + + bacpy(&chan->src, &hdev->bdaddr); + chan->src_type = BDADDR_LE_PUBLIC; + chan->state = BT_LISTEN; + chan->mode = L2CAP_MODE_BASIC; + chan->imtu = L2CAP_DEFAULT_MTU; + chan->ops = &smp_root_chan_ops; + + hdev->smp_data = chan; + return 0; } void smp_unregister(struct hci_dev *hdev) { - BT_DBG("%s", hdev->name); + struct l2cap_chan *chan = hdev->smp_data; + + if (!chan) + return; + + BT_DBG("%s chan %p", hdev->name, chan); if (hdev->tfm_aes) { crypto_free_blkcipher(hdev->tfm_aes); hdev->tfm_aes = NULL; } + + hdev->smp_data = NULL; + l2cap_chan_put(chan); } -- GitLab From defce9e83666658d4420d65e45ab1ad190992f72 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:37:17 +0300 Subject: [PATCH 0375/9167] Bluetooth: Make AES crypto context private to SMP Now that we have per-adapter SMP data thanks to the root SMP L2CAP channel we can take advantage of it and attach the AES crypto context (only used for SMP) to it. This means that the smp_irk_matches() and smp_generate_rpa() function can be converted to internally handle the AES context. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/hci_core.h | 1 - net/bluetooth/hci_core.c | 13 ++-------- net/bluetooth/smp.c | 41 ++++++++++++++++++++++---------- net/bluetooth/smp.h | 5 ++-- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 2571fc1cb1c5..5f0b77b71b45 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -302,7 +302,6 @@ struct hci_dev { __u32 req_status; __u32 req_result; - struct crypto_blkcipher *tfm_aes; void *smp_data; struct discovery_state discovery; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 88575a633601..abeb5e47311e 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -3234,11 +3234,8 @@ struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa) return irk; } - if (!hdev->tfm_aes) - return NULL; - list_for_each_entry(irk, &hdev->identity_resolving_keys, list) { - if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) { + if (smp_irk_matches(hdev, irk->val, rpa)) { bacpy(&irk->rpa, rpa); return irk; } @@ -3887,13 +3884,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, !bacmp(&hdev->random_addr, &hdev->rpa)) return 0; - if (!hdev->tfm_aes) { - BT_ERR("%s crypto not available to generate RPA", - hdev->name); - return -EOPNOTSUPP; - } - - err = smp_generate_rpa(hdev->tfm_aes, hdev->irk, &hdev->rpa); + err = smp_generate_rpa(hdev, hdev->irk, &hdev->rpa); if (err < 0) { BT_ERR("%s failed to generate new RPA", hdev->name); return err; diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 2362ae35a4d5..6925fc4caaee 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -139,12 +139,18 @@ static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3]) return 0; } -bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], - bdaddr_t *bdaddr) +bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr) { + struct l2cap_chan *chan = hdev->smp_data; + struct crypto_blkcipher *tfm; u8 hash[3]; int err; + if (!chan || !chan->data) + return false; + + tfm = chan->data; + BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk); err = smp_ah(tfm, irk, &bdaddr->b[3], hash); @@ -154,10 +160,17 @@ bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], return !memcmp(bdaddr->b, hash, 3); } -int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa) +int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa) { + struct l2cap_chan *chan = hdev->smp_data; + struct crypto_blkcipher *tfm; int err; + if (!chan || !chan->data) + return -EOPNOTSUPP; + + tfm = chan->data; + get_random_bytes(&rpa->b[3], 3); rpa->b[5] &= 0x3f; /* Clear two most significant bits */ @@ -1555,25 +1568,25 @@ static const struct l2cap_ops smp_root_chan_ops = { int smp_register(struct hci_dev *hdev) { struct l2cap_chan *chan; + struct crypto_blkcipher *tfm_aes; BT_DBG("%s", hdev->name); - hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, - CRYPTO_ALG_ASYNC); - if (IS_ERR(hdev->tfm_aes)) { - int err = PTR_ERR(hdev->tfm_aes); + tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm_aes)) { + int err = PTR_ERR(tfm_aes); BT_ERR("Unable to create crypto context"); - hdev->tfm_aes = NULL; return err; } chan = l2cap_chan_create(); if (!chan) { - crypto_free_blkcipher(hdev->tfm_aes); - hdev->tfm_aes = NULL; + crypto_free_blkcipher(tfm_aes); return -ENOMEM; } + chan->data = tfm_aes; + /* FIXME: Using reserved 0x1f value for now - to be changed to * L2CAP_CID_SMP once all functionality is in place. */ @@ -1596,15 +1609,17 @@ int smp_register(struct hci_dev *hdev) void smp_unregister(struct hci_dev *hdev) { struct l2cap_chan *chan = hdev->smp_data; + struct crypto_blkcipher *tfm_aes; if (!chan) return; BT_DBG("%s chan %p", hdev->name, chan); - if (hdev->tfm_aes) { - crypto_free_blkcipher(hdev->tfm_aes); - hdev->tfm_aes = NULL; + tfm_aes = chan->data; + if (tfm_aes) { + chan->data = NULL; + crypto_free_blkcipher(tfm_aes); } hdev->smp_data = NULL; diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 6e29359f60a3..d3f6bd617940 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -132,9 +132,8 @@ int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); void smp_chan_destroy(struct l2cap_conn *conn); -bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16], - bdaddr_t *bdaddr); -int smp_generate_rpa(struct crypto_blkcipher *tfm, u8 irk[16], bdaddr_t *rpa); +bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr); +int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa); int smp_register(struct hci_dev *hdev); void smp_unregister(struct hci_dev *hdev); -- GitLab From 5d88cc73dded31a93fcc4821f33a8c3d755bf454 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 8 Aug 2014 09:37:18 +0300 Subject: [PATCH 0376/9167] Bluetooth: Convert SMP to use l2cap_chan infrastructure Now that we have all the necessary pieces in place we can fully convert SMP to use the L2CAP channel infrastructure. This patch adds the necessary callbacks and removes the now unneeded conn->smp_chan pointer. One notable behavioral change in this patch comes from the following code snippet: - case L2CAP_CID_SMP: - if (smp_sig_channel(conn, skb)) - l2cap_conn_del(conn->hcon, EACCES); This piece of code was essentially forcing a disconnection if garbage SMP data was received. The l2cap_conn_del() function is private to l2cap_conn.c so we don't have access to it anymore when using the L2CAP channel callbacks. Therefore, the behavior of the new code is simply to return errors in the recv() callback (which is simply the old smp_sig_channel()), but no disconnection will occur. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 - net/bluetooth/l2cap_core.c | 10 --- net/bluetooth/smp.c | 122 ++++++++++++++++++---------------- net/bluetooth/smp.h | 1 - 4 files changed, 66 insertions(+), 68 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 1a037ba4b6f4..bda6252e3722 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -636,7 +636,6 @@ struct l2cap_conn { __u8 disc_reason; struct delayed_work security_timer; - struct smp_chan *smp_chan; struct l2cap_chan *smp; struct list_head chan_l; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 8acfe6f57b5e..40b6c06ab2c0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1651,11 +1651,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) cancel_delayed_work_sync(&conn->info_timer); - if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { - cancel_delayed_work_sync(&conn->security_timer); - smp_chan_destroy(conn); - } - hcon->l2cap_data = NULL; conn->hchan = NULL; l2cap_conn_put(conn); @@ -6862,11 +6857,6 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) l2cap_le_sig_channel(conn, skb); break; - case L2CAP_CID_SMP: - if (smp_sig_channel(conn, skb)) - l2cap_conn_del(conn->hcon, EACCES); - break; - default: l2cap_data_channel(conn, cid, skb); break; diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 6925fc4caaee..744f678ac3e8 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -248,44 +248,29 @@ static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16], return err; } -static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, - u16 dlen, void *data) +static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) { - struct sk_buff *skb; - struct l2cap_hdr *lh; - int len; - - len = L2CAP_HDR_SIZE + sizeof(code) + dlen; - - if (len > conn->mtu) - return NULL; + struct l2cap_chan *chan = conn->smp; + struct kvec iv[2]; + struct msghdr msg; - skb = bt_skb_alloc(len, GFP_ATOMIC); - if (!skb) - return NULL; + if (!chan) + return; - lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); - lh->len = cpu_to_le16(sizeof(code) + dlen); - lh->cid = cpu_to_le16(L2CAP_CID_SMP); + BT_DBG("code 0x%2.2x", code); - memcpy(skb_put(skb, sizeof(code)), &code, sizeof(code)); + iv[0].iov_base = &code; + iv[0].iov_len = 1; - memcpy(skb_put(skb, dlen), data, dlen); + iv[1].iov_base = data; + iv[1].iov_len = len; - return skb; -} + memset(&msg, 0, sizeof(msg)); -static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) -{ - struct sk_buff *skb = smp_build_cmd(conn, code, len, data); + msg.msg_iov = (struct iovec *) &iv; + msg.msg_iovlen = 2; - BT_DBG("code 0x%2.2x", code); - - if (!skb) - return; - - skb->priority = HCI_PRIO_MAX; - hci_send_acl(conn->hchan, skb, 0); + l2cap_chan_send(chan, &msg, 1 + len); cancel_delayed_work_sync(&conn->security_timer); schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT); @@ -315,7 +300,8 @@ static void build_pairing_cmd(struct l2cap_conn *conn, struct smp_cmd_pairing *req, struct smp_cmd_pairing *rsp, __u8 authreq) { - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; u8 local_dist = 0, remote_dist = 0; @@ -358,7 +344,8 @@ static void build_pairing_cmd(struct l2cap_conn *conn, static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) { - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; if ((max_key_size > SMP_MAX_ENC_KEY_SIZE) || (max_key_size < SMP_MIN_ENC_KEY_SIZE)) @@ -418,7 +405,8 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth, u8 local_io, u8 remote_io) { struct hci_conn *hcon = conn->hcon; - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; u8 method; u32 passkey = 0; int ret = 0; @@ -589,6 +577,7 @@ static u8 smp_random(struct smp_chan *smp) static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) { + struct l2cap_chan *chan = conn->smp; struct smp_chan *smp; smp = kzalloc(sizeof(*smp), GFP_ATOMIC); @@ -606,7 +595,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) } smp->conn = conn; - conn->smp_chan = smp; + chan->data = smp; hci_conn_hold(conn->hcon); @@ -615,7 +604,8 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) void smp_chan_destroy(struct l2cap_conn *conn) { - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; bool complete; BUG_ON(!smp); @@ -646,14 +636,15 @@ void smp_chan_destroy(struct l2cap_conn *conn) } } + chan->data = NULL; kfree(smp); - conn->smp_chan = NULL; hci_conn_drop(conn->hcon); } int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) { struct l2cap_conn *conn = hcon->l2cap_data; + struct l2cap_chan *chan; struct smp_chan *smp; u32 value; @@ -662,7 +653,11 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) return -ENOTCONN; - smp = conn->smp_chan; + chan = conn->smp; + if (!chan) + return -ENOTCONN; + + smp = chan->data; switch (mgmt_op) { case MGMT_OP_USER_PASSKEY_REPLY: @@ -709,10 +704,12 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) if (conn->hcon->role != HCI_ROLE_SLAVE) return SMP_CMD_NOTSUPP; - if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) + if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { smp = smp_chan_create(conn); - else - smp = conn->smp_chan; + } else { + struct l2cap_chan *chan = conn->smp; + smp = chan->data; + } if (!smp) return SMP_UNSPECIFIED; @@ -766,7 +763,8 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_pairing *req, *rsp = (void *) skb->data; - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; u8 key_size, auth = SMP_AUTH_NONE; int ret; @@ -827,7 +825,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) { - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; BT_DBG("conn %p %s", conn, conn->hcon->out ? "master" : "slave"); @@ -850,7 +849,8 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) { - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; BT_DBG("conn %p", conn); @@ -1023,7 +1023,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_encrypt_info *rp = (void *) skb->data; - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; BT_DBG("conn %p", conn); @@ -1044,7 +1045,8 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_master_ident *rp = (void *) skb->data; - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; struct hci_dev *hdev = conn->hcon->hdev; struct hci_conn *hcon = conn->hcon; struct smp_ltk *ltk; @@ -1080,7 +1082,8 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_ident_info *info = (void *) skb->data; - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; BT_DBG(""); @@ -1102,7 +1105,8 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_ident_addr_info *info = (void *) skb->data; - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; struct hci_conn *hcon = conn->hcon; bdaddr_t rpa; @@ -1156,7 +1160,8 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) { struct smp_cmd_sign_info *rp = (void *) skb->data; - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; struct hci_dev *hdev = conn->hcon->hdev; struct smp_csrk *csrk; @@ -1187,8 +1192,9 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) return 0; } -int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) +static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) { + struct l2cap_conn *conn = chan->conn; struct hci_conn *hcon = conn->hcon; __u8 code, reason; int err = 0; @@ -1290,7 +1296,8 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) static void smp_notify_keys(struct l2cap_conn *conn) { - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; struct smp_cmd_pairing *req = (void *) &smp->preq[1]; @@ -1357,7 +1364,8 @@ static void smp_notify_keys(struct l2cap_conn *conn) int smp_distribute_keys(struct l2cap_conn *conn) { struct smp_cmd_pairing *req, *rsp; - struct smp_chan *smp = conn->smp_chan; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; __u8 *keydist; @@ -1475,6 +1483,11 @@ static void smp_teardown_cb(struct l2cap_chan *chan, int err) BT_DBG("chan %p", chan); + if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { + cancel_delayed_work_sync(&conn->security_timer); + smp_chan_destroy(conn); + } + conn->smp = NULL; l2cap_chan_put(chan); } @@ -1508,11 +1521,11 @@ static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, static const struct l2cap_ops smp_chan_ops = { .name = "Security Manager", .ready = smp_ready_cb, + .recv = smp_recv_cb, .alloc_skb = smp_alloc_skb_cb, .teardown = smp_teardown_cb, .new_connection = l2cap_chan_no_new_connection, - .recv = l2cap_chan_no_recv, .state_change = l2cap_chan_no_state_change, .close = l2cap_chan_no_close, .defer = l2cap_chan_no_defer, @@ -1587,10 +1600,7 @@ int smp_register(struct hci_dev *hdev) chan->data = tfm_aes; - /* FIXME: Using reserved 0x1f value for now - to be changed to - * L2CAP_CID_SMP once all functionality is in place. - */ - l2cap_add_scid(chan, 0x1f); + l2cap_add_scid(chan, L2CAP_CID_SMP); l2cap_chan_set_defaults(chan); diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index d3f6bd617940..161ace3c3234 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -126,7 +126,6 @@ enum { /* SMP Commands */ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); -int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb); int smp_distribute_keys(struct l2cap_conn *conn); int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); -- GitLab From 4807b51895dce8aa650ebebc51fa4a795ed6b8b8 Mon Sep 17 00:00:00 2001 From: Loic Poulain Date: Fri, 8 Aug 2014 19:07:16 +0200 Subject: [PATCH 0377/9167] Bluetooth: Fix HCI H5 corrupted ack value In this expression: seq = (seq - 1) % 8 seq (u8) is implicitly converted to an int in the arithmetic operation. So if seq value is 0, operation is ((0 - 1) % 8) => (-1 % 8) => -1. The new seq value is 0xff which is an invalid ACK value, we expect 0x07. It leads to frequent dropped ACK and retransmission. Fix this by using '&' binary operator instead of '%'. Signed-off-by: Loic Poulain Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org --- drivers/bluetooth/hci_h5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index caacb422995d..a22838669b4e 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -237,7 +237,7 @@ static void h5_pkt_cull(struct h5 *h5) break; to_remove--; - seq = (seq - 1) % 8; + seq = (seq - 1) & 0x07; } if (seq != h5->rx_ack) -- GitLab From ebef9c1236170fb3ba4dc05ccb41f6d842eb1c12 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 8 Aug 2014 17:32:45 +0530 Subject: [PATCH 0378/9167] MAINTAINERS: update maintainers info adds the mailing list address for bluetooth 6loWPAN and IEEE-802.15.4 subsystems. Also adds web page info. Signed-off-by: Varka Bhadram Signed-off-by: Marcel Holtmann --- MAINTAINERS | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 2f85f55c8fb8..5cc0b81e4a33 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -152,8 +152,8 @@ F: drivers/scsi/53c700* 6LOWPAN GENERIC (BTLE/IEEE 802.15.4) M: Alexander Aring -L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) L: linux-bluetooth@vger.kernel.org +L: linux-wpan@vger.kernel.org S: Maintained F: net/6lowpan/ F: include/net/6lowpan.h @@ -4564,13 +4564,14 @@ F: drivers/idle/i7300_idle.c IEEE 802.15.4 SUBSYSTEM M: Alexander Aring -L: linux-zigbee-devel@lists.sourceforge.net (moderated for non-subscribers) -W: http://apps.sourceforge.net/trac/linux-zigbee -T: git git://git.kernel.org/pub/scm/linux/kernel/git/lowpan/lowpan.git +L: linux-wpan@vger.kernel.org +W: https://github.com/linux-wpan +T: git git://github.com/linux-wpan/linux-wpan-next.git S: Maintained F: net/ieee802154/ F: net/mac802154/ F: drivers/net/ieee802154/ +F: Documentation/networking/ieee802154.txt IGUANAWORKS USB IR TRANSCEIVER M: Sean Young -- GitLab From 89d2975fa06e66ea0d3665d91f799fb1ce4b8bad Mon Sep 17 00:00:00 2001 From: Vincent Zwanenburg Date: Fri, 8 Aug 2014 12:33:56 +0100 Subject: [PATCH 0379/9167] Add a new PID/VID 0227/0930 for AR3012. usb devices info: T: Bus=01 Lev=02 Prnt=05 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=0930 ProdID=0227 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: Vincent Zwanenburg 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 a0d7355ef127..d85ced27ebd5 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -88,6 +88,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x300b) }, { USB_DEVICE(0x0930, 0x0219) }, { USB_DEVICE(0x0930, 0x0220) }, + { USB_DEVICE(0x0930, 0x0227) }, { USB_DEVICE(0x0b05, 0x17d0) }, { USB_DEVICE(0x0CF3, 0x0036) }, { USB_DEVICE(0x0CF3, 0x3004) }, @@ -138,6 +139,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 292c38e8aa17..0527b29c3954 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -165,6 +165,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0227), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0b05, 0x17d0), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, -- GitLab From 44f1a7ab51ebe1ca189445837e0599a5edc6efb1 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:36 +0300 Subject: [PATCH 0380/9167] Bluetooth: Use L2CAP resume callback to call smp_distribute_keys There's no need to export the smp_distribute_keys() function since the resume callback is called in the same scenario. This patch makes the smp_notify_keys function private (at the same time moving it higher up in smp.c to avoid forward declarations) and adds a resume callback for SMP to call it from there instead. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 6 - net/bluetooth/smp.c | 380 +++++++++++++++++++------------------ net/bluetooth/smp.h | 1 - 3 files changed, 196 insertions(+), 191 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 40b6c06ab2c0..4de1e1827055 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -7281,12 +7281,6 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); - if (hcon->type == LE_LINK) { - if (!status && encrypt) - smp_distribute_keys(conn); - cancel_delayed_work(&conn->security_timer); - } - mutex_lock(&conn->chan_lock); list_for_each_entry(chan, &conn->chan_l, list) { diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 744f678ac3e8..28014ad3d2d3 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -575,6 +575,189 @@ static u8 smp_random(struct smp_chan *smp) return 0; } +static void smp_notify_keys(struct l2cap_conn *conn) +{ + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; + struct hci_conn *hcon = conn->hcon; + struct hci_dev *hdev = hcon->hdev; + struct smp_cmd_pairing *req = (void *) &smp->preq[1]; + struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; + bool persistent; + + if (smp->remote_irk) { + mgmt_new_irk(hdev, smp->remote_irk); + /* Now that user space can be considered to know the + * identity address track the connection based on it + * from now on. + */ + bacpy(&hcon->dst, &smp->remote_irk->bdaddr); + hcon->dst_type = smp->remote_irk->addr_type; + l2cap_conn_update_id_addr(hcon); + + /* When receiving an indentity resolving key for + * a remote device that does not use a resolvable + * private address, just remove the key so that + * it is possible to use the controller white + * list for scanning. + * + * Userspace will have been told to not store + * this key at this point. So it is safe to + * just remove it. + */ + if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) { + list_del(&smp->remote_irk->list); + kfree(smp->remote_irk); + smp->remote_irk = NULL; + } + } + + /* The LTKs and CSRKs should be persistent only if both sides + * had the bonding bit set in their authentication requests. + */ + persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING); + + if (smp->csrk) { + smp->csrk->bdaddr_type = hcon->dst_type; + bacpy(&smp->csrk->bdaddr, &hcon->dst); + mgmt_new_csrk(hdev, smp->csrk, persistent); + } + + if (smp->slave_csrk) { + smp->slave_csrk->bdaddr_type = hcon->dst_type; + bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); + mgmt_new_csrk(hdev, smp->slave_csrk, persistent); + } + + if (smp->ltk) { + smp->ltk->bdaddr_type = hcon->dst_type; + bacpy(&smp->ltk->bdaddr, &hcon->dst); + mgmt_new_ltk(hdev, smp->ltk, persistent); + } + + if (smp->slave_ltk) { + smp->slave_ltk->bdaddr_type = hcon->dst_type; + bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); + mgmt_new_ltk(hdev, smp->slave_ltk, persistent); + } +} + +static int smp_distribute_keys(struct l2cap_conn *conn) +{ + struct smp_cmd_pairing *req, *rsp; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; + struct hci_conn *hcon = conn->hcon; + struct hci_dev *hdev = hcon->hdev; + __u8 *keydist; + + BT_DBG("conn %p", conn); + + if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) + return 0; + + rsp = (void *) &smp->prsp[1]; + + /* The responder sends its keys first */ + if (hcon->out && (smp->remote_key_dist & 0x07)) + return 0; + + req = (void *) &smp->preq[1]; + + if (hcon->out) { + keydist = &rsp->init_key_dist; + *keydist &= req->init_key_dist; + } else { + keydist = &rsp->resp_key_dist; + *keydist &= req->resp_key_dist; + } + + BT_DBG("keydist 0x%x", *keydist); + + if (*keydist & SMP_DIST_ENC_KEY) { + struct smp_cmd_encrypt_info enc; + struct smp_cmd_master_ident ident; + struct smp_ltk *ltk; + u8 authenticated; + __le16 ediv; + __le64 rand; + + get_random_bytes(enc.ltk, sizeof(enc.ltk)); + get_random_bytes(&ediv, sizeof(ediv)); + get_random_bytes(&rand, sizeof(rand)); + + smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); + + authenticated = hcon->sec_level == BT_SECURITY_HIGH; + ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, + SMP_LTK_SLAVE, authenticated, enc.ltk, + smp->enc_key_size, ediv, rand); + smp->slave_ltk = ltk; + + ident.ediv = ediv; + ident.rand = rand; + + smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); + + *keydist &= ~SMP_DIST_ENC_KEY; + } + + if (*keydist & SMP_DIST_ID_KEY) { + struct smp_cmd_ident_addr_info addrinfo; + struct smp_cmd_ident_info idinfo; + + memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); + + smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); + + /* The hci_conn contains the local identity address + * after the connection has been established. + * + * This is true even when the connection has been + * established using a resolvable random address. + */ + bacpy(&addrinfo.bdaddr, &hcon->src); + addrinfo.addr_type = hcon->src_type; + + smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), + &addrinfo); + + *keydist &= ~SMP_DIST_ID_KEY; + } + + if (*keydist & SMP_DIST_SIGN) { + struct smp_cmd_sign_info sign; + struct smp_csrk *csrk; + + /* Generate a new random key */ + get_random_bytes(sign.csrk, sizeof(sign.csrk)); + + csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); + if (csrk) { + csrk->master = 0x00; + memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); + } + smp->slave_csrk = csrk; + + smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); + + *keydist &= ~SMP_DIST_SIGN; + } + + /* If there are still keys to be received wait for them */ + if ((smp->remote_key_dist & 0x07)) + return 0; + + clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); + cancel_delayed_work_sync(&conn->security_timer); + set_bit(SMP_FLAG_COMPLETE, &smp->flags); + smp_notify_keys(conn); + + smp_chan_destroy(conn); + + return 0; +} + static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) { struct l2cap_chan *chan = conn->smp; @@ -1294,189 +1477,6 @@ static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) return err; } -static void smp_notify_keys(struct l2cap_conn *conn) -{ - struct l2cap_chan *chan = conn->smp; - struct smp_chan *smp = chan->data; - struct hci_conn *hcon = conn->hcon; - struct hci_dev *hdev = hcon->hdev; - struct smp_cmd_pairing *req = (void *) &smp->preq[1]; - struct smp_cmd_pairing *rsp = (void *) &smp->prsp[1]; - bool persistent; - - if (smp->remote_irk) { - mgmt_new_irk(hdev, smp->remote_irk); - /* Now that user space can be considered to know the - * identity address track the connection based on it - * from now on. - */ - bacpy(&hcon->dst, &smp->remote_irk->bdaddr); - hcon->dst_type = smp->remote_irk->addr_type; - l2cap_conn_update_id_addr(hcon); - - /* When receiving an indentity resolving key for - * a remote device that does not use a resolvable - * private address, just remove the key so that - * it is possible to use the controller white - * list for scanning. - * - * Userspace will have been told to not store - * this key at this point. So it is safe to - * just remove it. - */ - if (!bacmp(&smp->remote_irk->rpa, BDADDR_ANY)) { - list_del(&smp->remote_irk->list); - kfree(smp->remote_irk); - smp->remote_irk = NULL; - } - } - - /* The LTKs and CSRKs should be persistent only if both sides - * had the bonding bit set in their authentication requests. - */ - persistent = !!((req->auth_req & rsp->auth_req) & SMP_AUTH_BONDING); - - if (smp->csrk) { - smp->csrk->bdaddr_type = hcon->dst_type; - bacpy(&smp->csrk->bdaddr, &hcon->dst); - mgmt_new_csrk(hdev, smp->csrk, persistent); - } - - if (smp->slave_csrk) { - smp->slave_csrk->bdaddr_type = hcon->dst_type; - bacpy(&smp->slave_csrk->bdaddr, &hcon->dst); - mgmt_new_csrk(hdev, smp->slave_csrk, persistent); - } - - if (smp->ltk) { - smp->ltk->bdaddr_type = hcon->dst_type; - bacpy(&smp->ltk->bdaddr, &hcon->dst); - mgmt_new_ltk(hdev, smp->ltk, persistent); - } - - if (smp->slave_ltk) { - smp->slave_ltk->bdaddr_type = hcon->dst_type; - bacpy(&smp->slave_ltk->bdaddr, &hcon->dst); - mgmt_new_ltk(hdev, smp->slave_ltk, persistent); - } -} - -int smp_distribute_keys(struct l2cap_conn *conn) -{ - struct smp_cmd_pairing *req, *rsp; - struct l2cap_chan *chan = conn->smp; - struct smp_chan *smp = chan->data; - struct hci_conn *hcon = conn->hcon; - struct hci_dev *hdev = hcon->hdev; - __u8 *keydist; - - BT_DBG("conn %p", conn); - - if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) - return 0; - - rsp = (void *) &smp->prsp[1]; - - /* The responder sends its keys first */ - if (hcon->out && (smp->remote_key_dist & 0x07)) - return 0; - - req = (void *) &smp->preq[1]; - - if (hcon->out) { - keydist = &rsp->init_key_dist; - *keydist &= req->init_key_dist; - } else { - keydist = &rsp->resp_key_dist; - *keydist &= req->resp_key_dist; - } - - BT_DBG("keydist 0x%x", *keydist); - - if (*keydist & SMP_DIST_ENC_KEY) { - struct smp_cmd_encrypt_info enc; - struct smp_cmd_master_ident ident; - struct smp_ltk *ltk; - u8 authenticated; - __le16 ediv; - __le64 rand; - - get_random_bytes(enc.ltk, sizeof(enc.ltk)); - get_random_bytes(&ediv, sizeof(ediv)); - get_random_bytes(&rand, sizeof(rand)); - - smp_send_cmd(conn, SMP_CMD_ENCRYPT_INFO, sizeof(enc), &enc); - - authenticated = hcon->sec_level == BT_SECURITY_HIGH; - ltk = hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, - SMP_LTK_SLAVE, authenticated, enc.ltk, - smp->enc_key_size, ediv, rand); - smp->slave_ltk = ltk; - - ident.ediv = ediv; - ident.rand = rand; - - smp_send_cmd(conn, SMP_CMD_MASTER_IDENT, sizeof(ident), &ident); - - *keydist &= ~SMP_DIST_ENC_KEY; - } - - if (*keydist & SMP_DIST_ID_KEY) { - struct smp_cmd_ident_addr_info addrinfo; - struct smp_cmd_ident_info idinfo; - - memcpy(idinfo.irk, hdev->irk, sizeof(idinfo.irk)); - - smp_send_cmd(conn, SMP_CMD_IDENT_INFO, sizeof(idinfo), &idinfo); - - /* The hci_conn contains the local identity address - * after the connection has been established. - * - * This is true even when the connection has been - * established using a resolvable random address. - */ - bacpy(&addrinfo.bdaddr, &hcon->src); - addrinfo.addr_type = hcon->src_type; - - smp_send_cmd(conn, SMP_CMD_IDENT_ADDR_INFO, sizeof(addrinfo), - &addrinfo); - - *keydist &= ~SMP_DIST_ID_KEY; - } - - if (*keydist & SMP_DIST_SIGN) { - struct smp_cmd_sign_info sign; - struct smp_csrk *csrk; - - /* Generate a new random key */ - get_random_bytes(sign.csrk, sizeof(sign.csrk)); - - csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); - if (csrk) { - csrk->master = 0x00; - memcpy(csrk->val, sign.csrk, sizeof(csrk->val)); - } - smp->slave_csrk = csrk; - - smp_send_cmd(conn, SMP_CMD_SIGN_INFO, sizeof(sign), &sign); - - *keydist &= ~SMP_DIST_SIGN; - } - - /* If there are still keys to be received wait for them */ - if ((smp->remote_key_dist & 0x07)) - return 0; - - clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); - cancel_delayed_work_sync(&conn->security_timer); - set_bit(SMP_FLAG_COMPLETE, &smp->flags); - smp_notify_keys(conn); - - smp_chan_destroy(conn); - - return 0; -} - static void smp_teardown_cb(struct l2cap_chan *chan, int err) { struct l2cap_conn *conn = chan->conn; @@ -1492,6 +1492,18 @@ static void smp_teardown_cb(struct l2cap_chan *chan, int err) l2cap_chan_put(chan); } +static void smp_resume_cb(struct l2cap_chan *chan) +{ + struct l2cap_conn *conn = chan->conn; + struct hci_conn *hcon = conn->hcon; + + BT_DBG("chan %p", chan); + + if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) + smp_distribute_keys(conn); + cancel_delayed_work(&conn->security_timer); +} + static void smp_ready_cb(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; @@ -1524,13 +1536,13 @@ static const struct l2cap_ops smp_chan_ops = { .recv = smp_recv_cb, .alloc_skb = smp_alloc_skb_cb, .teardown = smp_teardown_cb, + .resume = smp_resume_cb, .new_connection = l2cap_chan_no_new_connection, .state_change = l2cap_chan_no_state_change, .close = l2cap_chan_no_close, .defer = l2cap_chan_no_defer, .suspend = l2cap_chan_no_suspend, - .resume = l2cap_chan_no_resume, .set_shutdown = l2cap_chan_no_set_shutdown, .get_sndtimeo = l2cap_chan_no_get_sndtimeo, .memcpy_fromiovec = l2cap_chan_no_memcpy_fromiovec, diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 161ace3c3234..59a594278a85 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -126,7 +126,6 @@ enum { /* SMP Commands */ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); -int smp_distribute_keys(struct l2cap_conn *conn); int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey); void smp_chan_destroy(struct l2cap_conn *conn); -- GitLab From dec5b49235e2526d7aacf5b93ea48f5e30c2f7c3 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:37 +0300 Subject: [PATCH 0381/9167] Bluetooth: Add public l2cap_conn_shutdown() API to request disconnection Since we no-longer do special handling of SMP within l2cap_core.c we don't have any code for calling l2cap_conn_del() when smp.c doesn't like the data it gets. At the same time we cannot simply export l2cap_conn_del() since it will try to lock the channels it calls into whereas we already hold the lock in the smp.c l2cap_chan callbacks (i.e. it'd lead to a deadlock). This patch adds a new l2cap_conn_shutdown() API which is very similar to l2cap_conn_del() except that it defers the call to l2cap_conn_del() through a workqueue, thereby making it safe to use it from an L2CAP channel callback. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 4 ++++ net/bluetooth/l2cap_core.c | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index bda6252e3722..40f34866b6da 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -625,6 +625,9 @@ struct l2cap_conn { struct delayed_work info_timer; + int disconn_err; + struct work_struct disconn_work; + struct sk_buff *rx_skb; __u32 rx_len; __u8 tx_ident; @@ -944,6 +947,7 @@ void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, u8 status); void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); +void l2cap_conn_shutdown(struct l2cap_conn *conn, int err); void l2cap_conn_get(struct l2cap_conn *conn); void l2cap_conn_put(struct l2cap_conn *conn); diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 4de1e1827055..404998efa7e2 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1627,6 +1627,9 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) if (work_pending(&conn->pending_rx_work)) cancel_work_sync(&conn->pending_rx_work); + if (work_pending(&conn->disconn_work)) + cancel_work_sync(&conn->disconn_work); + l2cap_unregister_all_users(conn); mutex_lock(&conn->chan_lock); @@ -1669,6 +1672,26 @@ static void security_timeout(struct work_struct *work) } } +static void disconn_work(struct work_struct *work) +{ + struct l2cap_conn *conn = container_of(work, struct l2cap_conn, + disconn_work); + + BT_DBG("conn %p", conn); + + l2cap_conn_del(conn->hcon, conn->disconn_err); +} + +void l2cap_conn_shutdown(struct l2cap_conn *conn, int err) +{ + struct hci_dev *hdev = conn->hcon->hdev; + + BT_DBG("conn %p err %d", conn, err); + + conn->disconn_err = err; + queue_work(hdev->workqueue, &conn->disconn_work); +} + static void l2cap_conn_free(struct kref *ref) { struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref); @@ -6930,6 +6953,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) else INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); + INIT_WORK(&conn->disconn_work, disconn_work); + skb_queue_head_init(&conn->pending_rx); INIT_WORK(&conn->pending_rx_work, process_pending_rx); -- GitLab From 4befb867b9de8adc56c683f4cf6c9e6c035e94e3 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:38 +0300 Subject: [PATCH 0382/9167] Bluetooth: Call l2cap_conn_shutdown() when SMP recv callback fails To restore pre-l2cap_chan functionality we should be trying to disconnect the connection when receviving garbage SMP data (i.e. when the SMP command handler fails). This patch renames the command handler back to smp_sig_channel() and adds a smp_recv_cb() wrapper function for calling it. If smp_sig_channel() fails the code calls l2cap_conn_shutdown(). Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 28014ad3d2d3..7a295d7edc44 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1375,7 +1375,7 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) return 0; } -static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) +static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) { struct l2cap_conn *conn = chan->conn; struct hci_conn *hcon = conn->hcon; @@ -1514,6 +1514,24 @@ static void smp_ready_cb(struct l2cap_chan *chan) l2cap_chan_hold(chan); } +static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) +{ + int err; + + BT_DBG("chan %p", chan); + + err = smp_sig_channel(chan, skb); + if (err) { + struct l2cap_conn *conn = chan->conn; + + cancel_delayed_work_sync(&conn->security_timer); + + l2cap_conn_shutdown(chan->conn, -err); + } + + return err; +} + static struct sk_buff *smp_alloc_skb_cb(struct l2cap_chan *chan, unsigned long hdr_len, unsigned long len, int nb) -- GitLab From 8ae9b9845b3252216cf5d2e033e5cca41bae48ef Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:39 +0300 Subject: [PATCH 0383/9167] Bluetooth: Fix double free of SMP data skb In the case that the SMP recv callback returns error the calling code in l2cap_core.c expects that it still owns the skb and will try to free it. The SMP code should therefore not try to free the skb if it return an error. This patch fixes such behavior in the SMP command handler function. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 7a295d7edc44..5103dc739a17 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1387,10 +1387,8 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) return 0; } - if (skb->len < 1) { - kfree_skb(skb); + if (skb->len < 1) return -EILSEQ; - } if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) { err = -EOPNOTSUPP; @@ -1410,8 +1408,9 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); - kfree_skb(skb); - return -EOPNOTSUPP; + reason = SMP_CMD_NOTSUPP; + err = -EOPNOTSUPP; + goto done; } switch (code) { @@ -1472,8 +1471,8 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) done: if (reason) smp_failure(conn, reason); - - kfree_skb(skb); + if (!err) + kfree_skb(skb); return err; } -- GitLab From b68fda6848ebef3499905500971d40b84faa8319 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:40 +0300 Subject: [PATCH 0384/9167] Bluetooth: Add SMP-internal timeout callback This patch adds an SMP-internal timeout callback to remove the depenency on (the soon to be removed) l2cap_conn->security_timer. The behavior is the same as with l2cap_conn->security_timer except that the new l2cap_conn_shutdown() public function is used instead of the L2CAP core internal l2cap_conn_del(). Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 52 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 5103dc739a17..7ab5f52955cb 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -44,7 +44,9 @@ enum { }; struct smp_chan { - struct l2cap_conn *conn; + struct l2cap_conn *conn; + struct delayed_work security_timer; + u8 preq[7]; /* SMP Pairing Request */ u8 prsp[7]; /* SMP Pairing Response */ u8 prnd[16]; /* SMP Pairing Random (local) */ @@ -251,6 +253,7 @@ static int smp_s1(struct smp_chan *smp, u8 k[16], u8 r1[16], u8 r2[16], static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) { struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp; struct kvec iv[2]; struct msghdr msg; @@ -272,8 +275,14 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) l2cap_chan_send(chan, &msg, 1 + len); - cancel_delayed_work_sync(&conn->security_timer); - schedule_delayed_work(&conn->security_timer, SMP_TIMEOUT); + if (!chan->data) + return; + + smp = chan->data; + + cancel_delayed_work_sync(&smp->security_timer); + if (test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) + schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); } static __u8 authreq_to_seclevel(__u8 authreq) @@ -359,6 +368,8 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) static void smp_failure(struct l2cap_conn *conn, u8 reason) { struct hci_conn *hcon = conn->hcon; + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp; if (reason) smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), @@ -368,7 +379,12 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason) mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, HCI_ERROR_AUTH_FAILURE); - cancel_delayed_work_sync(&conn->security_timer); + if (!chan->data) + return; + + smp = chan->data; + + cancel_delayed_work_sync(&smp->security_timer); if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) smp_chan_destroy(conn); @@ -749,7 +765,7 @@ static int smp_distribute_keys(struct l2cap_conn *conn) return 0; clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); - cancel_delayed_work_sync(&conn->security_timer); + cancel_delayed_work_sync(&smp->security_timer); set_bit(SMP_FLAG_COMPLETE, &smp->flags); smp_notify_keys(conn); @@ -758,6 +774,17 @@ static int smp_distribute_keys(struct l2cap_conn *conn) return 0; } +static void smp_timeout(struct work_struct *work) +{ + struct smp_chan *smp = container_of(work, struct smp_chan, + security_timer.work); + struct l2cap_conn *conn = smp->conn; + + BT_DBG("conn %p", conn); + + l2cap_conn_shutdown(conn, ETIMEDOUT); +} + static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) { struct l2cap_chan *chan = conn->smp; @@ -780,6 +807,8 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) smp->conn = conn; chan->data = smp; + INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); + hci_conn_hold(conn->hcon); return smp; @@ -1479,11 +1508,12 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) static void smp_teardown_cb(struct l2cap_chan *chan, int err) { struct l2cap_conn *conn = chan->conn; + struct smp_chan *smp = chan->data; BT_DBG("chan %p", chan); if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { - cancel_delayed_work_sync(&conn->security_timer); + cancel_delayed_work_sync(&smp->security_timer); smp_chan_destroy(conn); } @@ -1493,6 +1523,7 @@ static void smp_teardown_cb(struct l2cap_chan *chan, int err) static void smp_resume_cb(struct l2cap_chan *chan) { + struct smp_chan *smp = chan->data; struct l2cap_conn *conn = chan->conn; struct hci_conn *hcon = conn->hcon; @@ -1500,7 +1531,9 @@ static void smp_resume_cb(struct l2cap_chan *chan) if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) smp_distribute_keys(conn); - cancel_delayed_work(&conn->security_timer); + + if (smp) + cancel_delayed_work(&smp->security_timer); } static void smp_ready_cb(struct l2cap_chan *chan) @@ -1521,9 +1554,10 @@ static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) err = smp_sig_channel(chan, skb); if (err) { - struct l2cap_conn *conn = chan->conn; + struct smp_chan *smp = chan->data; - cancel_delayed_work_sync(&conn->security_timer); + if (smp) + cancel_delayed_work_sync(&smp->security_timer); l2cap_conn_shutdown(chan->conn, -err); } -- GitLab From 276d807317dead63ef2f13aa46e3c17d57ba0713 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:41 +0300 Subject: [PATCH 0385/9167] Bluetooth: Remove unused l2cap_conn->security_timer Now that there are no-longer any users for l2cap_conn->security_timer we can go ahead and simply remove it. The patch makes initialization of the conn->info_timer unconditional since it's better not to leave any l2cap_conn data structures uninitialized no matter what the underlying transport. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- include/net/bluetooth/l2cap.h | 1 - net/bluetooth/l2cap_core.c | 18 +----------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 40f34866b6da..cedda399f9c0 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -638,7 +638,6 @@ struct l2cap_conn { __u8 disc_reason; - struct delayed_work security_timer; struct l2cap_chan *smp; struct list_head chan_l; diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 404998efa7e2..0cd7ed99558b 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1659,19 +1659,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) l2cap_conn_put(conn); } -static void security_timeout(struct work_struct *work) -{ - struct l2cap_conn *conn = container_of(work, struct l2cap_conn, - security_timer.work); - - BT_DBG("conn %p", conn); - - if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { - smp_chan_destroy(conn); - l2cap_conn_del(conn->hcon, ETIMEDOUT); - } -} - static void disconn_work(struct work_struct *work) { struct l2cap_conn *conn = container_of(work, struct l2cap_conn, @@ -6948,10 +6935,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) INIT_LIST_HEAD(&conn->chan_l); INIT_LIST_HEAD(&conn->users); - if (hcon->type == LE_LINK) - INIT_DELAYED_WORK(&conn->security_timer, security_timeout); - else - INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); + INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); INIT_WORK(&conn->disconn_work, disconn_work); -- GitLab From 109ec2309eb996fbe03302fbd40dec9014c6f849 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:42 +0300 Subject: [PATCH 0386/9167] Bluetooth: Move canceling security_timer into smp_chan_destroy() All places needing to cancel the security timer also call smp_chan_destroy() in the same go. To eliminate the need to do these two calls in multiple places simply move the timer cancellation into smp_chan_destroy(). Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 7ab5f52955cb..cdae40869447 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -384,8 +384,6 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason) smp = chan->data; - cancel_delayed_work_sync(&smp->security_timer); - if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) smp_chan_destroy(conn); } @@ -765,7 +763,6 @@ static int smp_distribute_keys(struct l2cap_conn *conn) return 0; clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); - cancel_delayed_work_sync(&smp->security_timer); set_bit(SMP_FLAG_COMPLETE, &smp->flags); smp_notify_keys(conn); @@ -822,6 +819,11 @@ void smp_chan_destroy(struct l2cap_conn *conn) BUG_ON(!smp); + cancel_delayed_work_sync(&smp->security_timer); + /* In case the timeout freed the SMP context */ + if (!chan->data) + return; + complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); mgmt_smp_complete(conn->hcon, complete); @@ -1512,10 +1514,8 @@ static void smp_teardown_cb(struct l2cap_chan *chan, int err) BT_DBG("chan %p", chan); - if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { - cancel_delayed_work_sync(&smp->security_timer); + if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) smp_chan_destroy(conn); - } conn->smp = NULL; l2cap_chan_put(chan); -- GitLab From 86d1407cb9cd3cb866eae24a2aedb8006160db69 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:43 +0300 Subject: [PATCH 0387/9167] Bluetooth: Always call smp_distribute_keys() from a workqueue The smp_distribute_keys() function calls smp_notify_keys() which in turn calls l2cap_conn_update_id_addr(). The l2cap_conn_update_id_addr() function will iterate through all L2CAP channels for the respective connection: lock the channel, update the address information and unlock the channel. Since SMP is now using l2cap_chan callbacks each callback is called with the channel lock held. Therefore, calling l2cap_conn_update_id_addr() would cause a deadlock calling l2cap_chan_lock() on the SMP channel. This patch moves calling smp_distribute_keys() through a workqueue so that it is never called from an L2CAP channel callback. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index cdae40869447..312ea5ec2d7d 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -46,6 +46,7 @@ enum { struct smp_chan { struct l2cap_conn *conn; struct delayed_work security_timer; + struct work_struct distribute_work; u8 preq[7]; /* SMP Pairing Request */ u8 prsp[7]; /* SMP Pairing Response */ @@ -656,11 +657,12 @@ static void smp_notify_keys(struct l2cap_conn *conn) } } -static int smp_distribute_keys(struct l2cap_conn *conn) +static void smp_distribute_keys(struct work_struct *work) { + struct smp_chan *smp = container_of(work, struct smp_chan, + distribute_work); struct smp_cmd_pairing *req, *rsp; - struct l2cap_chan *chan = conn->smp; - struct smp_chan *smp = chan->data; + struct l2cap_conn *conn = smp->conn; struct hci_conn *hcon = conn->hcon; struct hci_dev *hdev = hcon->hdev; __u8 *keydist; @@ -668,13 +670,13 @@ static int smp_distribute_keys(struct l2cap_conn *conn) BT_DBG("conn %p", conn); if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) - return 0; + return; rsp = (void *) &smp->prsp[1]; /* The responder sends its keys first */ if (hcon->out && (smp->remote_key_dist & 0x07)) - return 0; + return; req = (void *) &smp->preq[1]; @@ -760,15 +762,13 @@ static int smp_distribute_keys(struct l2cap_conn *conn) /* If there are still keys to be received wait for them */ if ((smp->remote_key_dist & 0x07)) - return 0; + return; clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); set_bit(SMP_FLAG_COMPLETE, &smp->flags); smp_notify_keys(conn); smp_chan_destroy(conn); - - return 0; } static void smp_timeout(struct work_struct *work) @@ -804,6 +804,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) smp->conn = conn; chan->data = smp; + INIT_WORK(&smp->distribute_work, smp_distribute_keys); INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); hci_conn_hold(conn->hcon); @@ -824,6 +825,12 @@ void smp_chan_destroy(struct l2cap_conn *conn) if (!chan->data) return; + if (work_pending(&smp->distribute_work)) { + cancel_work_sync(&smp->distribute_work); + if (!chan->data) + return; + } + complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); mgmt_smp_complete(conn->hcon, complete); @@ -1287,7 +1294,7 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) rp->ediv, rp->rand); smp->ltk = ltk; if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) - smp_distribute_keys(conn); + queue_work(hdev->workqueue, &smp->distribute_work); hci_dev_unlock(hdev); return 0; @@ -1322,6 +1329,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, struct l2cap_chan *chan = conn->smp; struct smp_chan *smp = chan->data; struct hci_conn *hcon = conn->hcon; + struct hci_dev *hdev = hcon->hdev; bdaddr_t rpa; BT_DBG(""); @@ -1364,7 +1372,7 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, smp->id_addr_type, smp->irk, &rpa); distribute: - smp_distribute_keys(conn); + queue_work(hdev->workqueue, &smp->distribute_work); hci_dev_unlock(hcon->hdev); @@ -1400,7 +1408,7 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); } smp->csrk = csrk; - smp_distribute_keys(conn); + queue_work(hdev->workqueue, &smp->distribute_work); hci_dev_unlock(hdev); return 0; @@ -1510,7 +1518,6 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) static void smp_teardown_cb(struct l2cap_chan *chan, int err) { struct l2cap_conn *conn = chan->conn; - struct smp_chan *smp = chan->data; BT_DBG("chan %p", chan); @@ -1526,14 +1533,17 @@ static void smp_resume_cb(struct l2cap_chan *chan) struct smp_chan *smp = chan->data; struct l2cap_conn *conn = chan->conn; struct hci_conn *hcon = conn->hcon; + struct hci_dev *hdev = hcon->hdev; BT_DBG("chan %p", chan); - if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) - smp_distribute_keys(conn); + if (!smp) + return; - if (smp) - cancel_delayed_work(&smp->security_timer); + cancel_delayed_work(&smp->security_timer); + + if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) + queue_work(hdev->workqueue, &smp->distribute_work); } static void smp_ready_cb(struct l2cap_chan *chan) -- GitLab From 6f48e260a95c1a0161e5be39adb0f20c737fe459 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 11 Aug 2014 22:06:44 +0300 Subject: [PATCH 0388/9167] Bluetooth: Make smp_chan_destroy() private to smp.c There are no external users of smp_chan_destroy() so make it private to smp.c. The patch also moves the function higher up in the c-file in order to avoid forward declarations. Signed-off-by: Johan Hedberg Signed-off-by: Marcel Holtmann --- net/bluetooth/smp.c | 100 ++++++++++++++++++++++---------------------- net/bluetooth/smp.h | 2 - 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 312ea5ec2d7d..07ca4ce0943b 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -366,6 +366,56 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) return 0; } +static void smp_chan_destroy(struct l2cap_conn *conn) +{ + struct l2cap_chan *chan = conn->smp; + struct smp_chan *smp = chan->data; + bool complete; + + BUG_ON(!smp); + + cancel_delayed_work_sync(&smp->security_timer); + /* In case the timeout freed the SMP context */ + if (!chan->data) + return; + + if (work_pending(&smp->distribute_work)) { + cancel_work_sync(&smp->distribute_work); + if (!chan->data) + return; + } + + complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); + mgmt_smp_complete(conn->hcon, complete); + + kfree(smp->csrk); + kfree(smp->slave_csrk); + + crypto_free_blkcipher(smp->tfm_aes); + + /* If pairing failed clean up any keys we might have */ + if (!complete) { + if (smp->ltk) { + list_del(&smp->ltk->list); + kfree(smp->ltk); + } + + if (smp->slave_ltk) { + list_del(&smp->slave_ltk->list); + kfree(smp->slave_ltk); + } + + if (smp->remote_irk) { + list_del(&smp->remote_irk->list); + kfree(smp->remote_irk); + } + } + + chan->data = NULL; + kfree(smp); + hci_conn_drop(conn->hcon); +} + static void smp_failure(struct l2cap_conn *conn, u8 reason) { struct hci_conn *hcon = conn->hcon; @@ -812,56 +862,6 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) return smp; } -void smp_chan_destroy(struct l2cap_conn *conn) -{ - struct l2cap_chan *chan = conn->smp; - struct smp_chan *smp = chan->data; - bool complete; - - BUG_ON(!smp); - - cancel_delayed_work_sync(&smp->security_timer); - /* In case the timeout freed the SMP context */ - if (!chan->data) - return; - - if (work_pending(&smp->distribute_work)) { - cancel_work_sync(&smp->distribute_work); - if (!chan->data) - return; - } - - complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); - mgmt_smp_complete(conn->hcon, complete); - - kfree(smp->csrk); - kfree(smp->slave_csrk); - - crypto_free_blkcipher(smp->tfm_aes); - - /* If pairing failed clean up any keys we might have */ - if (!complete) { - if (smp->ltk) { - list_del(&smp->ltk->list); - kfree(smp->ltk); - } - - if (smp->slave_ltk) { - list_del(&smp->slave_ltk->list); - kfree(smp->slave_ltk); - } - - if (smp->remote_irk) { - list_del(&smp->remote_irk->list); - kfree(smp->remote_irk); - } - } - - chan->data = NULL; - kfree(smp); - hci_conn_drop(conn->hcon); -} - int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) { struct l2cap_conn *conn = hcon->l2cap_data; diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index 59a594278a85..cf1094617c69 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h @@ -128,8 +128,6 @@ bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); 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); -void smp_chan_destroy(struct l2cap_conn *conn); - bool smp_irk_matches(struct hci_dev *hdev, u8 irk[16], bdaddr_t *bdaddr); int smp_generate_rpa(struct hci_dev *hdev, u8 irk[16], bdaddr_t *rpa); -- GitLab From 24bbd44a96c7a209fafbf1b28f0ac1a00cf4e551 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Mon, 11 Aug 2014 13:25:07 +0200 Subject: [PATCH 0389/9167] mac802154: cleanup in rx path This patch replace the sizeof(struct rx_work) with sizeof(*work) and directly passing the skb in mac802154_subif_rx() Signed-off-by: Varka Bhadram Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/rx.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index 7f820a108a9c..a14cf9ede171 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -86,9 +86,8 @@ mac802154_subif_rx(struct ieee802154_dev *hw, struct sk_buff *skb, u8 lqi) static void mac802154_rx_worker(struct work_struct *work) { struct rx_work *rw = container_of(work, struct rx_work, work); - struct sk_buff *skb = rw->skb; - mac802154_subif_rx(rw->dev, skb, rw->lqi); + mac802154_subif_rx(rw->dev, rw->skb, rw->lqi); kfree(rw); } @@ -101,7 +100,7 @@ ieee802154_rx_irqsafe(struct ieee802154_dev *dev, struct sk_buff *skb, u8 lqi) if (!skb) return; - work = kzalloc(sizeof(struct rx_work), GFP_ATOMIC); + work = kzalloc(sizeof(*work), GFP_ATOMIC); if (!work) return; -- GitLab From b288a4963f09459c29cca240d3352cc7915710fc Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Mon, 11 Aug 2014 13:25:08 +0200 Subject: [PATCH 0390/9167] mac802154: common error path By introducing label fail, making the common error path for mac802154_llsec_decrypt() and packet type default case. Signed-off-by: Varka Bhadram Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/wpan.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/mac802154/wpan.c b/net/mac802154/wpan.c index 3c3069fd6971..ce1757001917 100644 --- a/net/mac802154/wpan.c +++ b/net/mac802154/wpan.c @@ -472,8 +472,7 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, rc = mac802154_llsec_decrypt(&sdata->sec, skb); if (rc) { pr_debug("decryption failed: %i\n", rc); - kfree_skb(skb); - return NET_RX_DROP; + goto fail; } sdata->dev->stats.rx_packets++; @@ -485,9 +484,12 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb, default: pr_warn("ieee802154: bad frame received (type = %d)\n", mac_cb(skb)->type); - kfree_skb(skb); - return NET_RX_DROP; + goto fail; } + +fail: + kfree_skb(skb); + return NET_RX_DROP; } static void mac802154_print_addr(const char *name, -- GitLab From 0ba1f94e72b811215ce2f4610fe0f6cf88f4b28a Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Mon, 11 Aug 2014 13:25:09 +0200 Subject: [PATCH 0391/9167] ieee802154: 6lowpan: remove unused function Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/ieee802154/6lowpan_rtnl.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c index 016b77ee88f0..509d7a625a4b 100644 --- a/net/ieee802154/6lowpan_rtnl.c +++ b/net/ieee802154/6lowpan_rtnl.c @@ -77,14 +77,6 @@ lowpan_dev_info *lowpan_dev_info(const struct net_device *dev) return netdev_priv(dev); } -static inline void lowpan_address_flip(u8 *src, u8 *dest) -{ - int i; - - for (i = 0; i < IEEE802154_ADDR_LEN; i++) - (dest)[IEEE802154_ADDR_LEN - i - 1] = (src)[i]; -} - static int lowpan_header_create(struct sk_buff *skb, struct net_device *dev, unsigned short type, const void *_daddr, const void *_saddr, unsigned int len) -- GitLab From f55889128a776b51581394b20abd0b470304cf95 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Mon, 11 Aug 2014 13:25:10 +0200 Subject: [PATCH 0392/9167] mac802154: common tx error path This patch introduce the common error path on failure of Tx by inserting the label 'err_tx'. Signed-off-by: Varka Bhadram Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- net/mac802154/tx.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c index 8124353646ae..fdf4c0e67259 100644 --- a/net/mac802154/tx.c +++ b/net/mac802154/tx.c @@ -89,8 +89,7 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, if (!(priv->phy->channels_supported[page] & (1 << chan))) { WARN_ON(1); - kfree_skb(skb); - return NETDEV_TX_OK; + goto err_tx; } mac802154_monitors_rx(mac802154_to_priv(&priv->hw), skb); @@ -103,12 +102,10 @@ 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)) { - kfree_skb(skb); - return NETDEV_TX_OK; - } + if (skb_cow_head(skb, priv->hw.extra_tx_headroom)) + goto err_tx; - work = kzalloc(sizeof(struct xmit_work), GFP_ATOMIC); + work = kzalloc(sizeof(*work), GFP_ATOMIC); if (!work) { kfree_skb(skb); return NETDEV_TX_BUSY; @@ -129,4 +126,8 @@ netdev_tx_t mac802154_tx(struct mac802154_priv *priv, struct sk_buff *skb, queue_work(priv->dev_workqueue, &work->work); return NETDEV_TX_OK; + +err_tx: + kfree_skb(skb); + return NETDEV_TX_OK; } -- GitLab From d664cd9895b498da4fea3b43c72b4aacfc4126a2 Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Wed, 13 Aug 2014 14:53:31 +0530 Subject: [PATCH 0393/9167] Bluetooth: Remove typedef bluecard_info_t The Linux kernel coding style guidelines suggest not using typedefs for structure types. This patch gets rid of the typedef for bluecard_info_t. Also, the name of the struct is changed to drop the _t, to make the name look less typedef-like. The following Coccinelle semantic patch detects the case: @tn@ identifier i; type td; @@ -typedef struct i { ... } -td ; @@ type tn.td; identifier tn.i; @@ -td + struct i Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bluecard_cs.c | 35 +++++++++++++++++---------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index dfa5043e68ba..35e63aaa6f80 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c @@ -61,7 +61,7 @@ MODULE_LICENSE("GPL"); /* ======================== Local structures ======================== */ -typedef struct bluecard_info_t { +struct bluecard_info { struct pcmcia_device *p_dev; struct hci_dev *hdev; @@ -78,7 +78,7 @@ typedef struct bluecard_info_t { unsigned char ctrl_reg; unsigned long hw_state; /* Status of the hardware and LED control */ -} bluecard_info_t; +}; static int bluecard_config(struct pcmcia_device *link); @@ -157,7 +157,7 @@ static void bluecard_detach(struct pcmcia_device *p_dev); static void bluecard_activity_led_timeout(u_long arg) { - bluecard_info_t *info = (bluecard_info_t *)arg; + struct bluecard_info *info = (struct bluecard_info *)arg; unsigned int iobase = info->p_dev->resource[0]->start; if (!test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) @@ -173,7 +173,7 @@ static void bluecard_activity_led_timeout(u_long arg) } -static void bluecard_enable_activity_led(bluecard_info_t *info) +static void bluecard_enable_activity_led(struct bluecard_info *info) { unsigned int iobase = info->p_dev->resource[0]->start; @@ -215,7 +215,7 @@ static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, i } -static void bluecard_write_wakeup(bluecard_info_t *info) +static void bluecard_write_wakeup(struct bluecard_info *info) { if (!info) { BT_ERR("Unknown device"); @@ -368,7 +368,8 @@ static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, in } -static void bluecard_receive(bluecard_info_t *info, unsigned int offset) +static void bluecard_receive(struct bluecard_info *info, + unsigned int offset) { unsigned int iobase; unsigned char buf[31]; @@ -497,7 +498,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset) static irqreturn_t bluecard_interrupt(int irq, void *dev_inst) { - bluecard_info_t *info = dev_inst; + struct bluecard_info *info = dev_inst; unsigned int iobase; unsigned char reg; @@ -562,7 +563,7 @@ static irqreturn_t bluecard_interrupt(int irq, void *dev_inst) static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud) { - bluecard_info_t *info = hci_get_drvdata(hdev); + struct bluecard_info *info = hci_get_drvdata(hdev); struct sk_buff *skb; /* Ericsson baud rate command */ @@ -611,7 +612,7 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud) static int bluecard_hci_flush(struct hci_dev *hdev) { - bluecard_info_t *info = hci_get_drvdata(hdev); + struct bluecard_info *info = hci_get_drvdata(hdev); /* Drop TX queue */ skb_queue_purge(&(info->txq)); @@ -622,7 +623,7 @@ static int bluecard_hci_flush(struct hci_dev *hdev) static int bluecard_hci_open(struct hci_dev *hdev) { - bluecard_info_t *info = hci_get_drvdata(hdev); + struct bluecard_info *info = hci_get_drvdata(hdev); if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); @@ -643,7 +644,7 @@ static int bluecard_hci_open(struct hci_dev *hdev) static int bluecard_hci_close(struct hci_dev *hdev) { - bluecard_info_t *info = hci_get_drvdata(hdev); + struct bluecard_info *info = hci_get_drvdata(hdev); if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) return 0; @@ -663,7 +664,7 @@ static int bluecard_hci_close(struct hci_dev *hdev) static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - bluecard_info_t *info = hci_get_drvdata(hdev); + struct bluecard_info *info = hci_get_drvdata(hdev); switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -691,7 +692,7 @@ static int bluecard_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) /* ======================== Card services HCI interaction ======================== */ -static int bluecard_open(bluecard_info_t *info) +static int bluecard_open(struct bluecard_info *info) { unsigned int iobase = info->p_dev->resource[0]->start; struct hci_dev *hdev; @@ -806,7 +807,7 @@ static int bluecard_open(bluecard_info_t *info) } -static int bluecard_close(bluecard_info_t *info) +static int bluecard_close(struct bluecard_info *info) { unsigned int iobase = info->p_dev->resource[0]->start; struct hci_dev *hdev = info->hdev; @@ -833,7 +834,7 @@ static int bluecard_close(bluecard_info_t *info) static int bluecard_probe(struct pcmcia_device *link) { - bluecard_info_t *info; + struct bluecard_info *info; /* Create new info device */ info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); @@ -857,7 +858,7 @@ static void bluecard_detach(struct pcmcia_device *link) static int bluecard_config(struct pcmcia_device *link) { - bluecard_info_t *info = link->priv; + struct bluecard_info *info = link->priv; int i, n; link->config_index = 0x20; @@ -897,7 +898,7 @@ static int bluecard_config(struct pcmcia_device *link) static void bluecard_release(struct pcmcia_device *link) { - bluecard_info_t *info = link->priv; + struct bluecard_info *info = link->priv; bluecard_close(info); -- GitLab From ad709d4867985de0b239d01702f9ac6bb578099e Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Wed, 13 Aug 2014 14:51:39 +0530 Subject: [PATCH 0394/9167] Bluetooth: Remove typedef btuart_info_t The Linux kernel coding style guidelines suggest not using typedefs for structure types. This patch gets rid of the typedef for btuart_info_t. Also, the name of the struct is changed to drop the _t, to make the name look less typedef-like. The following Coccinelle semantic patch detects the case: @tn@ identifier i; type td; @@ -typedef struct i { ... } -td ; @@ type tn.td; identifier tn.i; @@ -td + struct i Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btuart_cs.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index fb948f02eda5..abb4d2106db4 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c @@ -62,7 +62,7 @@ MODULE_LICENSE("GPL"); /* ======================== Local structures ======================== */ -typedef struct btuart_info_t { +struct btuart_info { struct pcmcia_device *p_dev; struct hci_dev *hdev; @@ -75,7 +75,7 @@ typedef struct btuart_info_t { unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; -} btuart_info_t; +}; static int btuart_config(struct pcmcia_device *link); @@ -127,7 +127,7 @@ static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) } -static void btuart_write_wakeup(btuart_info_t *info) +static void btuart_write_wakeup(struct btuart_info *info) { if (!info) { BT_ERR("Unknown device"); @@ -172,7 +172,7 @@ static void btuart_write_wakeup(btuart_info_t *info) } -static void btuart_receive(btuart_info_t *info) +static void btuart_receive(struct btuart_info *info) { unsigned int iobase; int boguscount = 0; @@ -286,7 +286,7 @@ static void btuart_receive(btuart_info_t *info) static irqreturn_t btuart_interrupt(int irq, void *dev_inst) { - btuart_info_t *info = dev_inst; + struct btuart_info *info = dev_inst; unsigned int iobase; int boguscount = 0; int iir, lsr; @@ -340,7 +340,8 @@ static irqreturn_t btuart_interrupt(int irq, void *dev_inst) } -static void btuart_change_speed(btuart_info_t *info, unsigned int speed) +static void btuart_change_speed(struct btuart_info *info, + unsigned int speed) { unsigned long flags; unsigned int iobase; @@ -397,7 +398,7 @@ static void btuart_change_speed(btuart_info_t *info, unsigned int speed) static int btuart_hci_flush(struct hci_dev *hdev) { - btuart_info_t *info = hci_get_drvdata(hdev); + struct btuart_info *info = hci_get_drvdata(hdev); /* Drop TX queue */ skb_queue_purge(&(info->txq)); @@ -427,7 +428,7 @@ static int btuart_hci_close(struct hci_dev *hdev) static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - btuart_info_t *info = hci_get_drvdata(hdev); + struct btuart_info *info = hci_get_drvdata(hdev); switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -455,7 +456,7 @@ static int btuart_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) /* ======================== Card services HCI interaction ======================== */ -static int btuart_open(btuart_info_t *info) +static int btuart_open(struct btuart_info *info) { unsigned long flags; unsigned int iobase = info->p_dev->resource[0]->start; @@ -521,7 +522,7 @@ static int btuart_open(btuart_info_t *info) } -static int btuart_close(btuart_info_t *info) +static int btuart_close(struct btuart_info *info) { unsigned long flags; unsigned int iobase = info->p_dev->resource[0]->start; @@ -550,7 +551,7 @@ static int btuart_close(btuart_info_t *info) static int btuart_probe(struct pcmcia_device *link) { - btuart_info_t *info; + struct btuart_info *info; /* Create new info device */ info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); @@ -613,7 +614,7 @@ static int btuart_check_config_notpicky(struct pcmcia_device *p_dev, static int btuart_config(struct pcmcia_device *link) { - btuart_info_t *info = link->priv; + struct btuart_info *info = link->priv; int i; int try; @@ -654,7 +655,7 @@ static int btuart_config(struct pcmcia_device *link) static void btuart_release(struct pcmcia_device *link) { - btuart_info_t *info = link->priv; + struct btuart_info *info = link->priv; btuart_close(info); -- GitLab From 66f4e0e43a0389a7f2814f0cc6df39019aead54f Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Wed, 13 Aug 2014 14:52:27 +0530 Subject: [PATCH 0395/9167] Bluetooth: Remove typedefs nsh_t and dtl1_info_t The Linux kernel coding style guidelines suggest not using typedefs for structure types. This patch gets rid of the typedefs for nsh_t and dtl1_info_t. Also, the name of the struct is changed to drop the _t, to make the name look less typedef-like. The following Coccinelle semantic patch detects the case for dtl1_info_t and a similar patch finds the nsh_t case: @tn@ identifier i; type td; @@ -typedef struct i { ... } -td ; @@ type tn.td; identifier tn.i; @@ -td + struct i Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Marcel Holtmann --- drivers/bluetooth/dtl1_cs.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index 2bd8fad17206..78e10f0c65b2 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c @@ -62,7 +62,7 @@ MODULE_LICENSE("GPL"); /* ======================== Local structures ======================== */ -typedef struct dtl1_info_t { +struct dtl1_info { struct pcmcia_device *p_dev; struct hci_dev *hdev; @@ -78,7 +78,7 @@ typedef struct dtl1_info_t { unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; -} dtl1_info_t; +}; static int dtl1_config(struct pcmcia_device *link); @@ -94,11 +94,11 @@ static int dtl1_config(struct pcmcia_device *link); #define RECV_WAIT_DATA 1 -typedef struct { +struct nsh { u8 type; u8 zero; u16 len; -} __packed nsh_t; /* Nokia Specific Header */ +} __packed; /* Nokia Specific Header */ #define NSHL 4 /* Nokia Specific Header Length */ @@ -126,7 +126,7 @@ static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) } -static void dtl1_write_wakeup(dtl1_info_t *info) +static void dtl1_write_wakeup(struct dtl1_info *info) { if (!info) { BT_ERR("Unknown device"); @@ -176,7 +176,7 @@ static void dtl1_write_wakeup(dtl1_info_t *info) } -static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb) +static void dtl1_control(struct dtl1_info *info, struct sk_buff *skb) { u8 flowmask = *(u8 *)skb->data; int i; @@ -199,10 +199,10 @@ static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb) } -static void dtl1_receive(dtl1_info_t *info) +static void dtl1_receive(struct dtl1_info *info) { unsigned int iobase; - nsh_t *nsh; + struct nsh *nsh; int boguscount = 0; if (!info) { @@ -227,7 +227,7 @@ static void dtl1_receive(dtl1_info_t *info) } *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX); - nsh = (nsh_t *)info->rx_skb->data; + nsh = (struct nsh *)info->rx_skb->data; info->rx_count--; @@ -287,7 +287,7 @@ static void dtl1_receive(dtl1_info_t *info) static irqreturn_t dtl1_interrupt(int irq, void *dev_inst) { - dtl1_info_t *info = dev_inst; + struct dtl1_info *info = dev_inst; unsigned int iobase; unsigned char msr; int boguscount = 0; @@ -365,7 +365,7 @@ static int dtl1_hci_open(struct hci_dev *hdev) static int dtl1_hci_flush(struct hci_dev *hdev) { - dtl1_info_t *info = hci_get_drvdata(hdev); + struct dtl1_info *info = hci_get_drvdata(hdev); /* Drop TX queue */ skb_queue_purge(&(info->txq)); @@ -387,9 +387,9 @@ static int dtl1_hci_close(struct hci_dev *hdev) static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - dtl1_info_t *info = hci_get_drvdata(hdev); + struct dtl1_info *info = hci_get_drvdata(hdev); struct sk_buff *s; - nsh_t nsh; + struct nsh nsh; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: @@ -436,7 +436,7 @@ static int dtl1_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) /* ======================== Card services HCI interaction ======================== */ -static int dtl1_open(dtl1_info_t *info) +static int dtl1_open(struct dtl1_info *info) { unsigned long flags; unsigned int iobase = info->p_dev->resource[0]->start; @@ -505,7 +505,7 @@ static int dtl1_open(dtl1_info_t *info) } -static int dtl1_close(dtl1_info_t *info) +static int dtl1_close(struct dtl1_info *info) { unsigned long flags; unsigned int iobase = info->p_dev->resource[0]->start; @@ -534,7 +534,7 @@ static int dtl1_close(dtl1_info_t *info) static int dtl1_probe(struct pcmcia_device *link) { - dtl1_info_t *info; + struct dtl1_info *info; /* Create new info device */ info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); @@ -552,7 +552,7 @@ static int dtl1_probe(struct pcmcia_device *link) static void dtl1_detach(struct pcmcia_device *link) { - dtl1_info_t *info = link->priv; + struct dtl1_info *info = link->priv; dtl1_close(info); pcmcia_disable_device(link); @@ -571,7 +571,7 @@ static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data) static int dtl1_config(struct pcmcia_device *link) { - dtl1_info_t *info = link->priv; + struct dtl1_info *info = link->priv; int ret; /* Look for a generic full-sized window */ -- GitLab From 3bbaf812065e8b0feca02b6c7e5117b731709008 Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Wed, 13 Aug 2014 14:49:56 +0530 Subject: [PATCH 0396/9167] Bluetooth: Remove typedef bt3c_info_t The Linux kernel coding style guidelines suggest not using typedefs for structure types. This patch gets rid of the typedef for bt3c_info_t. Also, the name of the struct is changed to drop the _t, to make the name look less typedef-like. The following Coccinelle semantic patch detects the case: @tn@ identifier i; type td; @@ -typedef struct i { ... } -td ; @@ type tn.td; identifier tn.i; @@ -td + struct i Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bt3c_cs.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 1d82721cf9c6..4f7e8d400bc0 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -67,7 +67,7 @@ MODULE_FIRMWARE("BT3CPCC.bin"); /* ======================== Local structures ======================== */ -typedef struct bt3c_info_t { +struct bt3c_info { struct pcmcia_device *p_dev; struct hci_dev *hdev; @@ -80,7 +80,7 @@ typedef struct bt3c_info_t { unsigned long rx_state; unsigned long rx_count; struct sk_buff *rx_skb; -} bt3c_info_t; +}; static int bt3c_config(struct pcmcia_device *link); @@ -175,7 +175,7 @@ static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len) } -static void bt3c_write_wakeup(bt3c_info_t *info) +static void bt3c_write_wakeup(struct bt3c_info *info) { if (!info) { BT_ERR("Unknown device"); @@ -214,7 +214,7 @@ static void bt3c_write_wakeup(bt3c_info_t *info) } -static void bt3c_receive(bt3c_info_t *info) +static void bt3c_receive(struct bt3c_info *info) { unsigned int iobase; int size = 0, avail; @@ -336,7 +336,7 @@ static void bt3c_receive(bt3c_info_t *info) static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) { - bt3c_info_t *info = dev_inst; + struct bt3c_info *info = dev_inst; unsigned int iobase; int iir; irqreturn_t r = IRQ_NONE; @@ -388,7 +388,7 @@ static irqreturn_t bt3c_interrupt(int irq, void *dev_inst) static int bt3c_hci_flush(struct hci_dev *hdev) { - bt3c_info_t *info = hci_get_drvdata(hdev); + struct bt3c_info *info = hci_get_drvdata(hdev); /* Drop TX queue */ skb_queue_purge(&(info->txq)); @@ -418,7 +418,7 @@ static int bt3c_hci_close(struct hci_dev *hdev) static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) { - bt3c_info_t *info = hci_get_drvdata(hdev); + struct bt3c_info *info = hci_get_drvdata(hdev); unsigned long flags; switch (bt_cb(skb)->pkt_type) { @@ -451,7 +451,8 @@ static int bt3c_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) /* ======================== Card services HCI interaction ======================== */ -static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware, +static int bt3c_load_firmware(struct bt3c_info *info, + const unsigned char *firmware, int count) { char *ptr = (char *) firmware; @@ -536,7 +537,7 @@ static int bt3c_load_firmware(bt3c_info_t *info, const unsigned char *firmware, } -static int bt3c_open(bt3c_info_t *info) +static int bt3c_open(struct bt3c_info *info) { const struct firmware *firmware; struct hci_dev *hdev; @@ -603,7 +604,7 @@ static int bt3c_open(bt3c_info_t *info) } -static int bt3c_close(bt3c_info_t *info) +static int bt3c_close(struct bt3c_info *info) { struct hci_dev *hdev = info->hdev; @@ -620,7 +621,7 @@ static int bt3c_close(bt3c_info_t *info) static int bt3c_probe(struct pcmcia_device *link) { - bt3c_info_t *info; + struct bt3c_info *info; /* Create new info device */ info = devm_kzalloc(&link->dev, sizeof(*info), GFP_KERNEL); @@ -683,7 +684,7 @@ static int bt3c_check_config_notpicky(struct pcmcia_device *p_dev, static int bt3c_config(struct pcmcia_device *link) { - bt3c_info_t *info = link->priv; + struct bt3c_info *info = link->priv; int i; unsigned long try; @@ -724,7 +725,7 @@ static int bt3c_config(struct pcmcia_device *link) static void bt3c_release(struct pcmcia_device *link) { - bt3c_info_t *info = link->priv; + struct bt3c_info *info = link->priv; bt3c_close(info); -- GitLab From 069cb27017de6476d47a70fbf144f69200d3e854 Mon Sep 17 00:00:00 2001 From: Lukasz Rymanowski Date: Wed, 13 Aug 2014 16:01:41 +0200 Subject: [PATCH 0397/9167] Bluetooth: Improve data packing in SAR mode There is no need to decrease pdu size with L2CAP SDU lenght in Start L2CAP SDU frame. Start packtet is just 2 bytes longer as specified and we can keep payload as long as possible. When testing SAR L2CAP against PTS, L2CAP channel is usually configured in that way, that SDU = MPS * 3. PTS expets then 3 I-Frames from IUT: Start, Continuation and End frame. Without this fix, we sent 4 I-Frames. We could pass a test by using -b option in l2test and send just two bytes less than SDU length. With this patch no need to use -b option. Signed-off-by: Lukasz Rymanowski Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 0cd7ed99558b..ebe7454362f0 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -2275,7 +2275,6 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, } else { sar = L2CAP_SAR_START; sdu_len = len; - pdu_len -= L2CAP_SDULEN_SIZE; } while (len > 0) { @@ -2290,10 +2289,8 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, __skb_queue_tail(seg_queue, skb); len -= pdu_len; - if (sdu_len) { + if (sdu_len) sdu_len = 0; - pdu_len += L2CAP_SDULEN_SIZE; - } if (len <= pdu_len) { sar = L2CAP_SAR_END; -- GitLab From 13cac15296afe7e42088ecfcd0f1d4b658248c46 Mon Sep 17 00:00:00 2001 From: Lukasz Rymanowski Date: Thu, 14 Aug 2014 09:35:34 +0200 Subject: [PATCH 0398/9167] Bluetooth: Fix ERTM L2CAP resend packet I-Frame which is going to be resend already has FCS field added and set (if it was required). Adding additional FCS field calculated from data + old FCS in resend function is incorrect. This patch fix that. Issue has been found during PTS testing. Signed-off-by: Lukasz Rymanowski Signed-off-by: Marcel Holtmann --- net/bluetooth/l2cap_core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index ebe7454362f0..4a90438d99df 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -1968,10 +1968,12 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) tx_skb->data + L2CAP_HDR_SIZE); } + /* Update FCS */ if (chan->fcs == L2CAP_FCS_CRC16) { - u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len); - put_unaligned_le16(fcs, skb_put(tx_skb, - L2CAP_FCS_SIZE)); + u16 fcs = crc16(0, (u8 *) tx_skb->data, + tx_skb->len - L2CAP_FCS_SIZE); + put_unaligned_le16(fcs, skb_tail_pointer(tx_skb) - + L2CAP_FCS_SIZE); } l2cap_do_send(chan, tx_skb); -- GitLab From f6b4ecee0eb7bfa66ae8d5652105ed4da53209a3 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 23 Apr 2014 17:02:18 +0200 Subject: [PATCH 0399/9167] locking,x86: Kill atomic_or_long() There are no users, kill it. Signed-off-by: Peter Zijlstra Cc: Jesse Brandeburg Cc: Linus Torvalds Cc: Paul E. McKenney Link: http://lkml.kernel.org/r/20140508135851.768177189@infradead.org Signed-off-by: Ingo Molnar --- arch/x86/include/asm/atomic.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h index 6dd1c7dd0473..bf20c817ed34 100644 --- a/arch/x86/include/asm/atomic.h +++ b/arch/x86/include/asm/atomic.h @@ -219,21 +219,6 @@ static inline short int atomic_inc_short(short int *v) return *v; } -#ifdef CONFIG_X86_64 -/** - * atomic_or_long - OR of two long integers - * @v1: pointer to type unsigned long - * @v2: pointer to type unsigned long - * - * Atomically ORs @v1 and @v2 - * Returns the result of the OR - */ -static inline void atomic_or_long(unsigned long *v1, unsigned long v2) -{ - asm(LOCK_PREFIX "orq %1, %0" : "+m" (*v1) : "r" (v2)); -} -#endif - /* These are x86-specific, used by some header files */ #define atomic_clear_mask(mask, addr) \ asm volatile(LOCK_PREFIX "andl %0,%1" \ -- GitLab From b93c7b8c5b281bf3646d6c5b6e05249b98cc5ab7 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 16:25:53 +0100 Subject: [PATCH 0400/9167] locking,arch,alpha: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Cc: Matt Turner Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Linus Torvalds Signed-off-by: Peter Zijlstra Cc: Ivan Kokshaysky Cc: Linus Torvalds Cc: Matt Turner Cc: Paul E. McKenney Cc: Richard Henderson Cc: linux-alpha@vger.kernel.org Link: http://lkml.kernel.org/r/20140508135851.832107183@infradead.org Signed-off-by: Ingo Molnar --- arch/alpha/include/asm/atomic.h | 213 ++++++++++++-------------------- 1 file changed, 80 insertions(+), 133 deletions(-) diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index ed60a1ee1ed3..6fbb53a13049 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h @@ -29,145 +29,92 @@ * branch back to restart the operation. */ -static __inline__ void atomic_add(int i, atomic_t * v) -{ - unsigned long temp; - __asm__ __volatile__( - "1: ldl_l %0,%1\n" - " addl %0,%2,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter) - :"Ir" (i), "m" (v->counter)); -} - -static __inline__ void atomic64_add(long i, atomic64_t * v) -{ - unsigned long temp; - __asm__ __volatile__( - "1: ldq_l %0,%1\n" - " addq %0,%2,%0\n" - " stq_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter) - :"Ir" (i), "m" (v->counter)); -} - -static __inline__ void atomic_sub(int i, atomic_t * v) -{ - unsigned long temp; - __asm__ __volatile__( - "1: ldl_l %0,%1\n" - " subl %0,%2,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter) - :"Ir" (i), "m" (v->counter)); +#define ATOMIC_OP(op) \ +static __inline__ void atomic_##op(int i, atomic_t * v) \ +{ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "1: ldl_l %0,%1\n" \ + " " #op "l %0,%2,%0\n" \ + " stl_c %0,%1\n" \ + " beq %0,2f\n" \ + ".subsection 2\n" \ + "2: br 1b\n" \ + ".previous" \ + :"=&r" (temp), "=m" (v->counter) \ + :"Ir" (i), "m" (v->counter)); \ +} \ + +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + long temp, result; \ + smp_mb(); \ + __asm__ __volatile__( \ + "1: ldl_l %0,%1\n" \ + " " #op "l %0,%3,%2\n" \ + " " #op "l %0,%3,%0\n" \ + " stl_c %0,%1\n" \ + " beq %0,2f\n" \ + ".subsection 2\n" \ + "2: br 1b\n" \ + ".previous" \ + :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ + :"Ir" (i), "m" (v->counter) : "memory"); \ + smp_mb(); \ + return result; \ } -static __inline__ void atomic64_sub(long i, atomic64_t * v) -{ - unsigned long temp; - __asm__ __volatile__( - "1: ldq_l %0,%1\n" - " subq %0,%2,%0\n" - " stq_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter) - :"Ir" (i), "m" (v->counter)); -} - - -/* - * Same as above, but return the result value - */ -static inline int atomic_add_return(int i, atomic_t *v) -{ - long temp, result; - smp_mb(); - __asm__ __volatile__( - "1: ldl_l %0,%1\n" - " addl %0,%3,%2\n" - " addl %0,%3,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter), "=&r" (result) - :"Ir" (i), "m" (v->counter) : "memory"); - smp_mb(); - return result; +#define ATOMIC64_OP(op) \ +static __inline__ void atomic64_##op(long i, atomic64_t * v) \ +{ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "1: ldq_l %0,%1\n" \ + " " #op "q %0,%2,%0\n" \ + " stq_c %0,%1\n" \ + " beq %0,2f\n" \ + ".subsection 2\n" \ + "2: br 1b\n" \ + ".previous" \ + :"=&r" (temp), "=m" (v->counter) \ + :"Ir" (i), "m" (v->counter)); \ +} \ + +#define ATOMIC64_OP_RETURN(op) \ +static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \ +{ \ + long temp, result; \ + smp_mb(); \ + __asm__ __volatile__( \ + "1: ldq_l %0,%1\n" \ + " " #op "q %0,%3,%2\n" \ + " " #op "q %0,%3,%0\n" \ + " stq_c %0,%1\n" \ + " beq %0,2f\n" \ + ".subsection 2\n" \ + "2: br 1b\n" \ + ".previous" \ + :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ + :"Ir" (i), "m" (v->counter) : "memory"); \ + smp_mb(); \ + return result; \ } -static __inline__ long atomic64_add_return(long i, atomic64_t * v) -{ - long temp, result; - smp_mb(); - __asm__ __volatile__( - "1: ldq_l %0,%1\n" - " addq %0,%3,%2\n" - " addq %0,%3,%0\n" - " stq_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter), "=&r" (result) - :"Ir" (i), "m" (v->counter) : "memory"); - smp_mb(); - return result; -} +#define ATOMIC_OPS(opg) \ + ATOMIC_OP(opg) \ + ATOMIC_OP_RETURN(opg) \ + ATOMIC64_OP(opg) \ + ATOMIC64_OP_RETURN(opg) -static __inline__ long atomic_sub_return(int i, atomic_t * v) -{ - long temp, result; - smp_mb(); - __asm__ __volatile__( - "1: ldl_l %0,%1\n" - " subl %0,%3,%2\n" - " subl %0,%3,%0\n" - " stl_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter), "=&r" (result) - :"Ir" (i), "m" (v->counter) : "memory"); - smp_mb(); - return result; -} +ATOMIC_OPS(add) +ATOMIC_OPS(sub) -static __inline__ long atomic64_sub_return(long i, atomic64_t * v) -{ - long temp, result; - smp_mb(); - __asm__ __volatile__( - "1: ldq_l %0,%1\n" - " subq %0,%3,%2\n" - " subq %0,%3,%0\n" - " stq_c %0,%1\n" - " beq %0,2f\n" - ".subsection 2\n" - "2: br 1b\n" - ".previous" - :"=&r" (temp), "=m" (v->counter), "=&r" (result) - :"Ir" (i), "m" (v->counter) : "memory"); - smp_mb(); - return result; -} +#undef ATOMIC_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP #define atomic64_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) -- GitLab From f7d11e93ee97a37da1947b7c4e1794705a6f360c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 16:29:31 +0100 Subject: [PATCH 0401/9167] locking,arch,arc: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Vineet Gupta Link: http://lkml.kernel.org/r/20140508135851.886055622@infradead.org Signed-off-by: Ingo Molnar --- arch/arc/include/asm/atomic.h | 184 ++++++++++++---------------------- 1 file changed, 63 insertions(+), 121 deletions(-) diff --git a/arch/arc/include/asm/atomic.h b/arch/arc/include/asm/atomic.h index 83f03ca6caf6..173f303a868f 100644 --- a/arch/arc/include/asm/atomic.h +++ b/arch/arc/include/asm/atomic.h @@ -25,79 +25,36 @@ #define atomic_set(v, i) (((v)->counter) = (i)) -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned int temp; - - __asm__ __volatile__( - "1: llock %0, [%1] \n" - " add %0, %0, %2 \n" - " scond %0, [%1] \n" - " bnz 1b \n" - : "=&r"(temp) /* Early clobber, to prevent reg reuse */ - : "r"(&v->counter), "ir"(i) - : "cc"); -} - -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned int temp; - - __asm__ __volatile__( - "1: llock %0, [%1] \n" - " sub %0, %0, %2 \n" - " scond %0, [%1] \n" - " bnz 1b \n" - : "=&r"(temp) - : "r"(&v->counter), "ir"(i) - : "cc"); -} - -/* add and also return the new value */ -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned int temp; - - __asm__ __volatile__( - "1: llock %0, [%1] \n" - " add %0, %0, %2 \n" - " scond %0, [%1] \n" - " bnz 1b \n" - : "=&r"(temp) - : "r"(&v->counter), "ir"(i) - : "cc"); - - return temp; -} - -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned int temp; - - __asm__ __volatile__( - "1: llock %0, [%1] \n" - " sub %0, %0, %2 \n" - " scond %0, [%1] \n" - " bnz 1b \n" - : "=&r"(temp) - : "r"(&v->counter), "ir"(i) - : "cc"); - - return temp; -} - -static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) -{ - unsigned int temp; - - __asm__ __volatile__( - "1: llock %0, [%1] \n" - " bic %0, %0, %2 \n" - " scond %0, [%1] \n" - " bnz 1b \n" - : "=&r"(temp) - : "r"(addr), "ir"(mask) - : "cc"); +#define ATOMIC_OP(op, c_op, asm_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned int temp; \ + \ + __asm__ __volatile__( \ + "1: llock %0, [%1] \n" \ + " " #asm_op " %0, %0, %2 \n" \ + " scond %0, [%1] \n" \ + " bnz 1b \n" \ + : "=&r"(temp) /* Early clobber, to prevent reg reuse */ \ + : "r"(&v->counter), "ir"(i) \ + : "cc"); \ +} \ + +#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned int temp; \ + \ + __asm__ __volatile__( \ + "1: llock %0, [%1] \n" \ + " " #asm_op " %0, %0, %2 \n" \ + " scond %0, [%1] \n" \ + " bnz 1b \n" \ + : "=&r"(temp) \ + : "r"(&v->counter), "ir"(i) \ + : "cc"); \ + \ + return temp; \ } #else /* !CONFIG_ARC_HAS_LLSC */ @@ -126,6 +83,7 @@ static inline void atomic_set(atomic_t *v, int i) v->counter = i; atomic_ops_unlock(flags); } + #endif /* @@ -133,62 +91,46 @@ static inline void atomic_set(atomic_t *v, int i) * Locking would change to irq-disabling only (UP) and spinlocks (SMP) */ -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned long flags; - - atomic_ops_lock(flags); - v->counter += i; - atomic_ops_unlock(flags); +#define ATOMIC_OP(op, c_op, asm_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + \ + atomic_ops_lock(flags); \ + v->counter c_op i; \ + atomic_ops_unlock(flags); \ } -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned long flags; - - atomic_ops_lock(flags); - v->counter -= i; - atomic_ops_unlock(flags); +#define ATOMIC_OP_RETURN(op, c_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + unsigned long temp; \ + \ + atomic_ops_lock(flags); \ + temp = v->counter; \ + temp c_op i; \ + v->counter = temp; \ + atomic_ops_unlock(flags); \ + \ + return temp; \ } -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned long flags; - unsigned long temp; - - atomic_ops_lock(flags); - temp = v->counter; - temp += i; - v->counter = temp; - atomic_ops_unlock(flags); - - return temp; -} - -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long flags; - unsigned long temp; - - atomic_ops_lock(flags); - temp = v->counter; - temp -= i; - v->counter = temp; - atomic_ops_unlock(flags); +#endif /* !CONFIG_ARC_HAS_LLSC */ - return temp; -} +#define ATOMIC_OPS(op, c_op, asm_op) \ + ATOMIC_OP(op, c_op, asm_op) \ + ATOMIC_OP_RETURN(op, c_op, asm_op) -static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) -{ - unsigned long flags; +ATOMIC_OPS(add, +=, add) +ATOMIC_OPS(sub, -=, sub) +ATOMIC_OP(and, &=, and) - atomic_ops_lock(flags); - *addr &= ~mask; - atomic_ops_unlock(flags); -} +#define atomic_clear_mask(mask, v) atomic_and(~(mask), (v)) -#endif /* !CONFIG_ARC_HAS_LLSC */ +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP /** * __atomic_add_unless - add unless the number is a given value -- GitLab From aee9a55452f0371258e18b41649ce650ff344090 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 16:38:18 +0100 Subject: [PATCH 0402/9167] locking,arch,arm: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Requires the asm_op because of eor. Signed-off-by: Peter Zijlstra Acked-by: Will Deacon Cc: Chen Gang Cc: Linus Torvalds Cc: Nicolas Pitre Cc: Paul E. McKenney Cc: Russell King Cc: Albin Tonnerre Cc: Victor Kamensky Cc: Catalin Marinas Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20140508135851.939725247@infradead.org Signed-off-by: Ingo Molnar --- arch/arm/include/asm/atomic.h | 305 ++++++++++++++-------------------- 1 file changed, 123 insertions(+), 182 deletions(-) diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index 3040359094d9..832f1cdfcd6a 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h @@ -37,84 +37,47 @@ * store exclusive to ensure that these are atomic. We may loop * to ensure that the update happens. */ -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - - prefetchw(&v->counter); - __asm__ __volatile__("@ atomic_add\n" -"1: ldrex %0, [%3]\n" -" add %0, %0, %4\n" -" strex %1, %0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) - : "r" (&v->counter), "Ir" (i) - : "cc"); -} -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - - smp_mb(); - prefetchw(&v->counter); - - __asm__ __volatile__("@ atomic_add_return\n" -"1: ldrex %0, [%3]\n" -" add %0, %0, %4\n" -" strex %1, %0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) - : "r" (&v->counter), "Ir" (i) - : "cc"); - - smp_mb(); - - return result; -} - -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - - prefetchw(&v->counter); - __asm__ __volatile__("@ atomic_sub\n" -"1: ldrex %0, [%3]\n" -" sub %0, %0, %4\n" -" strex %1, %0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) - : "r" (&v->counter), "Ir" (i) - : "cc"); -} - -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - - smp_mb(); - prefetchw(&v->counter); - - __asm__ __volatile__("@ atomic_sub_return\n" -"1: ldrex %0, [%3]\n" -" sub %0, %0, %4\n" -" strex %1, %0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) - : "r" (&v->counter), "Ir" (i) - : "cc"); - - smp_mb(); - - return result; +#define ATOMIC_OP(op, c_op, asm_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + prefetchw(&v->counter); \ + __asm__ __volatile__("@ atomic_" #op "\n" \ +"1: ldrex %0, [%3]\n" \ +" " #asm_op " %0, %0, %4\n" \ +" strex %1, %0, [%3]\n" \ +" teq %1, #0\n" \ +" bne 1b" \ + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \ + : "r" (&v->counter), "Ir" (i) \ + : "cc"); \ +} \ + +#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + smp_mb(); \ + prefetchw(&v->counter); \ + \ + __asm__ __volatile__("@ atomic_" #op "_return\n" \ +"1: ldrex %0, [%3]\n" \ +" " #asm_op " %0, %0, %4\n" \ +" strex %1, %0, [%3]\n" \ +" teq %1, #0\n" \ +" bne 1b" \ + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \ + : "r" (&v->counter), "Ir" (i) \ + : "cc"); \ + \ + smp_mb(); \ + \ + return result; \ } static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) @@ -174,33 +137,29 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) #error SMP not supported on pre-ARMv6 CPUs #endif -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned long flags; - int val; - - raw_local_irq_save(flags); - val = v->counter; - v->counter = val += i; - raw_local_irq_restore(flags); - - return val; -} -#define atomic_add(i, v) (void) atomic_add_return(i, v) - -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long flags; - int val; - - raw_local_irq_save(flags); - val = v->counter; - v->counter = val -= i; - raw_local_irq_restore(flags); - - return val; +#define ATOMIC_OP(op, c_op, asm_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + 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) \ +{ \ + unsigned long flags; \ + int val; \ + \ + raw_local_irq_save(flags); \ + v->counter c_op i; \ + val = v->counter; \ + raw_local_irq_restore(flags); \ + \ + return val; \ } -#define atomic_sub(i, v) (void) atomic_sub_return(i, v) static inline int atomic_cmpxchg(atomic_t *v, int old, int new) { @@ -228,6 +187,17 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) #endif /* __LINUX_ARM_ARCH__ */ +#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, +=, add) +ATOMIC_OPS(sub, -=, sub) + +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP + #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) #define atomic_inc(v) atomic_add(1, v) @@ -300,89 +270,60 @@ static inline void atomic64_set(atomic64_t *v, long long i) } #endif -static inline void atomic64_add(long long i, atomic64_t *v) -{ - long long result; - unsigned long tmp; - - prefetchw(&v->counter); - __asm__ __volatile__("@ atomic64_add\n" -"1: ldrexd %0, %H0, [%3]\n" -" adds %Q0, %Q0, %Q4\n" -" adc %R0, %R0, %R4\n" -" strexd %1, %0, %H0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) - : "r" (&v->counter), "r" (i) - : "cc"); -} - -static inline long long atomic64_add_return(long long i, atomic64_t *v) -{ - long long result; - unsigned long tmp; - - smp_mb(); - prefetchw(&v->counter); - - __asm__ __volatile__("@ atomic64_add_return\n" -"1: ldrexd %0, %H0, [%3]\n" -" adds %Q0, %Q0, %Q4\n" -" adc %R0, %R0, %R4\n" -" strexd %1, %0, %H0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) - : "r" (&v->counter), "r" (i) - : "cc"); - - smp_mb(); - - return result; -} - -static inline void atomic64_sub(long long i, atomic64_t *v) -{ - long long result; - unsigned long tmp; - - prefetchw(&v->counter); - __asm__ __volatile__("@ atomic64_sub\n" -"1: ldrexd %0, %H0, [%3]\n" -" subs %Q0, %Q0, %Q4\n" -" sbc %R0, %R0, %R4\n" -" strexd %1, %0, %H0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) - : "r" (&v->counter), "r" (i) - : "cc"); +#define ATOMIC64_OP(op, op1, op2) \ +static inline void atomic64_##op(long long i, atomic64_t *v) \ +{ \ + long long result; \ + unsigned long tmp; \ + \ + prefetchw(&v->counter); \ + __asm__ __volatile__("@ atomic64_" #op "\n" \ +"1: ldrexd %0, %H0, [%3]\n" \ +" " #op1 " %Q0, %Q0, %Q4\n" \ +" " #op2 " %R0, %R0, %R4\n" \ +" strexd %1, %0, %H0, [%3]\n" \ +" teq %1, #0\n" \ +" bne 1b" \ + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \ + : "r" (&v->counter), "r" (i) \ + : "cc"); \ +} \ + +#define ATOMIC64_OP_RETURN(op, op1, op2) \ +static inline long long atomic64_##op##_return(long long i, atomic64_t *v) \ +{ \ + long long result; \ + unsigned long tmp; \ + \ + smp_mb(); \ + prefetchw(&v->counter); \ + \ + __asm__ __volatile__("@ atomic64_" #op "_return\n" \ +"1: ldrexd %0, %H0, [%3]\n" \ +" " #op1 " %Q0, %Q0, %Q4\n" \ +" " #op2 " %R0, %R0, %R4\n" \ +" strexd %1, %0, %H0, [%3]\n" \ +" teq %1, #0\n" \ +" bne 1b" \ + : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) \ + : "r" (&v->counter), "r" (i) \ + : "cc"); \ + \ + smp_mb(); \ + \ + return result; \ } -static inline long long atomic64_sub_return(long long i, atomic64_t *v) -{ - long long result; - unsigned long tmp; - - smp_mb(); - prefetchw(&v->counter); - - __asm__ __volatile__("@ atomic64_sub_return\n" -"1: ldrexd %0, %H0, [%3]\n" -" subs %Q0, %Q0, %Q4\n" -" sbc %R0, %R0, %R4\n" -" strexd %1, %0, %H0, [%3]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter) - : "r" (&v->counter), "r" (i) - : "cc"); +#define ATOMIC64_OPS(op, op1, op2) \ + ATOMIC64_OP(op, op1, op2) \ + ATOMIC64_OP_RETURN(op, op1, op2) - smp_mb(); +ATOMIC64_OPS(add, adds, adc) +ATOMIC64_OPS(sub, subs, sbc) - return result; -} +#undef ATOMIC64_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP static inline long long atomic64_cmpxchg(atomic64_t *ptr, long long old, long long new) -- GitLab From 92ba1f530b4f90db78eb45f4b6598e75939146bd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 16:57:20 +0100 Subject: [PATCH 0403/9167] locking,arch,arm64: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Requires the asm_op due to eor. Signed-off-by: Peter Zijlstra Acked-by: Will Deacon Cc: Bjorn Helgaas Cc: Catalin Marinas Cc: Chen Gang Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Russell King Cc: linux-arm-kernel@lists.infradead.org Link: http://lkml.kernel.org/r/20140508135851.995123148@infradead.org Signed-off-by: Ingo Molnar --- arch/arm64/include/asm/atomic.h | 197 +++++++++++++------------------- 1 file changed, 80 insertions(+), 117 deletions(-) diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h index 65f1569ac96e..b83c325e587f 100644 --- a/arch/arm64/include/asm/atomic.h +++ b/arch/arm64/include/asm/atomic.h @@ -43,69 +43,51 @@ * store exclusive to ensure that these are atomic. We may loop * to ensure that the update happens. */ -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - - asm volatile("// atomic_add\n" -"1: ldxr %w0, %2\n" -" add %w0, %w0, %w3\n" -" stxr %w1, %w0, %2\n" -" cbnz %w1, 1b" - : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) - : "Ir" (i)); -} - -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - - asm volatile("// atomic_add_return\n" -"1: ldxr %w0, %2\n" -" add %w0, %w0, %w3\n" -" stlxr %w1, %w0, %2\n" -" cbnz %w1, 1b" - : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) - : "Ir" (i) - : "memory"); - - smp_mb(); - return result; -} - -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - asm volatile("// atomic_sub\n" -"1: ldxr %w0, %2\n" -" sub %w0, %w0, %w3\n" -" stxr %w1, %w0, %2\n" -" cbnz %w1, 1b" - : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) - : "Ir" (i)); +#define ATOMIC_OP(op, asm_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + asm volatile("// atomic_" #op "\n" \ +"1: ldxr %w0, %2\n" \ +" " #asm_op " %w0, %w0, %w3\n" \ +" stxr %w1, %w0, %2\n" \ +" cbnz %w1, 1b" \ + : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \ + : "Ir" (i)); \ +} \ + +#define ATOMIC_OP_RETURN(op, asm_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + asm volatile("// atomic_" #op "_return\n" \ +"1: ldxr %w0, %2\n" \ +" " #asm_op " %w0, %w0, %w3\n" \ +" stlxr %w1, %w0, %2\n" \ +" cbnz %w1, 1b" \ + : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \ + : "Ir" (i) \ + : "memory"); \ + \ + smp_mb(); \ + return result; \ } -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long tmp; - int result; +#define ATOMIC_OPS(op, asm_op) \ + ATOMIC_OP(op, asm_op) \ + ATOMIC_OP_RETURN(op, asm_op) - asm volatile("// atomic_sub_return\n" -"1: ldxr %w0, %2\n" -" sub %w0, %w0, %w3\n" -" stlxr %w1, %w0, %2\n" -" cbnz %w1, 1b" - : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) - : "Ir" (i) - : "memory"); +ATOMIC_OPS(add, add) +ATOMIC_OPS(sub, sub) - smp_mb(); - return result; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) { @@ -160,69 +142,50 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) #define atomic64_read(v) (*(volatile long *)&(v)->counter) #define atomic64_set(v,i) (((v)->counter) = (i)) -static inline void atomic64_add(u64 i, atomic64_t *v) -{ - long result; - unsigned long tmp; - - asm volatile("// atomic64_add\n" -"1: ldxr %0, %2\n" -" add %0, %0, %3\n" -" stxr %w1, %0, %2\n" -" cbnz %w1, 1b" - : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) - : "Ir" (i)); +#define ATOMIC64_OP(op, asm_op) \ +static inline void atomic64_##op(long i, atomic64_t *v) \ +{ \ + long result; \ + unsigned long tmp; \ + \ + asm volatile("// atomic64_" #op "\n" \ +"1: ldxr %0, %2\n" \ +" " #asm_op " %0, %0, %3\n" \ +" stxr %w1, %0, %2\n" \ +" cbnz %w1, 1b" \ + : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \ + : "Ir" (i)); \ +} \ + +#define ATOMIC64_OP_RETURN(op, asm_op) \ +static inline long atomic64_##op##_return(long i, atomic64_t *v) \ +{ \ + long result; \ + unsigned long tmp; \ + \ + asm volatile("// atomic64_" #op "_return\n" \ +"1: ldxr %0, %2\n" \ +" " #asm_op " %0, %0, %3\n" \ +" stlxr %w1, %0, %2\n" \ +" cbnz %w1, 1b" \ + : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) \ + : "Ir" (i) \ + : "memory"); \ + \ + smp_mb(); \ + return result; \ } -static inline long atomic64_add_return(long i, atomic64_t *v) -{ - long result; - unsigned long tmp; +#define ATOMIC64_OPS(op, asm_op) \ + ATOMIC64_OP(op, asm_op) \ + ATOMIC64_OP_RETURN(op, asm_op) - asm volatile("// atomic64_add_return\n" -"1: ldxr %0, %2\n" -" add %0, %0, %3\n" -" stlxr %w1, %0, %2\n" -" cbnz %w1, 1b" - : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) - : "Ir" (i) - : "memory"); +ATOMIC64_OPS(add, add) +ATOMIC64_OPS(sub, sub) - smp_mb(); - return result; -} - -static inline void atomic64_sub(u64 i, atomic64_t *v) -{ - long result; - unsigned long tmp; - - asm volatile("// atomic64_sub\n" -"1: ldxr %0, %2\n" -" sub %0, %0, %3\n" -" stxr %w1, %0, %2\n" -" cbnz %w1, 1b" - : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) - : "Ir" (i)); -} - -static inline long atomic64_sub_return(long i, atomic64_t *v) -{ - long result; - unsigned long tmp; - - asm volatile("// atomic64_sub_return\n" -"1: ldxr %0, %2\n" -" sub %0, %0, %3\n" -" stlxr %w1, %0, %2\n" -" cbnz %w1, 1b" - : "=&r" (result), "=&r" (tmp), "+Q" (v->counter) - : "Ir" (i) - : "memory"); - - smp_mb(); - return result; -} +#undef ATOMIC64_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP static inline long atomic64_cmpxchg(atomic64_t *ptr, long old, long new) { -- GitLab From d325209b6000dcd13404ee946d2292e15a56718c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 9 Apr 2014 21:51:29 +0200 Subject: [PATCH 0404/9167] locking,arch,avr32: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Requires the asm_op because of eor. AVR32 is a bit special in that its ADD/SUB instructions are not symmetric. Its SUB instruction allows for an 21bit immediate. Signed-off-by: Peter Zijlstra Cc: Hans-Christian Egtvedt Cc: Haavard Skinnemoen Cc: Hans-Christian Egtvedt Cc: Linus Torvalds Cc: Paul E. McKenney Link: http://lkml.kernel.org/r/20140531141445.GD16155@laptop.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- arch/avr32/include/asm/atomic.h | 123 ++++++++++++++++---------------- 1 file changed, 62 insertions(+), 61 deletions(-) diff --git a/arch/avr32/include/asm/atomic.h b/arch/avr32/include/asm/atomic.h index 0780f3f2415b..83e980a4e483 100644 --- a/arch/avr32/include/asm/atomic.h +++ b/arch/avr32/include/asm/atomic.h @@ -22,30 +22,43 @@ #define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic_set(v, i) (((v)->counter) = i) +#define ATOMIC_OP_RETURN(op, asm_op, asm_con) \ +static inline int __atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int result; \ + \ + asm volatile( \ + "/* atomic_" #op "_return */\n" \ + "1: ssrf 5\n" \ + " ld.w %0, %2\n" \ + " " #asm_op " %0, %3\n" \ + " stcond %1, %0\n" \ + " brne 1b" \ + : "=&r" (result), "=o" (v->counter) \ + : "m" (v->counter), #asm_con (i) \ + : "cc"); \ + \ + return result; \ +} + +ATOMIC_OP_RETURN(sub, sub, rKs21) +ATOMIC_OP_RETURN(add, add, r) + +#undef ATOMIC_OP_RETURN + /* - * atomic_sub_return - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t + * Probably found the reason why we want to use sub with the signed 21-bit + * limit, it uses one less register than the add instruction that can add up to + * 32-bit values. * - * Atomically subtracts @i from @v. Returns the resulting value. + * Both instructions are 32-bit, to use a 16-bit instruction the immediate is + * very small; 4 bit. + * + * sub 32-bit, type IV, takes a register and subtracts a 21-bit immediate. + * add 32-bit, type II, adds two register values together. */ -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int result; - - asm volatile( - "/* atomic_sub_return */\n" - "1: ssrf 5\n" - " ld.w %0, %2\n" - " sub %0, %3\n" - " stcond %1, %0\n" - " brne 1b" - : "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "rKs21"(i) - : "cc"); - - return result; -} +#define IS_21BIT_CONST(i) \ + (__builtin_constant_p(i) && ((i) >= -1048575) && ((i) <= 1048576)) /* * atomic_add_return - add integer to atomic variable @@ -56,51 +69,25 @@ static inline int atomic_sub_return(int i, atomic_t *v) */ static inline int atomic_add_return(int i, atomic_t *v) { - int result; - - if (__builtin_constant_p(i) && (i >= -1048575) && (i <= 1048576)) - result = atomic_sub_return(-i, v); - else - asm volatile( - "/* atomic_add_return */\n" - "1: ssrf 5\n" - " ld.w %0, %1\n" - " add %0, %3\n" - " stcond %2, %0\n" - " brne 1b" - : "=&r"(result), "=o"(v->counter) - : "m"(v->counter), "r"(i) - : "cc", "memory"); + if (IS_21BIT_CONST(i)) + return __atomic_sub_return(-i, v); - return result; + return __atomic_add_return(i, v); } /* - * atomic_sub_unless - sub unless the number is a given value + * atomic_sub_return - subtract the atomic variable + * @i: integer value to subtract * @v: pointer of type atomic_t - * @a: the amount to subtract from v... - * @u: ...unless v is equal to u. * - * Atomically subtract @a from @v, so long as it was not @u. - * Returns the old value of @v. -*/ -static inline void atomic_sub_unless(atomic_t *v, int a, int u) + * Atomically subtracts @i from @v. Returns the resulting value. + */ +static inline int atomic_sub_return(int i, atomic_t *v) { - int tmp; + if (IS_21BIT_CONST(i)) + return __atomic_sub_return(i, v); - asm volatile( - "/* atomic_sub_unless */\n" - "1: ssrf 5\n" - " ld.w %0, %2\n" - " cp.w %0, %4\n" - " breq 1f\n" - " sub %0, %3\n" - " stcond %1, %0\n" - " brne 1b\n" - "1:" - : "=&r"(tmp), "=o"(v->counter) - : "m"(v->counter), "rKs21"(a), "rKs21"(u) - : "cc", "memory"); + return __atomic_add_return(-i, v); } /* @@ -116,9 +103,21 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) { int tmp, old = atomic_read(v); - if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576)) - atomic_sub_unless(v, -a, u); - else { + if (IS_21BIT_CONST(a)) { + asm volatile( + "/* __atomic_sub_unless */\n" + "1: ssrf 5\n" + " ld.w %0, %2\n" + " cp.w %0, %4\n" + " breq 1f\n" + " sub %0, %3\n" + " stcond %1, %0\n" + " brne 1b\n" + "1:" + : "=&r"(tmp), "=o"(v->counter) + : "m"(v->counter), "rKs21"(-a), "rKs21"(u) + : "cc", "memory"); + } else { asm volatile( "/* __atomic_add_unless */\n" "1: ssrf 5\n" @@ -137,6 +136,8 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u) return old; } +#undef IS_21BIT_CONST + /* * atomic_sub_if_positive - conditionally subtract integer from atomic variable * @i: integer value to subtract -- GitLab From 7179e30ef66a5bae91592ae7fbacf3df6c627dd6 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 18:19:25 +0100 Subject: [PATCH 0405/9167] locking,arch,cris: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Acked-by: Jesper Nilsson Cc: Geert Uytterhoeven Cc: Linus Torvalds Cc: Mikael Starvik Cc: Paul E. McKenney Cc: linux-cris-kernel@axis.com Link: http://lkml.kernel.org/r/20140508135852.104572724@infradead.org Signed-off-by: Ingo Molnar --- arch/cris/include/asm/atomic.h | 57 +++++++++++++++------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/arch/cris/include/asm/atomic.h b/arch/cris/include/asm/atomic.h index aa429baebaf9..0033f9dfea24 100644 --- a/arch/cris/include/asm/atomic.h +++ b/arch/cris/include/asm/atomic.h @@ -22,43 +22,36 @@ /* These should be written in asm but we do it in C for now. */ -static inline void atomic_add(int i, volatile atomic_t *v) -{ - unsigned long flags; - cris_atomic_save(v, flags); - v->counter += i; - cris_atomic_restore(v, flags); +#define ATOMIC_OP(op, c_op) \ +static inline void atomic_##op(int i, volatile atomic_t *v) \ +{ \ + unsigned long flags; \ + cris_atomic_save(v, flags); \ + v->counter c_op i; \ + cris_atomic_restore(v, flags); \ +} \ + +#define ATOMIC_OP_RETURN(op, c_op) \ +static inline int atomic_##op##_return(int i, volatile atomic_t *v) \ +{ \ + unsigned long flags; \ + int retval; \ + cris_atomic_save(v, flags); \ + retval = (v->counter c_op i); \ + cris_atomic_restore(v, flags); \ + return retval; \ } -static inline void atomic_sub(int i, volatile atomic_t *v) -{ - unsigned long flags; - cris_atomic_save(v, flags); - v->counter -= i; - cris_atomic_restore(v, flags); -} +#define ATOMIC_OPS(op, c_op) ATOMIC_OP(op, c_op) ATOMIC_OP_RETURN(op, c_op) -static inline int atomic_add_return(int i, volatile atomic_t *v) -{ - unsigned long flags; - int retval; - cris_atomic_save(v, flags); - retval = (v->counter += i); - cris_atomic_restore(v, flags); - return retval; -} +ATOMIC_OPS(add, +=) +ATOMIC_OPS(sub, -=) -#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP -static inline int atomic_sub_return(int i, volatile atomic_t *v) -{ - unsigned long flags; - int retval; - cris_atomic_save(v, flags); - retval = (v->counter -= i); - cris_atomic_restore(v, flags); - return retval; -} +#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) static inline int atomic_sub_and_test(int i, volatile atomic_t *v) { -- GitLab From 50f853e38b0b90a5703ab14b70e20eb5a8ccd5de Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 18:20:26 +0100 Subject: [PATCH 0406/9167] locking,arch,hexagon: Fold atomic_ops OK, no LoC saved in this case because the !return variants were defined in terms of the return ops. Still do it because this also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Acked-by: Richard Kuo Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Vineet Gupta Cc: linux-hexagon@vger.kernel.org Link: http://lkml.kernel.org/r/20140508135852.171567636@infradead.org Signed-off-by: Ingo Molnar --- arch/hexagon/include/asm/atomic.h | 68 +++++++++++++++++-------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/arch/hexagon/include/asm/atomic.h b/arch/hexagon/include/asm/atomic.h index de916b11bff5..93d07025f183 100644 --- a/arch/hexagon/include/asm/atomic.h +++ b/arch/hexagon/include/asm/atomic.h @@ -94,41 +94,47 @@ static inline int atomic_cmpxchg(atomic_t *v, int old, int new) return __oldval; } -static inline int atomic_add_return(int i, atomic_t *v) -{ - int output; - - __asm__ __volatile__ ( - "1: %0 = memw_locked(%1);\n" - " %0 = add(%0,%2);\n" - " memw_locked(%1,P3)=%0;\n" - " if !P3 jump 1b;\n" - : "=&r" (output) - : "r" (&v->counter), "r" (i) - : "memory", "p3" - ); - return output; - +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + int output; \ + \ + __asm__ __volatile__ ( \ + "1: %0 = memw_locked(%1);\n" \ + " %0 = "#op "(%0,%2);\n" \ + " memw_locked(%1,P3)=%0;\n" \ + " if !P3 jump 1b;\n" \ + : "=&r" (output) \ + : "r" (&v->counter), "r" (i) \ + : "memory", "p3" \ + ); \ +} \ + +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int output; \ + \ + __asm__ __volatile__ ( \ + "1: %0 = memw_locked(%1);\n" \ + " %0 = "#op "(%0,%2);\n" \ + " memw_locked(%1,P3)=%0;\n" \ + " if !P3 jump 1b;\n" \ + : "=&r" (output) \ + : "r" (&v->counter), "r" (i) \ + : "memory", "p3" \ + ); \ + return output; \ } -#define atomic_add(i, v) atomic_add_return(i, (v)) +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int output; - __asm__ __volatile__ ( - "1: %0 = memw_locked(%1);\n" - " %0 = sub(%0,%2);\n" - " memw_locked(%1,P3)=%0\n" - " if !P3 jump 1b;\n" - : "=&r" (output) - : "r" (&v->counter), "r" (i) - : "memory", "p3" - ); - return output; -} +ATOMIC_OPS(add) +ATOMIC_OPS(sub) -#define atomic_sub(i, v) atomic_sub_return(i, (v)) +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP /** * __atomic_add_unless - add unless the number is a given value -- GitLab From 08be2dab191431f23f5f98ba2db76513d0d853e7 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 18:20:30 +0100 Subject: [PATCH 0407/9167] locking,arch,ia64: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Cc: Fenghua Yu Cc: Linus Torvalds Cc: Akinobu Mita Cc: Paul E. McKenney Cc: Tony Luck Cc: linux-ia64@vger.kernel.org Link: http://lkml.kernel.org/r/20140508135852.245224472@infradead.org Signed-off-by: Ingo Molnar --- arch/ia64/include/asm/atomic.h | 188 +++++++++++++++------------------ 1 file changed, 86 insertions(+), 102 deletions(-) diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h index 0f8bf48dadf3..42919a831c6c 100644 --- a/arch/ia64/include/asm/atomic.h +++ b/arch/ia64/include/asm/atomic.h @@ -27,62 +27,94 @@ #define atomic_set(v,i) (((v)->counter) = (i)) #define atomic64_set(v,i) (((v)->counter) = (i)) -static __inline__ int -ia64_atomic_add (int i, atomic_t *v) -{ - __s32 old, new; - CMPXCHG_BUGCHECK_DECL - - do { - CMPXCHG_BUGCHECK(v); - old = atomic_read(v); - new = old + i; - } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); - return new; +#define ATOMIC_OP(op, c_op) \ +static __inline__ int \ +ia64_atomic_##op (int i, atomic_t *v) \ +{ \ + __s32 old, new; \ + CMPXCHG_BUGCHECK_DECL \ + \ + do { \ + CMPXCHG_BUGCHECK(v); \ + old = atomic_read(v); \ + new = old c_op i; \ + } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); \ + return new; \ } -static __inline__ long -ia64_atomic64_add (__s64 i, atomic64_t *v) -{ - __s64 old, new; - CMPXCHG_BUGCHECK_DECL - - do { - CMPXCHG_BUGCHECK(v); - old = atomic64_read(v); - new = old + i; - } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); - return new; -} +ATOMIC_OP(add, +) +ATOMIC_OP(sub, -) -static __inline__ int -ia64_atomic_sub (int i, atomic_t *v) -{ - __s32 old, new; - CMPXCHG_BUGCHECK_DECL - - do { - CMPXCHG_BUGCHECK(v); - old = atomic_read(v); - new = old - i; - } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic_t)) != old); - return new; -} +#undef ATOMIC_OP -static __inline__ long -ia64_atomic64_sub (__s64 i, atomic64_t *v) -{ - __s64 old, new; - CMPXCHG_BUGCHECK_DECL - - do { - CMPXCHG_BUGCHECK(v); - old = atomic64_read(v); - new = old - i; - } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); - return new; +#define atomic_add_return(i,v) \ +({ \ + int __ia64_aar_i = (i); \ + (__builtin_constant_p(i) \ + && ( (__ia64_aar_i == 1) || (__ia64_aar_i == 4) \ + || (__ia64_aar_i == 8) || (__ia64_aar_i == 16) \ + || (__ia64_aar_i == -1) || (__ia64_aar_i == -4) \ + || (__ia64_aar_i == -8) || (__ia64_aar_i == -16))) \ + ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \ + : ia64_atomic_add(__ia64_aar_i, v); \ +}) + +#define atomic_sub_return(i,v) \ +({ \ + int __ia64_asr_i = (i); \ + (__builtin_constant_p(i) \ + && ( (__ia64_asr_i == 1) || (__ia64_asr_i == 4) \ + || (__ia64_asr_i == 8) || (__ia64_asr_i == 16) \ + || (__ia64_asr_i == -1) || (__ia64_asr_i == -4) \ + || (__ia64_asr_i == -8) || (__ia64_asr_i == -16))) \ + ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \ + : ia64_atomic_sub(__ia64_asr_i, v); \ +}) + +#define ATOMIC64_OP(op, c_op) \ +static __inline__ long \ +ia64_atomic64_##op (__s64 i, atomic64_t *v) \ +{ \ + __s64 old, new; \ + CMPXCHG_BUGCHECK_DECL \ + \ + do { \ + CMPXCHG_BUGCHECK(v); \ + old = atomic64_read(v); \ + new = old c_op i; \ + } while (ia64_cmpxchg(acq, v, old, new, sizeof(atomic64_t)) != old); \ + return new; \ } +ATOMIC64_OP(add, +) +ATOMIC64_OP(sub, -) + +#undef ATOMIC64_OP + +#define atomic64_add_return(i,v) \ +({ \ + long __ia64_aar_i = (i); \ + (__builtin_constant_p(i) \ + && ( (__ia64_aar_i == 1) || (__ia64_aar_i == 4) \ + || (__ia64_aar_i == 8) || (__ia64_aar_i == 16) \ + || (__ia64_aar_i == -1) || (__ia64_aar_i == -4) \ + || (__ia64_aar_i == -8) || (__ia64_aar_i == -16))) \ + ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \ + : ia64_atomic64_add(__ia64_aar_i, v); \ +}) + +#define atomic64_sub_return(i,v) \ +({ \ + long __ia64_asr_i = (i); \ + (__builtin_constant_p(i) \ + && ( (__ia64_asr_i == 1) || (__ia64_asr_i == 4) \ + || (__ia64_asr_i == 8) || (__ia64_asr_i == 16) \ + || (__ia64_asr_i == -1) || (__ia64_asr_i == -4) \ + || (__ia64_asr_i == -8) || (__ia64_asr_i == -16))) \ + ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \ + : ia64_atomic64_sub(__ia64_asr_i, v); \ +}) + #define atomic_cmpxchg(v, old, new) (cmpxchg(&((v)->counter), old, new)) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) @@ -123,30 +155,6 @@ static __inline__ long atomic64_add_unless(atomic64_t *v, long a, long u) #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) -#define atomic_add_return(i,v) \ -({ \ - int __ia64_aar_i = (i); \ - (__builtin_constant_p(i) \ - && ( (__ia64_aar_i == 1) || (__ia64_aar_i == 4) \ - || (__ia64_aar_i == 8) || (__ia64_aar_i == 16) \ - || (__ia64_aar_i == -1) || (__ia64_aar_i == -4) \ - || (__ia64_aar_i == -8) || (__ia64_aar_i == -16))) \ - ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \ - : ia64_atomic_add(__ia64_aar_i, v); \ -}) - -#define atomic64_add_return(i,v) \ -({ \ - long __ia64_aar_i = (i); \ - (__builtin_constant_p(i) \ - && ( (__ia64_aar_i == 1) || (__ia64_aar_i == 4) \ - || (__ia64_aar_i == 8) || (__ia64_aar_i == 16) \ - || (__ia64_aar_i == -1) || (__ia64_aar_i == -4) \ - || (__ia64_aar_i == -8) || (__ia64_aar_i == -16))) \ - ? ia64_fetch_and_add(__ia64_aar_i, &(v)->counter) \ - : ia64_atomic64_add(__ia64_aar_i, v); \ -}) - /* * Atomically add I to V and return TRUE if the resulting value is * negative. @@ -163,30 +171,6 @@ atomic64_add_negative (__s64 i, atomic64_t *v) return atomic64_add_return(i, v) < 0; } -#define atomic_sub_return(i,v) \ -({ \ - int __ia64_asr_i = (i); \ - (__builtin_constant_p(i) \ - && ( (__ia64_asr_i == 1) || (__ia64_asr_i == 4) \ - || (__ia64_asr_i == 8) || (__ia64_asr_i == 16) \ - || (__ia64_asr_i == -1) || (__ia64_asr_i == -4) \ - || (__ia64_asr_i == -8) || (__ia64_asr_i == -16))) \ - ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \ - : ia64_atomic_sub(__ia64_asr_i, v); \ -}) - -#define atomic64_sub_return(i,v) \ -({ \ - long __ia64_asr_i = (i); \ - (__builtin_constant_p(i) \ - && ( (__ia64_asr_i == 1) || (__ia64_asr_i == 4) \ - || (__ia64_asr_i == 8) || (__ia64_asr_i == 16) \ - || (__ia64_asr_i == -1) || (__ia64_asr_i == -4) \ - || (__ia64_asr_i == -8) || (__ia64_asr_i == -16))) \ - ? ia64_fetch_and_add(-__ia64_asr_i, &(v)->counter) \ - : ia64_atomic64_sub(__ia64_asr_i, v); \ -}) - #define atomic_dec_return(v) atomic_sub_return(1, (v)) #define atomic_inc_return(v) atomic_add_return(1, (v)) #define atomic64_dec_return(v) atomic64_sub_return(1, (v)) @@ -199,13 +183,13 @@ atomic64_add_negative (__s64 i, atomic64_t *v) #define atomic64_dec_and_test(v) (atomic64_sub_return(1, (v)) == 0) #define atomic64_inc_and_test(v) (atomic64_add_return(1, (v)) == 0) -#define atomic_add(i,v) atomic_add_return((i), (v)) -#define atomic_sub(i,v) atomic_sub_return((i), (v)) +#define atomic_add(i,v) (void)atomic_add_return((i), (v)) +#define atomic_sub(i,v) (void)atomic_sub_return((i), (v)) #define atomic_inc(v) atomic_add(1, (v)) #define atomic_dec(v) atomic_sub(1, (v)) -#define atomic64_add(i,v) atomic64_add_return((i), (v)) -#define atomic64_sub(i,v) atomic64_sub_return((i), (v)) +#define atomic64_add(i,v) (void)atomic64_add_return((i), (v)) +#define atomic64_sub(i,v) (void)atomic64_sub_return((i), (v)) #define atomic64_inc(v) atomic64_add(1, (v)) #define atomic64_dec(v) atomic64_sub(1, (v)) -- GitLab From c9ebe21b204f95e3aba84ee91c8b9347d73806f1 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 19:02:22 +0100 Subject: [PATCH 0408/9167] locking,arch,m32r: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Cc: Hirokazu Takata Cc: Linus Torvalds Cc: Paul E. McKenney Cc: linux-m32r-ja@ml.linux-m32r.org Cc: linux-m32r@ml.linux-m32r.org Link: http://lkml.kernel.org/r/20140508135852.318635136@infradead.org Signed-off-by: Ingo Molnar --- arch/m32r/include/asm/atomic.h | 143 +++++++++++++-------------------- 1 file changed, 57 insertions(+), 86 deletions(-) diff --git a/arch/m32r/include/asm/atomic.h b/arch/m32r/include/asm/atomic.h index 8ad0ed4182a5..3946b2c8d971 100644 --- a/arch/m32r/include/asm/atomic.h +++ b/arch/m32r/include/asm/atomic.h @@ -39,85 +39,64 @@ */ #define atomic_set(v,i) (((v)->counter) = (i)) -/** - * atomic_add_return - add integer to atomic variable and return it - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v and return (@i + @v). - */ -static __inline__ int atomic_add_return(int i, atomic_t *v) -{ - unsigned long flags; - int result; - - local_irq_save(flags); - __asm__ __volatile__ ( - "# atomic_add_return \n\t" - DCACHE_CLEAR("%0", "r4", "%1") - M32R_LOCK" %0, @%1; \n\t" - "add %0, %2; \n\t" - M32R_UNLOCK" %0, @%1; \n\t" - : "=&r" (result) - : "r" (&v->counter), "r" (i) - : "memory" #ifdef CONFIG_CHIP_M32700_TS1 - , "r4" -#endif /* CONFIG_CHIP_M32700_TS1 */ - ); - local_irq_restore(flags); - - return result; +#define __ATOMIC_CLOBBER , "r4" +#else +#define __ATOMIC_CLOBBER +#endif + +#define ATOMIC_OP(op) \ +static __inline__ void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + int result; \ + \ + local_irq_save(flags); \ + __asm__ __volatile__ ( \ + "# atomic_" #op " \n\t" \ + DCACHE_CLEAR("%0", "r4", "%1") \ + M32R_LOCK" %0, @%1; \n\t" \ + #op " %0, %2; \n\t" \ + M32R_UNLOCK" %0, @%1; \n\t" \ + : "=&r" (result) \ + : "r" (&v->counter), "r" (i) \ + : "memory" \ + __ATOMIC_CLOBBER \ + ); \ + local_irq_restore(flags); \ +} \ + +#define ATOMIC_OP_RETURN(op) \ +static __inline__ int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + int result; \ + \ + local_irq_save(flags); \ + __asm__ __volatile__ ( \ + "# atomic_" #op "_return \n\t" \ + DCACHE_CLEAR("%0", "r4", "%1") \ + M32R_LOCK" %0, @%1; \n\t" \ + #op " %0, %2; \n\t" \ + M32R_UNLOCK" %0, @%1; \n\t" \ + : "=&r" (result) \ + : "r" (&v->counter), "r" (i) \ + : "memory" \ + __ATOMIC_CLOBBER \ + ); \ + local_irq_restore(flags); \ + \ + return result; \ } -/** - * atomic_sub_return - subtract integer from atomic variable and return it - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v and return (@v - @i). - */ -static __inline__ int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long flags; - int result; - - local_irq_save(flags); - __asm__ __volatile__ ( - "# atomic_sub_return \n\t" - DCACHE_CLEAR("%0", "r4", "%1") - M32R_LOCK" %0, @%1; \n\t" - "sub %0, %2; \n\t" - M32R_UNLOCK" %0, @%1; \n\t" - : "=&r" (result) - : "r" (&v->counter), "r" (i) - : "memory" -#ifdef CONFIG_CHIP_M32700_TS1 - , "r4" -#endif /* CONFIG_CHIP_M32700_TS1 */ - ); - local_irq_restore(flags); - - return result; -} +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) -/** - * atomic_add - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v. - */ -#define atomic_add(i,v) ((void) atomic_add_return((i), (v))) +ATOMIC_OPS(add) +ATOMIC_OPS(sub) -/** - * atomic_sub - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v. - */ -#define atomic_sub(i,v) ((void) atomic_sub_return((i), (v))) +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP /** * atomic_sub_and_test - subtract value from variable and test result @@ -151,9 +130,7 @@ static __inline__ int atomic_inc_return(atomic_t *v) : "=&r" (result) : "r" (&v->counter) : "memory" -#ifdef CONFIG_CHIP_M32700_TS1 - , "r4" -#endif /* CONFIG_CHIP_M32700_TS1 */ + __ATOMIC_CLOBBER ); local_irq_restore(flags); @@ -181,9 +158,7 @@ static __inline__ int atomic_dec_return(atomic_t *v) : "=&r" (result) : "r" (&v->counter) : "memory" -#ifdef CONFIG_CHIP_M32700_TS1 - , "r4" -#endif /* CONFIG_CHIP_M32700_TS1 */ + __ATOMIC_CLOBBER ); local_irq_restore(flags); @@ -280,9 +255,7 @@ static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t *addr) : "=&r" (tmp) : "r" (addr), "r" (~mask) : "memory" -#ifdef CONFIG_CHIP_M32700_TS1 - , "r5" -#endif /* CONFIG_CHIP_M32700_TS1 */ + __ATOMIC_CLOBBER ); local_irq_restore(flags); } @@ -302,9 +275,7 @@ static __inline__ void atomic_set_mask(unsigned long mask, atomic_t *addr) : "=&r" (tmp) : "r" (addr), "r" (mask) : "memory" -#ifdef CONFIG_CHIP_M32700_TS1 - , "r5" -#endif /* CONFIG_CHIP_M32700_TS1 */ + __ATOMIC_CLOBBER ); local_irq_restore(flags); } -- GitLab From d839bae4269aea46bff4133066a411cfba5c7c46 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 19:06:34 +0100 Subject: [PATCH 0409/9167] locking,arch,m68k: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Requires asm_op due to eor. Signed-off-by: Peter Zijlstra Acked-by: Geert Uytterhoeven Cc: Linus Torvalds Cc: Paul E. McKenney Cc: linux-m68k@lists.linux-m68k.org Link: http://lkml.kernel.org/r/20140509091646.GO30445@twins.programming.kicks-ass.net Signed-off-by: Ingo Molnar --- arch/m68k/include/asm/atomic.h | 109 ++++++++++++++------------------- 1 file changed, 47 insertions(+), 62 deletions(-) diff --git a/arch/m68k/include/asm/atomic.h b/arch/m68k/include/asm/atomic.h index 55695212a2ae..663d4ba2462c 100644 --- a/arch/m68k/include/asm/atomic.h +++ b/arch/m68k/include/asm/atomic.h @@ -30,16 +30,57 @@ #define ASM_DI "di" #endif -static inline void atomic_add(int i, atomic_t *v) -{ - __asm__ __volatile__("addl %1,%0" : "+m" (*v) : ASM_DI (i)); +#define ATOMIC_OP(op, c_op, asm_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + __asm__ __volatile__(#asm_op "l %1,%0" : "+m" (*v) : ASM_DI (i));\ +} \ + +#ifdef CONFIG_RMW_INSNS + +#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int t, tmp; \ + \ + __asm__ __volatile__( \ + "1: movel %2,%1\n" \ + " " #asm_op "l %3,%1\n" \ + " casl %2,%1,%0\n" \ + " jne 1b" \ + : "+m" (*v), "=&d" (t), "=&d" (tmp) \ + : "g" (i), "2" (atomic_read(v))); \ + return t; \ } -static inline void atomic_sub(int i, atomic_t *v) -{ - __asm__ __volatile__("subl %1,%0" : "+m" (*v) : ASM_DI (i)); +#else + +#define ATOMIC_OP_RETURN(op, c_op, asm_op) \ +static inline int atomic_##op##_return(int i, atomic_t * v) \ +{ \ + unsigned long flags; \ + int t; \ + \ + local_irq_save(flags); \ + t = (v->counter c_op i); \ + local_irq_restore(flags); \ + \ + return t; \ } +#endif /* CONFIG_RMW_INSNS */ + +#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, +=, add) +ATOMIC_OPS(sub, -=, sub) + +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP + static inline void atomic_inc(atomic_t *v) { __asm__ __volatile__("addql #1,%0" : "+m" (*v)); @@ -76,67 +117,11 @@ static inline int atomic_inc_and_test(atomic_t *v) #ifdef CONFIG_RMW_INSNS -static inline int atomic_add_return(int i, atomic_t *v) -{ - int t, tmp; - - __asm__ __volatile__( - "1: movel %2,%1\n" - " addl %3,%1\n" - " casl %2,%1,%0\n" - " jne 1b" - : "+m" (*v), "=&d" (t), "=&d" (tmp) - : "g" (i), "2" (atomic_read(v))); - return t; -} - -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int t, tmp; - - __asm__ __volatile__( - "1: movel %2,%1\n" - " subl %3,%1\n" - " casl %2,%1,%0\n" - " jne 1b" - : "+m" (*v), "=&d" (t), "=&d" (tmp) - : "g" (i), "2" (atomic_read(v))); - return t; -} - #define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) #else /* !CONFIG_RMW_INSNS */ -static inline int atomic_add_return(int i, atomic_t * v) -{ - unsigned long flags; - int t; - - local_irq_save(flags); - t = atomic_read(v); - t += i; - atomic_set(v, t); - local_irq_restore(flags); - - return t; -} - -static inline int atomic_sub_return(int i, atomic_t * v) -{ - unsigned long flags; - int t; - - local_irq_save(flags); - t = atomic_read(v); - t -= i; - atomic_set(v, t); - local_irq_restore(flags); - - return t; -} - static inline int atomic_cmpxchg(atomic_t *v, int old, int new) { unsigned long flags; -- GitLab From d6dfe2509da935a15583cace7cd3837b1e8addef Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sun, 23 Mar 2014 19:08:25 +0100 Subject: [PATCH 0410/9167] locking,arch,metag: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Acked-by: James Hogan Cc: Linus Torvalds Cc: linux-metag@vger.kernel.org Link: http://lkml.kernel.org/r/20140508135852.453864110@infradead.org Signed-off-by: Ingo Molnar --- arch/metag/include/asm/atomic_lnkget.h | 121 ++++++++++--------------- arch/metag/include/asm/atomic_lock1.h | 76 +++++++--------- 2 files changed, 77 insertions(+), 120 deletions(-) diff --git a/arch/metag/include/asm/atomic_lnkget.h b/arch/metag/include/asm/atomic_lnkget.h index d2e60a18986c..948d8688643c 100644 --- a/arch/metag/include/asm/atomic_lnkget.h +++ b/arch/metag/include/asm/atomic_lnkget.h @@ -27,85 +27,56 @@ static inline int atomic_read(const atomic_t *v) return temp; } -static inline void atomic_add(int i, atomic_t *v) -{ - int temp; - - asm volatile ( - "1: LNKGETD %0, [%1]\n" - " ADD %0, %0, %2\n" - " LNKSETD [%1], %0\n" - " DEFR %0, TXSTAT\n" - " ANDT %0, %0, #HI(0x3f000000)\n" - " CMPT %0, #HI(0x02000000)\n" - " BNZ 1b\n" - : "=&d" (temp) - : "da" (&v->counter), "bd" (i) - : "cc"); +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + int temp; \ + \ + asm volatile ( \ + "1: LNKGETD %0, [%1]\n" \ + " " #op " %0, %0, %2\n" \ + " LNKSETD [%1], %0\n" \ + " DEFR %0, TXSTAT\n" \ + " ANDT %0, %0, #HI(0x3f000000)\n" \ + " CMPT %0, #HI(0x02000000)\n" \ + " BNZ 1b\n" \ + : "=&d" (temp) \ + : "da" (&v->counter), "bd" (i) \ + : "cc"); \ +} \ + +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int result, temp; \ + \ + smp_mb(); \ + \ + asm volatile ( \ + "1: LNKGETD %1, [%2]\n" \ + " " #op " %1, %1, %3\n" \ + " LNKSETD [%2], %1\n" \ + " DEFR %0, TXSTAT\n" \ + " ANDT %0, %0, #HI(0x3f000000)\n" \ + " CMPT %0, #HI(0x02000000)\n" \ + " BNZ 1b\n" \ + : "=&d" (temp), "=&da" (result) \ + : "da" (&v->counter), "bd" (i) \ + : "cc"); \ + \ + smp_mb(); \ + \ + return result; \ } -static inline void atomic_sub(int i, atomic_t *v) -{ - int temp; +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) - asm volatile ( - "1: LNKGETD %0, [%1]\n" - " SUB %0, %0, %2\n" - " LNKSETD [%1], %0\n" - " DEFR %0, TXSTAT\n" - " ANDT %0, %0, #HI(0x3f000000)\n" - " CMPT %0, #HI(0x02000000)\n" - " BNZ 1b\n" - : "=&d" (temp) - : "da" (&v->counter), "bd" (i) - : "cc"); -} +ATOMIC_OPS(add) +ATOMIC_OPS(sub) -static inline int atomic_add_return(int i, atomic_t *v) -{ - int result, temp; - - smp_mb(); - - asm volatile ( - "1: LNKGETD %1, [%2]\n" - " ADD %1, %1, %3\n" - " LNKSETD [%2], %1\n" - " DEFR %0, TXSTAT\n" - " ANDT %0, %0, #HI(0x3f000000)\n" - " CMPT %0, #HI(0x02000000)\n" - " BNZ 1b\n" - : "=&d" (temp), "=&da" (result) - : "da" (&v->counter), "bd" (i) - : "cc"); - - smp_mb(); - - return result; -} - -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int result, temp; - - smp_mb(); - - asm volatile ( - "1: LNKGETD %1, [%2]\n" - " SUB %1, %1, %3\n" - " LNKSETD [%2], %1\n" - " DEFR %0, TXSTAT\n" - " ANDT %0, %0, #HI(0x3f000000)\n" - " CMPT %0, #HI(0x02000000)\n" - " BNZ 1b\n" - : "=&d" (temp), "=&da" (result) - : "da" (&v->counter), "bd" (i) - : "cc"); - - smp_mb(); - - return result; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { diff --git a/arch/metag/include/asm/atomic_lock1.h b/arch/metag/include/asm/atomic_lock1.h index e578955e674b..f5d5898c1020 100644 --- a/arch/metag/include/asm/atomic_lock1.h +++ b/arch/metag/include/asm/atomic_lock1.h @@ -37,55 +37,41 @@ static inline int atomic_set(atomic_t *v, int i) return i; } -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned long flags; - - __global_lock1(flags); - fence(); - v->counter += i; - __global_unlock1(flags); +#define ATOMIC_OP(op, c_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + \ + __global_lock1(flags); \ + fence(); \ + v->counter c_op i; \ + __global_unlock1(flags); \ +} \ + +#define ATOMIC_OP_RETURN(op, c_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long result; \ + unsigned long flags; \ + \ + __global_lock1(flags); \ + result = v->counter; \ + result c_op i; \ + fence(); \ + v->counter = result; \ + __global_unlock1(flags); \ + \ + return result; \ } -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned long flags; +#define ATOMIC_OPS(op, c_op) ATOMIC_OP(op, c_op) ATOMIC_OP_RETURN(op, c_op) - __global_lock1(flags); - fence(); - v->counter -= i; - __global_unlock1(flags); -} - -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned long result; - unsigned long flags; +ATOMIC_OPS(add, +=) +ATOMIC_OPS(sub, -=) - __global_lock1(flags); - result = v->counter; - result += i; - fence(); - v->counter = result; - __global_unlock1(flags); - - return result; -} - -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long result; - unsigned long flags; - - __global_lock1(flags); - result = v->counter; - result -= i; - fence(); - v->counter = result; - __global_unlock1(flags); - - return result; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { -- GitLab From ef31563e950c60bb41b97c2b61c32de874f3c949 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 26 Mar 2014 17:56:43 +0100 Subject: [PATCH 0411/9167] locking,arch,mips: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Cc: Maciej W. Rozycki Cc: Paul E. McKenney Cc: Ralf Baechle Cc: linux-mips@linux-mips.org Link: http://lkml.kernel.org/r/20140508135852.521548500@infradead.org Signed-off-by: Ingo Molnar --- arch/mips/include/asm/atomic.h | 557 +++++++++++---------------------- 1 file changed, 187 insertions(+), 370 deletions(-) diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h index 37b2befe651a..476fe3b5dfc6 100644 --- a/arch/mips/include/asm/atomic.h +++ b/arch/mips/include/asm/atomic.h @@ -40,195 +40,103 @@ */ #define atomic_set(v, i) ((v)->counter = (i)) -/* - * atomic_add - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v. - */ -static __inline__ void atomic_add(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_add \n" - " addu %0, %2 \n" - " sc %0, %1 \n" - " beqzl %0, 1b \n" - " .set mips0 \n" - : "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } else if (kernel_uses_llsc) { - int temp; - - do { - __asm__ __volatile__( - " .set arch=r4000 \n" - " ll %0, %1 # atomic_add \n" - " addu %0, %2 \n" - " sc %0, %1 \n" - " .set mips0 \n" - : "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } while (unlikely(!temp)); - } else { - unsigned long flags; - - raw_local_irq_save(flags); - v->counter += i; - raw_local_irq_restore(flags); - } -} - -/* - * atomic_sub - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v. - */ -static __inline__ void atomic_sub(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_sub \n" - " subu %0, %2 \n" - " sc %0, %1 \n" - " beqzl %0, 1b \n" - " .set mips0 \n" - : "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } else if (kernel_uses_llsc) { - int temp; - - do { - __asm__ __volatile__( - " .set arch=r4000 \n" - " ll %0, %1 # atomic_sub \n" - " subu %0, %2 \n" - " sc %0, %1 \n" - " .set mips0 \n" - : "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } while (unlikely(!temp)); - } else { - unsigned long flags; - - raw_local_irq_save(flags); - v->counter -= i; - raw_local_irq_restore(flags); - } -} - -/* - * Same as above, but return the result value - */ -static __inline__ int atomic_add_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_add_return \n" - " addu %0, %1, %3 \n" - " sc %0, %2 \n" - " beqzl %0, 1b \n" - " addu %0, %1, %3 \n" - " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } else if (kernel_uses_llsc) { - int temp; - - do { - __asm__ __volatile__( - " .set arch=r4000 \n" - " ll %1, %2 # atomic_add_return \n" - " addu %0, %1, %3 \n" - " sc %0, %2 \n" - " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } while (unlikely(!result)); - - result = temp + i; - } else { - unsigned long flags; - - raw_local_irq_save(flags); - result = v->counter; - result += 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), "+m" (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), "+m" (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" \ + " addu %0, %1, %3 \n" \ + " .set mips0 \n" \ + : "=&r" (result), "=&r" (temp), "+m" (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), "+m" (v->counter) \ + : "Ir" (i)); \ + } while (unlikely(!result)); \ + \ + result = temp + 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; \ } -static __inline__ int atomic_sub_return(int i, atomic_t * v) -{ - int result; +#define ATOMIC_OPS(op, c_op, asm_op) \ + ATOMIC_OP(op, c_op, asm_op) \ + ATOMIC_OP_RETURN(op, c_op, asm_op) - smp_mb__before_llsc(); +ATOMIC_OPS(add, +=, addu) +ATOMIC_OPS(sub, -=, subu) - if (kernel_uses_llsc && R10000_LLSC_WAR) { - int temp; - - __asm__ __volatile__( - " .set arch=r4000 \n" - "1: ll %1, %2 # atomic_sub_return \n" - " subu %0, %1, %3 \n" - " sc %0, %2 \n" - " beqzl %0, 1b \n" - " subu %0, %1, %3 \n" - " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter) - : "memory"); - - result = temp - i; - } else if (kernel_uses_llsc) { - int temp; - - do { - __asm__ __volatile__( - " .set arch=r4000 \n" - " ll %1, %2 # atomic_sub_return \n" - " subu %0, %1, %3 \n" - " sc %0, %2 \n" - " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } while (unlikely(!result)); - - result = temp - i; - } else { - unsigned long flags; - - raw_local_irq_save(flags); - result = v->counter; - result -= i; - v->counter = result; - raw_local_irq_restore(flags); - } - - smp_llsc_mb(); - - return result; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP /* * atomic_sub_if_positive - conditionally subtract integer from atomic variable @@ -407,195 +315,104 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) */ #define atomic64_set(v, i) ((v)->counter = (i)) -/* - * atomic64_add - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic64_t - * - * Atomically adds @i to @v. - */ -static __inline__ void atomic64_add(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_add \n" - " daddu %0, %2 \n" - " scd %0, %1 \n" - " beqzl %0, 1b \n" - " .set mips0 \n" - : "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } else if (kernel_uses_llsc) { - long temp; - - do { - __asm__ __volatile__( - " .set arch=r4000 \n" - " lld %0, %1 # atomic64_add \n" - " daddu %0, %2 \n" - " scd %0, %1 \n" - " .set mips0 \n" - : "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } while (unlikely(!temp)); - } else { - unsigned long flags; - - raw_local_irq_save(flags); - v->counter += i; - raw_local_irq_restore(flags); - } +#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), "+m" (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), "+m" (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), "+m" (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), "=m" (v->counter) \ + : "Ir" (i), "m" (v->counter) \ + : "memory"); \ + } while (unlikely(!result)); \ + \ + result = temp + 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; \ } -/* - * atomic64_sub - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic64_t - * - * Atomically subtracts @i from @v. - */ -static __inline__ void atomic64_sub(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_sub \n" - " dsubu %0, %2 \n" - " scd %0, %1 \n" - " beqzl %0, 1b \n" - " .set mips0 \n" - : "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } else if (kernel_uses_llsc) { - long temp; - - do { - __asm__ __volatile__( - " .set arch=r4000 \n" - " lld %0, %1 # atomic64_sub \n" - " dsubu %0, %2 \n" - " scd %0, %1 \n" - " .set mips0 \n" - : "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } while (unlikely(!temp)); - } else { - unsigned long flags; - - raw_local_irq_save(flags); - v->counter -= i; - raw_local_irq_restore(flags); - } -} - -/* - * Same as above, but return the result value - */ -static __inline__ long atomic64_add_return(long i, atomic64_t * v) -{ - long result; +#define ATOMIC64_OPS(op, c_op, asm_op) \ + ATOMIC64_OP(op, c_op, asm_op) \ + ATOMIC64_OP_RETURN(op, c_op, asm_op) - smp_mb__before_llsc(); +ATOMIC64_OPS(add, +=, daddu) +ATOMIC64_OPS(sub, -=, dsubu) - if (kernel_uses_llsc && R10000_LLSC_WAR) { - long temp; - - __asm__ __volatile__( - " .set arch=r4000 \n" - "1: lld %1, %2 # atomic64_add_return \n" - " daddu %0, %1, %3 \n" - " scd %0, %2 \n" - " beqzl %0, 1b \n" - " daddu %0, %1, %3 \n" - " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "+m" (v->counter) - : "Ir" (i)); - } else if (kernel_uses_llsc) { - long temp; - - do { - __asm__ __volatile__( - " .set arch=r4000 \n" - " lld %1, %2 # atomic64_add_return \n" - " daddu %0, %1, %3 \n" - " scd %0, %2 \n" - " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter) - : "memory"); - } while (unlikely(!result)); - - result = temp + i; - } else { - unsigned long flags; - - raw_local_irq_save(flags); - result = v->counter; - result += i; - v->counter = result; - raw_local_irq_restore(flags); - } - - smp_llsc_mb(); - - return result; -} - -static __inline__ long atomic64_sub_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_sub_return \n" - " dsubu %0, %1, %3 \n" - " scd %0, %2 \n" - " beqzl %0, 1b \n" - " dsubu %0, %1, %3 \n" - " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter) - : "memory"); - } else if (kernel_uses_llsc) { - long temp; - - do { - __asm__ __volatile__( - " .set arch=r4000 \n" - " lld %1, %2 # atomic64_sub_return \n" - " dsubu %0, %1, %3 \n" - " scd %0, %2 \n" - " .set mips0 \n" - : "=&r" (result), "=&r" (temp), "=m" (v->counter) - : "Ir" (i), "m" (v->counter) - : "memory"); - } while (unlikely(!result)); - - result = temp - i; - } else { - unsigned long flags; - - raw_local_irq_save(flags); - result = v->counter; - result -= i; - v->counter = result; - raw_local_irq_restore(flags); - } - - smp_llsc_mb(); - - return result; -} +#undef ATOMIC64_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP /* * atomic64_sub_if_positive - conditionally subtract integer from atomic variable -- GitLab From e69a0ef76627005e3e83d0e086e6bb1d247bb65b Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 26 Mar 2014 17:59:04 +0100 Subject: [PATCH 0412/9167] locking,arch,mn10300: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Cc: David Howells Cc: Koichi Yasutake Cc: Linus Torvalds Cc: Paul E. McKenney Cc: linux-am33-list@redhat.com Link: http://lkml.kernel.org/r/20140508135852.605324173@infradead.org Signed-off-by: Ingo Molnar --- arch/mn10300/include/asm/atomic.h | 125 ++++++++++-------------------- 1 file changed, 42 insertions(+), 83 deletions(-) diff --git a/arch/mn10300/include/asm/atomic.h b/arch/mn10300/include/asm/atomic.h index cadeb1e2cdfc..5be655e83e70 100644 --- a/arch/mn10300/include/asm/atomic.h +++ b/arch/mn10300/include/asm/atomic.h @@ -33,7 +33,6 @@ * @v: pointer of type atomic_t * * Atomically reads the value of @v. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. */ #define atomic_read(v) (ACCESS_ONCE((v)->counter)) @@ -43,102 +42,62 @@ * @i: required value * * Atomically sets the value of @v to @i. Note that the guaranteed - * useful range of an atomic_t is only 24 bits. */ #define atomic_set(v, i) (((v)->counter) = (i)) -/** - * atomic_add_return - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v and returns the result - * Note that the guaranteed useful range of an atomic_t is only 24 bits. - */ -static inline int atomic_add_return(int i, atomic_t *v) -{ - int retval; -#ifdef CONFIG_SMP - int status; - - asm volatile( - "1: mov %4,(_AAR,%3) \n" - " mov (_ADR,%3),%1 \n" - " add %5,%1 \n" - " mov %1,(_ADR,%3) \n" - " mov (_ADR,%3),%0 \n" /* flush */ - " mov (_ASR,%3),%0 \n" - " or %0,%0 \n" - " bne 1b \n" - : "=&r"(status), "=&r"(retval), "=m"(v->counter) - : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i) - : "memory", "cc"); - -#else - unsigned long flags; +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + int retval, status; \ + \ + asm volatile( \ + "1: mov %4,(_AAR,%3) \n" \ + " mov (_ADR,%3),%1 \n" \ + " " #op " %5,%1 \n" \ + " mov %1,(_ADR,%3) \n" \ + " mov (_ADR,%3),%0 \n" /* flush */ \ + " mov (_ASR,%3),%0 \n" \ + " or %0,%0 \n" \ + " bne 1b \n" \ + : "=&r"(status), "=&r"(retval), "=m"(v->counter) \ + : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i) \ + : "memory", "cc"); \ +} - flags = arch_local_cli_save(); - retval = v->counter; - retval += i; - v->counter = retval; - arch_local_irq_restore(flags); -#endif - return retval; +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int retval, status; \ + \ + asm volatile( \ + "1: mov %4,(_AAR,%3) \n" \ + " mov (_ADR,%3),%1 \n" \ + " " #op " %5,%1 \n" \ + " mov %1,(_ADR,%3) \n" \ + " mov (_ADR,%3),%0 \n" /* flush */ \ + " mov (_ASR,%3),%0 \n" \ + " or %0,%0 \n" \ + " bne 1b \n" \ + : "=&r"(status), "=&r"(retval), "=m"(v->counter) \ + : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i) \ + : "memory", "cc"); \ + return retval; \ } -/** - * atomic_sub_return - subtract integer from atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v and returns the result - * Note that the guaranteed useful range of an atomic_t is only 24 bits. - */ -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int retval; -#ifdef CONFIG_SMP - int status; +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) - asm volatile( - "1: mov %4,(_AAR,%3) \n" - " mov (_ADR,%3),%1 \n" - " sub %5,%1 \n" - " mov %1,(_ADR,%3) \n" - " mov (_ADR,%3),%0 \n" /* flush */ - " mov (_ASR,%3),%0 \n" - " or %0,%0 \n" - " bne 1b \n" - : "=&r"(status), "=&r"(retval), "=m"(v->counter) - : "a"(ATOMIC_OPS_BASE_ADDR), "r"(&v->counter), "r"(i) - : "memory", "cc"); +ATOMIC_OPS(add) +ATOMIC_OPS(sub) -#else - unsigned long flags; - flags = arch_local_cli_save(); - retval = v->counter; - retval -= i; - v->counter = retval; - arch_local_irq_restore(flags); -#endif - return retval; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP static inline int atomic_add_negative(int i, atomic_t *v) { return atomic_add_return(i, v) < 0; } -static inline void atomic_add(int i, atomic_t *v) -{ - atomic_add_return(i, v); -} - -static inline void atomic_sub(int i, atomic_t *v) -{ - atomic_sub_return(i, v); -} - static inline void atomic_inc(atomic_t *v) { atomic_add_return(1, v); -- GitLab From 15e3f6d782fc6ff7e004b40642ad895b91ae78bf Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 26 Mar 2014 18:04:44 +0100 Subject: [PATCH 0413/9167] locking,arch,parisc: Fold atomic_ops OK, no LoC saved in this case because sub was defined in terms of add. Still do it because this also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Cc: Helge Deller Cc: James E.J. Bottomley Cc: Linus Torvalds Cc: Paul E. McKenney Cc: linux-parisc@vger.kernel.org Link: http://lkml.kernel.org/r/20140508135852.659342353@infradead.org Signed-off-by: Ingo Molnar --- arch/parisc/include/asm/atomic.h | 113 +++++++++++++++++++------------ 1 file changed, 69 insertions(+), 44 deletions(-) diff --git a/arch/parisc/include/asm/atomic.h b/arch/parisc/include/asm/atomic.h index 0be2db2c7d44..219750bb4ae7 100644 --- a/arch/parisc/include/asm/atomic.h +++ b/arch/parisc/include/asm/atomic.h @@ -55,24 +55,7 @@ extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; * are atomic, so a reader never sees inconsistent values. */ -/* It's possible to reduce all atomic operations to either - * __atomic_add_return, atomic_set and atomic_read (the latter - * is there only for consistency). - */ - -static __inline__ int __atomic_add_return(int i, atomic_t *v) -{ - int ret; - unsigned long flags; - _atomic_spin_lock_irqsave(v, flags); - - ret = (v->counter += i); - - _atomic_spin_unlock_irqrestore(v, flags); - return ret; -} - -static __inline__ void atomic_set(atomic_t *v, int i) +static __inline__ void atomic_set(atomic_t *v, int i) { unsigned long flags; _atomic_spin_lock_irqsave(v, flags); @@ -115,16 +98,43 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) return c; } +#define ATOMIC_OP(op, c_op) \ +static __inline__ void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + \ + _atomic_spin_lock_irqsave(v, flags); \ + v->counter c_op i; \ + _atomic_spin_unlock_irqrestore(v, flags); \ +} \ + +#define ATOMIC_OP_RETURN(op, c_op) \ +static __inline__ int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + int ret; \ + \ + _atomic_spin_lock_irqsave(v, flags); \ + ret = (v->counter c_op i); \ + _atomic_spin_unlock_irqrestore(v, flags); \ + \ + return ret; \ +} + +#define ATOMIC_OPS(op, c_op) ATOMIC_OP(op, c_op) ATOMIC_OP_RETURN(op, c_op) + +ATOMIC_OPS(add, +=) +ATOMIC_OPS(sub, -=) + +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP -#define atomic_add(i,v) ((void)(__atomic_add_return( (i),(v)))) -#define atomic_sub(i,v) ((void)(__atomic_add_return(-((int) (i)),(v)))) -#define atomic_inc(v) ((void)(__atomic_add_return( 1,(v)))) -#define atomic_dec(v) ((void)(__atomic_add_return( -1,(v)))) +#define atomic_inc(v) (atomic_add( 1,(v))) +#define atomic_dec(v) (atomic_add( -1,(v))) -#define atomic_add_return(i,v) (__atomic_add_return( (i),(v))) -#define atomic_sub_return(i,v) (__atomic_add_return(-(i),(v))) -#define atomic_inc_return(v) (__atomic_add_return( 1,(v))) -#define atomic_dec_return(v) (__atomic_add_return( -1,(v))) +#define atomic_inc_return(v) (atomic_add_return( 1,(v))) +#define atomic_dec_return(v) (atomic_add_return( -1,(v))) #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) @@ -148,18 +158,37 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) #define ATOMIC64_INIT(i) { (i) } -static __inline__ s64 -__atomic64_add_return(s64 i, atomic64_t *v) -{ - s64 ret; - unsigned long flags; - _atomic_spin_lock_irqsave(v, flags); +#define ATOMIC64_OP(op, c_op) \ +static __inline__ void atomic64_##op(s64 i, atomic64_t *v) \ +{ \ + unsigned long flags; \ + \ + _atomic_spin_lock_irqsave(v, flags); \ + v->counter c_op i; \ + _atomic_spin_unlock_irqrestore(v, flags); \ +} \ + +#define ATOMIC64_OP_RETURN(op, c_op) \ +static __inline__ s64 atomic64_##op##_return(s64 i, atomic64_t *v) \ +{ \ + unsigned long flags; \ + s64 ret; \ + \ + _atomic_spin_lock_irqsave(v, flags); \ + ret = (v->counter c_op i); \ + _atomic_spin_unlock_irqrestore(v, flags); \ + \ + return ret; \ +} - ret = (v->counter += i); +#define ATOMIC64_OPS(op, c_op) ATOMIC64_OP(op, c_op) ATOMIC64_OP_RETURN(op, c_op) - _atomic_spin_unlock_irqrestore(v, flags); - return ret; -} +ATOMIC64_OPS(add, +=) +ATOMIC64_OPS(sub, -=) + +#undef ATOMIC64_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP static __inline__ void atomic64_set(atomic64_t *v, s64 i) @@ -178,15 +207,11 @@ atomic64_read(const atomic64_t *v) return (*(volatile long *)&(v)->counter); } -#define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)(i)),(v)))) -#define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)(i)),(v)))) -#define atomic64_inc(v) ((void)(__atomic64_add_return( 1,(v)))) -#define atomic64_dec(v) ((void)(__atomic64_add_return( -1,(v)))) +#define atomic64_inc(v) (atomic64_add( 1,(v))) +#define atomic64_dec(v) (atomic64_add( -1,(v))) -#define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)(i)),(v))) -#define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)(i)),(v))) -#define atomic64_inc_return(v) (__atomic64_add_return( 1,(v))) -#define atomic64_dec_return(v) (__atomic64_add_return( -1,(v))) +#define atomic64_inc_return(v) (atomic64_add_return( 1,(v))) +#define atomic64_dec_return(v) (atomic64_add_return( -1,(v))) #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) -- GitLab From af095dd60bdc52b11c186c3151e8e38d6faa094c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 26 Mar 2014 18:11:31 +0100 Subject: [PATCH 0414/9167] locking,arch,powerpc: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. Requires asm_op because PPC asm is weird :-) Signed-off-by: Peter Zijlstra Cc: Benjamin Herrenschmidt Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Paul Mackerras Cc: Mahesh Salgaonkar Cc: Paul Gortmaker Cc: linuxppc-dev@lists.ozlabs.org Link: http://lkml.kernel.org/r/20140508135852.713980957@infradead.org Signed-off-by: Ingo Molnar --- arch/powerpc/include/asm/atomic.h | 198 ++++++++++++------------------ 1 file changed, 77 insertions(+), 121 deletions(-) diff --git a/arch/powerpc/include/asm/atomic.h b/arch/powerpc/include/asm/atomic.h index 28992d012926..512d2782b043 100644 --- a/arch/powerpc/include/asm/atomic.h +++ b/arch/powerpc/include/asm/atomic.h @@ -26,76 +26,53 @@ static __inline__ void atomic_set(atomic_t *v, int i) __asm__ __volatile__("stw%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i)); } -static __inline__ void atomic_add(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_add\n\ - add %0,%2,%0\n" - PPC405_ERR77(0,%3) -" stwcx. %0,0,%3 \n\ - bne- 1b" - : "=&r" (t), "+m" (v->counter) - : "r" (a), "r" (&v->counter) - : "cc"); +#define ATOMIC_OP(op, asm_op) \ +static __inline__ void atomic_##op(int a, atomic_t *v) \ +{ \ + int t; \ + \ + __asm__ __volatile__( \ +"1: lwarx %0,0,%3 # atomic_" #op "\n" \ + #asm_op " %0,%2,%0\n" \ + PPC405_ERR77(0,%3) \ +" stwcx. %0,0,%3 \n" \ +" bne- 1b\n" \ + : "=&r" (t), "+m" (v->counter) \ + : "r" (a), "r" (&v->counter) \ + : "cc"); \ +} \ + +#define ATOMIC_OP_RETURN(op, asm_op) \ +static __inline__ int atomic_##op##_return(int a, atomic_t *v) \ +{ \ + int t; \ + \ + __asm__ __volatile__( \ + PPC_ATOMIC_ENTRY_BARRIER \ +"1: lwarx %0,0,%2 # atomic_" #op "_return\n" \ + #asm_op " %0,%1,%0\n" \ + PPC405_ERR77(0,%2) \ +" stwcx. %0,0,%2 \n" \ +" bne- 1b\n" \ + PPC_ATOMIC_EXIT_BARRIER \ + : "=&r" (t) \ + : "r" (a), "r" (&v->counter) \ + : "cc", "memory"); \ + \ + return t; \ } -static __inline__ int atomic_add_return(int a, atomic_t *v) -{ - int t; +#define ATOMIC_OPS(op, asm_op) ATOMIC_OP(op, asm_op) ATOMIC_OP_RETURN(op, asm_op) - __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER -"1: lwarx %0,0,%2 # atomic_add_return\n\ - add %0,%1,%0\n" - PPC405_ERR77(0,%2) -" stwcx. %0,0,%2 \n\ - bne- 1b" - PPC_ATOMIC_EXIT_BARRIER - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); +ATOMIC_OPS(add, add) +ATOMIC_OPS(sub, subf) - return t; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) -static __inline__ void atomic_sub(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( -"1: lwarx %0,0,%3 # atomic_sub\n\ - subf %0,%2,%0\n" - PPC405_ERR77(0,%3) -" stwcx. %0,0,%3 \n\ - bne- 1b" - : "=&r" (t), "+m" (v->counter) - : "r" (a), "r" (&v->counter) - : "cc"); -} - -static __inline__ int atomic_sub_return(int a, atomic_t *v) -{ - int t; - - __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER -"1: lwarx %0,0,%2 # atomic_sub_return\n\ - subf %0,%1,%0\n" - PPC405_ERR77(0,%2) -" stwcx. %0,0,%2 \n\ - bne- 1b" - PPC_ATOMIC_EXIT_BARRIER - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; -} - static __inline__ void atomic_inc(atomic_t *v) { int t; @@ -289,71 +266,50 @@ static __inline__ void atomic64_set(atomic64_t *v, long i) __asm__ __volatile__("std%U0%X0 %1,%0" : "=m"(v->counter) : "r"(i)); } -static __inline__ void atomic64_add(long a, atomic64_t *v) -{ - long t; - - __asm__ __volatile__( -"1: ldarx %0,0,%3 # atomic64_add\n\ - add %0,%2,%0\n\ - stdcx. %0,0,%3 \n\ - bne- 1b" - : "=&r" (t), "+m" (v->counter) - : "r" (a), "r" (&v->counter) - : "cc"); +#define ATOMIC64_OP(op, asm_op) \ +static __inline__ void atomic64_##op(long a, atomic64_t *v) \ +{ \ + long t; \ + \ + __asm__ __volatile__( \ +"1: ldarx %0,0,%3 # atomic64_" #op "\n" \ + #asm_op " %0,%2,%0\n" \ +" stdcx. %0,0,%3 \n" \ +" bne- 1b\n" \ + : "=&r" (t), "+m" (v->counter) \ + : "r" (a), "r" (&v->counter) \ + : "cc"); \ } -static __inline__ long atomic64_add_return(long a, atomic64_t *v) -{ - long t; - - __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER -"1: ldarx %0,0,%2 # atomic64_add_return\n\ - add %0,%1,%0\n\ - stdcx. %0,0,%2 \n\ - bne- 1b" - PPC_ATOMIC_EXIT_BARRIER - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); - - return t; +#define ATOMIC64_OP_RETURN(op, asm_op) \ +static __inline__ long atomic64_##op##_return(long a, atomic64_t *v) \ +{ \ + long t; \ + \ + __asm__ __volatile__( \ + PPC_ATOMIC_ENTRY_BARRIER \ +"1: ldarx %0,0,%2 # atomic64_" #op "_return\n" \ + #asm_op " %0,%1,%0\n" \ +" stdcx. %0,0,%2 \n" \ +" bne- 1b\n" \ + PPC_ATOMIC_EXIT_BARRIER \ + : "=&r" (t) \ + : "r" (a), "r" (&v->counter) \ + : "cc", "memory"); \ + \ + return t; \ } -#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) - -static __inline__ void atomic64_sub(long a, atomic64_t *v) -{ - long t; - - __asm__ __volatile__( -"1: ldarx %0,0,%3 # atomic64_sub\n\ - subf %0,%2,%0\n\ - stdcx. %0,0,%3 \n\ - bne- 1b" - : "=&r" (t), "+m" (v->counter) - : "r" (a), "r" (&v->counter) - : "cc"); -} +#define ATOMIC64_OPS(op, asm_op) ATOMIC64_OP(op, asm_op) ATOMIC64_OP_RETURN(op, asm_op) -static __inline__ long atomic64_sub_return(long a, atomic64_t *v) -{ - long t; +ATOMIC64_OPS(add, add) +ATOMIC64_OPS(sub, subf) - __asm__ __volatile__( - PPC_ATOMIC_ENTRY_BARRIER -"1: ldarx %0,0,%2 # atomic64_sub_return\n\ - subf %0,%1,%0\n\ - stdcx. %0,0,%2 \n\ - bne- 1b" - PPC_ATOMIC_EXIT_BARRIER - : "=&r" (t) - : "r" (a), "r" (&v->counter) - : "cc", "memory"); +#undef ATOMIC64_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP - return t; -} +#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) static __inline__ void atomic64_inc(atomic64_t *v) { -- GitLab From c6470150dff9aff682063890c9b8eac71b695def Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 26 Mar 2014 18:12:45 +0100 Subject: [PATCH 0415/9167] locking,arch,sh: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Cc: linux-sh@vger.kernel.org Link: http://lkml.kernel.org/r/20140508135852.770036493@infradead.org Signed-off-by: Ingo Molnar --- arch/sh/include/asm/atomic-grb.h | 119 +++++++++++------------------- arch/sh/include/asm/atomic-irq.h | 62 +++++++--------- arch/sh/include/asm/atomic-llsc.h | 101 ++++++++++--------------- 3 files changed, 112 insertions(+), 170 deletions(-) diff --git a/arch/sh/include/asm/atomic-grb.h b/arch/sh/include/asm/atomic-grb.h index a273c88578fc..97a5fda83450 100644 --- a/arch/sh/include/asm/atomic-grb.h +++ b/arch/sh/include/asm/atomic-grb.h @@ -1,85 +1,56 @@ #ifndef __ASM_SH_ATOMIC_GRB_H #define __ASM_SH_ATOMIC_GRB_H -static inline void atomic_add(int i, atomic_t *v) -{ - int tmp; - - __asm__ __volatile__ ( - " .align 2 \n\t" - " mova 1f, r0 \n\t" /* r0 = end point */ - " mov r15, r1 \n\t" /* r1 = saved sp */ - " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ - " mov.l @%1, %0 \n\t" /* load old value */ - " add %2, %0 \n\t" /* add */ - " mov.l %0, @%1 \n\t" /* store new value */ - "1: mov r1, r15 \n\t" /* LOGOUT */ - : "=&r" (tmp), - "+r" (v) - : "r" (i) - : "memory" , "r0", "r1"); -} - -static inline void atomic_sub(int i, atomic_t *v) -{ - int tmp; - - __asm__ __volatile__ ( - " .align 2 \n\t" - " mova 1f, r0 \n\t" /* r0 = end point */ - " mov r15, r1 \n\t" /* r1 = saved sp */ - " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ - " mov.l @%1, %0 \n\t" /* load old value */ - " sub %2, %0 \n\t" /* sub */ - " mov.l %0, @%1 \n\t" /* store new value */ - "1: mov r1, r15 \n\t" /* LOGOUT */ - : "=&r" (tmp), - "+r" (v) - : "r" (i) - : "memory" , "r0", "r1"); -} - -static inline int atomic_add_return(int i, atomic_t *v) -{ - int tmp; +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + int tmp; \ + \ + __asm__ __volatile__ ( \ + " .align 2 \n\t" \ + " mova 1f, r0 \n\t" /* r0 = end point */ \ + " mov r15, r1 \n\t" /* r1 = saved sp */ \ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \ + " mov.l @%1, %0 \n\t" /* load old value */ \ + " " #op " %2, %0 \n\t" /* $op */ \ + " mov.l %0, @%1 \n\t" /* store new value */ \ + "1: mov r1, r15 \n\t" /* LOGOUT */ \ + : "=&r" (tmp), \ + "+r" (v) \ + : "r" (i) \ + : "memory" , "r0", "r1"); \ +} \ - __asm__ __volatile__ ( - " .align 2 \n\t" - " mova 1f, r0 \n\t" /* r0 = end point */ - " mov r15, r1 \n\t" /* r1 = saved sp */ - " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ - " mov.l @%1, %0 \n\t" /* load old value */ - " add %2, %0 \n\t" /* add */ - " mov.l %0, @%1 \n\t" /* store new value */ - "1: mov r1, r15 \n\t" /* LOGOUT */ - : "=&r" (tmp), - "+r" (v) - : "r" (i) - : "memory" , "r0", "r1"); - - return tmp; +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int tmp; \ + \ + __asm__ __volatile__ ( \ + " .align 2 \n\t" \ + " mova 1f, r0 \n\t" /* r0 = end point */ \ + " mov r15, r1 \n\t" /* r1 = saved sp */ \ + " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ \ + " mov.l @%1, %0 \n\t" /* load old value */ \ + " " #op " %2, %0 \n\t" /* $op */ \ + " mov.l %0, @%1 \n\t" /* store new value */ \ + "1: mov r1, r15 \n\t" /* LOGOUT */ \ + : "=&r" (tmp), \ + "+r" (v) \ + : "r" (i) \ + : "memory" , "r0", "r1"); \ + \ + return tmp; \ } -static inline int atomic_sub_return(int i, atomic_t *v) -{ - int tmp; +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) - __asm__ __volatile__ ( - " .align 2 \n\t" - " mova 1f, r0 \n\t" /* r0 = end point */ - " mov r15, r1 \n\t" /* r1 = saved sp */ - " mov #-6, r15 \n\t" /* LOGIN: r15 = size */ - " mov.l @%1, %0 \n\t" /* load old value */ - " sub %2, %0 \n\t" /* sub */ - " mov.l %0, @%1 \n\t" /* store new value */ - "1: mov r1, r15 \n\t" /* LOGOUT */ - : "=&r" (tmp), - "+r" (v) - : "r" (i) - : "memory", "r0", "r1"); +ATOMIC_OPS(add) +ATOMIC_OPS(sub) - return tmp; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { diff --git a/arch/sh/include/asm/atomic-irq.h b/arch/sh/include/asm/atomic-irq.h index 9f7c56609e53..61d107523f06 100644 --- a/arch/sh/include/asm/atomic-irq.h +++ b/arch/sh/include/asm/atomic-irq.h @@ -8,49 +8,39 @@ * forward to code at the end of this object's .text section, then * branch back to restart the operation. */ -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned long flags; - - raw_local_irq_save(flags); - v->counter += i; - raw_local_irq_restore(flags); -} -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned long flags; - - raw_local_irq_save(flags); - v->counter -= i; - raw_local_irq_restore(flags); +#define ATOMIC_OP(op, c_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + \ + raw_local_irq_save(flags); \ + v->counter c_op i; \ + raw_local_irq_restore(flags); \ } -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned long temp, flags; - - raw_local_irq_save(flags); - temp = v->counter; - temp += i; - v->counter = temp; - raw_local_irq_restore(flags); - - return temp; +#define ATOMIC_OP_RETURN(op, c_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long temp, flags; \ + \ + raw_local_irq_save(flags); \ + temp = v->counter; \ + temp c_op i; \ + v->counter = temp; \ + raw_local_irq_restore(flags); \ + \ + return temp; \ } -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long temp, flags; +#define ATOMIC_OPS(op, c_op) ATOMIC_OP(op, c_op) ATOMIC_OP_RETURN(op, c_op) - raw_local_irq_save(flags); - temp = v->counter; - temp -= i; - v->counter = temp; - raw_local_irq_restore(flags); +ATOMIC_OPS(add, +=) +ATOMIC_OPS(sub, -=) - return temp; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { diff --git a/arch/sh/include/asm/atomic-llsc.h b/arch/sh/include/asm/atomic-llsc.h index 4b00b78e3f4f..8575dccb9ef7 100644 --- a/arch/sh/include/asm/atomic-llsc.h +++ b/arch/sh/include/asm/atomic-llsc.h @@ -1,39 +1,6 @@ #ifndef __ASM_SH_ATOMIC_LLSC_H #define __ASM_SH_ATOMIC_LLSC_H -/* - * To get proper branch prediction for the main line, we must branch - * forward to code at the end of this object's .text section, then - * branch back to restart the operation. - */ -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned long tmp; - - __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_add \n" -" add %1, %0 \n" -" movco.l %0, @%2 \n" -" bf 1b \n" - : "=&z" (tmp) - : "r" (i), "r" (&v->counter) - : "t"); -} - -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned long tmp; - - __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_sub \n" -" sub %1, %0 \n" -" movco.l %0, @%2 \n" -" bf 1b \n" - : "=&z" (tmp) - : "r" (i), "r" (&v->counter) - : "t"); -} - /* * SH-4A note: * @@ -42,39 +9,53 @@ static inline void atomic_sub(int i, atomic_t *v) * encoding, so the retval is automatically set without having to * do any special work. */ -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned long temp; +/* + * To get proper branch prediction for the main line, we must branch + * forward to code at the end of this object's .text section, then + * branch back to restart the operation. + */ - __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_add_return \n" -" add %1, %0 \n" -" movco.l %0, @%2 \n" -" bf 1b \n" -" synco \n" - : "=&z" (temp) - : "r" (i), "r" (&v->counter) - : "t"); +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long tmp; \ + \ + __asm__ __volatile__ ( \ +"1: movli.l @%2, %0 ! atomic_" #op "\n" \ +" " #op " %1, %0 \n" \ +" movco.l %0, @%2 \n" \ +" bf 1b \n" \ + : "=&z" (tmp) \ + : "r" (i), "r" (&v->counter) \ + : "t"); \ +} - return temp; +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long temp; \ + \ + __asm__ __volatile__ ( \ +"1: movli.l @%2, %0 ! atomic_" #op "_return \n" \ +" " #op " %1, %0 \n" \ +" movco.l %0, @%2 \n" \ +" bf 1b \n" \ +" synco \n" \ + : "=&z" (temp) \ + : "r" (i), "r" (&v->counter) \ + : "t"); \ + \ + return temp; \ } -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long temp; +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) - __asm__ __volatile__ ( -"1: movli.l @%2, %0 ! atomic_sub_return \n" -" sub %1, %0 \n" -" movco.l %0, @%2 \n" -" bf 1b \n" -" synco \n" - : "=&z" (temp) - : "r" (i), "r" (&v->counter) - : "t"); +ATOMIC_OPS(add) +ATOMIC_OPS(sub) - return temp; -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { -- GitLab From 4f3316c2b5fe2062c26c9b66915b5a5c80c60a5c Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 26 Mar 2014 18:29:28 +0100 Subject: [PATCH 0416/9167] locking,arch,sparc: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Acked-by: David S. Miller Cc: Bjorn Helgaas Cc: Kirill Tkhai Cc: Linus Torvalds Cc: Paul E. McKenney Cc: Sam Ravnborg Cc: sparclinux@vger.kernel.org Link: http://lkml.kernel.org/r/20140508135852.825281379@infradead.org Signed-off-by: Ingo Molnar --- arch/sparc/include/asm/atomic_32.h | 17 ++- arch/sparc/include/asm/atomic_64.h | 45 ++++---- arch/sparc/kernel/smp_64.c | 2 +- arch/sparc/lib/atomic32.c | 29 ++--- arch/sparc/lib/atomic_64.S | 163 ++++++++++++----------------- arch/sparc/lib/ksyms.c | 25 +++-- 6 files changed, 133 insertions(+), 148 deletions(-) diff --git a/arch/sparc/include/asm/atomic_32.h b/arch/sparc/include/asm/atomic_32.h index 7aed2be45b44..7b024f02a7ce 100644 --- a/arch/sparc/include/asm/atomic_32.h +++ b/arch/sparc/include/asm/atomic_32.h @@ -20,7 +20,7 @@ #define ATOMIC_INIT(i) { (i) } -int __atomic_add_return(int, atomic_t *); +int atomic_add_return(int, atomic_t *); int atomic_cmpxchg(atomic_t *, int, int); #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) int __atomic_add_unless(atomic_t *, int, int); @@ -28,15 +28,14 @@ void atomic_set(atomic_t *, int); #define atomic_read(v) (*(volatile int *)&(v)->counter) -#define atomic_add(i, v) ((void)__atomic_add_return( (int)(i), (v))) -#define atomic_sub(i, v) ((void)__atomic_add_return(-(int)(i), (v))) -#define atomic_inc(v) ((void)__atomic_add_return( 1, (v))) -#define atomic_dec(v) ((void)__atomic_add_return( -1, (v))) +#define atomic_add(i, v) ((void)atomic_add_return( (int)(i), (v))) +#define atomic_sub(i, v) ((void)atomic_add_return(-(int)(i), (v))) +#define atomic_inc(v) ((void)atomic_add_return( 1, (v))) +#define atomic_dec(v) ((void)atomic_add_return( -1, (v))) -#define atomic_add_return(i, v) (__atomic_add_return( (int)(i), (v))) -#define atomic_sub_return(i, v) (__atomic_add_return(-(int)(i), (v))) -#define atomic_inc_return(v) (__atomic_add_return( 1, (v))) -#define atomic_dec_return(v) (__atomic_add_return( -1, (v))) +#define atomic_sub_return(i, v) (atomic_add_return(-(int)(i), (v))) +#define atomic_inc_return(v) (atomic_add_return( 1, (v))) +#define atomic_dec_return(v) (atomic_add_return( -1, (v))) #define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0) diff --git a/arch/sparc/include/asm/atomic_64.h b/arch/sparc/include/asm/atomic_64.h index bb894c8bec56..7e4ca1e73cd9 100644 --- a/arch/sparc/include/asm/atomic_64.h +++ b/arch/sparc/include/asm/atomic_64.h @@ -20,27 +20,28 @@ #define atomic_set(v, i) (((v)->counter) = i) #define atomic64_set(v, i) (((v)->counter) = i) -void atomic_add(int, atomic_t *); -void atomic64_add(long, atomic64_t *); -void atomic_sub(int, atomic_t *); -void atomic64_sub(long, atomic64_t *); +#define ATOMIC_OP(op) \ +void atomic_##op(int, atomic_t *); \ +void atomic64_##op(long, atomic64_t *); -int atomic_add_ret(int, atomic_t *); -long atomic64_add_ret(long, atomic64_t *); -int atomic_sub_ret(int, atomic_t *); -long atomic64_sub_ret(long, atomic64_t *); +#define ATOMIC_OP_RETURN(op) \ +int atomic_##op##_return(int, atomic_t *); \ +long atomic64_##op##_return(long, atomic64_t *); -#define atomic_dec_return(v) atomic_sub_ret(1, v) -#define atomic64_dec_return(v) atomic64_sub_ret(1, v) +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) -#define atomic_inc_return(v) atomic_add_ret(1, v) -#define atomic64_inc_return(v) atomic64_add_ret(1, v) +ATOMIC_OPS(add) +ATOMIC_OPS(sub) -#define atomic_sub_return(i, v) atomic_sub_ret(i, v) -#define atomic64_sub_return(i, v) atomic64_sub_ret(i, v) +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP -#define atomic_add_return(i, v) atomic_add_ret(i, v) -#define atomic64_add_return(i, v) atomic64_add_ret(i, v) +#define atomic_dec_return(v) atomic_sub_return(1, v) +#define atomic64_dec_return(v) atomic64_sub_return(1, v) + +#define atomic_inc_return(v) atomic_add_return(1, v) +#define atomic64_inc_return(v) atomic64_add_return(1, v) /* * atomic_inc_and_test - increment and test @@ -53,11 +54,11 @@ long atomic64_sub_ret(long, atomic64_t *); #define atomic_inc_and_test(v) (atomic_inc_return(v) == 0) #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) -#define atomic_sub_and_test(i, v) (atomic_sub_ret(i, v) == 0) -#define atomic64_sub_and_test(i, v) (atomic64_sub_ret(i, v) == 0) +#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0) +#define atomic64_sub_and_test(i, v) (atomic64_sub_return(i, v) == 0) -#define atomic_dec_and_test(v) (atomic_sub_ret(1, v) == 0) -#define atomic64_dec_and_test(v) (atomic64_sub_ret(1, v) == 0) +#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0) +#define atomic64_dec_and_test(v) (atomic64_sub_return(1, v) == 0) #define atomic_inc(v) atomic_add(1, v) #define atomic64_inc(v) atomic64_add(1, v) @@ -65,8 +66,8 @@ long atomic64_sub_ret(long, atomic64_t *); #define atomic_dec(v) atomic_sub(1, v) #define atomic64_dec(v) atomic64_sub(1, v) -#define atomic_add_negative(i, v) (atomic_add_ret(i, v) < 0) -#define atomic64_add_negative(i, v) (atomic64_add_ret(i, v) < 0) +#define atomic_add_negative(i, v) (atomic_add_return(i, v) < 0) +#define atomic64_add_negative(i, v) (atomic64_add_return(i, v) < 0) #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n))) #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 41aa2478f3ca..32dab009915f 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -1138,7 +1138,7 @@ static unsigned long penguins_are_doing_time; void smp_capture(void) { - int result = atomic_add_ret(1, &smp_capture_depth); + int result = atomic_add_return(1, &smp_capture_depth); if (result == 1) { int ncpus = num_online_cpus(); diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c index 1d32b54089aa..a7c418ac26af 100644 --- a/arch/sparc/lib/atomic32.c +++ b/arch/sparc/lib/atomic32.c @@ -27,18 +27,23 @@ static DEFINE_SPINLOCK(dummy); #endif /* SMP */ -int __atomic_add_return(int i, atomic_t *v) -{ - int ret; - unsigned long flags; - spin_lock_irqsave(ATOMIC_HASH(v), flags); - - ret = (v->counter += i); - - spin_unlock_irqrestore(ATOMIC_HASH(v), flags); - return ret; -} -EXPORT_SYMBOL(__atomic_add_return); +#define ATOMIC_OP(op, cop) \ +int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int ret; \ + unsigned long flags; \ + spin_lock_irqsave(ATOMIC_HASH(v), flags); \ + \ + ret = (v->counter cop i); \ + \ + spin_unlock_irqrestore(ATOMIC_HASH(v), flags); \ + return ret; \ +} \ +EXPORT_SYMBOL(atomic_##op##_return); + +ATOMIC_OP(add, +=) + +#undef ATOMIC_OP int atomic_cmpxchg(atomic_t *v, int old, int new) { diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S index 85c233d0a340..96d70b4dbe77 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S @@ -14,109 +14,80 @@ * memory barriers, and a second which returns * a value and does the barriers. */ -ENTRY(atomic_add) /* %o0 = increment, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: lduw [%o1], %g1 - add %g1, %o0, %g7 - cas [%o1], %g1, %g7 - cmp %g1, %g7 - bne,pn %icc, BACKOFF_LABEL(2f, 1b) - nop - retl - nop -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic_add) -ENTRY(atomic_sub) /* %o0 = decrement, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: lduw [%o1], %g1 - sub %g1, %o0, %g7 - cas [%o1], %g1, %g7 - cmp %g1, %g7 - bne,pn %icc, BACKOFF_LABEL(2f, 1b) - nop - retl - nop -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic_sub) +#define ATOMIC_OP(op) \ +ENTRY(atomic_##op) /* %o0 = increment, %o1 = atomic_ptr */ \ + BACKOFF_SETUP(%o2); \ +1: lduw [%o1], %g1; \ + op %g1, %o0, %g7; \ + cas [%o1], %g1, %g7; \ + cmp %g1, %g7; \ + bne,pn %icc, BACKOFF_LABEL(2f, 1b); \ + nop; \ + retl; \ + nop; \ +2: BACKOFF_SPIN(%o2, %o3, 1b); \ +ENDPROC(atomic_##op); \ -ENTRY(atomic_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: lduw [%o1], %g1 - add %g1, %o0, %g7 - cas [%o1], %g1, %g7 - cmp %g1, %g7 - bne,pn %icc, BACKOFF_LABEL(2f, 1b) - add %g1, %o0, %g1 - retl - sra %g1, 0, %o0 -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic_add_ret) +#define ATOMIC_OP_RETURN(op) \ +ENTRY(atomic_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \ + BACKOFF_SETUP(%o2); \ +1: lduw [%o1], %g1; \ + op %g1, %o0, %g7; \ + cas [%o1], %g1, %g7; \ + cmp %g1, %g7; \ + bne,pn %icc, BACKOFF_LABEL(2f, 1b); \ + add %g1, %o0, %g1; \ + retl; \ + sra %g1, 0, %o0; \ +2: BACKOFF_SPIN(%o2, %o3, 1b); \ +ENDPROC(atomic_##op##_return); -ENTRY(atomic_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: lduw [%o1], %g1 - sub %g1, %o0, %g7 - cas [%o1], %g1, %g7 - cmp %g1, %g7 - bne,pn %icc, BACKOFF_LABEL(2f, 1b) - sub %g1, %o0, %g1 - retl - sra %g1, 0, %o0 -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic_sub_ret) +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) -ENTRY(atomic64_add) /* %o0 = increment, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: ldx [%o1], %g1 - add %g1, %o0, %g7 - casx [%o1], %g1, %g7 - cmp %g1, %g7 - bne,pn %xcc, BACKOFF_LABEL(2f, 1b) - nop - retl - nop -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_add) +ATOMIC_OPS(add) +ATOMIC_OPS(sub) -ENTRY(atomic64_sub) /* %o0 = decrement, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: ldx [%o1], %g1 - sub %g1, %o0, %g7 - casx [%o1], %g1, %g7 - cmp %g1, %g7 - bne,pn %xcc, BACKOFF_LABEL(2f, 1b) - nop - retl - nop -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_sub) +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP -ENTRY(atomic64_add_ret) /* %o0 = increment, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: ldx [%o1], %g1 - add %g1, %o0, %g7 - casx [%o1], %g1, %g7 - cmp %g1, %g7 - bne,pn %xcc, BACKOFF_LABEL(2f, 1b) - nop - retl - add %g1, %o0, %o0 -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_add_ret) +#define ATOMIC64_OP(op) \ +ENTRY(atomic64_##op) /* %o0 = increment, %o1 = atomic_ptr */ \ + BACKOFF_SETUP(%o2); \ +1: ldx [%o1], %g1; \ + op %g1, %o0, %g7; \ + casx [%o1], %g1, %g7; \ + cmp %g1, %g7; \ + bne,pn %xcc, BACKOFF_LABEL(2f, 1b); \ + nop; \ + retl; \ + nop; \ +2: BACKOFF_SPIN(%o2, %o3, 1b); \ +ENDPROC(atomic64_##op); \ -ENTRY(atomic64_sub_ret) /* %o0 = decrement, %o1 = atomic_ptr */ - BACKOFF_SETUP(%o2) -1: ldx [%o1], %g1 - sub %g1, %o0, %g7 - casx [%o1], %g1, %g7 - cmp %g1, %g7 - bne,pn %xcc, BACKOFF_LABEL(2f, 1b) - nop - retl - sub %g1, %o0, %o0 -2: BACKOFF_SPIN(%o2, %o3, 1b) -ENDPROC(atomic64_sub_ret) +#define ATOMIC64_OP_RETURN(op) \ +ENTRY(atomic64_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \ + BACKOFF_SETUP(%o2); \ +1: ldx [%o1], %g1; \ + op %g1, %o0, %g7; \ + casx [%o1], %g1, %g7; \ + cmp %g1, %g7; \ + bne,pn %xcc, BACKOFF_LABEL(2f, 1b); \ + nop; \ + retl; \ + add %g1, %o0, %o0; \ +2: BACKOFF_SPIN(%o2, %o3, 1b); \ +ENDPROC(atomic64_##op##_return); + +#define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_OP_RETURN(op) + +ATOMIC64_OPS(add) +ATOMIC64_OPS(sub) + +#undef ATOMIC64_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP ENTRY(atomic64_dec_if_positive) /* %o0 = atomic_ptr */ BACKOFF_SETUP(%o2) diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c index 323335b9cd2b..1d649a95660c 100644 --- a/arch/sparc/lib/ksyms.c +++ b/arch/sparc/lib/ksyms.c @@ -99,14 +99,23 @@ EXPORT_SYMBOL(___copy_in_user); EXPORT_SYMBOL(__clear_user); /* Atomic counter implementation. */ -EXPORT_SYMBOL(atomic_add); -EXPORT_SYMBOL(atomic_add_ret); -EXPORT_SYMBOL(atomic_sub); -EXPORT_SYMBOL(atomic_sub_ret); -EXPORT_SYMBOL(atomic64_add); -EXPORT_SYMBOL(atomic64_add_ret); -EXPORT_SYMBOL(atomic64_sub); -EXPORT_SYMBOL(atomic64_sub_ret); +#define ATOMIC_OP(op) \ +EXPORT_SYMBOL(atomic_##op); \ +EXPORT_SYMBOL(atomic64_##op); + +#define ATOMIC_OP_RETURN(op) \ +EXPORT_SYMBOL(atomic_##op##_return); \ +EXPORT_SYMBOL(atomic64_##op##_return); + +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) + +ATOMIC_OPS(add) +ATOMIC_OPS(sub) + +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP + EXPORT_SYMBOL(atomic64_dec_if_positive); /* Atomic bit operations. */ -- GitLab From d4608dd5b4ec13855680b89f719d8d4b2da92411 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 26 Mar 2014 18:31:12 +0100 Subject: [PATCH 0417/9167] locking,arch,xtensa: Fold atomic_ops Many of the atomic op implementations are the same except for one instruction; fold the lot into a few CPP macros and reduce LoC. This also prepares for easy addition of new ops. Signed-off-by: Peter Zijlstra Cc: Chris Zankel Cc: Linus Torvalds Cc: Max Filippov Cc: Geert Uytterhoeven Cc: Paul E. McKenney Cc: linux-xtensa@linux-xtensa.org Link: http://lkml.kernel.org/r/20140508135852.879575796@infradead.org Signed-off-by: Ingo Molnar --- arch/xtensa/include/asm/atomic.h | 233 +++++++++++-------------------- 1 file changed, 82 insertions(+), 151 deletions(-) diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index e5103b47a8ce..626676660b80 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h @@ -58,165 +58,96 @@ */ #define atomic_set(v,i) ((v)->counter = (i)) -/** - * atomic_add - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v. - */ -static inline void atomic_add(int i, atomic_t * v) -{ #if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " add %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (result), "=&a" (tmp) - : "a" (i), "a" (v) - : "memory" - ); -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15, "__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " add %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); -#endif -} - -/** - * atomic_sub - subtract the atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v. - */ -static inline void atomic_sub(int i, atomic_t *v) -{ -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " sub %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (result), "=&a" (tmp) - : "a" (i), "a" (v) - : "memory" - ); -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15, "__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " sub %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); -#endif +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t * v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + __asm__ __volatile__( \ + "1: l32i %1, %3, 0\n" \ + " wsr %1, scompare1\n" \ + " " #op " %0, %1, %2\n" \ + " s32c1i %0, %3, 0\n" \ + " bne %0, %1, 1b\n" \ + : "=&a" (result), "=&a" (tmp) \ + : "a" (i), "a" (v) \ + : "memory" \ + ); \ +} \ + +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t * v) \ +{ \ + unsigned long tmp; \ + int result; \ + \ + __asm__ __volatile__( \ + "1: l32i %1, %3, 0\n" \ + " wsr %1, scompare1\n" \ + " " #op " %0, %1, %2\n" \ + " s32c1i %0, %3, 0\n" \ + " bne %0, %1, 1b\n" \ + " " #op " %0, %0, %2\n" \ + : "=&a" (result), "=&a" (tmp) \ + : "a" (i), "a" (v) \ + : "memory" \ + ); \ + \ + return result; \ } -/* - * We use atomic_{add|sub}_return to define other functions. - */ - -static inline int atomic_add_return(int i, atomic_t * v) -{ -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " add %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - " add %0, %0, %2\n" - : "=&a" (result), "=&a" (tmp) - : "a" (i), "a" (v) - : "memory" - ); - - return result; -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15,"__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " add %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); - - return vval; -#endif +#else /* XCHAL_HAVE_S32C1I */ + +#define ATOMIC_OP(op) \ +static inline void atomic_##op(int i, atomic_t * v) \ +{ \ + unsigned int vval; \ + \ + __asm__ __volatile__( \ + " rsil a15, "__stringify(LOCKLEVEL)"\n"\ + " l32i %0, %2, 0\n" \ + " " #op " %0, %0, %1\n" \ + " s32i %0, %2, 0\n" \ + " wsr a15, ps\n" \ + " rsync\n" \ + : "=&a" (vval) \ + : "a" (i), "a" (v) \ + : "a15", "memory" \ + ); \ +} \ + +#define ATOMIC_OP_RETURN(op) \ +static inline int atomic_##op##_return(int i, atomic_t * v) \ +{ \ + unsigned int vval; \ + \ + __asm__ __volatile__( \ + " rsil a15,"__stringify(LOCKLEVEL)"\n" \ + " l32i %0, %2, 0\n" \ + " " #op " %0, %0, %1\n" \ + " s32i %0, %2, 0\n" \ + " wsr a15, ps\n" \ + " rsync\n" \ + : "=&a" (vval) \ + : "a" (i), "a" (v) \ + : "a15", "memory" \ + ); \ + \ + return vval; \ } -static inline int atomic_sub_return(int i, atomic_t * v) -{ -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; +#endif /* XCHAL_HAVE_S32C1I */ - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " sub %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - " sub %0, %0, %2\n" - : "=&a" (result), "=&a" (tmp) - : "a" (i), "a" (v) - : "memory" - ); +#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) - return result; -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15,"__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " sub %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); +ATOMIC_OPS(add) +ATOMIC_OPS(sub) - return vval; -#endif -} +#undef ATOMIC_OPS +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP /** * atomic_sub_and_test - subtract value from variable and test result -- GitLab From 560cb12a4080a48b84da8b96878cafbd193c4d64 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 23 Apr 2014 16:12:30 +0200 Subject: [PATCH 0418/9167] locking,arch: Rewrite generic atomic support Rewrite generic atomic support to only require cmpxchg(), generate all other primitives from that. Furthermore reduce the endless repetition for all these primitives to a few CPP macros. This way we get more for less lines. Signed-off-by: Peter Zijlstra Link: http://lkml.kernel.org/r/20140508135852.940119622@infradead.org Cc: Arnd Bergmann Cc: David Howells Cc: Paul E. McKenney Cc: David S. Miller Cc: Linus Torvalds Cc: linux-arch@vger.kernel.org Signed-off-by: Ingo Molnar --- include/asm-generic/atomic.h | 192 ++++++++++++++++----------------- include/asm-generic/atomic64.h | 20 +++- lib/atomic64.c | 83 +++++++------- 3 files changed, 148 insertions(+), 147 deletions(-) diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h index 9c79e7603459..56d4d36e1531 100644 --- a/include/asm-generic/atomic.h +++ b/include/asm-generic/atomic.h @@ -18,14 +18,100 @@ #include #include +/* + * atomic_$op() - $op integer to atomic variable + * @i: integer value to $op + * @v: pointer to the atomic variable + * + * Atomically $ops @i to @v. Does not strictly guarantee a memory-barrier, use + * smp_mb__{before,after}_atomic(). + */ + +/* + * atomic_$op_return() - $op interer to atomic variable and returns the result + * @i: integer value to $op + * @v: pointer to the atomic variable + * + * Atomically $ops @i to @v. Does imply a full memory barrier. + */ + #ifdef CONFIG_SMP -/* Force people to define core atomics */ -# if !defined(atomic_add_return) || !defined(atomic_sub_return) || \ - !defined(atomic_clear_mask) || !defined(atomic_set_mask) -# error "SMP requires a little arch-specific magic" -# endif + +/* we can build all atomic primitives from cmpxchg */ + +#define ATOMIC_OP(op, c_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + int c, old; \ + \ + c = v->counter; \ + while ((old = cmpxchg(&v->counter, c, c c_op i)) != c) \ + c = old; \ +} + +#define ATOMIC_OP_RETURN(op, c_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + int c, old; \ + \ + c = v->counter; \ + while ((old = cmpxchg(&v->counter, c, c c_op i)) != c) \ + c = old; \ + \ + return c c_op i; \ +} + +#else + +#include + +#define ATOMIC_OP(op, c_op) \ +static inline void atomic_##op(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + \ + raw_local_irq_save(flags); \ + v->counter = v->counter c_op i; \ + raw_local_irq_restore(flags); \ +} + +#define ATOMIC_OP_RETURN(op, c_op) \ +static inline int atomic_##op##_return(int i, atomic_t *v) \ +{ \ + unsigned long flags; \ + int ret; \ + \ + raw_local_irq_save(flags); \ + ret = (v->counter = v->counter c_op i); \ + raw_local_irq_restore(flags); \ + \ + return ret; \ +} + +#endif /* CONFIG_SMP */ + +#ifndef atomic_add_return +ATOMIC_OP_RETURN(add, +) +#endif + +#ifndef atomic_sub_return +ATOMIC_OP_RETURN(sub, -) +#endif + +#ifndef atomic_clear_mask +ATOMIC_OP(and, &) +#define atomic_clear_mask(i, v) atomic_and(~(i), (v)) #endif +#ifndef atomic_set_mask +#define CONFIG_ARCH_HAS_ATOMIC_OR +ATOMIC_OP(or, |) +#define atomic_set_mask(i, v) atomic_or((i), (v)) +#endif + +#undef ATOMIC_OP_RETURN +#undef ATOMIC_OP + /* * Atomic operations that C can't guarantee us. Useful for * resource counting etc.. @@ -33,8 +119,6 @@ #define ATOMIC_INIT(i) { (i) } -#ifdef __KERNEL__ - /** * atomic_read - read atomic variable * @v: pointer of type atomic_t @@ -56,52 +140,6 @@ #include -/** - * atomic_add_return - add integer to atomic variable - * @i: integer value to add - * @v: pointer of type atomic_t - * - * Atomically adds @i to @v and returns the result - */ -#ifndef atomic_add_return -static inline int atomic_add_return(int i, atomic_t *v) -{ - unsigned long flags; - int temp; - - raw_local_irq_save(flags); /* Don't trace it in an irqsoff handler */ - temp = v->counter; - temp += i; - v->counter = temp; - raw_local_irq_restore(flags); - - return temp; -} -#endif - -/** - * atomic_sub_return - subtract integer from atomic variable - * @i: integer value to subtract - * @v: pointer of type atomic_t - * - * Atomically subtracts @i from @v and returns the result - */ -#ifndef atomic_sub_return -static inline int atomic_sub_return(int i, atomic_t *v) -{ - unsigned long flags; - int temp; - - raw_local_irq_save(flags); /* Don't trace it in an irqsoff handler */ - temp = v->counter; - temp -= i; - v->counter = temp; - raw_local_irq_restore(flags); - - return temp; -} -#endif - static inline int atomic_add_negative(int i, atomic_t *v) { return atomic_add_return(i, v) < 0; @@ -139,49 +177,11 @@ static inline void atomic_dec(atomic_t *v) static inline int __atomic_add_unless(atomic_t *v, int a, int u) { - int c, old; - c = atomic_read(v); - while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c) - c = old; - return c; -} - -/** - * atomic_clear_mask - Atomically clear bits in atomic variable - * @mask: Mask of the bits to be cleared - * @v: pointer of type atomic_t - * - * Atomically clears the bits set in @mask from @v - */ -#ifndef atomic_clear_mask -static inline void atomic_clear_mask(unsigned long mask, atomic_t *v) -{ - unsigned long flags; - - mask = ~mask; - raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */ - v->counter &= mask; - raw_local_irq_restore(flags); + int c, old; + c = atomic_read(v); + while (c != u && (old = atomic_cmpxchg(v, c, c + a)) != c) + c = old; + return c; } -#endif - -/** - * atomic_set_mask - Atomically set bits in atomic variable - * @mask: Mask of the bits to be set - * @v: pointer of type atomic_t - * - * Atomically sets the bits set in @mask in @v - */ -#ifndef atomic_set_mask -static inline void atomic_set_mask(unsigned int mask, atomic_t *v) -{ - unsigned long flags; - - raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */ - v->counter |= mask; - raw_local_irq_restore(flags); -} -#endif -#endif /* __KERNEL__ */ #endif /* __ASM_GENERIC_ATOMIC_H */ diff --git a/include/asm-generic/atomic64.h b/include/asm-generic/atomic64.h index b18ce4f9ee3d..30ad9c86cebb 100644 --- a/include/asm-generic/atomic64.h +++ b/include/asm-generic/atomic64.h @@ -20,10 +20,22 @@ typedef struct { extern long long atomic64_read(const atomic64_t *v); extern void atomic64_set(atomic64_t *v, long long i); -extern void atomic64_add(long long a, atomic64_t *v); -extern long long atomic64_add_return(long long a, atomic64_t *v); -extern void atomic64_sub(long long a, atomic64_t *v); -extern long long atomic64_sub_return(long long a, atomic64_t *v); + +#define ATOMIC64_OP(op) \ +extern void atomic64_##op(long long a, atomic64_t *v); + +#define ATOMIC64_OP_RETURN(op) \ +extern long long atomic64_##op##_return(long long a, atomic64_t *v); + +#define ATOMIC64_OPS(op) ATOMIC64_OP(op) ATOMIC64_OP_RETURN(op) + +ATOMIC64_OPS(add) +ATOMIC64_OPS(sub) + +#undef ATOMIC64_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP + extern long long atomic64_dec_if_positive(atomic64_t *v); extern long long atomic64_cmpxchg(atomic64_t *v, long long o, long long n); extern long long atomic64_xchg(atomic64_t *v, long long new); diff --git a/lib/atomic64.c b/lib/atomic64.c index 08a4f068e61e..1298c05ef528 100644 --- a/lib/atomic64.c +++ b/lib/atomic64.c @@ -70,53 +70,42 @@ void atomic64_set(atomic64_t *v, long long i) } EXPORT_SYMBOL(atomic64_set); -void atomic64_add(long long a, atomic64_t *v) -{ - unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); - - raw_spin_lock_irqsave(lock, flags); - v->counter += a; - raw_spin_unlock_irqrestore(lock, flags); -} -EXPORT_SYMBOL(atomic64_add); - -long long atomic64_add_return(long long a, atomic64_t *v) -{ - unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); - long long val; - - raw_spin_lock_irqsave(lock, flags); - val = v->counter += a; - raw_spin_unlock_irqrestore(lock, flags); - return val; -} -EXPORT_SYMBOL(atomic64_add_return); - -void atomic64_sub(long long a, atomic64_t *v) -{ - unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); - - raw_spin_lock_irqsave(lock, flags); - v->counter -= a; - raw_spin_unlock_irqrestore(lock, flags); -} -EXPORT_SYMBOL(atomic64_sub); - -long long atomic64_sub_return(long long a, atomic64_t *v) -{ - unsigned long flags; - raw_spinlock_t *lock = lock_addr(v); - long long val; - - raw_spin_lock_irqsave(lock, flags); - val = v->counter -= a; - raw_spin_unlock_irqrestore(lock, flags); - return val; -} -EXPORT_SYMBOL(atomic64_sub_return); +#define ATOMIC64_OP(op, c_op) \ +void atomic64_##op(long long a, atomic64_t *v) \ +{ \ + unsigned long flags; \ + raw_spinlock_t *lock = lock_addr(v); \ + \ + raw_spin_lock_irqsave(lock, flags); \ + v->counter c_op a; \ + raw_spin_unlock_irqrestore(lock, flags); \ +} \ +EXPORT_SYMBOL(atomic64_##op); + +#define ATOMIC64_OP_RETURN(op, c_op) \ +long long atomic64_##op##_return(long long a, atomic64_t *v) \ +{ \ + unsigned long flags; \ + raw_spinlock_t *lock = lock_addr(v); \ + long long val; \ + \ + raw_spin_lock_irqsave(lock, flags); \ + val = (v->counter c_op a); \ + raw_spin_unlock_irqrestore(lock, flags); \ + return val; \ +} \ +EXPORT_SYMBOL(atomic64_##op##_return); + +#define ATOMIC64_OPS(op, c_op) \ + ATOMIC64_OP(op, c_op) \ + ATOMIC64_OP_RETURN(op, c_op) + +ATOMIC64_OPS(add, +=) +ATOMIC64_OPS(sub, -=) + +#undef ATOMIC64_OPS +#undef ATOMIC64_OP_RETURN +#undef ATOMIC64_OP long long atomic64_dec_if_positive(atomic64_t *v) { -- GitLab From a9aefb3b3761a55117c6d1a526ac0305c3be5f46 Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 12 Aug 2014 11:02:19 +0300 Subject: [PATCH 0419/9167] ath10k: improve vdev map handling Check vdev map has space before calling ffs, fix invalid cleanup in failure to create vdev case. Open-code the BIT() logic since BIT does not properly handle 64-bit bitfields and future patches will make use of larger bitfields. Signed-off-by: Ben Greear Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/mac.c | 29 +++++++++++---------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index a5ec7c2502b5..4b62973f6276 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -597,14 +597,14 @@ static int ath10k_monitor_vdev_create(struct ath10k *ar) lockdep_assert_held(&ar->conf_mutex); - bit = ffs(ar->free_vdev_map); - if (bit == 0) { + if (ar->free_vdev_map == 0) { ath10k_warn("failed to find free vdev id for monitor vdev\n"); return -ENOMEM; } + bit = ffs(ar->free_vdev_map); + ar->monitor_vdev_id = bit - 1; - ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id); ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id, WMI_VDEV_TYPE_MONITOR, @@ -612,20 +612,14 @@ static int ath10k_monitor_vdev_create(struct ath10k *ar) if (ret) { ath10k_warn("failed to request monitor vdev %i creation: %d\n", ar->monitor_vdev_id, ret); - goto vdev_fail; + return ret; } + ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id); ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n", ar->monitor_vdev_id); return 0; - -vdev_fail: - /* - * Restore the ID to the global map. - */ - ar->free_vdev_map |= 1 << (ar->monitor_vdev_id); - return ret; } static int ath10k_monitor_vdev_delete(struct ath10k *ar) @@ -641,7 +635,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 |= 1 << ar->monitor_vdev_id; ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", ar->monitor_vdev_id); @@ -2780,11 +2774,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); INIT_LIST_HEAD(&arvif->list); - bit = ffs(ar->free_vdev_map); - if (bit == 0) { + if (ar->free_vdev_map == 0) { + ath10k_warn("Free vdev map is empty, no more interfaces allowed.\n"); ret = -EBUSY; goto err; } + bit = ffs(ar->free_vdev_map); arvif->vdev_id = bit - 1; arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; @@ -2827,7 +2822,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw, goto err; } - ar->free_vdev_map &= ~BIT(arvif->vdev_id); + ar->free_vdev_map &= ~(1 << arvif->vdev_id); list_add(&arvif->list, &ar->arvifs); vdev_param = ar->wmi.vdev_param->def_keyid; @@ -2920,7 +2915,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 &= ~BIT(arvif->vdev_id); + ar->free_vdev_map |= 1 << arvif->vdev_id; list_del(&arvif->list); err: @@ -2956,7 +2951,7 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, ath10k_warn("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 |= 1 << arvif->vdev_id; list_del(&arvif->list); if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -- GitLab From f2bc4d203edf2c5a6054134765ad5935454dc6ea Mon Sep 17 00:00:00 2001 From: Ben Greear Date: Tue, 12 Aug 2014 11:02:20 +0300 Subject: [PATCH 0420/9167] ath10k: fix typo in error message tranmist -> transmit Signed-off-by: Ben Greear 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 4b62973f6276..e568882a17de 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -2003,7 +2003,7 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb) ar->fw_features)) { if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >= ATH10K_MAX_NUM_MGMT_PENDING) { - ath10k_warn("reached WMI management tranmist queue limit\n"); + ath10k_warn("reached WMI management transmit queue limit\n"); ret = -EBUSY; goto exit; } -- GitLab From beb4be849a92172b4b95185a19db1691e6223f22 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Tue, 12 Aug 2014 11:45:59 +0100 Subject: [PATCH 0421/9167] ath6kl: Add SDIO device ID for QCA6234X Support This patch adds device ID 402 to support QCA6234X found in APQ8064 SOC in IFC6410 board. Tested with mainline mmci sdio driver. Signed-off-by: Srinivas Kandagatla Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 339d89f14d32..eab0ab976af2 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1400,6 +1400,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = { {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))}, {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x0))}, {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x1))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x2))}, {}, }; -- GitLab From 804eef14790f8917f74945f82db8b55903f76af4 Mon Sep 17 00:00:00 2001 From: Simon Wunderlich Date: Tue, 12 Aug 2014 17:12:17 +0200 Subject: [PATCH 0422/9167] ath10k: unregister spectral before mac If spectral is unregistered after mac80211, the relayfs file has already been removed recursively by mac/cfg80211, and spectral tries to remove the file once more, thus leading to double free problems. Better clean up spectral before to avoid that problem. Reported-by: Kalle Valo Signed-off-by: Simon Wunderlich Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath10k/core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index d3474b43ac47..ba2e87ab19bd 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -1043,6 +1043,12 @@ void ath10k_core_unregister(struct ath10k *ar) if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) return; + /* Stop spectral before unregistering from mac80211 to remove the + * relayfs debugfs file cleanly. Otherwise the parent debugfs tree + * would be already be free'd recursively, leading to a double free. + */ + ath10k_spectral_destroy(ar); + /* We must unregister from mac80211 before we stop HTC and HIF. * Otherwise we will fail to submit commands to FW and mac80211 will be * unhappy about callback failures. */ @@ -1050,8 +1056,6 @@ void ath10k_core_unregister(struct ath10k *ar) ath10k_core_free_firmware_files(ar); - ath10k_spectral_destroy(ar); - ath10k_debug_destroy(ar); } EXPORT_SYMBOL(ath10k_core_unregister); -- GitLab From ebc3282409ae4d1e90c2f9608665cc4d8fbf7e73 Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Wed, 13 Aug 2014 23:07:05 +0530 Subject: [PATCH 0423/9167] drm/i915: Created common handler for platform specific suspend/resume With this change, intel_runtime_suspend and intel_runtime_resume functions become completely platform agnostic. Platform specific suspend/resume changes are moved to intel_suspend_complete and intel_resume_prepare. Cc: Imre Deak Cc: Paulo Zanoni Cc: Daniel Vetter Cc: Jani Nikula Cc: Goel, Akash Signed-off-by: Sagar Kamble Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 76 +++++++++++++++++++++------------ 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 01de97776d81..b06e975dba39 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -494,6 +494,10 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) return true; } + +static int intel_suspend_complete(struct drm_i915_private *dev_priv); +static int intel_resume_prepare(struct drm_i915_private *dev_priv); + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -959,14 +963,14 @@ static int i915_pm_poweroff(struct device *dev) return i915_drm_freeze(drm_dev); } -static int hsw_runtime_suspend(struct drm_i915_private *dev_priv) +static int hsw_suspend_complete(struct drm_i915_private *dev_priv) { hsw_enable_pc8(dev_priv); return 0; } -static int snb_runtime_resume(struct drm_i915_private *dev_priv) +static int snb_resume_prepare(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; @@ -975,7 +979,7 @@ static int snb_runtime_resume(struct drm_i915_private *dev_priv) return 0; } -static int hsw_runtime_resume(struct drm_i915_private *dev_priv) +static int hsw_resume_prepare(struct drm_i915_private *dev_priv) { hsw_disable_pc8(dev_priv); @@ -1271,7 +1275,7 @@ static void vlv_check_no_gt_access(struct drm_i915_private *dev_priv) I915_WRITE(VLV_GTLC_PW_STATUS, VLV_GTLC_ALLOWWAKEERR); } -static int vlv_runtime_suspend(struct drm_i915_private *dev_priv) +static int vlv_suspend_complete(struct drm_i915_private *dev_priv) { u32 mask; int err; @@ -1311,7 +1315,7 @@ static int vlv_runtime_suspend(struct drm_i915_private *dev_priv) return err; } -static int vlv_runtime_resume(struct drm_i915_private *dev_priv) +static int vlv_resume_prepare(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; int err; @@ -1389,17 +1393,7 @@ static int intel_runtime_suspend(struct device *device) cancel_work_sync(&dev_priv->rps.work); intel_runtime_pm_disable_interrupts(dev); - if (IS_GEN6(dev)) { - ret = 0; - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - ret = hsw_runtime_suspend(dev_priv); - } else if (IS_VALLEYVIEW(dev)) { - ret = vlv_runtime_suspend(dev_priv); - } else { - ret = -ENODEV; - WARN_ON(1); - } - + ret = intel_suspend_complete(dev_priv); if (ret) { DRM_ERROR("Runtime suspend failed, disabling it (%d)\n", ret); intel_runtime_pm_restore_interrupts(dev); @@ -1437,17 +1431,7 @@ static int intel_runtime_resume(struct device *device) intel_opregion_notify_adapter(dev, PCI_D0); dev_priv->pm.suspended = false; - if (IS_GEN6(dev)) { - ret = snb_runtime_resume(dev_priv); - } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - ret = hsw_runtime_resume(dev_priv); - } else if (IS_VALLEYVIEW(dev)) { - ret = vlv_runtime_resume(dev_priv); - } else { - WARN_ON(1); - ret = -ENODEV; - } - + ret = intel_resume_prepare(dev_priv); /* * 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). @@ -1466,6 +1450,44 @@ static int intel_runtime_resume(struct device *device) return ret; } +static int intel_suspend_complete(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + int ret; + + if (IS_GEN6(dev)) { + ret = 0; + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + ret = hsw_suspend_complete(dev_priv); + } else if (IS_VALLEYVIEW(dev)) { + ret = vlv_suspend_complete(dev_priv); + } else { + ret = -ENODEV; + WARN_ON(1); + } + + return ret; +} + +static int intel_resume_prepare(struct drm_i915_private *dev_priv) +{ + struct drm_device *dev = dev_priv->dev; + int ret; + + if (IS_GEN6(dev)) { + ret = snb_resume_prepare(dev_priv); + } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { + ret = hsw_resume_prepare(dev_priv); + } else if (IS_VALLEYVIEW(dev)) { + ret = vlv_resume_prepare(dev_priv); + } else { + WARN_ON(1); + ret = -ENODEV; + } + + return ret; +} + static const struct dev_pm_ops i915_pm_ops = { .suspend = i915_pm_suspend, .suspend_late = i915_pm_suspend_late, -- GitLab From 016970beb05da6285c2f3ed2bee1c676cb75972e Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Wed, 13 Aug 2014 23:07:06 +0530 Subject: [PATCH 0424/9167] drm/i915: Sharing platform specific sequence between runtime and system suspend/ resume paths On VLV, post S0i3 during i915_drm_thaw following issue is observed during ring initialization. [ 335.604039] [drm:stop_ring] ERROR render ring :timed out trying to stop ring [ 336.607340] [drm:stop_ring] ERROR render ring :timed out trying to stop ring [ 336.607345] [drm:init_ring_common] ERROR failed to set render ring head to zero ctl 00000000 head 00000000 tail 00000000 start 00000000 [ 337.610645] [drm:stop_ring] ERROR bsd ring :timed out trying to stop ring [ 338.613952] [drm:stop_ring] ERROR bsd ring :timed out trying to stop ring [ 338.613956] [drm:init_ring_common] ERROR failed to set bsd ring head to zero ctl 00000000 head 00000000 tail 00000000 start 00000000 [ 339.617256] [drm:stop_ring] ERROR render ring :timed out trying to stop ring [ 339.617258] -----------[ cut here ]----------- [ 339.617267] WARNING: CPU: 0 PID: 6 at drivers/gpu/drm/i915/intel_ringbuffer.c:1666 intel_cleanup_ring+0xe6/0xf0() [ 339.617396] --[ end trace 5ef5ed1a3c92e2a6 ]-- [ 339.617428] [drm:__i915_drm_thaw] ERROR failed to re-initialize GPU, declaring wedged! This is happening since wake is not enabled and Gunit registers are not restored. For this system suspend/resume paths need to follow save/restore and additional platform specific setup in suspend_complete and resume_prepare. suspend_complete is shared unconditionaly for VLV, HSW, BDW. resume_prepare for HSW and BDW has pc8 disabling which is needed during thaw_early so sharing uncondtionally. For VLV and SNB runtime resume specific sequence exists. Cc: Imre Deak Cc: Paulo Zanoni Cc: Daniel Vetter Cc: Jani Nikula Cc: Goel, Akash Signed-off-by: Sagar Kamble Reviewed-by: Imre Deak Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 63 ++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b06e975dba39..2f112853c36f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -496,7 +496,8 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) static int intel_suspend_complete(struct drm_i915_private *dev_priv); -static int intel_resume_prepare(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) { @@ -604,15 +605,17 @@ int i915_suspend(struct drm_device *dev, pm_message_t state) static int i915_drm_thaw_early(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + int ret; - if (IS_HASWELL(dev) || IS_BROADWELL(dev)) - hsw_disable_pc8(dev_priv); + 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 0; + return ret; } static int __i915_drm_thaw(struct drm_device *dev, bool restore_gtt_mappings) @@ -888,6 +891,7 @@ 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 @@ -901,13 +905,16 @@ static int i915_pm_suspend_late(struct device *dev) if (drm_dev->switch_power_state == DRM_SWITCH_POWER_OFF) return 0; - if (IS_HASWELL(drm_dev) || IS_BROADWELL(drm_dev)) - hsw_enable_pc8(dev_priv); + ret = intel_suspend_complete(dev_priv); - pci_disable_device(pdev); - pci_set_power_state(pdev, PCI_D3hot); + if (ret) + DRM_ERROR("Suspend complete failed: %d\n", ret); + else { + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + } - return 0; + return ret; } static int i915_pm_resume_early(struct device *dev) @@ -970,16 +977,19 @@ static int hsw_suspend_complete(struct drm_i915_private *dev_priv) return 0; } -static int snb_resume_prepare(struct drm_i915_private *dev_priv) +static int snb_resume_prepare(struct drm_i915_private *dev_priv, + bool rpm_resume) { struct drm_device *dev = dev_priv->dev; - intel_init_pch_refclk(dev); + if (rpm_resume) + intel_init_pch_refclk(dev); return 0; } -static int hsw_resume_prepare(struct drm_i915_private *dev_priv) +static int hsw_resume_prepare(struct drm_i915_private *dev_priv, + bool rpm_resume) { hsw_disable_pc8(dev_priv); @@ -1315,7 +1325,8 @@ static int vlv_suspend_complete(struct drm_i915_private *dev_priv) return err; } -static int vlv_resume_prepare(struct drm_i915_private *dev_priv) +static int vlv_resume_prepare(struct drm_i915_private *dev_priv, + bool rpm_resume) { struct drm_device *dev = dev_priv->dev; int err; @@ -1340,8 +1351,10 @@ static int vlv_resume_prepare(struct drm_i915_private *dev_priv) vlv_check_no_gt_access(dev_priv); - intel_init_clock_gating(dev); - i915_gem_restore_fences(dev); + if (rpm_resume) { + intel_init_clock_gating(dev); + i915_gem_restore_fences(dev); + } return ret; } @@ -1431,7 +1444,7 @@ 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); + ret = intel_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). @@ -1450,6 +1463,10 @@ static int intel_runtime_resume(struct device *device) return ret; } +/* + * This function implements common functionality of runtime and system + * suspend sequence. + */ static int intel_suspend_complete(struct drm_i915_private *dev_priv) { struct drm_device *dev = dev_priv->dev; @@ -1469,17 +1486,23 @@ static int intel_suspend_complete(struct drm_i915_private *dev_priv) return ret; } -static int intel_resume_prepare(struct drm_i915_private *dev_priv) +/* + * 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); + ret = snb_resume_prepare(dev_priv, rpm_resume); } else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) { - ret = hsw_resume_prepare(dev_priv); + ret = hsw_resume_prepare(dev_priv, rpm_resume); } else if (IS_VALLEYVIEW(dev)) { - ret = vlv_resume_prepare(dev_priv); + ret = vlv_resume_prepare(dev_priv, rpm_resume); } else { WARN_ON(1); ret = -ENODEV; -- GitLab From 3a448734902359113b0c7c3454ce4cd56dc1e61f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 12 Aug 2014 20:05:47 +0100 Subject: [PATCH 0425/9167] drm/i915: Print captured bo for all VM in error state The current error state harks back to the era of just a single VM. For full-ppgtt, we capture every bo on every VM. It behoves us to then print every bo for every VM, which we currently fail to do and so miss vital information in the error state. v2: Use the vma address rather than -1! Signed-off-by: Chris Wilson Reviewed-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 2 + drivers/gpu/drm/i915/i915_gpu_error.c | 80 +++++++++++++++++++-------- 2 files changed, 58 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 541fb6f295bb..ed52ac744105 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -396,6 +396,7 @@ struct drm_i915_error_state { pid_t pid; char comm[TASK_COMM_LEN]; } ring[I915_NUM_RINGS]; + struct drm_i915_error_buffer { u32 size; u32 name; @@ -414,6 +415,7 @@ struct drm_i915_error_state { } **active_bo, **pinned_bo; u32 *active_bo_count, *pinned_bo_count; + u32 vm_count; }; struct intel_connector; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index fc11ac6b0373..35e70d5d6282 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -192,10 +192,10 @@ static void print_error_buffers(struct drm_i915_error_state_buf *m, struct drm_i915_error_buffer *err, int count) { - err_printf(m, "%s [%d]:\n", name, count); + err_printf(m, " %s [%d]:\n", name, count); while (count--) { - err_printf(m, " %08x %8u %02x %02x %x %x", + err_printf(m, " %08x %8u %02x %02x %x %x", err->gtt_offset, err->size, err->read_domains, @@ -393,15 +393,17 @@ int i915_error_state_to_str(struct drm_i915_error_state_buf *m, i915_ring_error_state(m, dev, &error->ring[i]); } - if (error->active_bo) + for (i = 0; i < error->vm_count; i++) { + err_printf(m, "vm[%d]\n", i); + print_error_buffers(m, "Active", - error->active_bo[0], - error->active_bo_count[0]); + error->active_bo[i], + error->active_bo_count[i]); - if (error->pinned_bo) print_error_buffers(m, "Pinned", - error->pinned_bo[0], - error->pinned_bo_count[0]); + error->pinned_bo[i], + error->pinned_bo_count[i]); + } for (i = 0; i < ARRAY_SIZE(error->ring); i++) { obj = error->ring[i].batchbuffer; @@ -644,13 +646,15 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv, (src)->base.size>>PAGE_SHIFT) static void capture_bo(struct drm_i915_error_buffer *err, - struct drm_i915_gem_object *obj) + struct i915_vma *vma) { + struct drm_i915_gem_object *obj = vma->obj; + err->size = obj->base.size; err->name = obj->base.name; err->rseqno = obj->last_read_seqno; err->wseqno = obj->last_write_seqno; - err->gtt_offset = i915_gem_obj_ggtt_offset(obj); + err->gtt_offset = vma->node.start; err->read_domains = obj->base.read_domains; err->write_domain = obj->base.write_domain; err->fence_reg = obj->fence_reg; @@ -674,7 +678,7 @@ static u32 capture_active_bo(struct drm_i915_error_buffer *err, int i = 0; list_for_each_entry(vma, head, mm_list) { - capture_bo(err++, vma->obj); + capture_bo(err++, vma); if (++i == count) break; } @@ -683,21 +687,27 @@ static u32 capture_active_bo(struct drm_i915_error_buffer *err, } static u32 capture_pinned_bo(struct drm_i915_error_buffer *err, - int count, struct list_head *head) + int count, struct list_head *head, + struct i915_address_space *vm) { struct drm_i915_gem_object *obj; - int i = 0; + struct drm_i915_error_buffer * const first = err; + struct drm_i915_error_buffer * const last = err + count; list_for_each_entry(obj, head, global_list) { - if (!i915_gem_obj_is_pinned(obj)) - continue; + struct i915_vma *vma; - capture_bo(err++, obj); - if (++i == count) + if (err == last) break; + + list_for_each_entry(vma, &obj->vma_list, vma_link) + if (vma->vm == vm && vma->pin_count > 0) { + capture_bo(err++, vma); + break; + } } - return i; + return err - first; } /* Generate a semi-unique error code. The code is not meant to have meaning, The @@ -1053,9 +1063,14 @@ static void i915_gem_capture_vm(struct drm_i915_private *dev_priv, list_for_each_entry(vma, &vm->active_list, mm_list) i++; error->active_bo_count[ndx] = i; - list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) - if (i915_gem_obj_is_pinned(obj)) - i++; + + list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) { + list_for_each_entry(vma, &obj->vma_list, vma_link) + if (vma->vm == vm && vma->pin_count > 0) { + i++; + break; + } + } error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx]; if (i) { @@ -1074,7 +1089,7 @@ static void i915_gem_capture_vm(struct drm_i915_private *dev_priv, error->pinned_bo_count[ndx] = capture_pinned_bo(pinned_bo, error->pinned_bo_count[ndx], - &dev_priv->mm.bound_list); + &dev_priv->mm.bound_list, vm); error->active_bo[ndx] = active_bo; error->pinned_bo[ndx] = pinned_bo; } @@ -1095,8 +1110,25 @@ static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv, error->pinned_bo_count = kcalloc(cnt, sizeof(*error->pinned_bo_count), GFP_ATOMIC); - list_for_each_entry(vm, &dev_priv->vm_list, global_link) - i915_gem_capture_vm(dev_priv, error, vm, i++); + if (error->active_bo == NULL || + error->pinned_bo == NULL || + error->active_bo_count == NULL || + error->pinned_bo_count == NULL) { + kfree(error->active_bo); + kfree(error->active_bo_count); + kfree(error->pinned_bo); + kfree(error->pinned_bo_count); + + error->active_bo = NULL; + error->active_bo_count = NULL; + error->pinned_bo = NULL; + error->pinned_bo_count = NULL; + } else { + list_for_each_entry(vm, &dev_priv->vm_list, global_link) + i915_gem_capture_vm(dev_priv, error, vm, i++); + + error->vm_count = cnt; + } } /* Capture all registers which don't fit into another category. */ -- GitLab From 582d67f0b19afc2299bc8977aba835d8d25bb591 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:16 +0100 Subject: [PATCH 0426/9167] drm/i915: Add temporary ring->ctx backpointer The execlist patches have a bit a convoluted and long history and due to that have the actual submission still misplaced deeply burried in the low-level ringbuffer handling code. This design goes back to the legacy ringbuffer code with its tricky lazy request and simple work submissiion using ring tail writes. For that reason they need a ring->ctx backpointer. The goal is to unburry that code and move it up into a level where the full execlist context is available so that we can ditch this backpointer. Until that's done make it really obvious that there's work still to be done. Cc: Oscar Mateo Cc: Thomas Daniel Acked-by: Thomas Daniel Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 2 ++ drivers/gpu/drm/i915/intel_ringbuffer.h | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6b5f416b5c0d..c2352d1b23fa 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -1086,6 +1086,8 @@ int intel_lr_context_deferred_create(struct intel_context *ctx, } ringbuf->ring = ring; + ringbuf->FIXME_lrc_ctx = ctx; + ringbuf->size = 32 * PAGE_SIZE; ringbuf->effective_size = ringbuf->size; ringbuf->head = 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 24437da91f77..26785ca72530 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -99,6 +99,13 @@ struct intel_ringbuffer { struct intel_engine_cs *ring; + /* + * FIXME: This backpointer is an artifact of the history of how the + * execlist patches came into being. It will get removed once the basic + * code has landed. + */ + struct intel_context *FIXME_lrc_ctx; + u32 head; u32 tail; int space; -- GitLab From 29db3cd372d1e75e2fadce5fd9961b7ef271061e Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Sat, 8 Feb 2014 23:11:00 +0000 Subject: [PATCH 0427/9167] HID: hid-sensor-hub: use devm_ functions consistently Use devm_kzalloc for all calls to kzalloc and not just the first. Use devm functions for other allocations as well. The calls to free the allocated memory in the probe and remove functions are done away with and a label is removed in the probe function. The semantic match that finds the inconsistency is as follows: // @@ @@ *devm_kzalloc(...) ... *kzalloc(...) // Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Reviewed-by: Srinivas Pandruvada Signed-off-by: Jonathan Cameron --- drivers/hid/hid-sensor-hub.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index e244e449cbba..2ac25760a9a9 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -604,9 +604,9 @@ static int sensor_hub_probe(struct hid_device *hdev, ret = -EINVAL; goto err_stop_hw; } - sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt * - sizeof(struct mfd_cell), - GFP_KERNEL); + sd->hid_sensor_hub_client_devs = devm_kzalloc(&hdev->dev, dev_cnt * + sizeof(struct mfd_cell), + GFP_KERNEL); if (sd->hid_sensor_hub_client_devs == NULL) { hid_err(hdev, "Failed to allocate memory for mfd cells\n"); ret = -ENOMEM; @@ -618,11 +618,12 @@ static int sensor_hub_probe(struct hid_device *hdev, if (collection->type == HID_COLLECTION_PHYSICAL) { - hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL); + hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), + GFP_KERNEL); if (!hsdev) { hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); ret = -ENOMEM; - goto err_no_mem; + goto err_stop_hw; } hsdev->hdev = hdev; hsdev->vendor_id = hdev->vendor; @@ -631,13 +632,13 @@ static int sensor_hub_probe(struct hid_device *hdev, if (last_hsdev) last_hsdev->end_collection_index = i; last_hsdev = hsdev; - name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", - collection->usage); + name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "HID-SENSOR-%x", + collection->usage); if (name == NULL) { hid_err(hdev, "Failed MFD device name\n"); ret = -ENOMEM; - kfree(hsdev); - goto err_no_mem; + goto err_stop_hw; } sd->hid_sensor_hub_client_devs[ sd->hid_sensor_client_cnt].id = @@ -661,16 +662,10 @@ static int sensor_hub_probe(struct hid_device *hdev, ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, sd->hid_sensor_client_cnt, NULL, 0, NULL); if (ret < 0) - goto err_no_mem; + goto err_stop_hw; return ret; -err_no_mem: - for (i = 0; i < sd->hid_sensor_client_cnt; ++i) { - kfree(sd->hid_sensor_hub_client_devs[i].name); - kfree(sd->hid_sensor_hub_client_devs[i].platform_data); - } - kfree(sd->hid_sensor_hub_client_devs); err_stop_hw: hid_hw_stop(hdev); @@ -681,7 +676,6 @@ static void sensor_hub_remove(struct hid_device *hdev) { struct sensor_hub_data *data = hid_get_drvdata(hdev); unsigned long flags; - int i; hid_dbg(hdev, " hardware removed\n"); hid_hw_close(hdev); @@ -691,11 +685,6 @@ static void sensor_hub_remove(struct hid_device *hdev) complete(&data->pending.ready); spin_unlock_irqrestore(&data->lock, flags); mfd_remove_devices(&hdev->dev); - for (i = 0; i < data->hid_sensor_client_cnt; ++i) { - kfree(data->hid_sensor_hub_client_devs[i].name); - kfree(data->hid_sensor_hub_client_devs[i].platform_data); - } - kfree(data->hid_sensor_hub_client_devs); hid_set_drvdata(hdev, NULL); mutex_destroy(&data->mutex); } -- GitLab From 295ee85316aedfe1878306d71b5e9c7d4498fb1b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 30 Jul 2014 14:23:44 +0200 Subject: [PATCH 0428/9167] drm: Docbook fixes Bunch of small leftovers spotted by looking at the make htmldocs output. I've left out dp mst, there's too much amiss there. v2: Also add the missing parameter docbook in the dp mst code - Dave Airlie correctly pointed out that we don't actually want kerneldoc for the missing structure members in header files. Cc: Dave Airlie Reviewed-by: Matt Roper Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 5 +++-- drivers/gpu/drm/drm_dp_mst_topology.c | 1 + drivers/gpu/drm/drm_edid.c | 2 +- drivers/gpu/drm/drm_modeset_lock.c | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 285e62a134b2..f09b75212081 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3512,9 +3512,10 @@ EXPORT_SYMBOL(drm_property_create_enum); * @flags: flags specifying the property type * @name: name of the property * @props: enumeration lists with property bitflags - * @num_values: number of pre-defined values + * @num_props: size of the @props array + * @supported_bits: bitmask of all supported enumeration values * - * This creates a new generic drm property which can then be attached to a drm + * This creates a new bitmask drm property which can then be attached to a drm * object with drm_object_attach_property. The returned property object must be * freed with drm_property_destroy. * diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index ac3c2738db94..352f5d6c763c 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -2071,6 +2071,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) * drm_dp_mst_hpd_irq() - MST hotplug IRQ notify * @mgr: manager to notify irq for. * @esi: 4 bytes from SINK_COUNT_ESI + * @handled: whether the hpd interrupt was consumed or not * * This should be called from the driver when it detects a short IRQ, * along with the value of the DEVICE_SERVICE_IRQ_VECTOR_ESI0. The diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 1dbf3bc4c6a3..f905c63c0f68 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -3433,10 +3433,10 @@ EXPORT_SYMBOL(drm_rgb_quant_range_selectable); /** * drm_assign_hdmi_deep_color_info - detect whether monitor supports * hdmi deep color modes and update drm_display_info if so. - * * @edid: monitor EDID information * @info: Updated with maximum supported deep color bpc and color format * if deep color supported. + * @connector: DRM connector, used only for debug output * * Parse the CEA extension according to CEA-861-B. * Return true if HDMI deep color supported, false if not or unknown. diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index 5280b64a0230..8749fc06570e 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -199,7 +199,7 @@ EXPORT_SYMBOL(drm_modeset_lock_crtc); /** * drm_modeset_legacy_acquire_ctx - find acquire ctx for legacy ioctls - * crtc: drm crtc + * @crtc: drm crtc * * Legacy ioctl operations like cursor updates or page flips only have per-crtc * locking, and store the acquire ctx in the corresponding crtc. All other -- GitLab From c11cda52193dfa459dfea38f00b19bc9325fa922 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 8 Aug 2014 18:50:18 +0100 Subject: [PATCH 0429/9167] drm: Don't return 0 for a value used as a denominator Static analysis will be unhappy if a function can theoretically return 0 and we're trying to divide by that value. Mark that case that cannot occur as a BUG() instead. Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_dp_mst_topology.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c index 352f5d6c763c..b3adf1445020 100644 --- a/drivers/gpu/drm/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/drm_dp_mst_topology.c @@ -1772,7 +1772,7 @@ static int drm_dp_get_vc_payload_bw(int dp_link_bw, int dp_link_count) case DP_LINK_BW_5_4: return 10 * dp_link_count; } - return 0; + BUG(); } /** -- GitLab From 14f476fa24e81d0beea1aa14d763102958518d60 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 8 Aug 2014 19:15:20 +0100 Subject: [PATCH 0430/9167] drm: Use the type of the array element when reallocating Static analysers find it 'suspicious', that we're trying to allocate memory for elements of size sizeof(struct drm_fb_helper_connector) when the array is defined as struct drm_fb_helper_connector **. Use sizeof(struct drm_fb_helper_connector *) instead. Note that the structure being defined as: struct drm_fb_helper_connector { struct drm_connector *connector; }; This was still doing the right thing, but may not in the future if additional fields are added. Cc: Todd Previte Cc: Dave Airlie Signed-off-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_fb_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 7b7b9565188f..6019392b19cc 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -126,7 +126,7 @@ int drm_fb_helper_add_one_connector(struct drm_fb_helper *fb_helper, struct drm_ WARN_ON(!mutex_is_locked(&fb_helper->dev->mode_config.mutex)); if (fb_helper->connector_count + 1 > fb_helper->connector_info_alloc_count) { - temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector) * (fb_helper->connector_count + 1), GFP_KERNEL); + temp = krealloc(fb_helper->connector_info, sizeof(struct drm_fb_helper_connector *) * (fb_helper->connector_count + 1), GFP_KERNEL); if (!temp) return -ENOMEM; -- GitLab From 48e29f5535b9eb506c44bd8f41bd9348fd219435 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:29 +0100 Subject: [PATCH 0431/9167] drm/i915/bdw: Emission of requests with logical rings On a previous iteration of this patch, I created an Execlists version of __i915_add_request and asbtracted it away as a vfunc. Daniel Vetter wondered then why that was needed: "with the clean split in command submission I expect every function to know wether it'll submit to an lrc (everything in intel_lrc.c) or wether it'll submit to a legacy ring (existing code), so I don't see a need for an add_request vfunc." The honest, hairy truth is that this patch is the glue keeping the whole logical ring puzzle together: - i915_add_request is used by intel_ring_idle, which in turn is used by i915_gpu_idle, which in turn is used in several places inside the eviction and gtt codes. - Also, it is used by i915_gem_check_olr, which is littered all over i915_gem.c - ... If I were to duplicate all the code that directly or indirectly uses __i915_add_request, I'll end up creating a separate driver. To show the differences between the existing legacy version and the new Execlists one, this time I have special-cased __i915_add_request instead of adding an add_request vfunc. I hope this helps to untangle this Gordian knot. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Adjust to ringbuf->FIXME_lrc_ctx per the discussion with Thomas Daniel.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 72 +++++++++++++++++++++++--------- drivers/gpu/drm/i915/intel_lrc.c | 30 +++++++++++-- drivers/gpu/drm/i915/intel_lrc.h | 1 + 3 files changed, 80 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6c2f0b886eb0..32fa1e9eb844 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2311,10 +2311,21 @@ int __i915_add_request(struct intel_engine_cs *ring, { struct drm_i915_private *dev_priv = ring->dev->dev_private; struct drm_i915_gem_request *request; + struct intel_ringbuffer *ringbuf; u32 request_ring_position, request_start; int ret; - request_start = intel_ring_get_tail(ring->buffer); + request = ring->preallocated_lazy_request; + if (WARN_ON(request == NULL)) + return -ENOMEM; + + if (i915.enable_execlists) { + struct intel_context *ctx = request->ctx; + ringbuf = ctx->engine[ring->id].ringbuf; + } else + ringbuf = ring->buffer; + + request_start = intel_ring_get_tail(ringbuf); /* * Emit any outstanding flushes - execbuf can fail to emit the flush * after having emitted the batchbuffer command. Hence we need to fix @@ -2322,24 +2333,32 @@ int __i915_add_request(struct intel_engine_cs *ring, * is that the flush _must_ happen before the next request, no matter * what. */ - ret = intel_ring_flush_all_caches(ring); - if (ret) - return ret; - - request = ring->preallocated_lazy_request; - if (WARN_ON(request == NULL)) - return -ENOMEM; + if (i915.enable_execlists) { + ret = logical_ring_flush_all_caches(ringbuf); + if (ret) + return ret; + } else { + ret = intel_ring_flush_all_caches(ring); + if (ret) + return ret; + } /* Record the position of the start of the request so that * should we detect the updated seqno part-way through the * GPU processing the request, we never over-estimate the * position of the head. */ - request_ring_position = intel_ring_get_tail(ring->buffer); + request_ring_position = intel_ring_get_tail(ringbuf); - ret = ring->add_request(ring); - if (ret) - return ret; + if (i915.enable_execlists) { + ret = ring->emit_request(ringbuf); + if (ret) + return ret; + } else { + ret = ring->add_request(ring); + if (ret) + return ret; + } request->seqno = intel_ring_get_seqno(ring); request->ring = ring; @@ -2354,12 +2373,14 @@ int __i915_add_request(struct intel_engine_cs *ring, */ request->batch_obj = obj; - /* Hold a reference to the current context so that we can inspect - * it later in case a hangcheck error event fires. - */ - request->ctx = ring->last_context; - if (request->ctx) - i915_gem_context_reference(request->ctx); + if (!i915.enable_execlists) { + /* Hold a reference to the current context so that we can inspect + * it later in case a hangcheck error event fires. + */ + request->ctx = ring->last_context; + if (request->ctx) + i915_gem_context_reference(request->ctx); + } request->emitted_jiffies = jiffies; list_add_tail(&request->list, &ring->request_list); @@ -2614,6 +2635,7 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) while (!list_empty(&ring->request_list)) { struct drm_i915_gem_request *request; + struct intel_ringbuffer *ringbuf; request = list_first_entry(&ring->request_list, struct drm_i915_gem_request, @@ -2623,12 +2645,24 @@ i915_gem_retire_requests_ring(struct intel_engine_cs *ring) break; trace_i915_gem_request_retire(ring, request->seqno); + + /* This is one of the few common intersection points + * between legacy ringbuffer submission and execlists: + * we need to tell them apart in order to find the correct + * ringbuffer to which the request belongs to. + */ + if (i915.enable_execlists) { + struct intel_context *ctx = request->ctx; + ringbuf = ctx->engine[ring->id].ringbuf; + } else + ringbuf = ring->buffer; + /* We know the GPU must have read the request to have * sent us the seqno + interrupt, so use the position * of tail of the request to update the last known position * of the GPU head. */ - ring->buffer->last_retired_head = request->tail; + ringbuf->last_retired_head = request->tail; i915_gem_free_request(request); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index c2352d1b23fa..cd6ddd80e54c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -252,6 +252,22 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring) I915_WRITE_MODE(ring, _MASKED_BIT_DISABLE(STOP_RING)); } +int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf) +{ + struct intel_engine_cs *ring = ringbuf->ring; + int ret; + + if (!ring->gpu_caches_dirty) + return 0; + + ret = ring->emit_flush(ringbuf, 0, I915_GEM_GPU_DOMAINS); + if (ret) + return ret; + + ring->gpu_caches_dirty = false; + return 0; +} + void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) { intel_logical_ring_advance(ringbuf); @@ -262,7 +278,8 @@ void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) /* TODO: how to submit a context to the ELSP is not here yet */ } -static int logical_ring_alloc_seqno(struct intel_engine_cs *ring) +static int logical_ring_alloc_seqno(struct intel_engine_cs *ring, + struct intel_context *ctx) { if (ring->outstanding_lazy_seqno) return 0; @@ -274,6 +291,13 @@ static int logical_ring_alloc_seqno(struct intel_engine_cs *ring) if (request == NULL) return -ENOMEM; + /* Hold a reference to the context this request belongs to + * (we will need it when the time comes to emit/retire the + * request). + */ + request->ctx = ctx; + i915_gem_context_reference(request->ctx); + ring->preallocated_lazy_request = request; } @@ -312,8 +336,6 @@ static int logical_ring_wait_request(struct intel_ringbuffer *ringbuf, if (ret) return ret; - /* TODO: make sure we update the right ringbuffer's last_retired_head - * when retiring requests */ i915_gem_retire_requests_ring(ring); ringbuf->head = ringbuf->last_retired_head; ringbuf->last_retired_head = -1; @@ -433,7 +455,7 @@ int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords) return ret; /* Preallocate the olr before touching the ring */ - ret = logical_ring_alloc_seqno(ring); + ret = logical_ring_alloc_seqno(ring, ringbuf->FIXME_lrc_ctx); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 4e032875c1fd..460e1af15600 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -29,6 +29,7 @@ void intel_logical_ring_stop(struct intel_engine_cs *ring); void intel_logical_ring_cleanup(struct intel_engine_cs *ring); int intel_logical_rings_init(struct drm_device *dev); +int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf); void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf); static inline void intel_logical_ring_advance(struct intel_ringbuffer *ringbuf) { -- GitLab From 84b790f80e5153d8d54074aa4eae49ff3070f2f1 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 24 Jul 2014 17:04:36 +0100 Subject: [PATCH 0432/9167] drm/i915/bdw: Implement context switching (somewhat) A context switch occurs by submitting a context descriptor to the ExecList Submission Port. Given that we can now initialize a context, it's possible to begin implementing the context switch by creating the descriptor and submitting it to ELSP (actually two, since the ELSP has two ports). The context object must be mapped in the GGTT, which means it must exist in the 0-4GB graphics VA range. Signed-off-by: Ben Widawsky v2: This code has changed quite a lot in various rebases. Of particular importance is that now we use the globally unique Submission ID to send to the hardware. Also, context pages are now pinned unconditionally to GGTT, so there is no need to bind them. v3: Use LRCA[31:12] as hwCtxId[19:0]. This guarantees that the HW context ID we submit to the ELSP is globally unique and != 0 (Bspec requirements of the software use-only bits of the Context ID in the Context Descriptor Format) without the hassle of the previous submission Id construction. Also, re-add the ELSP porting read (it was dropped somewhere during the rebases). v4: - Squash with "drm/i915/bdw: Add forcewake lock around ELSP writes" (BSPEC says: "SW must set Force Wakeup bit to prevent GT from entering C6 while ELSP writes are in progress") as noted by Thomas Daniel (thomas.daniel@intel.com). - Rename functions and use an execlists/intel_execlists_ namespace. - The BUG_ON only checked that the LRCA was <32 bits, but it didn't make sure that it was properly aligned. Spotted by Alistair Mcaulay . v5: - Improved source code comments as suggested by Chris Wilson. - No need to abstract submit_ctx away, as pointed by Brad Volkin. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Checkpatch. Sigh.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 116 ++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_lrc.h | 1 + 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cd6ddd80e54c..aa81fd41b9c1 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -47,6 +47,7 @@ #define GEN8_LR_CONTEXT_ALIGN 4096 #define RING_ELSP(ring) ((ring)->mmio_base+0x230) +#define RING_EXECLIST_STATUS(ring) ((ring)->mmio_base+0x234) #define RING_CONTEXT_CONTROL(ring) ((ring)->mmio_base+0x244) #define CTX_LRI_HEADER_0 0x01 @@ -78,6 +79,26 @@ #define CTX_R_PWR_CLK_STATE 0x42 #define CTX_GPGPU_CSR_BASE_ADDRESS 0x44 +#define GEN8_CTX_VALID (1<<0) +#define GEN8_CTX_FORCE_PD_RESTORE (1<<1) +#define GEN8_CTX_FORCE_RESTORE (1<<2) +#define GEN8_CTX_L3LLC_COHERENT (1<<5) +#define GEN8_CTX_PRIVILEGE (1<<8) +enum { + ADVANCED_CONTEXT = 0, + LEGACY_CONTEXT, + ADVANCED_AD_CONTEXT, + LEGACY_64B_CONTEXT +}; +#define GEN8_CTX_MODE_SHIFT 3 +enum { + FAULT_AND_HANG = 0, + FAULT_AND_HALT, /* Debug only */ + FAULT_AND_STREAM, + FAULT_AND_CONTINUE /* Unsupported */ +}; +#define GEN8_CTX_ID_SHIFT 32 + int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) { WARN_ON(i915.enable_ppgtt == -1); @@ -92,6 +113,93 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj) +{ + u32 lrca = i915_gem_obj_ggtt_offset(ctx_obj); + + /* LRCA is required to be 4K aligned so the more significant 20 bits + * are globally unique */ + return lrca >> 12; +} + +static uint64_t execlists_ctx_descriptor(struct drm_i915_gem_object *ctx_obj) +{ + uint64_t desc; + uint64_t lrca = i915_gem_obj_ggtt_offset(ctx_obj); + BUG_ON(lrca & 0xFFFFFFFF00000FFFULL); + + desc = GEN8_CTX_VALID; + desc |= LEGACY_CONTEXT << GEN8_CTX_MODE_SHIFT; + desc |= GEN8_CTX_L3LLC_COHERENT; + desc |= GEN8_CTX_PRIVILEGE; + desc |= lrca; + desc |= (u64)intel_execlists_ctx_id(ctx_obj) << GEN8_CTX_ID_SHIFT; + + /* TODO: WaDisableLiteRestore when we start using semaphore + * signalling between Command Streamers */ + /* desc |= GEN8_CTX_FORCE_RESTORE; */ + + return desc; +} + +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; + uint64_t temp = 0; + uint32_t desc[4]; + + /* XXX: You must always write both descriptors in the order below. */ + if (ctx_obj1) + temp = execlists_ctx_descriptor(ctx_obj1); + else + temp = 0; + desc[1] = (u32)(temp >> 32); + desc[0] = (u32)temp; + + temp = execlists_ctx_descriptor(ctx_obj0); + desc[3] = (u32)(temp >> 32); + desc[2] = (u32)temp; + + /* Set Force Wakeup bit to prevent GT from entering C6 while + * ELSP writes are in progress */ + gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); + + I915_WRITE(RING_ELSP(ring), desc[1]); + I915_WRITE(RING_ELSP(ring), desc[0]); + I915_WRITE(RING_ELSP(ring), desc[3]); + /* The context is automatically loaded after the following */ + I915_WRITE(RING_ELSP(ring), desc[2]); + + /* ELSP is a wo register, so use another nearby reg for posting instead */ + POSTING_READ(RING_EXECLIST_STATUS(ring)); + + gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); +} + +static int execlists_submit_context(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; + + ctx_obj0 = to0->engine[ring->id].state; + BUG_ON(!ctx_obj0); + BUG_ON(!i915_gem_obj_is_pinned(ctx_obj0)); + + if (to1) { + ctx_obj1 = to1->engine[ring->id].state; + BUG_ON(!ctx_obj1); + BUG_ON(!i915_gem_obj_is_pinned(ctx_obj1)); + } + + execlists_elsp_write(ring, ctx_obj0, ctx_obj1); + + return 0; +} + static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf) { struct intel_engine_cs *ring = ringbuf->ring; @@ -270,12 +378,16 @@ int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf) void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) { + struct intel_engine_cs *ring = ringbuf->ring; + struct intel_context *ctx = ringbuf->FIXME_lrc_ctx; + intel_logical_ring_advance(ringbuf); - if (intel_ring_stopped(ringbuf->ring)) + if (intel_ring_stopped(ring)) return; - /* TODO: how to submit a context to the ELSP is not here yet */ + /* FIXME: too cheeky, we don't even check if the ELSP is ready */ + execlists_submit_context(ring, ctx, ringbuf->tail, NULL, 0); } static int logical_ring_alloc_seqno(struct intel_engine_cs *ring, diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 460e1af15600..69605b158235 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -57,5 +57,6 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, struct list_head *vmas, struct drm_i915_gem_object *batch_obj, u64 exec_start, u32 flags); +u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj); #endif /* _INTEL_LRC_H_ */ -- GitLab From ae1250b9da308acd16554365d125b4afb795b825 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:37 +0100 Subject: [PATCH 0433/9167] drm/i915/bdw: Write the tail pointer, LRC style Each logical ring context has the tail pointer in the context object, so update it before submission. v2: New namespace. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index aa81fd41b9c1..26bc063f137b 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -178,6 +178,21 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); } +static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tail) +{ + struct page *page; + uint32_t *reg_state; + + page = i915_gem_object_get_page(ctx_obj, 1); + reg_state = kmap_atomic(page); + + reg_state[CTX_RING_TAIL+1] = tail; + + kunmap_atomic(reg_state); + + return 0; +} + static int execlists_submit_context(struct intel_engine_cs *ring, struct intel_context *to0, u32 tail0, struct intel_context *to1, u32 tail1) @@ -189,10 +204,14 @@ static int execlists_submit_context(struct intel_engine_cs *ring, BUG_ON(!ctx_obj0); BUG_ON(!i915_gem_obj_is_pinned(ctx_obj0)); + execlists_ctx_write_tail(ctx_obj0, tail0); + if (to1) { ctx_obj1 = to1->engine[ring->id].state; BUG_ON(!ctx_obj1); BUG_ON(!i915_gem_obj_is_pinned(ctx_obj1)); + + execlists_ctx_write_tail(ctx_obj1, tail1); } execlists_elsp_write(ring, ctx_obj0, ctx_obj1); -- GitLab From acdd884a2e1b873995c120d5eabd8cab77f48f20 Mon Sep 17 00:00:00 2001 From: Michel Thierry Date: Thu, 24 Jul 2014 17:04:38 +0100 Subject: [PATCH 0434/9167] drm/i915/bdw: Two-stage execlist submit process Context switch (and execlist submission) should happen only when other contexts are not active, otherwise pre-emption occurs. To assure this, we place context switch requests in a queue and those request are later consumed when the right context switch interrupt is received (still TODO). v2: Use a spinlock, do not remove the requests on unqueue (wait for context switch completion). Signed-off-by: Thomas Daniel v3: Several rebases and code changes. Use unique ID. v4: - Move the queue/lock init to the late ring initialization. - Damien's kmalloc review comments: check return, use sizeof(*req), do not cast. v5: - Do not reuse drm_i915_gem_request. Instead, create our own. - New namespace. Signed-off-by: Michel Thierry (v1) Signed-off-by: Oscar Mateo (v2-v5) Reviewed-by: Damien Lespiau [davnet: Checkpatch + wash-up s/BUG_ON/WARN_ON/.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 72 +++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_lrc.h | 8 +++ drivers/gpu/drm/i915/intel_ringbuffer.h | 2 + 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 26bc063f137b..e81f5f6c49b9 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -126,7 +126,8 @@ static uint64_t execlists_ctx_descriptor(struct drm_i915_gem_object *ctx_obj) { uint64_t desc; uint64_t lrca = i915_gem_obj_ggtt_offset(ctx_obj); - BUG_ON(lrca & 0xFFFFFFFF00000FFFULL); + + WARN_ON(lrca & 0xFFFFFFFF00000FFFULL); desc = GEN8_CTX_VALID; desc |= LEGACY_CONTEXT << GEN8_CTX_MODE_SHIFT; @@ -202,14 +203,14 @@ static int execlists_submit_context(struct intel_engine_cs *ring, ctx_obj0 = to0->engine[ring->id].state; BUG_ON(!ctx_obj0); - BUG_ON(!i915_gem_obj_is_pinned(ctx_obj0)); + WARN_ON(!i915_gem_obj_is_pinned(ctx_obj0)); execlists_ctx_write_tail(ctx_obj0, tail0); if (to1) { ctx_obj1 = to1->engine[ring->id].state; BUG_ON(!ctx_obj1); - BUG_ON(!i915_gem_obj_is_pinned(ctx_obj1)); + WARN_ON(!i915_gem_obj_is_pinned(ctx_obj1)); execlists_ctx_write_tail(ctx_obj1, tail1); } @@ -219,6 +220,65 @@ static int execlists_submit_context(struct intel_engine_cs *ring, return 0; } +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; + + if (list_empty(&ring->execlist_queue)) + return; + + /* Try to read in pairs */ + list_for_each_entry_safe(cursor, tmp, &ring->execlist_queue, + execlist_link) { + if (!req0) { + req0 = cursor; + } else if (req0->ctx == cursor->ctx) { + /* Same ctx: ignore first request, as second request + * will update tail past first request's workload */ + list_del(&req0->execlist_link); + i915_gem_context_unreference(req0->ctx); + kfree(req0); + req0 = cursor; + } else { + req1 = cursor; + break; + } + } + + WARN_ON(execlists_submit_context(ring, req0->ctx, req0->tail, + req1 ? req1->ctx : NULL, + req1 ? req1->tail : 0)); +} + +static int execlists_context_queue(struct intel_engine_cs *ring, + struct intel_context *to, + u32 tail) +{ + struct intel_ctx_submit_request *req = NULL; + unsigned long flags; + bool was_empty; + + req = kzalloc(sizeof(*req), GFP_KERNEL); + if (req == NULL) + return -ENOMEM; + req->ctx = to; + i915_gem_context_reference(req->ctx); + req->ring = ring; + req->tail = tail; + + spin_lock_irqsave(&ring->execlist_lock, flags); + + was_empty = list_empty(&ring->execlist_queue); + list_add_tail(&req->execlist_link, &ring->execlist_queue); + if (was_empty) + execlists_context_unqueue(ring); + + spin_unlock_irqrestore(&ring->execlist_lock, flags); + + return 0; +} + static int logical_ring_invalidate_all_caches(struct intel_ringbuffer *ringbuf) { struct intel_engine_cs *ring = ringbuf->ring; @@ -405,8 +465,7 @@ void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) if (intel_ring_stopped(ring)) return; - /* FIXME: too cheeky, we don't even check if the ELSP is ready */ - execlists_submit_context(ring, ctx, ringbuf->tail, NULL, 0); + execlists_context_queue(ring, ctx, ringbuf->tail); } static int logical_ring_alloc_seqno(struct intel_engine_cs *ring, @@ -846,6 +905,9 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin INIT_LIST_HEAD(&ring->request_list); init_waitqueue_head(&ring->irq_queue); + INIT_LIST_HEAD(&ring->execlist_queue); + spin_lock_init(&ring->execlist_lock); + ret = intel_lr_context_deferred_create(dctx, ring); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 69605b158235..3c389b3a2b75 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -59,4 +59,12 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, u64 exec_start, u32 flags); u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj); +struct intel_ctx_submit_request { + struct intel_context *ctx; + struct intel_engine_cs *ring; + u32 tail; + + struct list_head execlist_link; +}; + #endif /* _INTEL_LRC_H_ */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 26785ca72530..670262dabb6c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -231,6 +231,8 @@ struct intel_engine_cs { } semaphore; /* Execlists */ + spinlock_t execlist_lock; + struct list_head execlist_queue; u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */ int (*emit_request)(struct intel_ringbuffer *ringbuf); int (*emit_flush)(struct intel_ringbuffer *ringbuf, -- GitLab From e981e7b17f2b41970e7e2367d4225e0bb3310667 Mon Sep 17 00:00:00 2001 From: Thomas Daniel Date: Thu, 24 Jul 2014 17:04:39 +0100 Subject: [PATCH 0435/9167] drm/i915/bdw: Handle context switch events Handle all context status events in the context status buffer on every context switch interrupt. We only remove work from the execlist queue after a context status buffer reports that it has completed and we only attempt to schedule new contexts on interrupt when a previously submitted context completes (unless no contexts are queued, which means the GPU is free). We canot call intel_runtime_pm_get() in an interrupt (or with a spinlock grabbed, FWIW), because it might sleep, which is not a nice thing to do. Instead, do the runtime_pm get/put together with the create/destroy request, and handle the forcewake get/put directly. Signed-off-by: Thomas Daniel v2: Unreferencing the context when we are freeing the request might free the backing bo, which requires the struct_mutex to be grabbed, so defer unreferencing and freeing to a bottom half. v3: - Ack the interrupt inmediately, before trying to handle it (fix for missing interrupts by Bob Beckett ). - Update the Context Status Buffer Read Pointer, just in case (spotted by Damien Lespiau). v4: New namespace and multiple rebase changes. v5: Squash with "drm/i915/bdw: Do not call intel_runtime_pm_get() in an interrupt", as suggested by Daniel. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Checkpatch ...] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 35 +++++-- drivers/gpu/drm/i915/intel_lrc.c | 133 ++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_lrc.h | 3 + drivers/gpu/drm/i915/intel_ringbuffer.h | 1 + 4 files changed, 155 insertions(+), 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 00957fa0b877..f5d6795887d2 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1632,6 +1632,7 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, struct drm_i915_private *dev_priv, u32 master_ctl) { + struct intel_engine_cs *ring; u32 rcs, bcs, vcs; uint32_t tmp = 0; irqreturn_t ret = IRQ_NONE; @@ -1641,14 +1642,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(0), tmp); ret = IRQ_HANDLED; + rcs = tmp >> GEN8_RCS_IRQ_SHIFT; - bcs = tmp >> GEN8_BCS_IRQ_SHIFT; + ring = &dev_priv->ring[RCS]; if (rcs & GT_RENDER_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[RCS]); + notify_ring(dev, ring); + if (rcs & GT_CONTEXT_SWITCH_INTERRUPT) + intel_execlists_handle_ctx_events(ring); + + bcs = tmp >> GEN8_BCS_IRQ_SHIFT; + ring = &dev_priv->ring[BCS]; if (bcs & GT_RENDER_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[BCS]); - if ((rcs | bcs) & GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER("TODO: Context switch\n"); + notify_ring(dev, ring); + if (bcs & GT_CONTEXT_SWITCH_INTERRUPT) + intel_execlists_handle_ctx_events(ring); } else DRM_ERROR("The master control interrupt lied (GT0)!\n"); } @@ -1658,16 +1665,20 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(1), tmp); ret = IRQ_HANDLED; + vcs = tmp >> GEN8_VCS1_IRQ_SHIFT; + ring = &dev_priv->ring[VCS]; if (vcs & GT_RENDER_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[VCS]); + notify_ring(dev, ring); if (vcs & GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER("TODO: Context switch\n"); + intel_execlists_handle_ctx_events(ring); + vcs = tmp >> GEN8_VCS2_IRQ_SHIFT; + ring = &dev_priv->ring[VCS2]; if (vcs & GT_RENDER_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[VCS2]); + notify_ring(dev, ring); if (vcs & GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER("TODO: Context switch\n"); + intel_execlists_handle_ctx_events(ring); } else DRM_ERROR("The master control interrupt lied (GT1)!\n"); } @@ -1688,11 +1699,13 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_device *dev, if (tmp) { I915_WRITE(GEN8_GT_IIR(3), tmp); ret = IRQ_HANDLED; + vcs = tmp >> GEN8_VECS_IRQ_SHIFT; + ring = &dev_priv->ring[VECS]; if (vcs & GT_RENDER_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[VECS]); + notify_ring(dev, ring); if (vcs & GT_CONTEXT_SWITCH_INTERRUPT) - DRM_DEBUG_DRIVER("TODO: Context switch\n"); + intel_execlists_handle_ctx_events(ring); } else DRM_ERROR("The master control interrupt lied (GT3)!\n"); } diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index e81f5f6c49b9..22f6a7c0cb18 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -49,6 +49,22 @@ #define RING_ELSP(ring) ((ring)->mmio_base+0x230) #define RING_EXECLIST_STATUS(ring) ((ring)->mmio_base+0x234) #define RING_CONTEXT_CONTROL(ring) ((ring)->mmio_base+0x244) +#define RING_CONTEXT_STATUS_BUF(ring) ((ring)->mmio_base+0x370) +#define RING_CONTEXT_STATUS_PTR(ring) ((ring)->mmio_base+0x3a0) + +#define RING_EXECLIST_QFULL (1 << 0x2) +#define RING_EXECLIST1_VALID (1 << 0x3) +#define RING_EXECLIST0_VALID (1 << 0x4) +#define RING_EXECLIST_ACTIVE_STATUS (3 << 0xE) +#define RING_EXECLIST1_ACTIVE (1 << 0x11) +#define RING_EXECLIST0_ACTIVE (1 << 0x12) + +#define GEN8_CTX_STATUS_IDLE_ACTIVE (1 << 0) +#define GEN8_CTX_STATUS_PREEMPTED (1 << 1) +#define GEN8_CTX_STATUS_ELEMENT_SWITCH (1 << 2) +#define GEN8_CTX_STATUS_ACTIVE_IDLE (1 << 3) +#define GEN8_CTX_STATUS_COMPLETE (1 << 4) +#define GEN8_CTX_STATUS_LITE_RESTORE (1 << 15) #define CTX_LRI_HEADER_0 0x01 #define CTX_CONTEXT_CONTROL 0x02 @@ -150,6 +166,7 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, struct drm_i915_private *dev_priv = ring->dev->dev_private; uint64_t temp = 0; uint32_t desc[4]; + unsigned long flags; /* XXX: You must always write both descriptors in the order below. */ if (ctx_obj1) @@ -163,9 +180,17 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, desc[3] = (u32)(temp >> 32); desc[2] = (u32)temp; - /* Set Force Wakeup bit to prevent GT from entering C6 while - * ELSP writes are in progress */ - gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL); + /* Set Force Wakeup bit to prevent GT from entering C6 while ELSP writes + * are in progress. + * + * The other problem is that we can't just call gen6_gt_force_wake_get() + * because that function calls intel_runtime_pm_get(), which might sleep. + * Instead, we do the runtime_pm_get/put when creating/destroying requests. + */ + spin_lock_irqsave(&dev_priv->uncore.lock, flags); + 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, flags); I915_WRITE(RING_ELSP(ring), desc[1]); I915_WRITE(RING_ELSP(ring), desc[0]); @@ -176,7 +201,11 @@ static void execlists_elsp_write(struct intel_engine_cs *ring, /* ELSP is a wo register, so use another nearby reg for posting instead */ POSTING_READ(RING_EXECLIST_STATUS(ring)); - gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL); + /* Release Force Wakeup (see the big comment above). */ + spin_lock_irqsave(&dev_priv->uncore.lock, flags); + 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, flags); } static int execlists_ctx_write_tail(struct drm_i915_gem_object *ctx_obj, u32 tail) @@ -224,6 +253,9 @@ 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); if (list_empty(&ring->execlist_queue)) return; @@ -237,8 +269,7 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) /* Same ctx: ignore first request, as second request * will update tail past first request's workload */ list_del(&req0->execlist_link); - i915_gem_context_unreference(req0->ctx); - kfree(req0); + queue_work(dev_priv->wq, &req0->work); req0 = cursor; } else { req1 = cursor; @@ -251,11 +282,97 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) req1 ? req1->tail : 0)); } +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); + + head_req = list_first_entry_or_null(&ring->execlist_queue, + struct intel_ctx_submit_request, + execlist_link); + + if (head_req != NULL) { + struct drm_i915_gem_object *ctx_obj = + head_req->ctx->engine[ring->id].state; + if (intel_execlists_ctx_id(ctx_obj) == request_id) { + list_del(&head_req->execlist_link); + queue_work(dev_priv->wq, &head_req->work); + return true; + } + } + + return false; +} + +void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring) +{ + struct drm_i915_private *dev_priv = ring->dev->dev_private; + u32 status_pointer; + u8 read_pointer; + u8 write_pointer; + u32 status; + u32 status_id; + u32 submit_contexts = 0; + + status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring)); + + read_pointer = ring->next_context_status_buffer; + write_pointer = status_pointer & 0x07; + if (read_pointer > write_pointer) + write_pointer += 6; + + spin_lock(&ring->execlist_lock); + + while (read_pointer < write_pointer) { + read_pointer++; + status = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + + (read_pointer % 6) * 8); + status_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + + (read_pointer % 6) * 8 + 4); + + if (status & GEN8_CTX_STATUS_COMPLETE) { + if (execlists_check_remove_request(ring, status_id)) + submit_contexts++; + } + } + + if (submit_contexts != 0) + execlists_context_unqueue(ring); + + spin_unlock(&ring->execlist_lock); + + WARN(submit_contexts > 2, "More than two context complete events?\n"); + ring->next_context_status_buffer = write_pointer % 6; + + I915_WRITE(RING_CONTEXT_STATUS_PTR(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) { struct intel_ctx_submit_request *req = NULL; + struct drm_i915_private *dev_priv = ring->dev->dev_private; unsigned long flags; bool was_empty; @@ -266,6 +383,9 @@ 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); spin_lock_irqsave(&ring->execlist_lock, flags); @@ -907,6 +1027,7 @@ static int logical_ring_init(struct drm_device *dev, struct intel_engine_cs *rin INIT_LIST_HEAD(&ring->execlist_queue); spin_lock_init(&ring->execlist_lock); + ring->next_context_status_buffer = 0; ret = intel_lr_context_deferred_create(dctx, ring); if (ret) diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 3c389b3a2b75..a3f135cf439e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -65,6 +65,9 @@ struct intel_ctx_submit_request { u32 tail; struct list_head execlist_link; + struct work_struct work; }; +void intel_execlists_handle_ctx_events(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 670262dabb6c..9cbf7b0ebc99 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -233,6 +233,7 @@ struct intel_engine_cs { /* Execlists */ spinlock_t execlist_lock; struct list_head execlist_queue; + u8 next_context_status_buffer; u32 irq_keep_mask; /* bitmask for interrupts that should not be masked */ int (*emit_request)(struct intel_ringbuffer *ringbuf); int (*emit_flush)(struct intel_ringbuffer *ringbuf, -- GitLab From e1fee72c2ea2e9c0c6e6743d32a6832f21337d6c Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:40 +0100 Subject: [PATCH 0436/9167] drm/i915/bdw: Avoid non-lite-restore preemptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the current Execlists feeding mechanism, full preemption is not supported yet: only lite-restores are allowed (this is: the GPU simply samples a new tail pointer for the context currently in execution). But we have identified an scenario in which a full preemption occurs: 1) We submit two contexts for execution (A & B). 2) The GPU finishes with the first one (A), switches to the second one (B) and informs us. 3) We submit B again (hoping to cause a lite restore) together with C, but in the time we spend writing to the ELSP, the GPU finishes B. 4) The GPU start executing B again (since we told it so). 5) We receive a B finished interrupt and, mistakenly, we submit C (again) and D, causing a full preemption of B. The race is avoided by keeping track of how many times a context has been submitted to the hardware and by better discriminating the received context switch interrupts: in the example, when we have submitted B twice, we won´t submit C and D as soon as we receive the notification that B is completed because we were expecting to get a LITE_RESTORE and we didn´t, so we know a second completion will be received shortly. Without this explicit checking, somehow, the batch buffer execution order gets messed with. This can be verified with the IGT test I sent together with the series. I don´t know the exact mechanism by which the pre-emption messes with the execution order but, since other people is working on the Scheduler + Preemption on Execlists, I didn´t try to fix it. In these series, only Lite Restores are supported (other kind of preemptions WARN). v2: elsp_submitted belongs in the new intel_ctx_submit_request. Several rebase changes. v3: Clarify how the race is avoided, as requested by Daniel. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Align function parameters ...] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 29 +++++++++++++++++++++++++---- drivers/gpu/drm/i915/intel_lrc.h | 2 ++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 22f6a7c0cb18..0f1b6b2b0f0e 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -268,6 +268,7 @@ static void execlists_context_unqueue(struct intel_engine_cs *ring) } else if (req0->ctx == cursor->ctx) { /* Same ctx: ignore first request, as second request * 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); req0 = cursor; @@ -277,9 +278,15 @@ 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)); + + req0->elsp_submitted++; + if (req1) + req1->elsp_submitted++; } static bool execlists_check_remove_request(struct intel_engine_cs *ring, @@ -298,9 +305,14 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, struct drm_i915_gem_object *ctx_obj = head_req->ctx->engine[ring->id].state; if (intel_execlists_ctx_id(ctx_obj) == request_id) { - list_del(&head_req->execlist_link); - queue_work(dev_priv->wq, &head_req->work); - return true; + WARN(head_req->elsp_submitted == 0, + "Never submitted head request\n"); + + if (--head_req->elsp_submitted <= 0) { + list_del(&head_req->execlist_link); + queue_work(dev_priv->wq, &head_req->work); + return true; + } } } @@ -333,7 +345,16 @@ void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring) status_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + (read_pointer % 6) * 8 + 4); - if (status & GEN8_CTX_STATUS_COMPLETE) { + if (status & GEN8_CTX_STATUS_PREEMPTED) { + if (status & GEN8_CTX_STATUS_LITE_RESTORE) { + if (execlists_check_remove_request(ring, status_id)) + WARN(1, "Lite Restored request removed from queue\n"); + } else + WARN(1, "Preemption without Lite Restore\n"); + } + + if ((status & GEN8_CTX_STATUS_ACTIVE_IDLE) || + (status & GEN8_CTX_STATUS_ELEMENT_SWITCH)) { if (execlists_check_remove_request(ring, status_id)) submit_contexts++; } diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index a3f135cf439e..331c6c2ba376 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -66,6 +66,8 @@ struct intel_ctx_submit_request { struct list_head execlist_link; struct work_struct work; + + int elsp_submitted; }; void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring); -- GitLab From f1ad5a1fd4127b3a5e21b8f5ef7f1921a5d3063e Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:41 +0100 Subject: [PATCH 0437/9167] drm/i915/bdw: Help out the ctx switch interrupt handler If we receive a storm of requests for the same context (see gem_storedw_loop_*) we might end up iterating over too many elements in interrupt time, looking for contexts to squash together. Instead, share the burden by giving more intelligence to the queue function. At most, the interrupt will iterate over three elements. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Checkpatch.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_lrc.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 0f1b6b2b0f0e..6f6c5a931faf 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -392,10 +392,10 @@ static int execlists_context_queue(struct intel_engine_cs *ring, struct intel_context *to, u32 tail) { - struct intel_ctx_submit_request *req = NULL; + struct intel_ctx_submit_request *req = NULL, *cursor; struct drm_i915_private *dev_priv = ring->dev->dev_private; unsigned long flags; - bool was_empty; + int num_elements = 0; req = kzalloc(sizeof(*req), GFP_KERNEL); if (req == NULL) @@ -410,9 +410,27 @@ static int execlists_context_queue(struct intel_engine_cs *ring, spin_lock_irqsave(&ring->execlist_lock, flags); - was_empty = list_empty(&ring->execlist_queue); + list_for_each_entry(cursor, &ring->execlist_queue, execlist_link) + if (++num_elements > 2) + break; + + if (num_elements > 2) { + struct intel_ctx_submit_request *tail_req; + + tail_req = list_last_entry(&ring->execlist_queue, + struct intel_ctx_submit_request, + execlist_link); + + if (to == tail_req->ctx) { + 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(&req->execlist_link, &ring->execlist_queue); - if (was_empty) + if (num_elements == 0) execlists_context_unqueue(ring); spin_unlock_irqrestore(&ring->execlist_lock, flags); -- GitLab From 4ed91096881449012b14b1e879f40b4a37533e0e Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 8 Aug 2014 20:27:01 +0200 Subject: [PATCH 0438/9167] drm/i915: Track cursor changes as frontbuffer tracking flushes We treat other plane updates in the same fashion. Spotted because Rodrigo kept reporting a bug in the PSR code where the frontbuffer was eternally stuck with a dirty cursor bit set. The psr testcase should have caught this, but that i-g-t is kaputt. Rodrigo is signed up to fix that. Cc: Rodrigo Vivi Tested-by-and-Reviewed-by: Rodrigo Vivi 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 fd15601f6360..b2e4eac7b70b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -11782,6 +11782,10 @@ intel_cursor_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, return intel_crtc_cursor_set_obj(crtc, obj, crtc_w, crtc_h); } else { intel_crtc_update_cursor(crtc, visible); + + intel_frontbuffer_flip(crtc->dev, + INTEL_FRONTBUFFER_CURSOR(intel_crtc->pipe)); + return 0; } } -- GitLab From a74a8c846fb699f3277c0c21278bd4c414074b4a Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 22 Jul 2014 14:50:47 +0200 Subject: [PATCH 0439/9167] mac80211: don't duplicate station QoS capability data We currently track the QoS capability twice: for all peer stations in the WLAN_STA_WME flag, and for any clients associated to an AP interface separately for drivers in the sta->sta.wme field. Remove the WLAN_STA_WME flag and track the capability only in the driver-visible field, getting rid of the limitation that the field is only valid in AP mode. Reviewed-by: Arik Nemtsov Signed-off-by: Johannes Berg --- include/net/mac80211.h | 2 +- net/mac80211/cfg.c | 13 +++---------- net/mac80211/debugfs_sta.c | 3 ++- net/mac80211/ibss.c | 2 +- net/mac80211/mesh_plink.c | 4 +--- net/mac80211/mlme.c | 3 +-- net/mac80211/sta_info.c | 4 ++-- net/mac80211/sta_info.h | 2 -- net/mac80211/tdls.c | 3 +-- net/mac80211/tx.c | 6 +++--- net/mac80211/wme.c | 4 ++-- 11 files changed, 17 insertions(+), 29 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index dae2e24616e1..1cd84444665c 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1405,7 +1405,7 @@ struct ieee80211_sta_rates { * @supp_rates: Bitmap of supported rates (per band) * @ht_cap: HT capabilities of this STA; restricted to our own capabilities * @vht_cap: VHT capabilities of this STA; restricted to our own capabilities - * @wme: indicates whether the STA supports WME. Only valid during AP-mode. + * @wme: indicates whether the STA supports QoS/WME. * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *), size is determined in hw information. * @uapsd_queues: bitmap of queues configured for uapsd. Only valid diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 927b4ea0128b..4d8989b87960 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1011,15 +1011,8 @@ static int sta_apply_parameters(struct ieee80211_local *local, clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); } - if (mask & BIT(NL80211_STA_FLAG_WME)) { - if (set & BIT(NL80211_STA_FLAG_WME)) { - set_sta_flag(sta, WLAN_STA_WME); - sta->sta.wme = true; - } else { - clear_sta_flag(sta, WLAN_STA_WME); - sta->sta.wme = false; - } - } + if (mask & BIT(NL80211_STA_FLAG_WME)) + sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME); if (mask & BIT(NL80211_STA_FLAG_MFP)) { if (set & BIT(NL80211_STA_FLAG_MFP)) @@ -3352,7 +3345,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, band = chanctx_conf->def.chan->band; sta = sta_info_get_bss(sdata, peer); if (sta) { - qos = test_sta_flag(sta, WLAN_STA_WME); + qos = sta->sta.wme; } else { rcu_read_unlock(); return -ENOLINK; diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 3db96648b45a..4a20fb8f1e23 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -77,7 +77,8 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, TEST(AUTH), TEST(ASSOC), TEST(PS_STA), TEST(PS_DRIVER), TEST(AUTHORIZED), TEST(SHORT_PREAMBLE), - TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), + sta->sta.wme ? "WME\n" : "", + 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), diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 9713dc54ea4b..5f9654d31a8d 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -1038,7 +1038,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, } if (sta && elems->wmm_info) - set_sta_flag(sta, WLAN_STA_WME); + sta->sta.wme = true; if (sta && elems->ht_operation && elems->ht_cap_elem && sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 63b874101b27..8d67c1ebfbda 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c @@ -431,14 +431,12 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr) return NULL; sta->plink_state = NL80211_PLINK_LISTEN; + sta->sta.wme = true; sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); - set_sta_flag(sta, WLAN_STA_WME); - sta->sta.wme = true; - return sta; } diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 31a8afaf7332..0e8d59a0e17e 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2677,8 +2677,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) set_sta_flag(sta, WLAN_STA_MFP); - if (elems.wmm_param) - set_sta_flag(sta, WLAN_STA_WME); + sta->sta.wme = elems.wmm_param; err = sta_info_move_state(sta, IEEE80211_STA_ASSOC); if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index c6ee2139fbc5..e1f957d5935e 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -1179,7 +1179,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb; int size = sizeof(*nullfunc); __le16 fc; - bool qos = test_sta_flag(sta, WLAN_STA_WME); + bool qos = sta->sta.wme; struct ieee80211_tx_info *info; struct ieee80211_chanctx_conf *chanctx_conf; @@ -1834,7 +1834,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); - if (test_sta_flag(sta, WLAN_STA_WME)) + if (sta->sta.wme) sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); if (test_sta_flag(sta, WLAN_STA_MFP)) sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index d411bcc8ef08..89c40d5c0633 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h @@ -31,7 +31,6 @@ * when virtual port control is not in use. * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble * frames. - * @WLAN_STA_WME: Station is a QoS-STA. * @WLAN_STA_WDS: Station is one of our WDS peers. * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next @@ -69,7 +68,6 @@ enum ieee80211_sta_info_flags { WLAN_STA_PS_STA, WLAN_STA_AUTHORIZED, WLAN_STA_SHORT_PREAMBLE, - WLAN_STA_WME, WLAN_STA_WDS, WLAN_STA_CLEAR_PS_FILT, WLAN_STA_MFP, diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 1b21050be174..f2cb3b6c1871 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -316,8 +316,7 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata, } /* add the QoS param IE if both the peer and we support it */ - if (local->hw.queues >= IEEE80211_NUM_ACS && - test_sta_flag(sta, WLAN_STA_WME)) + if (local->hw.queues >= IEEE80211_NUM_ACS && sta->sta.wme) ieee80211_tdls_add_wmm_param_ie(sdata, skb); /* add any custom IEs that go before HT operation */ diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 464106c023d8..2051cc60f8ce 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1844,7 +1844,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); hdrlen = 30; authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); - wme_sta = test_sta_flag(sta, WLAN_STA_WME); + wme_sta = sta->sta.wme; } ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); @@ -1957,7 +1957,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, if (sta) { authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); - wme_sta = test_sta_flag(sta, WLAN_STA_WME); + wme_sta = sta->sta.wme; tdls_peer = test_sta_flag(sta, WLAN_STA_TDLS_PEER); tdls_auth = test_sta_flag(sta, @@ -2035,7 +2035,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, sta = sta_info_get(sdata, hdr.addr1); if (sta) { authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); - wme_sta = test_sta_flag(sta, WLAN_STA_WME); + wme_sta = sta->sta.wme; } } diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index d51422c778de..6459946f0b74 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c @@ -118,7 +118,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, case NL80211_IFTYPE_AP_VLAN: sta = rcu_dereference(sdata->u.vlan.sta); if (sta) { - qos = test_sta_flag(sta, WLAN_STA_WME); + qos = sta->sta.wme; break; } case NL80211_IFTYPE_AP: @@ -145,7 +145,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, if (!sta && ra && !is_multicast_ether_addr(ra)) { sta = sta_info_get(sdata, ra); if (sta) - qos = test_sta_flag(sta, WLAN_STA_WME); + qos = sta->sta.wme; } rcu_read_unlock(); -- GitLab From 53b954ee4a71e782d7dfcdeee5bf4695caeeb112 Mon Sep 17 00:00:00 2001 From: Eliad Peller Date: Thu, 24 Jul 2014 11:20:05 +0300 Subject: [PATCH 0440/9167] mac80211: disable 40MHz support in case of 20MHz AP If the AP only advertises support for 20MHz (in the ht operation ie), disable 40MHz and VHT. This can improve interoperability with APs that don't like stations exceeding their own advertised capabilities. Signed-off-by: Eliad Peller Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0e8d59a0e17e..29fe91d6a094 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -149,6 +149,7 @@ static u32 ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, struct ieee80211_supported_band *sband, struct ieee80211_channel *channel, + const struct ieee80211_ht_cap *ht_cap, const struct ieee80211_ht_operation *ht_oper, const struct ieee80211_vht_operation *vht_oper, struct cfg80211_chan_def *chandef, bool tracking) @@ -162,13 +163,19 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, chandef->center_freq1 = channel->center_freq; chandef->center_freq2 = 0; - if (!ht_oper || !sband->ht_cap.ht_supported) { + if (!ht_cap || !ht_oper || !sband->ht_cap.ht_supported) { ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; goto out; } chandef->width = NL80211_CHAN_WIDTH_20; + if (!(ht_cap->cap_info & + cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40))) { + ret = IEEE80211_STA_DISABLE_40MHZ | IEEE80211_STA_DISABLE_VHT; + goto out; + } + ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan, channel->band); /* check that channel matches the right operating channel */ @@ -328,6 +335,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, + const struct ieee80211_ht_cap *ht_cap, const struct ieee80211_ht_operation *ht_oper, const struct ieee80211_vht_operation *vht_oper, const u8 *bssid, u32 *changed) @@ -367,8 +375,9 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, sband = local->hw.wiphy->bands[chan->band]; /* calculate new channel (type) based on HT/VHT operation IEs */ - flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper, - vht_oper, &chandef, true); + flags = ieee80211_determine_chantype(sdata, sband, chan, + ht_cap, ht_oper, vht_oper, + &chandef, true); /* * Downgrade the new channel if we associated with restricted @@ -3173,7 +3182,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, mutex_lock(&local->sta_mtx); sta = sta_info_get(sdata, bssid); - if (ieee80211_config_bw(sdata, sta, elems.ht_operation, + if (ieee80211_config_bw(sdata, sta, + elems.ht_cap_elem, elems.ht_operation, elems.vht_operation, bssid, &changed)) { mutex_unlock(&local->sta_mtx); ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, @@ -3807,6 +3817,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; + const struct ieee80211_ht_cap *ht_cap = NULL; const struct ieee80211_ht_operation *ht_oper = NULL; const struct ieee80211_vht_operation *vht_oper = NULL; struct ieee80211_supported_band *sband; @@ -3823,14 +3834,17 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && sband->ht_cap.ht_supported) { - const u8 *ht_oper_ie, *ht_cap; + const u8 *ht_oper_ie, *ht_cap_ie; ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION); if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) ht_oper = (void *)(ht_oper_ie + 2); - ht_cap = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY); - if (!ht_cap || ht_cap[1] < sizeof(struct ieee80211_ht_cap)) { + ht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY); + if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) + ht_cap = (void *)(ht_cap_ie + 2); + + if (!ht_cap) { ifmgd->flags |= IEEE80211_STA_DISABLE_HT; ht_oper = NULL; } @@ -3861,7 +3875,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, ifmgd->flags |= ieee80211_determine_chantype(sdata, sband, cbss->channel, - ht_oper, vht_oper, + ht_cap, ht_oper, vht_oper, &chandef, false); sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss), -- GitLab From 92561cb7883194714475c7a7775a11a9c40f75cb Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Fri, 15 Aug 2014 01:44:32 +0000 Subject: [PATCH 0441/9167] perf probe: Warn user to rebuild target with debuginfo Warn user to rebuild target with debuginfo when the perf probe fails to find debug information in the target binary. Without this, perf probe just reports the failure, but it's no hint for users. This gives more hint for users. Without this: $ strip perf $ ./perf probe -x perf -L argv_split Failed to open debuginfo file. Error: Failed to show lines. With this: $ strip perf $ ./perf probe -x perf -L argv_split The /home/fedora/ksrc/linux-3/tools/perf/perf file has no debug information. Rebuild with -g, or install an appropriate debuginfo package. Error: Failed to show lines. The "rebuild with ..." part changes to "rebuild with CONFIG_DEBUG_INFO" if the target is the kernel or a kernel module. Suggested-by: Arnaldo Carvalho de Melo Signed-off-by: Masami Hiramatsu Cc: Brendan Gregg Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: yrl.pp-manager.tt@hitachi.com Link: http://lkml.kernel.org/r/20140815014432.29869.57941.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-event.c | 41 ++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 784ea42ad8cb..ac15ff780009 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -258,21 +258,33 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) #ifdef HAVE_DWARF_SUPPORT /* Open new debuginfo of given module */ -static struct debuginfo *open_debuginfo(const char *module) +static struct debuginfo *open_debuginfo(const char *module, bool silent) { const char *path = module; + struct debuginfo *ret; if (!module || !strchr(module, '/')) { path = kernel_get_module_path(module); if (!path) { - pr_err("Failed to find path of %s module.\n", - module ?: "kernel"); + if (!silent) + pr_err("Failed to find path of %s module.\n", + module ?: "kernel"); return NULL; } } - return debuginfo__new(path); + ret = debuginfo__new(path); + if (!ret && !silent) { + pr_warning("The %s file has no debug information.\n", path); + if (!module || !strtailcmp(path, ".ko")) + pr_warning("Rebuild with CONFIG_DEBUG_INFO=y, "); + else + pr_warning("Rebuild with -g, "); + pr_warning("or install an appropriate debuginfo package.\n"); + } + return ret; } + static int get_text_start_address(const char *exec, unsigned long *address) { Elf *elf; @@ -333,15 +345,13 @@ static int find_perf_probe_point_from_dwarf(struct probe_trace_point *tp, pr_debug("try to find information at %" PRIx64 " in %s\n", addr, tp->module ? : "kernel"); - dinfo = open_debuginfo(tp->module); + dinfo = open_debuginfo(tp->module, verbose == 0); if (dinfo) { ret = debuginfo__find_probe_point(dinfo, (unsigned long)addr, pp); debuginfo__delete(dinfo); - } else { - pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n", addr); + } else ret = -ENOENT; - } if (ret > 0) { pp->retprobe = tp->retprobe; @@ -457,13 +467,11 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev, struct debuginfo *dinfo; int ntevs, ret = 0; - dinfo = open_debuginfo(target); + dinfo = open_debuginfo(target, !need_dwarf); if (!dinfo) { - if (need_dwarf) { - pr_warning("Failed to open debuginfo file.\n"); + if (need_dwarf) return -ENOENT; - } pr_debug("Could not open debuginfo. Try to use symbols.\n"); return 0; } @@ -620,11 +628,9 @@ static int __show_line_range(struct line_range *lr, const char *module) char *tmp; /* Search a line range */ - dinfo = open_debuginfo(module); - if (!dinfo) { - pr_warning("Failed to open debuginfo file.\n"); + dinfo = open_debuginfo(module, false); + if (!dinfo) return -ENOENT; - } ret = debuginfo__find_line_range(dinfo, lr); debuginfo__delete(dinfo); @@ -772,9 +778,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, if (ret < 0) return ret; - dinfo = open_debuginfo(module); + dinfo = open_debuginfo(module, false); if (!dinfo) { - pr_warning("Failed to open debuginfo file.\n"); ret = -ENOENT; goto out; } -- GitLab From 1e2bb043f171084e5f34816a4268304512d35a46 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 14 Aug 2014 14:03:00 -0700 Subject: [PATCH 0442/9167] perf annotate: Don't truncate Intel style addresses Instructions like "mov r9,QWORD PTR [rdx+0x8]" were being truncated to "mov r9,QWORD" by code that assuemd operands cannot have spaces. Signed-off-by: Alex Converse Cc: Adrian Hunter Cc: Andi Kleen Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1408050180-14088-1-git-send-email-aconverse@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/annotate.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 7745fec01a6b..36437527dbb3 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -232,9 +232,16 @@ static int mov__parse(struct ins_operands *ops) return -1; target = ++s; + comment = strchr(s, '#'); - while (s[0] != '\0' && !isspace(s[0])) - ++s; + if (comment != NULL) + s = comment - 1; + else + s = strchr(s, '\0') - 1; + + while (s > target && isspace(s[0])) + --s; + s++; prev = *s; *s = '\0'; @@ -244,7 +251,6 @@ static int mov__parse(struct ins_operands *ops) if (ops->target.raw == NULL) goto out_free_source; - comment = strchr(s, '#'); if (comment == NULL) return 0; -- GitLab From c4d2df495c5bf05661772abf9b88f2696fd810c4 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Thu, 14 Aug 2014 12:39:20 -0700 Subject: [PATCH 0443/9167] perf tools: Add arm64 triplets Adds the triplet used for arm64 by Android. Others will want to add their own later. Signed-off-by: Elliott Hughes Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814193920.A7D2D20572@enh.mtv.corp.google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/common.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/perf/arch/common.c b/tools/perf/arch/common.c index 42faf369211c..49776f190abf 100644 --- a/tools/perf/arch/common.c +++ b/tools/perf/arch/common.c @@ -12,6 +12,11 @@ const char *const arm_triplets[] = { NULL }; +const char *const arm64_triplets[] = { + "aarch64-linux-android-", + NULL +}; + const char *const powerpc_triplets[] = { "powerpc-unknown-linux-gnu-", "powerpc64-unknown-linux-gnu-", @@ -105,6 +110,8 @@ static const char *normalize_arch(char *arch) return "x86"; if (!strcmp(arch, "sun4u") || !strncmp(arch, "sparc", 5)) return "sparc"; + if (!strcmp(arch, "aarch64") || !strcmp(arch, "arm64")) + return "arm64"; if (!strncmp(arch, "arm", 3) || !strcmp(arch, "sa110")) return "arm"; if (!strncmp(arch, "s390", 4)) @@ -159,6 +166,8 @@ static int perf_session_env__lookup_binutils_path(struct perf_session_env *env, if (!strcmp(arch, "arm")) path_list = arm_triplets; + else if (!strcmp(arch, "arm64")) + path_list = arm64_triplets; else if (!strcmp(arch, "powerpc")) path_list = powerpc_triplets; else if (!strcmp(arch, "sh")) -- GitLab From 885b5930d6632fc7df55445d9021b87d8bb17a9b Mon Sep 17 00:00:00 2001 From: Cody P Schafer Date: Fri, 15 Aug 2014 00:26:14 -0700 Subject: [PATCH 0444/9167] perf tools: Annotate PMU related list_head members with type info So that we can more readily understand in which list heads structs are stored into. Signed-off-by: Cody P Schafer Cc: Andi Kleen Cc: Anshuman Khandual Cc: Cody P Schafer Cc: Haren Myneni Cc: Jiri Olsa Cc: Michael Ellerman Cc: Peter Zijlstra Cc: Stephane Eranian Cc: linuxppc-dev@lists.ozlabs.org Link: http://lkml.kernel.org/r/1408087583-32239-6-git-send-email-sukadev@linux.vnet.ibm.com Signed-off-by: Sukadev Bhattiprolu Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/pmu.c | 4 ++-- tools/perf/util/pmu.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 7a811eb61f75..9bf582750561 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -14,8 +14,8 @@ struct perf_pmu_alias { char *name; - struct list_head terms; - struct list_head list; + struct list_head terms; /* HEAD struct parse_events_term -> list */ + struct list_head list; /* ELEM */ char unit[UNIT_MAX_LEN+1]; double scale; }; diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index c14a543ce1f3..1c1e2eecbe1f 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -17,9 +17,9 @@ struct perf_pmu { char *name; __u32 type; struct cpu_map *cpus; - struct list_head format; - struct list_head aliases; - struct list_head list; + struct list_head format; /* HEAD struct perf_pmu_format -> list */ + struct list_head aliases; /* HEAD struct perf_pmu_alias -> list */ + struct list_head list; /* ELEM */ }; struct perf_pmu *perf_pmu__find(const char *name); -- GitLab From e8232f1ad4682c34e7e774c212ccd0c15bb5aa26 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 14 Aug 2014 15:01:38 +0900 Subject: [PATCH 0445/9167] perf report: Relax -g option parsing not to limit the option order Current perf report -g/--call-graph option parser requires for option argument having following order: type,min_percent[,print_limit],order,key But sometimes it's annoying to type all even if one just wants to change the "order" or "key" setting. This patch fixes it to remove the ordering restriction so that one can use just "-g caller", for instance. The only remaining restriction is that the "print_limit" always comes after the "min_percent". Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: Arun Sharma Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Rodrigo Campos Link: http://lkml.kernel.org/r/1407996100-6359-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/callchain.c | 95 +++++++++++++++---------------------- 1 file changed, 38 insertions(+), 57 deletions(-) diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 437ee09727e6..08f0fbf5527c 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -28,74 +28,55 @@ __thread struct callchain_cursor callchain_cursor; int parse_callchain_report_opt(const char *arg) { - char *tok, *tok2; + char *tok; char *endptr; + bool minpcnt_set = false; symbol_conf.use_callchain = true; if (!arg) return 0; - tok = strtok((char *)arg, ","); - if (!tok) - return -1; - - /* get the output mode */ - if (!strncmp(tok, "graph", strlen(arg))) { - callchain_param.mode = CHAIN_GRAPH_ABS; - - } else if (!strncmp(tok, "flat", strlen(arg))) { - callchain_param.mode = CHAIN_FLAT; - } else if (!strncmp(tok, "fractal", strlen(arg))) { - callchain_param.mode = CHAIN_GRAPH_REL; - } else if (!strncmp(tok, "none", strlen(arg))) { - callchain_param.mode = CHAIN_NONE; - symbol_conf.use_callchain = false; - return 0; - } else { - return -1; - } - - /* get the min percentage */ - tok = strtok(NULL, ","); - if (!tok) - goto setup; - - callchain_param.min_percent = strtod(tok, &endptr); - if (tok == endptr) - return -1; + while ((tok = strtok((char *)arg, ",")) != NULL) { + if (!strncmp(tok, "none", strlen(tok))) { + callchain_param.mode = CHAIN_NONE; + symbol_conf.use_callchain = false; + return 0; + } - /* get the print limit */ - tok2 = strtok(NULL, ","); - if (!tok2) - goto setup; + /* try to get the output mode */ + if (!strncmp(tok, "graph", strlen(tok))) + callchain_param.mode = CHAIN_GRAPH_ABS; + else if (!strncmp(tok, "flat", strlen(tok))) + callchain_param.mode = CHAIN_FLAT; + else if (!strncmp(tok, "fractal", strlen(tok))) + callchain_param.mode = CHAIN_GRAPH_REL; + /* try to get the call chain order */ + else if (!strncmp(tok, "caller", strlen(tok))) + callchain_param.order = ORDER_CALLER; + else if (!strncmp(tok, "callee", strlen(tok))) + callchain_param.order = ORDER_CALLEE; + /* try to get the sort key */ + else if (!strncmp(tok, "function", strlen(tok))) + callchain_param.key = CCKEY_FUNCTION; + else if (!strncmp(tok, "address", strlen(tok))) + callchain_param.key = CCKEY_ADDRESS; + /* try to get the min percent */ + else if (!minpcnt_set) { + callchain_param.min_percent = strtod(tok, &endptr); + if (tok == endptr) + return -1; + minpcnt_set = true; + } else { + /* try print limit at last */ + callchain_param.print_limit = strtoul(tok, &endptr, 0); + if (tok == endptr) + return -1; + } - if (tok2[0] != 'c') { - callchain_param.print_limit = strtoul(tok2, &endptr, 0); - tok2 = strtok(NULL, ","); - if (!tok2) - goto setup; + arg = NULL; } - /* get the call chain order */ - if (!strncmp(tok2, "caller", strlen("caller"))) - callchain_param.order = ORDER_CALLER; - else if (!strncmp(tok2, "callee", strlen("callee"))) - callchain_param.order = ORDER_CALLEE; - else - return -1; - - /* Get the sort key */ - tok2 = strtok(NULL, ","); - if (!tok2) - goto setup; - if (!strncmp(tok2, "function", strlen("function"))) - callchain_param.key = CCKEY_FUNCTION; - else if (!strncmp(tok2, "address", strlen("address"))) - callchain_param.key = CCKEY_ADDRESS; - else - return -1; -setup: if (callchain_register_param(&callchain_param) < 0) { pr_err("Can't register callchain params\n"); return -1; -- GitLab From 6eb08660962a91212902869672dab5199827cbfd Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:30 +0000 Subject: [PATCH 0446/9167] perf probe: Don't use strerror if strlist__add failed Since the strlist__add doesn't involves any IO, the failure reason must be ENOMEM or EINVAL, moreover this is just a debug message, we don't need to show the error string. And also, if get_probe_trace_command_rawlist() returns NULL, it doesn't mean the rawlist is empty, there is an error. So caller must use -ENOMEM for the error. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022230.3545.99254.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-event.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index ac15ff780009..bf39c23b275d 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1881,7 +1881,7 @@ static struct strlist *get_probe_trace_command_rawlist(int fd) p[idx] = '\0'; ret = strlist__add(sl, buf); if (ret < 0) { - pr_debug("strlist__add failed: %s\n", strerror(-ret)); + pr_debug("strlist__add failed (%d)\n", ret); strlist__delete(sl); return NULL; } @@ -1940,7 +1940,7 @@ static int __show_perf_probe_events(int fd, bool is_kprobe) rawlist = get_probe_trace_command_rawlist(fd); if (!rawlist) - return -ENOENT; + return -ENOMEM; strlist__for_each(ent, rawlist) { ret = parse_probe_trace_command(ent->s, &tev); @@ -2007,6 +2007,8 @@ static struct strlist *get_probe_trace_event_names(int fd, bool include_group) memset(&tev, 0, sizeof(tev)); rawlist = get_probe_trace_command_rawlist(fd); + if (!rawlist) + return NULL; sl = strlist__new(true, NULL); strlist__for_each(ent, rawlist) { ret = parse_probe_trace_command(ent->s, &tev); -- GitLab From b2348e1d8a67c58de44820587fabc4f987eafbb6 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:32 +0000 Subject: [PATCH 0447/9167] perf: Use strerror_r instead of strerror Use strerror_r instead of strerror in error messages for thread-safety. This also introduce STRERR_BUFSIZE macro for the default size of message buffer for strerror_r. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022232.3545.14026.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.c | 10 +++++++--- tools/perf/util/debug.h | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 2282d41879a2..452a8474d29d 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -313,6 +313,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) int status; struct stat st; const char *prefix; + char sbuf[STRERR_BUFSIZE]; prefix = NULL; if (p->option & RUN_SETUP) @@ -343,7 +344,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) status = 1; /* Check for ENOSPC and EIO errors.. */ if (fflush(stdout)) { - fprintf(stderr, "write failure on standard output: %s", strerror(errno)); + fprintf(stderr, "write failure on standard output: %s", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out; } if (ferror(stdout)) { @@ -351,7 +353,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) goto out; } if (fclose(stdout)) { - fprintf(stderr, "close failed on standard output: %s", strerror(errno)); + fprintf(stderr, "close failed on standard output: %s", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out; } status = 0; @@ -466,6 +469,7 @@ void pthread__unblock_sigwinch(void) int main(int argc, const char **argv) { const char *cmd; + char sbuf[STRERR_BUFSIZE]; /* The page_size is placed in util object. */ page_size = sysconf(_SC_PAGE_SIZE); @@ -561,7 +565,7 @@ int main(int argc, const char **argv) } fprintf(stderr, "Failed to run command '%s': %s\n", - cmd, strerror(errno)); + cmd, strerror_r(errno, sbuf, sizeof(sbuf))); out: return 1; } diff --git a/tools/perf/util/debug.h b/tools/perf/util/debug.h index 6944ea3a119b..be264d6f3b30 100644 --- a/tools/perf/util/debug.h +++ b/tools/perf/util/debug.h @@ -3,6 +3,7 @@ #define __PERF_DEBUG_H #include +#include #include "event.h" #include "../ui/helpline.h" #include "../ui/progress.h" @@ -36,6 +37,8 @@ extern int debug_ordered_events; #define pr_oe_time(t, fmt, ...) pr_time_N(1, debug_ordered_events, t, pr_fmt(fmt), ##__VA_ARGS__) #define pr_oe_time2(t, fmt, ...) pr_time_N(2, debug_ordered_events, t, pr_fmt(fmt), ##__VA_ARGS__) +#define STRERR_BUFSIZE 128 /* For the buffer size of strerror_r */ + int dump_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void trace_event(union perf_event *event); -- GitLab From 5f03cba41590b5e7db5b66d2b2aa3e146ff8a84f Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:34 +0000 Subject: [PATCH 0448/9167] perf probe: Make error messages thread-safe To make error messages thread-safe, this replaces strerror with strerror_r for warnings, and just shows the return value instead of using strerror for debug messages. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022234.3545.22199.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-probe.c | 5 ++++- tools/perf/util/probe-event.c | 28 +++++++++++++++------------- tools/perf/util/probe-finder.c | 7 +++++-- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index c63fa2925075..347729e29a92 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -290,8 +290,11 @@ static void cleanup_params(void) static void pr_err_with_code(const char *msg, int err) { + char sbuf[STRERR_BUFSIZE]; + pr_err("%s", msg); - pr_debug(" Reason: %s (Code: %d)", strerror(-err), err); + pr_debug(" Reason: %s (Code: %d)", + strerror_r(-err, sbuf, sizeof(sbuf)), err); pr_err("\n"); } diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index bf39c23b275d..f73595fc0627 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -573,7 +573,7 @@ static int get_real_path(const char *raw_path, const char *comp_dir, static int __show_one_line(FILE *fp, int l, bool skip, bool show_num) { - char buf[LINEBUF_SIZE]; + char buf[LINEBUF_SIZE], sbuf[STRERR_BUFSIZE]; const char *color = show_num ? "" : PERF_COLOR_BLUE; const char *prefix = NULL; @@ -593,7 +593,8 @@ static int __show_one_line(FILE *fp, int l, bool skip, bool show_num) return 1; error: if (ferror(fp)) { - pr_warning("File read error: %s\n", strerror(errno)); + pr_warning("File read error: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); return -1; } return 0; @@ -626,6 +627,7 @@ static int __show_line_range(struct line_range *lr, const char *module) FILE *fp; int ret; char *tmp; + char sbuf[STRERR_BUFSIZE]; /* Search a line range */ dinfo = open_debuginfo(module, false); @@ -662,7 +664,7 @@ static int __show_line_range(struct line_range *lr, const char *module) fp = fopen(lr->path, "r"); if (fp == NULL) { pr_warning("Failed to open %s: %s\n", lr->path, - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); return -errno; } /* Skip to starting line number */ @@ -1410,8 +1412,7 @@ int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len) return tmp - buf; error: - pr_debug("Failed to synthesize perf probe argument: %s\n", - strerror(-ret)); + pr_debug("Failed to synthesize perf probe argument: %d\n", ret); return ret; } @@ -1460,8 +1461,7 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp) return buf; error: - pr_debug("Failed to synthesize perf probe point: %s\n", - strerror(-ret)); + pr_debug("Failed to synthesize perf probe point: %d\n", ret); free(buf); return NULL; } @@ -1787,7 +1787,7 @@ static void clear_probe_trace_event(struct probe_trace_event *tev) static void print_open_warning(int err, bool is_kprobe) { - char sbuf[128]; + char sbuf[STRERR_BUFSIZE]; if (err == -ENOENT) { const char *config; @@ -1817,7 +1817,7 @@ static void print_both_open_warning(int kerr, int uerr) pr_warning("Please rebuild kernel with CONFIG_KPROBE_EVENTS " "or/and CONFIG_UPROBE_EVENTS.\n"); else { - char sbuf[128]; + char sbuf[STRERR_BUFSIZE]; pr_warning("Failed to open kprobe events: %s.\n", strerror_r(-kerr, sbuf, sizeof(sbuf))); pr_warning("Failed to open uprobe events: %s.\n", @@ -2038,6 +2038,7 @@ static int write_probe_trace_event(int fd, struct probe_trace_event *tev) { int ret = 0; char *buf = synthesize_probe_trace_command(tev); + char sbuf[STRERR_BUFSIZE]; if (!buf) { pr_debug("Failed to synthesize probe trace event.\n"); @@ -2049,7 +2050,7 @@ static int write_probe_trace_event(int fd, struct probe_trace_event *tev) ret = write(fd, buf, strlen(buf)); if (ret <= 0) pr_warning("Failed to write event: %s\n", - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); } free(buf); return ret; @@ -2063,7 +2064,7 @@ static int get_new_event_name(char *buf, size_t len, const char *base, /* Try no suffix */ ret = e_snprintf(buf, len, "%s", base); if (ret < 0) { - pr_debug("snprintf() failed: %s\n", strerror(-ret)); + pr_debug("snprintf() failed: %d\n", ret); return ret; } if (!strlist__has_entry(namelist, buf)) @@ -2079,7 +2080,7 @@ static int get_new_event_name(char *buf, size_t len, const char *base, for (i = 1; i < MAX_EVENT_INDEX; i++) { ret = e_snprintf(buf, len, "%s_%d", base, i); if (ret < 0) { - pr_debug("snprintf() failed: %s\n", strerror(-ret)); + pr_debug("snprintf() failed: %d\n", ret); return ret; } if (!strlist__has_entry(namelist, buf)) @@ -2444,7 +2445,8 @@ static int __del_trace_probe_event(int fd, struct str_node *ent) printf("Removed event: %s\n", ent->s); return 0; error: - pr_warning("Failed to delete event: %s\n", strerror(-ret)); + pr_warning("Failed to delete event: %s\n", + strerror_r(-ret, buf, sizeof(buf))); return ret; } diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index dca9145d704c..9c593561aa71 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -281,6 +281,7 @@ static int convert_variable_type(Dwarf_Die *vr_die, struct probe_trace_arg_ref **ref_ptr = &tvar->ref; Dwarf_Die type; char buf[16]; + char sbuf[STRERR_BUFSIZE]; int bsize, boffs, total; int ret; @@ -367,7 +368,7 @@ static int convert_variable_type(Dwarf_Die *vr_die, if (ret >= 16) ret = -E2BIG; pr_warning("Failed to convert variable type: %s\n", - strerror(-ret)); + strerror_r(-ret, sbuf, sizeof(sbuf))); return ret; } tvar->type = strdup(buf); @@ -779,10 +780,12 @@ static int find_lazy_match_lines(struct intlist *list, size_t line_len; ssize_t len; int count = 0, linenum = 1; + char sbuf[STRERR_BUFSIZE]; fp = fopen(fname, "r"); if (!fp) { - pr_warning("Failed to open %s: %s\n", fname, strerror(errno)); + pr_warning("Failed to open %s: %s\n", fname, + strerror_r(errno, sbuf, sizeof(sbuf))); return -errno; } -- GitLab From 6e81c74cbf4b64620170da14844f1dc8a9a5950f Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:36 +0000 Subject: [PATCH 0449/9167] perf util: Replace strerror with strerror_r for thread-safety Replaces all strerror with strerror_r in util for making the perf lib thread-safe. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022236.3545.3367.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/cloexec.c | 6 ++++-- tools/perf/util/data.c | 8 ++++++-- tools/perf/util/dso.c | 8 ++++++-- tools/perf/util/evlist.c | 2 +- tools/perf/util/evsel.c | 7 +++++-- tools/perf/util/parse-events.c | 5 ++++- tools/perf/util/run-command.c | 9 +++++++-- tools/perf/util/util.c | 5 +++-- 8 files changed, 36 insertions(+), 14 deletions(-) diff --git a/tools/perf/util/cloexec.c b/tools/perf/util/cloexec.c index 4945aa56a017..47b78b3f0325 100644 --- a/tools/perf/util/cloexec.c +++ b/tools/perf/util/cloexec.c @@ -3,6 +3,7 @@ #include "../perf.h" #include "cloexec.h" #include "asm/bug.h" +#include "debug.h" static unsigned long flag = PERF_FLAG_FD_CLOEXEC; @@ -18,6 +19,7 @@ static int perf_flag_probe(void) int err; int cpu; pid_t pid = -1; + char sbuf[STRERR_BUFSIZE]; cpu = sched_getcpu(); if (cpu < 0) @@ -42,7 +44,7 @@ static int perf_flag_probe(void) WARN_ONCE(err != EINVAL && err != EBUSY, "perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n", - err, strerror(err)); + err, strerror_r(err, sbuf, sizeof(sbuf))); /* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */ fd = sys_perf_event_open(&attr, pid, cpu, -1, 0); @@ -50,7 +52,7 @@ static int perf_flag_probe(void) if (WARN_ONCE(fd < 0 && err != EBUSY, "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n", - err, strerror(err))) + err, strerror_r(err, sbuf, sizeof(sbuf)))) return -1; close(fd); diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 29d720cf5844..1921942fc2e0 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -50,12 +50,14 @@ static int open_file_read(struct perf_data_file *file) { struct stat st; int fd; + char sbuf[STRERR_BUFSIZE]; fd = open(file->path, O_RDONLY); if (fd < 0) { int err = errno; - pr_err("failed to open %s: %s", file->path, strerror(err)); + pr_err("failed to open %s: %s", file->path, + strerror_r(err, sbuf, sizeof(sbuf))); if (err == ENOENT && !strcmp(file->path, "perf.data")) pr_err(" (try 'perf record' first)"); pr_err("\n"); @@ -88,6 +90,7 @@ static int open_file_read(struct perf_data_file *file) static int open_file_write(struct perf_data_file *file) { int fd; + char sbuf[STRERR_BUFSIZE]; if (check_backup(file)) return -1; @@ -95,7 +98,8 @@ static int open_file_write(struct perf_data_file *file) fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); if (fd < 0) - pr_err("failed to open %s : %s\n", file->path, strerror(errno)); + pr_err("failed to open %s : %s\n", file->path, + strerror_r(errno, sbuf, sizeof(sbuf))); return fd; } diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index bdafd306fb52..55e39dc1bcda 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -162,13 +162,15 @@ static void close_first_dso(void); static int do_open(char *name) { int fd; + char sbuf[STRERR_BUFSIZE]; do { fd = open(name, O_RDONLY); if (fd >= 0) return fd; - pr_debug("dso open failed, mmap: %s\n", strerror(errno)); + pr_debug("dso open failed, mmap: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); if (!dso__data_open_cnt || errno != EMFILE) break; @@ -530,10 +532,12 @@ static ssize_t cached_read(struct dso *dso, u64 offset, u8 *data, ssize_t size) static int data_file_size(struct dso *dso) { struct stat st; + char sbuf[STRERR_BUFSIZE]; if (!dso->data.file_size) { if (fstat(dso->data.fd, &st)) { - pr_err("dso mmap failed, fstat: %s\n", strerror(errno)); + pr_err("dso mmap failed, fstat: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); return -1; } dso->data.file_size = st.st_size; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 5dcd28c79c6e..a3e28b49128a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -1295,7 +1295,7 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused, int err, char *buf, size_t size) { int printed, value; - char sbuf[128], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); + char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf)); switch (err) { case EACCES: diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 01ce14c3575e..b38de5819323 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2027,6 +2027,8 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err, int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, int err, char *msg, size_t size) { + char sbuf[STRERR_BUFSIZE]; + switch (err) { case EPERM: case EACCES: @@ -2072,8 +2074,9 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, } return scnprintf(msg, size, - "The sys_perf_event_open() syscall returned with %d (%s) for event (%s). \n" + "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n" "/bin/dmesg may provide additional information.\n" "No CONFIG_PERF_EVENTS=y kernel support configured?\n", - err, strerror(err), perf_evsel__name(evsel)); + err, strerror_r(err, sbuf, sizeof(sbuf)), + perf_evsel__name(evsel)); } diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 1e15df10a88c..e34c81a0bcf3 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -10,6 +10,7 @@ #include "symbol.h" #include "cache.h" #include "header.h" +#include "debug.h" #include #include "parse-events-bison.h" #define YY_EXTRA_TYPE int @@ -1006,9 +1007,11 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob, struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; char evt_path[MAXPATHLEN]; char dir_path[MAXPATHLEN]; + char sbuf[STRERR_BUFSIZE]; if (debugfs_valid_mountpoint(tracing_events_path)) { - printf(" [ Tracepoints not available: %s ]\n", strerror(errno)); + printf(" [ Tracepoints not available: %s ]\n", + strerror_r(errno, sbuf, sizeof(sbuf))); return; } diff --git a/tools/perf/util/run-command.c b/tools/perf/util/run-command.c index da8e9b285f51..34622b53e733 100644 --- a/tools/perf/util/run-command.c +++ b/tools/perf/util/run-command.c @@ -1,6 +1,7 @@ #include "cache.h" #include "run-command.h" #include "exec_cmd.h" +#include "debug.h" static inline void close_pair(int fd[2]) { @@ -19,6 +20,7 @@ int start_command(struct child_process *cmd) { int need_in, need_out, need_err; int fdin[2], fdout[2], fderr[2]; + char sbuf[STRERR_BUFSIZE]; /* * In case of errors we must keep the promise to close FDs @@ -99,7 +101,7 @@ int start_command(struct child_process *cmd) if (cmd->dir && chdir(cmd->dir)) die("exec %s: cd to %s failed (%s)", cmd->argv[0], - cmd->dir, strerror(errno)); + cmd->dir, strerror_r(errno, sbuf, sizeof(sbuf))); if (cmd->env) { for (; *cmd->env; cmd->env++) { if (strchr(*cmd->env, '=')) @@ -153,6 +155,8 @@ int start_command(struct child_process *cmd) static int wait_or_whine(pid_t pid) { + char sbuf[STRERR_BUFSIZE]; + for (;;) { int status, code; pid_t waiting = waitpid(pid, &status, 0); @@ -160,7 +164,8 @@ static int wait_or_whine(pid_t pid) if (waiting < 0) { if (errno == EINTR) continue; - error("waitpid failed (%s)", strerror(errno)); + error("waitpid failed (%s)", + strerror_r(errno, sbuf, sizeof(sbuf))); return -ERR_RUN_COMMAND_WAITPID; } if (waiting != pid) diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 25822bdf7bbf..24e8d871b74e 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -456,6 +456,7 @@ int filename__read_str(const char *filename, char **buf, size_t *sizep) size_t size = 0, alloc_size = 0; void *bf = NULL, *nbf; int fd, n, err = 0; + char sbuf[STRERR_BUFSIZE]; fd = open(filename, O_RDONLY); if (fd < 0) @@ -476,8 +477,8 @@ int filename__read_str(const char *filename, char **buf, size_t *sizep) n = read(fd, bf + size, alloc_size - size); if (n < 0) { if (size) { - pr_warning("read failed %d: %s\n", - errno, strerror(errno)); + pr_warning("read failed %d: %s\n", errno, + strerror_r(errno, sbuf, sizeof(sbuf))); err = 0; } else err = -errno; -- GitLab From 809adea685f7dbc9bdcc38b27d24801c461d8413 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:38 +0000 Subject: [PATCH 0450/9167] perf top: Use strerror_r instead of strerror Use strerror_r instead of strerror in error message for thread-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022238.3545.15569.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 87a6615a40fa..a77ff6ca5fbd 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -899,7 +899,7 @@ static int perf_top__start_counters(struct perf_top *top) if (perf_evlist__mmap(evlist, opts->mmap_pages, false) < 0) { ui__error("Failed to mmap with %d (%s)\n", - errno, strerror(errno)); + errno, strerror_r(errno, msg, sizeof(msg))); goto out_err; } -- GitLab From 942a91ed3ffff0267944ed3161ae292d0960fd44 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:41 +0000 Subject: [PATCH 0451/9167] perf trace: Use strerror_r instead of strerror Use strerror_r instead of strerror in error message for thead-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022241.3545.97543.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-trace.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index d080b9cf0354..a9e96ff49c7f 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -1750,7 +1750,7 @@ static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel, signed_print: fprintf(trace->output, ") = %d", ret); } else if (ret < 0 && sc->fmt->errmsg) { - char bf[256]; + char bf[STRERR_BUFSIZE]; const char *emsg = strerror_r(-ret, bf, sizeof(bf)), *e = audit_errno_to_name(-ret); @@ -2044,6 +2044,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) int err = -1, i; unsigned long before; const bool forks = argc > 0; + char sbuf[STRERR_BUFSIZE]; trace->live = true; @@ -2105,7 +2106,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); if (err < 0) { - fprintf(trace->output, "Couldn't mmap the events: %s\n", strerror(errno)); + fprintf(trace->output, "Couldn't mmap the events: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } -- GitLab From 35550da389ba8752f024a44ef14b74001c4fc4d3 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:43 +0000 Subject: [PATCH 0452/9167] perf record: Use strerror_r instead of strerror Use strerror_r instead of strerror in error messages for thread-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022243.3545.7411.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-record.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 4db670d4b8da..87e28a4e33ba 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -161,7 +161,7 @@ static int record__open(struct record *rec) if (perf_evlist__apply_filters(evlist)) { error("failed to set filter with %d (%s)\n", errno, - strerror(errno)); + strerror_r(errno, msg, sizeof(msg))); rc = -1; goto out; } @@ -175,7 +175,8 @@ static int record__open(struct record *rec) "(current value: %u)\n", opts->mmap_pages); rc = -errno; } else { - pr_err("failed to mmap with %d (%s)\n", errno, strerror(errno)); + pr_err("failed to mmap with %d (%s)\n", errno, + strerror_r(errno, msg, sizeof(msg))); rc = -errno; } goto out; @@ -480,7 +481,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) } if (forks && workload_exec_errno) { - char msg[512]; + char msg[STRERR_BUFSIZE]; const char *emsg = strerror_r(workload_exec_errno, msg, sizeof(msg)); pr_err("Workload failed: %s\n", emsg); err = -1; -- GitLab From ba3dfff8ad2d98df0c8116faaeb281c93e161636 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:45 +0000 Subject: [PATCH 0453/9167] perf test: Use strerror_r instead of strerror Use strerror_r instead of strerror in error messages for thread-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022245.3545.91394.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/builtin-test.c | 4 +++- tools/perf/tests/mmap-basic.c | 7 ++++--- tools/perf/tests/open-syscall-all-cpus.c | 5 +++-- tools/perf/tests/open-syscall-tp-fields.c | 7 +++++-- tools/perf/tests/open-syscall.c | 3 ++- tools/perf/tests/perf-record.c | 13 +++++++++---- tools/perf/tests/rdpmc.c | 6 ++++-- tools/perf/tests/sw-clock.c | 6 ++++-- tools/perf/tests/task-exit.c | 6 ++++-- 9 files changed, 38 insertions(+), 19 deletions(-) diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index c6796d22423a..99481361b19f 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -185,9 +185,11 @@ static bool perf_test__matches(int curr, int argc, const char *argv[]) static int run_test(struct test *test) { int status, err = -1, child = fork(); + char sbuf[STRERR_BUFSIZE]; if (child < 0) { - pr_err("failed to fork test: %s\n", strerror(errno)); + pr_err("failed to fork test: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); return -1; } diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c index 142263492f6f..9b9622a33932 100644 --- a/tools/perf/tests/mmap-basic.c +++ b/tools/perf/tests/mmap-basic.c @@ -31,6 +31,7 @@ int test__basic_mmap(void) unsigned int nr_events[nsyscalls], expected_nr_events[nsyscalls], i, j; struct perf_evsel *evsels[nsyscalls], *evsel; + char sbuf[STRERR_BUFSIZE]; threads = thread_map__new(-1, getpid(), UINT_MAX); if (threads == NULL) { @@ -49,7 +50,7 @@ int test__basic_mmap(void) sched_setaffinity(0, sizeof(cpu_set), &cpu_set); if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { pr_debug("sched_setaffinity() failed on CPU %d: %s ", - cpus->map[0], strerror(errno)); + cpus->map[0], strerror_r(errno, sbuf, sizeof(sbuf))); goto out_free_cpus; } @@ -79,7 +80,7 @@ int test__basic_mmap(void) if (perf_evsel__open(evsels[i], cpus, threads) < 0) { pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } @@ -89,7 +90,7 @@ int test__basic_mmap(void) if (perf_evlist__mmap(evlist, 128, true) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/open-syscall-all-cpus.c index 5fecdbd2f5f7..8fa82d1700c7 100644 --- a/tools/perf/tests/open-syscall-all-cpus.c +++ b/tools/perf/tests/open-syscall-all-cpus.c @@ -12,6 +12,7 @@ int test__open_syscall_event_on_all_cpus(void) unsigned int nr_open_calls = 111, i; cpu_set_t cpu_set; struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); + char sbuf[STRERR_BUFSIZE]; if (threads == NULL) { pr_debug("thread_map__new\n"); @@ -35,7 +36,7 @@ int test__open_syscall_event_on_all_cpus(void) if (perf_evsel__open(evsel, cpus, threads) < 0) { pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_evsel_delete; } @@ -56,7 +57,7 @@ int test__open_syscall_event_on_all_cpus(void) if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) { pr_debug("sched_setaffinity() failed on CPU %d: %s ", cpus->map[cpu], - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_close_fd; } for (i = 0; i < ncalls; ++i) { diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c index 0785b64ffd6c..922bdb627950 100644 --- a/tools/perf/tests/open-syscall-tp-fields.c +++ b/tools/perf/tests/open-syscall-tp-fields.c @@ -22,6 +22,7 @@ int test__syscall_open_tp_fields(void) struct perf_evlist *evlist = perf_evlist__new(); struct perf_evsel *evsel; int err = -1, i, nr_events = 0, nr_polls = 0; + char sbuf[STRERR_BUFSIZE]; if (evlist == NULL) { pr_debug("%s: perf_evlist__new\n", __func__); @@ -48,13 +49,15 @@ int test__syscall_open_tp_fields(void) err = perf_evlist__open(evlist); if (err < 0) { - pr_debug("perf_evlist__open: %s\n", strerror(errno)); + pr_debug("perf_evlist__open: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } err = perf_evlist__mmap(evlist, UINT_MAX, false); if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); + pr_debug("perf_evlist__mmap: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/open-syscall.c index c1dc7d25f38c..a33b2daae40f 100644 --- a/tools/perf/tests/open-syscall.c +++ b/tools/perf/tests/open-syscall.c @@ -9,6 +9,7 @@ int test__open_syscall_event(void) struct perf_evsel *evsel; unsigned int nr_open_calls = 111, i; struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); + char sbuf[STRERR_BUFSIZE]; if (threads == NULL) { pr_debug("thread_map__new\n"); @@ -24,7 +25,7 @@ int test__open_syscall_event(void) if (perf_evsel__open_per_thread(evsel, threads) < 0) { pr_debug("failed to open counter: %s, " "tweak /proc/sys/kernel/perf_event_paranoid?\n", - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_evsel_delete; } diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c index aca1a83dd13a..2ce753c1db63 100644 --- a/tools/perf/tests/perf-record.c +++ b/tools/perf/tests/perf-record.c @@ -59,6 +59,7 @@ int test__PERF_RECORD(void) int err = -1, errs = 0, i, wakeups = 0; u32 cpu; int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; + char sbuf[STRERR_BUFSIZE]; if (evlist == NULL || argv == NULL) { pr_debug("Not enough memory to create evlist\n"); @@ -100,7 +101,8 @@ int test__PERF_RECORD(void) err = sched__get_first_possible_cpu(evlist->workload.pid, &cpu_mask); if (err < 0) { - pr_debug("sched__get_first_possible_cpu: %s\n", strerror(errno)); + pr_debug("sched__get_first_possible_cpu: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } @@ -110,7 +112,8 @@ int test__PERF_RECORD(void) * So that we can check perf_sample.cpu on all the samples. */ if (sched_setaffinity(evlist->workload.pid, cpu_mask_size, &cpu_mask) < 0) { - pr_debug("sched_setaffinity: %s\n", strerror(errno)); + pr_debug("sched_setaffinity: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } @@ -120,7 +123,8 @@ int test__PERF_RECORD(void) */ err = perf_evlist__open(evlist); if (err < 0) { - pr_debug("perf_evlist__open: %s\n", strerror(errno)); + pr_debug("perf_evlist__open: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } @@ -131,7 +135,8 @@ int test__PERF_RECORD(void) */ err = perf_evlist__mmap(evlist, opts.mmap_pages, false); if (err < 0) { - pr_debug("perf_evlist__mmap: %s\n", strerror(errno)); + pr_debug("perf_evlist__mmap: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } diff --git a/tools/perf/tests/rdpmc.c b/tools/perf/tests/rdpmc.c index c04d1f268576..d31f2c4d9f64 100644 --- a/tools/perf/tests/rdpmc.c +++ b/tools/perf/tests/rdpmc.c @@ -100,6 +100,7 @@ static int __test__rdpmc(void) }; u64 delta_sum = 0; struct sigaction sa; + char sbuf[STRERR_BUFSIZE]; sigfillset(&sa.sa_mask); sa.sa_sigaction = segfault_handler; @@ -109,14 +110,15 @@ static int __test__rdpmc(void) perf_event_open_cloexec_flag()); if (fd < 0) { pr_err("Error: sys_perf_event_open() syscall returned " - "with %d (%s)\n", fd, strerror(errno)); + "with %d (%s)\n", fd, + strerror_r(errno, sbuf, sizeof(sbuf))); return -1; } addr = mmap(NULL, page_size, PROT_READ, MAP_SHARED, fd, 0); if (addr == (void *)(-1)) { pr_err("Error: mmap() syscall returned with (%s)\n", - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_close; } diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 983d6b8562a8..1aa21c90731b 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -22,6 +22,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) volatile int tmp = 0; u64 total_periods = 0; int nr_samples = 0; + char sbuf[STRERR_BUFSIZE]; union perf_event *event; struct perf_evsel *evsel; struct perf_evlist *evlist; @@ -62,14 +63,15 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) err = -errno; pr_debug("Couldn't open evlist: %s\nHint: check %s, using %" PRIu64 " in this test.\n", - strerror(errno), knob, (u64)attr.sample_freq); + strerror_r(errno, sbuf, sizeof(sbuf)), + knob, (u64)attr.sample_freq); goto out_delete_evlist; } err = perf_evlist__mmap(evlist, 128, true); if (err < 0) { pr_debug("failed to mmap event: %d (%s)\n", errno, - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 5ff3db318f12..87522f01c7ad 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c @@ -42,6 +42,7 @@ int test__task_exit(void) .uses_mmap = true, }; const char *argv[] = { "true", NULL }; + char sbuf[STRERR_BUFSIZE]; signal(SIGCHLD, sig_handler); @@ -82,13 +83,14 @@ int test__task_exit(void) err = perf_evlist__open(evlist); if (err < 0) { - pr_debug("Couldn't open the evlist: %s\n", strerror(-err)); + pr_debug("Couldn't open the evlist: %s\n", + strerror_r(-err, sbuf, sizeof(sbuf))); goto out_delete_evlist; } if (perf_evlist__mmap(evlist, 128, true) < 0) { pr_debug("failed to mmap events: %d (%s)\n", errno, - strerror(errno)); + strerror_r(errno, sbuf, sizeof(sbuf))); goto out_delete_evlist; } -- GitLab From fb74fbda42dc5bcbd9bae5d75bfb6755948db21d Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:47 +0000 Subject: [PATCH 0454/9167] perf sched: Use strerror_r instead of strerror Use strerror_r instead of strerror in error message for thread-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022247.3545.4564.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-sched.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index f5874a27b346..9c9287fbf8e9 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -428,6 +428,7 @@ static u64 get_cpu_usage_nsec_parent(void) static int self_open_counters(void) { struct perf_event_attr attr; + char sbuf[STRERR_BUFSIZE]; int fd; memset(&attr, 0, sizeof(attr)); @@ -440,7 +441,8 @@ static int self_open_counters(void) if (fd < 0) pr_err("Error: sys_perf_event_open() syscall returned " - "with %d (%s)\n", fd, strerror(errno)); + "with %d (%s)\n", fd, + strerror_r(errno, sbuf, sizeof(sbuf))); return fd; } -- GitLab From 340481ada1af9322d99e9c1ba874391f53ff4fce Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:49 +0000 Subject: [PATCH 0455/9167] perf buildid-cache: Use strerror_r instead of strerror Use strerror_r instead of strerror in error messages for thread-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022249.3545.53211.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-buildid-cache.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index ac5838e0b1bd..70385756da63 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -291,6 +291,7 @@ int cmd_buildid_cache(int argc, const char **argv, *missing_filename = NULL, *update_name_list_str = NULL, *kcore_filename; + char sbuf[STRERR_BUFSIZE]; struct perf_data_file file = { .mode = PERF_DATA_MODE_READ, @@ -347,7 +348,7 @@ int cmd_buildid_cache(int argc, const char **argv, continue; } pr_warning("Couldn't add %s: %s\n", - pos->s, strerror(errno)); + pos->s, strerror_r(errno, sbuf, sizeof(sbuf))); } strlist__delete(list); @@ -365,7 +366,7 @@ int cmd_buildid_cache(int argc, const char **argv, continue; } pr_warning("Couldn't remove %s: %s\n", - pos->s, strerror(errno)); + pos->s, strerror_r(errno, sbuf, sizeof(sbuf))); } strlist__delete(list); @@ -386,7 +387,7 @@ int cmd_buildid_cache(int argc, const char **argv, continue; } pr_warning("Couldn't update %s: %s\n", - pos->s, strerror(errno)); + pos->s, strerror_r(errno, sbuf, sizeof(sbuf))); } strlist__delete(list); -- GitLab From f9f33fdba159a9c163ecf1dc0106ebd4c2498130 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:51 +0000 Subject: [PATCH 0456/9167] perf kvm: Use strerror_r instead of strerror Use strerror_r instead of strerror in error messages for thread-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022251.3545.83718.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-kvm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 14d03edc81c2..1a4ef9cd9d5f 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -990,6 +990,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) int err, rc = -1; struct perf_evsel *pos; struct perf_evlist *evlist = kvm->evlist; + char sbuf[STRERR_BUFSIZE]; perf_evlist__config(evlist, &kvm->opts); @@ -1026,12 +1027,14 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) err = perf_evlist__open(evlist); if (err < 0) { - printf("Couldn't create the events: %s\n", strerror(errno)); + printf("Couldn't create the events: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); goto out; } if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) { - ui__error("Failed to mmap the events: %s\n", strerror(errno)); + ui__error("Failed to mmap the events: %s\n", + strerror_r(errno, sbuf, sizeof(sbuf))); perf_evlist__close(evlist); goto out; } -- GitLab From ede395d27c60c06a2173e7a9c0f4a929a1fef73e Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:53 +0000 Subject: [PATCH 0457/9167] perf help: Use strerror_r instead of strerror Use strerror_r instead of strerror in error messages for thread-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022253.3545.82136.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-help.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 0384d930480b..25d20628212e 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -103,6 +103,8 @@ static int check_emacsclient_version(void) static void exec_woman_emacs(const char *path, const char *page) { + char sbuf[STRERR_BUFSIZE]; + if (!check_emacsclient_version()) { /* This works only with emacsclient version >= 22. */ struct strbuf man_page = STRBUF_INIT; @@ -111,16 +113,19 @@ static void exec_woman_emacs(const char *path, const char *page) path = "emacsclient"; strbuf_addf(&man_page, "(woman \"%s\")", page); execlp(path, "emacsclient", "-e", man_page.buf, NULL); - warning("failed to exec '%s': %s", path, strerror(errno)); + warning("failed to exec '%s': %s", path, + strerror_r(errno, sbuf, sizeof(sbuf))); } } static void exec_man_konqueror(const char *path, const char *page) { const char *display = getenv("DISPLAY"); + if (display && *display) { struct strbuf man_page = STRBUF_INIT; const char *filename = "kfmclient"; + char sbuf[STRERR_BUFSIZE]; /* It's simpler to launch konqueror using kfmclient. */ if (path) { @@ -139,24 +144,31 @@ static void exec_man_konqueror(const char *path, const char *page) path = "kfmclient"; strbuf_addf(&man_page, "man:%s(1)", page); execlp(path, filename, "newTab", man_page.buf, NULL); - warning("failed to exec '%s': %s", path, strerror(errno)); + warning("failed to exec '%s': %s", path, + strerror_r(errno, sbuf, sizeof(sbuf))); } } static void exec_man_man(const char *path, const char *page) { + char sbuf[STRERR_BUFSIZE]; + if (!path) path = "man"; execlp(path, "man", page, NULL); - warning("failed to exec '%s': %s", path, strerror(errno)); + warning("failed to exec '%s': %s", path, + strerror_r(errno, sbuf, sizeof(sbuf))); } static void exec_man_cmd(const char *cmd, const char *page) { struct strbuf shell_cmd = STRBUF_INIT; + char sbuf[STRERR_BUFSIZE]; + strbuf_addf(&shell_cmd, "%s %s", cmd, page); execl("/bin/sh", "sh", "-c", shell_cmd.buf, NULL); - warning("failed to exec '%s': %s", cmd, strerror(errno)); + warning("failed to exec '%s': %s", cmd, + strerror_r(errno, sbuf, sizeof(sbuf))); } static void add_man_viewer(const char *name) -- GitLab From 759e612bf96627b64fcafe4174b3f6f2dedf2c0d Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 14 Aug 2014 02:22:55 +0000 Subject: [PATCH 0458/9167] perf stat: Use strerror_r instead of strerror Use strerror_r instead of strerror in error message for thread-safety. Signed-off-by: Masami Hiramatsu Cc: Ingo Molnar Cc: Namhyung Kim Cc: Naohiro Aota Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20140814022255.3545.81549.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-stat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 3e80aa10cfd8..5fe0edb1de5d 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -593,7 +593,7 @@ static int __run_perf_stat(int argc, const char **argv) if (perf_evlist__apply_filters(evsel_list)) { error("failed to set filter with %d (%s)\n", errno, - strerror(errno)); + strerror_r(errno, msg, sizeof(msg))); return -1; } -- GitLab From 515d9b2c03943ca904cd135e1b1d9ddd168c1b27 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Tue, 12 Aug 2014 18:22:27 +0200 Subject: [PATCH 0459/9167] ata: remove deprecated struct ahci_platform_data The last user of the deprecated struct ahci_platform_data has been cleaned up recently (SPEAr1340 got a proper PHY driver). Signed-off-by: Bartlomiej Zolnierkiewicz Acked-by: Hans de Goede Signed-off-by: Tejun Heo --- drivers/ata/ahci_platform.c | 18 +----------------- drivers/ata/libahci_platform.c | 23 ----------------------- include/linux/ahci_platform.h | 13 ------------- 3 files changed, 1 insertion(+), 53 deletions(-) diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c index f61ddb9146d6..06f1d59fa678 100644 --- a/drivers/ata/ahci_platform.c +++ b/drivers/ata/ahci_platform.c @@ -32,7 +32,6 @@ static const struct ata_port_info ahci_port_info = { static int ahci_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct ahci_platform_data *pdata = dev_get_platdata(dev); struct ahci_host_priv *hpriv; int rc; @@ -44,29 +43,14 @@ static int ahci_probe(struct platform_device *pdev) if (rc) return rc; - /* - * Some platforms might need to prepare for mmio region access, - * which could be done in the following init call. So, the mmio - * region shouldn't be accessed before init (if provided) has - * returned successfully. - */ - if (pdata && pdata->init) { - rc = pdata->init(dev, hpriv->mmio); - if (rc) - goto disable_resources; - } - if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci")) hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ; rc = ahci_platform_init_host(pdev, hpriv, &ahci_port_info); if (rc) - goto pdata_exit; + goto disable_resources; return 0; -pdata_exit: - if (pdata && pdata->exit) - pdata->exit(dev); disable_resources: ahci_platform_disable_resources(hpriv); return rc; diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 5b92c290e6c6..c0510de8a4c9 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -502,13 +502,8 @@ EXPORT_SYMBOL_GPL(ahci_platform_init_host); static void ahci_host_stop(struct ata_host *host) { - struct device *dev = host->dev; - struct ahci_platform_data *pdata = dev_get_platdata(dev); struct ahci_host_priv *hpriv = host->private_data; - if (pdata && pdata->exit) - pdata->exit(dev); - ahci_platform_disable_resources(hpriv); } @@ -592,7 +587,6 @@ EXPORT_SYMBOL_GPL(ahci_platform_resume_host); */ int ahci_platform_suspend(struct device *dev) { - struct ahci_platform_data *pdata = dev_get_platdata(dev); struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; int rc; @@ -601,19 +595,9 @@ int ahci_platform_suspend(struct device *dev) if (rc) return rc; - if (pdata && pdata->suspend) { - rc = pdata->suspend(dev); - if (rc) - goto resume_host; - } - ahci_platform_disable_resources(hpriv); return 0; - -resume_host: - ahci_platform_resume_host(dev); - return rc; } EXPORT_SYMBOL_GPL(ahci_platform_suspend); @@ -629,7 +613,6 @@ EXPORT_SYMBOL_GPL(ahci_platform_suspend); */ int ahci_platform_resume(struct device *dev) { - struct ahci_platform_data *pdata = dev_get_platdata(dev); struct ata_host *host = dev_get_drvdata(dev); struct ahci_host_priv *hpriv = host->private_data; int rc; @@ -638,12 +621,6 @@ int ahci_platform_resume(struct device *dev) if (rc) return rc; - if (pdata && pdata->resume) { - rc = pdata->resume(dev); - if (rc) - goto disable_resources; - } - rc = ahci_platform_resume_host(dev); if (rc) goto disable_resources; diff --git a/include/linux/ahci_platform.h b/include/linux/ahci_platform.h index 09a947e8bc87..642d6ae4030c 100644 --- a/include/linux/ahci_platform.h +++ b/include/linux/ahci_platform.h @@ -22,19 +22,6 @@ struct ata_port_info; struct ahci_host_priv; struct platform_device; -/* - * Note ahci_platform_data is deprecated, it is only kept around for use - * by the old da850 and spear13xx ahci code. - * New drivers should instead declare their own platform_driver struct, and - * use ahci_platform* functions in their own probe, suspend and resume methods. - */ -struct ahci_platform_data { - int (*init)(struct device *dev, void __iomem *addr); - void (*exit)(struct device *dev); - int (*suspend)(struct device *dev); - int (*resume)(struct device *dev); -}; - int ahci_platform_enable_clks(struct ahci_host_priv *hpriv); void ahci_platform_disable_clks(struct ahci_host_priv *hpriv); int ahci_platform_enable_resources(struct ahci_host_priv *hpriv); -- GitLab From a5b4e003253a496a7414003c034ff51a365258d4 Mon Sep 17 00:00:00 2001 From: "Yee Chin, Chiam" Date: Wed, 6 Aug 2014 17:47:34 -0400 Subject: [PATCH 0460/9167] Staging: android: sw_sync.c: Fixed coding style issue. Fixed coding style issue where blank line is missing after declaration. Signed-off-by: Yee Chin, Chiam Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/sw_sync.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/android/sw_sync.c b/drivers/staging/android/sw_sync.c index a76db3ff87cb..863d4b17387a 100644 --- a/drivers/staging/android/sw_sync.c +++ b/drivers/staging/android/sw_sync.c @@ -97,6 +97,7 @@ static void sw_sync_pt_value_str(struct sync_pt *sync_pt, char *str, int size) { struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt; + snprintf(str, size, "%d", pt->value); } @@ -156,6 +157,7 @@ static int sw_sync_open(struct inode *inode, struct file *file) static int sw_sync_release(struct inode *inode, struct file *file) { struct sw_sync_timeline *obj = file->private_data; + sync_timeline_destroy(&obj->obj); return 0; } -- GitLab From 2eb61f38821979dd3d065a8bbb72dc9f6306f005 Mon Sep 17 00:00:00 2001 From: Martin Berglund Date: Sat, 9 Aug 2014 01:26:45 +0200 Subject: [PATCH 0461/9167] staging: vt6655: iowpa.h: Fix sparse warnings This resolves a sparse address space warning in wpactl.c Signed-off-by: Martin Berglund Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/iowpa.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/iowpa.h b/drivers/staging/vt6655/iowpa.h index 772bc4c2a7b9..fe4b22ed49f4 100644 --- a/drivers/staging/vt6655/iowpa.h +++ b/drivers/staging/vt6655/iowpa.h @@ -75,7 +75,7 @@ struct viawget_wpa_param { u8 bssid[6]; u8 ssid[32]; u8 ssid_len; - u8 *wpa_ie; + u8 __user *wpa_ie; u16 wpa_ie_len; int pairwise_suite; int group_suite; @@ -102,7 +102,7 @@ struct viawget_wpa_param { struct { u16 scan_count; - u8 *buf; + u8 __user *buf; } scan_results; } u; -- GitLab From 99a643b8aebb91d1dba8dff6c0e416dfd1140b07 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Thu, 31 Jul 2014 13:02:30 +0900 Subject: [PATCH 0462/9167] staging: dgap: introduce dgap_cleanup_nodes() When a configration file is parsed with dgap_parsefile(), makes nodes for saving configrations for board. Making a node will allocate node memory and strings for saving configrations with kstrdup(). So these are freed when dgap is unloaded or failed to initialize. Signed-off-by: Daeseok Youn Tested-by: Mark Hounschell Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 52 +++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 06c55cb57090..ac12e99f4c05 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -201,6 +201,7 @@ 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); @@ -619,6 +620,7 @@ static int dgap_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) free_flipbuf: dgap_free_flipbuf(brd); cleanup_brd: + dgap_cleanup_nodes(); dgap_release_remap(brd); kfree(brd); @@ -659,6 +661,8 @@ static void dgap_cleanup_module(void) dgap_cleanup_board(dgap_board[i]); } + dgap_cleanup_nodes(); + if (dgap_numboards) pci_unregister_driver(&dgap_driver); } @@ -6323,6 +6327,54 @@ 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. */ -- GitLab From 83d24f82293eaa32f0f5679c743d9168cd74cad8 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Sat, 9 Aug 2014 14:36:44 +0900 Subject: [PATCH 0463/9167] staging: dgap: remove useless variable dgap_major_serial_registered and dgap_major_transparent_print_registered could be checked whether a board is initialized. But it doesn't need to check that variables becasue dgap module isn't calling the dgap_cleanup_tty() without initializing for a board completely. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 52 ++++++++++++++++--------------------- drivers/staging/dgap/dgap.h | 3 --- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index ac12e99f4c05..55c06c981ead 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -1320,11 +1320,9 @@ static int dgap_tty_register(struct board_t *brd) if (rc < 0) goto unregister_serial_drv; - brd->dgap_major_serial_registered = TRUE; dgap_boards_by_major[brd->serial_driver->major] = brd; brd->dgap_serial_major = brd->serial_driver->major; - brd->dgap_major_transparent_print_registered = TRUE; dgap_boards_by_major[brd->print_driver->major] = brd; brd->dgap_transparent_print_major = brd->print_driver->major; @@ -1544,35 +1542,29 @@ static void dgap_cleanup_tty(struct board_t *brd) struct device *dev; int i; - if (brd->dgap_major_serial_registered) { - 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); - brd->dgap_major_serial_registered = FALSE; - } - - if (brd->dgap_major_transparent_print_registered) { - 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); - brd->dgap_major_transparent_print_registered = FALSE; + 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); } /*======================================================================= diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index 9728d59c94d1..0482a4cf6f28 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -586,9 +586,6 @@ struct board_t { struct tty_port *printer_ports; char print_name[200]; - u32 dgap_major_serial_registered; - u32 dgap_major_transparent_print_registered; - u32 dgap_serial_major; u32 dgap_transparent_print_major; -- GitLab From 274d8b35f88079870f1691413be7ce4341d9f87b Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Sat, 9 Aug 2014 14:37:11 +0900 Subject: [PATCH 0464/9167] staging: dgap: remove redundant declarations. These are already defined in dgap.h. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 55c06c981ead..b1253c01acce 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -158,12 +158,6 @@ static void dgap_err(char *s); /* * Function prototypes from dgap_sysfs.h */ -struct board_t; -struct channel_t; -struct un_t; -struct pci_driver; -struct class_device; - static void dgap_create_ports_sysfiles(struct board_t *bd); static void dgap_remove_ports_sysfiles(struct board_t *bd); -- GitLab From 35edf11bed147a8fe1df529035ccb551d671916d Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Sat, 9 Aug 2014 14:37:39 +0900 Subject: [PATCH 0465/9167] staging: dgap: cleanup duplicated warning message on dgap_tty_init() If true_count is not same with brd->nasync, warning messages are printed. But it has duplicated messages within if statement. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index b1253c01acce..51f9ebc9e3ce 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -1374,19 +1374,14 @@ static int dgap_tty_init(struct board_t *brd) brd->nasync = brd->maxports; if (true_count != brd->nasync) { - if ((brd->type == PPCM) && (true_count == 64)) { - pr_warn("dgap: %s configured for %d ports, has %d ports.\n", - brd->name, brd->nasync, true_count); - pr_warn("dgap: Please make SURE the EBI cable running from the card\n"); - pr_warn("dgap: to each EM module is plugged into EBI IN!\n"); - } else if ((brd->type == PPCM) && (true_count == 0)) { - pr_warn("dgap: %s configured for %d ports, has %d ports.\n", - brd->name, brd->nasync, true_count); + pr_warn("dgap: %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)) { pr_warn("dgap: Please make SURE the EBI cable running from the card\n"); pr_warn("dgap: to each EM module is plugged into EBI IN!\n"); - } else - pr_warn("dgap: %s configured for %d ports, has %d ports.\n", - brd->name, brd->nasync, true_count); + } brd->nasync = true_count; -- GitLab From 77a4492fcc5696efd667cf698cb806ae846ea163 Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Sat, 9 Aug 2014 14:38:14 +0900 Subject: [PATCH 0466/9167] staging: dgap: Simplify set a board type from configration file Board types need to separate normal command like IO, MEM and so on. And the board type will come after "board" string in config file normally. (If it is not, dgap_gettok returns an error with zero) After that, set a variable of a number which is matched with specific a board number to "board.type". The dgap_gettok() returns that number so just set to "board.type" and also "v_type" can be removed. In case of boards of PCI type are set variables to zero. These can be removed because "p" as cnode get memory from kzalloc so already set to zero. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 109 ++++++------------------------------ drivers/staging/dgap/dgap.h | 1 - 2 files changed, 16 insertions(+), 94 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 51f9ebc9e3ce..7fb54d18e32b 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -399,10 +399,7 @@ struct toklist { char *string; }; -static struct toklist dgap_tlist[] = { - { BEGIN, "config_begin" }, - { END, "config_end" }, - { BOARD, "board" }, +static struct toklist dgap_brdtype[] = { { PCX, "Digi_AccelePort_C/X_PCI" }, { PEPC, "Digi_AccelePort_EPC/X_PCI" }, { PPCM, "Digi_AccelePort_Xem_PCI" }, @@ -411,6 +408,13 @@ static struct toklist dgap_tlist[] = { { APORT8_920P, "Digi_AccelePort_8r_920_PCI" }, { PAPORT4, "Digi_AccelePort_4r_PCI(EIA-232/RS-422)" }, { PAPORT8, "Digi_AccelePort_8r_PCI(EIA-232/RS-422)" }, + { 0, NULL } +}; + +static struct toklist dgap_tlist[] = { + { BEGIN, "config_begin" }, + { END, "config_end" }, + { BOARD, "board" }, { IO, "io" }, { PCIINFO, "pciinfo" }, { LINE, "line" }, @@ -6382,6 +6386,8 @@ static int dgap_parsefile(char **in) } for (; ;) { + int board_type = 0; + rc = dgap_gettok(in); if (rc == 0) { dgap_err("unexpected EOF"); @@ -6412,88 +6418,13 @@ static int dgap_parsefile(char **in) line = conc = NULL; brd = p; linecnt = -1; - break; - - case APORT2_920P: /* AccelePort_4 */ - if (p->type != BNODE) { - dgap_err("unexpected Digi_2r_920 string"); - return -1; - } - p->u.board.type = APORT2_920P; - p->u.board.v_type = 1; - break; - case APORT4_920P: /* AccelePort_4 */ - if (p->type != BNODE) { - dgap_err("unexpected Digi_4r_920 string"); + board_type = dgap_gettok(in); + if (board_type == 0) return -1; - } - p->u.board.type = APORT4_920P; - p->u.board.v_type = 1; - break; - case APORT8_920P: /* AccelePort_8 */ - if (p->type != BNODE) { - dgap_err("unexpected Digi_8r_920 string"); - return -1; - } - p->u.board.type = APORT8_920P; - p->u.board.v_type = 1; - break; + p->u.board.type = board_type; - case PAPORT4: /* AccelePort_4 PCI */ - if (p->type != BNODE) { - dgap_err("unexpected Digi_4r(PCI) string"); - return -1; - } - p->u.board.type = PAPORT4; - p->u.board.v_type = 1; - break; - - case PAPORT8: /* AccelePort_8 PCI */ - if (p->type != BNODE) { - dgap_err("unexpected Digi_8r string"); - return -1; - } - p->u.board.type = PAPORT8; - p->u.board.v_type = 1; - break; - - case PCX: /* PCI C/X */ - if (p->type != BNODE) { - dgap_err("unexpected Digi_C/X_(PCI) string"); - return -1; - } - p->u.board.type = PCX; - p->u.board.v_type = 1; - p->u.board.conc1 = 0; - p->u.board.conc2 = 0; - p->u.board.module1 = 0; - p->u.board.module2 = 0; - break; - - case PEPC: /* PCI EPC/X */ - if (p->type != BNODE) { - dgap_err("unexpected \"Digi_EPC/X_(PCI)\" string"); - return -1; - } - p->u.board.type = PEPC; - p->u.board.v_type = 1; - p->u.board.conc1 = 0; - p->u.board.conc2 = 0; - p->u.board.module1 = 0; - p->u.board.module2 = 0; - break; - - case PPCM: /* PCI/Xem */ - if (p->type != BNODE) { - dgap_err("unexpected PCI/Xem string"); - return -1; - } - p->u.board.type = PPCM; - p->u.board.v_type = 1; - p->u.board.conc1 = 0; - p->u.board.conc2 = 0; break; case IO: /* i/o port */ @@ -7198,12 +7129,11 @@ static int dgap_gettok(char **in) if (strstr(dgap_cword, "board")) { w = dgap_getword(in); snprintf(dgap_cword, MAXCWORD, "%s", w); - for (t = dgap_tlist; t->token != 0; t++) { + for (t = dgap_brdtype; t->token != 0; t++) { if (!strcmp(w, t->string)) return t->token; } dgap_err("board !!type not specified"); - return 1; } else { while ((w = dgap_getword(in))) { snprintf(dgap_cword, MAXCWORD, "%s", w); @@ -7212,8 +7142,9 @@ static int dgap_gettok(char **in) return t->token; } } - return 0; } + + return 0; } /* @@ -7261,14 +7192,6 @@ static void dgap_err(char *s) static int dgap_checknode(struct cnode *p) { switch (p->type) { - case BNODE: - if (p->u.board.v_type == 0) { - dgap_err("board type !not specified"); - return 1; - } - - return 0; - case LNODE: if (p->u.line.v_speed == 0) { dgap_err("line speed not specified"); diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index 0482a4cf6f28..c01aa2820660 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -1172,7 +1172,6 @@ struct cnode { char *id; /* tty id */ long start; /* start of tty counting */ char *method; /* Install method */ - char v_type; char v_port; char v_addr; char v_pcibus; -- GitLab From f6aa0164cd3b1c5192e87f5651ec382c3bc3abac Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Sat, 9 Aug 2014 14:38:41 +0900 Subject: [PATCH 0467/9167] staging: dgap: Simplify to set a concentrator type It is same manner with setting a board type. For example of config file for concentrator, "conc ccon" or "conc epcon" After allocating a type of "CNODE" then set a type of concentrator. So remove cases in swith statement, just get a token from string and set to "conc.type". And also it doesn't need to "conc.v_type". Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 26 +++++++------------------- drivers/staging/dgap/dgap.h | 1 - 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 7fb54d18e32b..1d27976be1aa 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -6387,6 +6387,7 @@ static int dgap_parsefile(char **in) for (; ;) { int board_type = 0; + int conc_type = 0; rc = dgap_gettok(in); if (rc == 0) { @@ -6719,24 +6720,15 @@ static int dgap_parsefile(char **in) else brd->u.board.conc1++; - break; - - case CX: /* c/x type concentrator */ - if (p->type != CNODE) { - dgap_err("cx only valid for concentrators"); + conc_type = dgap_gettok(in); + if (conc_type == 0 || conc_type != CX || + conc_type != EPC) { + dgap_err("failed to set a type of concentratros"); return -1; } - p->u.conc.type = CX; - p->u.conc.v_type = 1; - break; - case EPC: /* epc type concentrator */ - if (p->type != CNODE) { - dgap_err("cx only valid for concentrators"); - return -1; - } - p->u.conc.type = EPC; - p->u.conc.v_type = 1; + p->u.conc.type = conc_type; + break; case MOD: /* EBI module */ @@ -7200,10 +7192,6 @@ static int dgap_checknode(struct cnode *p) return 0; case CNODE: - if (p->u.conc.v_type == 0) { - dgap_err("concentrator type not specified"); - return 1; - } if (p->u.conc.v_speed == 0) { dgap_err("concentrator line speed not specified"); return 1; diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index c01aa2820660..800f4077fe36 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -1206,7 +1206,6 @@ struct cnode { char *id; char *idstr; long start; - char v_type; char v_connect; char v_speed; char v_nport; -- GitLab From 3cfa648b124ccbf5bc6aea92beef8ed35a06f1ed Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Sat, 9 Aug 2014 14:39:05 +0900 Subject: [PATCH 0468/9167] staging: dgap: Simplify to set a module type It is same manner with setting a board type. After allocating a type of "MNODE", get a token value set to "module.type". Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 26 +++++++------------------- drivers/staging/dgap/dgap.h | 1 - 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index 1d27976be1aa..a54b8d4f74fe 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -6388,6 +6388,7 @@ static int dgap_parsefile(char **in) for (; ;) { int board_type = 0; int conc_type = 0; + int module_type = 0; rc = dgap_gettok(in); if (rc == 0) { @@ -6762,24 +6763,15 @@ static int dgap_parsefile(char **in) else brd->u.board.module1++; - break; - - case PORTS: /* ports type EBI module */ - if (p->type != MNODE) { - dgap_err("ports only valid for EBI modules"); + module_type = dgap_gettok(in); + if (module_type == 0 || module_type != PORTS || + module_type != MODEM) { + dgap_err("failed to set a type of module"); return -1; } - p->u.module.type = PORTS; - p->u.module.v_type = 1; - break; - case MODEM: /* ports type EBI module */ - if (p->type != MNODE) { - dgap_err("modem only valid for modem modules"); - return -1; - } - p->u.module.type = MODEM; - p->u.module.v_type = 1; + p->u.module.type = module_type; + break; case CABLE: @@ -7207,10 +7199,6 @@ static int dgap_checknode(struct cnode *p) return 0; case MNODE: - if (p->u.module.v_type == 0) { - dgap_err("EBI module type not specified"); - return 1; - } if (p->u.module.v_nport == 0) { dgap_err("number of ports on EBI module not specified"); return 1; diff --git a/drivers/staging/dgap/dgap.h b/drivers/staging/dgap/dgap.h index 800f4077fe36..52e1d649dedf 100644 --- a/drivers/staging/dgap/dgap.h +++ b/drivers/staging/dgap/dgap.h @@ -1219,7 +1219,6 @@ struct cnode { char *id; char *idstr; long start; - char v_type; char v_nport; char v_id; char v_start; -- GitLab From 6c66843dabbc2cb75832c7ebcaade9038d16702f Mon Sep 17 00:00:00 2001 From: Daeseok Youn Date: Sat, 9 Aug 2014 14:39:29 +0900 Subject: [PATCH 0469/9167] staging: dgap: cleanup print messages for dgap driver * use dev_{warn,err} instead of pr_{warn,err} * removes dgap_err() and just use pr_err(). pr_err() used in dgap_parsefile() not dev_err() because if dgap_parsefile() is failed, just one message is printed. * removes "out of memory" messages. Signed-off-by: Daeseok Youn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgap/dgap.c | 285 ++++++++++++++++-------------------- 1 file changed, 126 insertions(+), 159 deletions(-) diff --git a/drivers/staging/dgap/dgap.c b/drivers/staging/dgap/dgap.c index a54b8d4f74fe..45f20b4a0c14 100644 --- a/drivers/staging/dgap/dgap.c +++ b/drivers/staging/dgap/dgap.c @@ -41,6 +41,8 @@ */ #undef DIGI_CONCENTRATORS_SUPPORTED +#define pr_fmt(fmt) "dgap: " fmt + #include #include #include @@ -153,7 +155,6 @@ static void dgap_firmware_reset_port(struct channel_t *ch); static int dgap_gettok(char **in); static char *dgap_getword(char **in); static int dgap_checknode(struct cnode *p); -static void dgap_err(char *s); /* * Function prototypes from dgap_sysfs.h @@ -877,7 +878,7 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type, ret = request_firmware(&fw, fw_info[card_type].conf_name, &pdev->dev); if (ret) { - pr_err("dgap: config file %s not found\n", + dev_err(&pdev->dev, "config file %s not found\n", fw_info[card_type].conf_name); return ret; } @@ -922,7 +923,7 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type, dgap_find_config(PAPORT4, brd->pci_bus, brd->pci_slot); if (!brd->bd_config) { - pr_err("dgap: No valid configuration found\n"); + dev_err(&pdev->dev, "No valid configuration found\n"); return -EINVAL; } @@ -930,7 +931,7 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type, ret = request_firmware(&fw, fw_info[card_type].bios_name, &pdev->dev); if (ret) { - pr_err("dgap: bios file %s not found\n", + dev_err(&pdev->dev, "bios file %s not found\n", fw_info[card_type].bios_name); return ret; } @@ -947,7 +948,7 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type, ret = request_firmware(&fw, fw_info[card_type].fep_name, &pdev->dev); if (ret) { - pr_err("dgap: fep file %s not found\n", + dev_err(&pdev->dev, "dgap: fep file %s not found\n", fw_info[card_type].fep_name); return ret; } @@ -976,7 +977,7 @@ static int dgap_firmware_load(struct pci_dev *pdev, int card_type, ret = request_firmware(&fw, fw_info[card_type].con_name, &pdev->dev); if (ret) { - pr_err("dgap: conc file %s not found\n", + dev_err(&pdev->dev, "conc file %s not found\n", fw_info[card_type].con_name); return ret; } @@ -1378,13 +1379,16 @@ static int dgap_tty_init(struct board_t *brd) brd->nasync = brd->maxports; if (true_count != brd->nasync) { - pr_warn("dgap: %s configured for %d ports, has %d ports.\n", - brd->name, brd->nasync, true_count); + 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)) { - pr_warn("dgap: Please make SURE the EBI cable running from the card\n"); - pr_warn("dgap: to each EM module is plugged into EBI IN!\n"); + 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; @@ -4204,7 +4208,7 @@ static int dgap_test_bios(struct board_t *brd) /* Gave up on board after too long of time taken */ err1 = readw(addr + SEQUENCE); err2 = readw(addr + ERROR); - pr_warn("dgap: %s failed diagnostics. Error #(%x,%x).\n", + dev_warn(&brd->pdev->dev, "%s failed diagnostics. Error #(%x,%x).\n", brd->name, err1, err2); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOBIOS; @@ -4299,8 +4303,9 @@ static int dgap_test_fep(struct board_t *brd) /* Gave up on board after too long of time taken */ err1 = readw(addr + SEQUENCE); err2 = readw(addr + ERROR); - pr_warn("dgap: FEPOS for %s not functioning. Error #(%x,%x).\n", - brd->name, err1, err2); + 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; @@ -4332,7 +4337,8 @@ static void dgap_do_reset_board(struct board_t *brd) } if (i > 1000) { - pr_warn("dgap: Board not resetting... Failing board.\n"); + dev_warn(&brd->pdev->dev, + "dgap: Board not resetting... Failing board.\n"); brd->state = BOARD_FAILED; brd->dpastatus = BD_NOFEP; return; @@ -4347,8 +4353,9 @@ static void dgap_do_reset_board(struct board_t *brd) check2 = readl(brd->re_map_membase + HIGHMEM); if ((check1 != 0xa55a3cc3) || (check2 != 0x5aa5c33c)) { - pr_warn("dgap: No memory at %p for board.\n", - brd->re_map_membase); + 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; @@ -6380,7 +6387,7 @@ static int dgap_parsefile(char **in) /* file must start with a BEGIN */ while ((rc = dgap_gettok(in)) != BEGIN) { if (rc == 0) { - dgap_err("unexpected EOF"); + pr_err("unexpected EOF"); return -1; } } @@ -6392,13 +6399,13 @@ static int dgap_parsefile(char **in) rc = dgap_gettok(in); if (rc == 0) { - dgap_err("unexpected EOF"); + pr_err("unexpected EOF"); return -1; } switch (rc) { case BEGIN: /* should only be 1 begin */ - dgap_err("unexpected config_begin\n"); + pr_err("unexpected config_begin\n"); return -1; case END: @@ -6409,10 +6416,9 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } + p = p->next; p->type = BNODE; @@ -6422,8 +6428,10 @@ static int dgap_parsefile(char **in) linecnt = -1; board_type = dgap_gettok(in); - if (board_type == 0) + if (board_type == 0) { + pr_err("board !!type not specified"); return -1; + } p->u.board.type = board_type; @@ -6431,17 +6439,17 @@ static int dgap_parsefile(char **in) case IO: /* i/o port */ if (p->type != BNODE) { - dgap_err("IO port only vaild for boards"); + pr_err("IO port only vaild for boards"); return -1; } s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } p->u.board.portstr = kstrdup(s, GFP_KERNEL); if (kstrtol(s, 0, &p->u.board.port)) { - dgap_err("bad number for IO port"); + pr_err("bad number for IO port"); return -1; } p->u.board.v_port = 1; @@ -6449,17 +6457,17 @@ static int dgap_parsefile(char **in) case MEM: /* memory address */ if (p->type != BNODE) { - dgap_err("memory address only vaild for boards"); + pr_err("memory address only vaild for boards"); return -1; } s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } p->u.board.addrstr = kstrdup(s, GFP_KERNEL); if (kstrtoul(s, 0, &p->u.board.addr)) { - dgap_err("bad number for memory address"); + pr_err("bad number for memory address"); return -1; } p->u.board.v_addr = 1; @@ -6467,28 +6475,28 @@ static int dgap_parsefile(char **in) case PCIINFO: /* pci information */ if (p->type != BNODE) { - dgap_err("memory address only vaild for boards"); + pr_err("memory address only vaild for boards"); return -1; } s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } p->u.board.pcibusstr = kstrdup(s, GFP_KERNEL); if (kstrtoul(s, 0, &p->u.board.pcibus)) { - dgap_err("bad number for pci bus"); + pr_err("bad number for pci bus"); return -1; } p->u.board.v_pcibus = 1; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } p->u.board.pcislotstr = kstrdup(s, GFP_KERNEL); if (kstrtoul(s, 0, &p->u.board.pcislot)) { - dgap_err("bad number for pci slot"); + pr_err("bad number for pci slot"); return -1; } p->u.board.v_pcislot = 1; @@ -6496,12 +6504,12 @@ static int dgap_parsefile(char **in) case METHOD: if (p->type != BNODE) { - dgap_err("install method only vaild for boards"); + pr_err("install method only vaild for boards"); return -1; } s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } p->u.board.method = kstrdup(s, GFP_KERNEL); @@ -6510,12 +6518,12 @@ static int dgap_parsefile(char **in) case STATUS: if (p->type != BNODE) { - dgap_err("config status only vaild for boards"); + pr_err("config status only vaild for boards"); return -1; } s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } p->u.board.status = kstrdup(s, GFP_KERNEL); @@ -6525,38 +6533,38 @@ static int dgap_parsefile(char **in) if (p->type == BNODE) { s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.board.nport)) { - dgap_err("bad number for number of ports"); + 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) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.conc.nport)) { - dgap_err("bad number for number of ports"); + 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) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.module.nport)) { - dgap_err("bad number for number of ports"); + pr_err("bad number for number of ports"); return -1; } p->u.module.v_nport = 1; } else { - dgap_err("nports only valid for concentrators or modules"); + pr_err("nports only valid for concentrators or modules"); return -1; } break; @@ -6564,7 +6572,7 @@ static int dgap_parsefile(char **in) case ID: /* letter ID used in tty name */ s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } @@ -6577,7 +6585,7 @@ static int dgap_parsefile(char **in) p->u.module.id = kstrdup(s, GFP_KERNEL); p->u.module.v_id = 1; } else { - dgap_err("id only valid for concentrators or modules"); + pr_err("id only valid for concentrators or modules"); return -1; } break; @@ -6586,38 +6594,38 @@ static int dgap_parsefile(char **in) if (p->type == BNODE) { s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.board.start)) { - dgap_err("bad number for start of tty count"); + 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) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.conc.start)) { - dgap_err("bad number for start of tty count"); + 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) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.module.start)) { - dgap_err("bad number for start of tty count"); + pr_err("bad number for start of tty count"); return -1; } p->u.module.v_start = 1; } else { - dgap_err("start only valid for concentrators or modules"); + pr_err("start only valid for concentrators or modules"); return -1; } break; @@ -6627,24 +6635,21 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = TNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpeced end of file"); + pr_err("unexpeced end of file"); return -1; } p->u.ttyname = kstrdup(s, GFP_KERNEL); - if (!p->u.ttyname) { - dgap_err("out of memory"); + if (!p->u.ttyname) return -1; - } + break; case CU: /* cu name prefix */ @@ -6652,44 +6657,39 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = CUNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpeced end of file"); + pr_err("unexpeced end of file"); return -1; } p->u.cuname = kstrdup(s, GFP_KERNEL); - if (!p->u.cuname) { - dgap_err("out of memory"); + if (!p->u.cuname) return -1; - } + break; case LINE: /* line information */ if (dgap_checknode(p)) return -1; if (!brd) { - dgap_err("must specify board before line info"); + pr_err("must specify board before line info"); return -1; } switch (brd->u.board.type) { case PPCM: - dgap_err("line not vaild for PC/em"); + pr_err("line not vaild for PC/em"); return -1; } p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = LNODE; @@ -6702,15 +6702,13 @@ static int dgap_parsefile(char **in) if (dgap_checknode(p)) return -1; if (!line) { - dgap_err("must specify line info before concentrator"); + pr_err("must specify line info before concentrator"); return -1; } p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = CNODE; @@ -6724,7 +6722,7 @@ static int dgap_parsefile(char **in) conc_type = dgap_gettok(in); if (conc_type == 0 || conc_type != CX || conc_type != EPC) { - dgap_err("failed to set a type of concentratros"); + pr_err("failed to set a type of concentratros"); return -1; } @@ -6736,7 +6734,7 @@ static int dgap_parsefile(char **in) if (dgap_checknode(p)) return -1; if (!brd) { - dgap_err("must specify board info before EBI modules"); + pr_err("must specify board info before EBI modules"); return -1; } switch (brd->u.board.type) { @@ -6745,16 +6743,15 @@ static int dgap_parsefile(char **in) break; default: if (!conc) { - dgap_err("must specify concentrator info before EBI module"); + pr_err("must specify concentrator info before EBI module"); return -1; } } p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } + p = p->next; p->type = MNODE; @@ -6766,7 +6763,7 @@ static int dgap_parsefile(char **in) module_type = dgap_gettok(in); if (module_type == 0 || module_type != PORTS || module_type != MODEM) { - dgap_err("failed to set a type of module"); + pr_err("failed to set a type of module"); return -1; } @@ -6778,7 +6775,7 @@ static int dgap_parsefile(char **in) if (p->type == LNODE) { s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } p->u.line.cable = kstrdup(s, GFP_KERNEL); @@ -6790,27 +6787,27 @@ static int dgap_parsefile(char **in) if (p->type == LNODE) { s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.line.speed)) { - dgap_err("bad number for 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) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.conc.speed)) { - dgap_err("bad number for line speed"); + pr_err("bad number for line speed"); return -1; } p->u.conc.v_speed = 1; } else { - dgap_err("speed valid only for lines or concentrators."); + pr_err("speed valid only for lines or concentrators."); return -1; } break; @@ -6819,7 +6816,7 @@ static int dgap_parsefile(char **in) if (p->type == CNODE) { s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } p->u.conc.connect = kstrdup(s, GFP_KERNEL); @@ -6831,24 +6828,21 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = PNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpeced end of file"); + pr_err("unexpeced end of file"); return -1; } p->u.printname = kstrdup(s, GFP_KERNEL); - if (!p->u.printname) { - dgap_err("out of memory"); + if (!p->u.printname) return -1; - } + break; case CMAJOR: /* major number */ @@ -6856,21 +6850,19 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = JNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.majornumber)) { - dgap_err("bad number for major number"); + pr_err("bad number for major number"); return -1; } break; @@ -6880,21 +6872,19 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = ANODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.altpin)) { - dgap_err("bad number for altpin"); + pr_err("bad number for altpin"); return -1; } break; @@ -6904,19 +6894,18 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } + p = p->next; p->type = INTRNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.useintr)) { - dgap_err("bad number for useintr"); + pr_err("bad number for useintr"); return -1; } break; @@ -6926,21 +6915,19 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = TSNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.ttysize)) { - dgap_err("bad number for ttysize"); + pr_err("bad number for ttysize"); return -1; } break; @@ -6950,21 +6937,19 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = CSNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.chsize)) { - dgap_err("bad number for chsize"); + pr_err("bad number for chsize"); return -1; } break; @@ -6974,21 +6959,19 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = BSNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.bssize)) { - dgap_err("bad number for bssize"); + pr_err("bad number for bssize"); return -1; } break; @@ -6998,21 +6981,19 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = USNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.unsize)) { - dgap_err("bad number for schedsize"); + pr_err("bad number for schedsize"); return -1; } break; @@ -7022,21 +7003,19 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = FSNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.f2size)) { - dgap_err("bad number for f2200size"); + pr_err("bad number for f2200size"); return -1; } break; @@ -7046,21 +7025,19 @@ static int dgap_parsefile(char **in) return -1; p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL); - if (!p->next) { - dgap_err("out of memory"); + if (!p->next) return -1; - } p = p->next; p->type = VSNODE; s = dgap_getword(in); if (!s) { - dgap_err("unexpected end of file"); + pr_err("unexpected end of file"); return -1; } if (kstrtol(s, 0, &p->u.vpixsize)) { - dgap_err("bad number for vpixsize"); + pr_err("bad number for vpixsize"); return -1; } break; @@ -7117,7 +7094,6 @@ static int dgap_gettok(char **in) if (!strcmp(w, t->string)) return t->token; } - dgap_err("board !!type not specified"); } else { while ((w = dgap_getword(in))) { snprintf(dgap_cword, MAXCWORD, "%s", w); @@ -7160,15 +7136,6 @@ static char *dgap_getword(char **in) return ret_ptr; } -/* - * print an error message, giving the line number in the file where - * the error occurred. - */ -static void dgap_err(char *s) -{ - pr_err("dgap: parse: %s\n", s); -} - /* * dgap_checknode: see if all the necessary info has been supplied for a node * before creating the next node. @@ -7178,33 +7145,33 @@ static int dgap_checknode(struct cnode *p) switch (p->type) { case LNODE: if (p->u.line.v_speed == 0) { - dgap_err("line speed not specified"); + pr_err("line speed not specified"); return 1; } return 0; case CNODE: if (p->u.conc.v_speed == 0) { - dgap_err("concentrator line speed not specified"); + pr_err("concentrator line speed not specified"); return 1; } if (p->u.conc.v_nport == 0) { - dgap_err("number of ports on concentrator not specified"); + pr_err("number of ports on concentrator not specified"); return 1; } if (p->u.conc.v_id == 0) { - dgap_err("concentrator id letter not specified"); + pr_err("concentrator id letter not specified"); return 1; } return 0; case MNODE: if (p->u.module.v_nport == 0) { - dgap_err("number of ports on EBI module not specified"); + pr_err("number of ports on EBI module not specified"); return 1; } if (p->u.module.v_id == 0) { - dgap_err("EBI module id letter not specified"); + pr_err("EBI module id letter not specified"); return 1; } return 0; -- GitLab From 2e20c4a7c8179d3216eaf03c3c8fa8badfb35290 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Sat, 2 Aug 2014 22:03:37 -0400 Subject: [PATCH 0470/9167] staging: unisys: remove MEMCPY functions from commontypes.h This patch removes MEMCPY, MEMCPY_FROMIO, and MEMCPY_TOIO from commontypes.h, and switches all use of these macros to the appropriate built in definition. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 6 +++--- .../staging/unisys/common-spar/include/channels/iochannel.h | 4 ++-- drivers/staging/unisys/include/commontypes.h | 3 --- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index b9bf8e81677c..ade2fe0da154 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -73,7 +73,7 @@ visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal) */ psignal = (char __iomem *)pqhdr + readq(&pqhdr->oSignalBase) + (head * readl(&pqhdr->SignalSize)); - MEMCPY_TOIO(psignal, pSignal, readl(&pqhdr->SignalSize)); + memcpy_toio(psignal, pSignal, readl(&pqhdr->SignalSize)); VolatileBarrier(); writel(head, &pqhdr->Head); @@ -126,7 +126,7 @@ visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal) /* 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)); + memcpy_fromio(pSignal, psource, readl(&pqhdr->SignalSize)); VolatileBarrier(); writel(tail, &pqhdr->Tail); @@ -183,7 +183,7 @@ SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, void *pSignal) psource = (char *) pqhdr + pqhdr->oSignalBase + (tail * pqhdr->SignalSize); - MEMCPY((char *) pSignal + (pqhdr->SignalSize * signalCount), + memcpy((char *) pSignal + (pqhdr->SignalSize * signalCount), psource, pqhdr->SignalSize); VolatileBarrier(); diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 24e11858e0ee..8e81bc93c01d 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -775,7 +775,7 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { if (clientStr) { \ chan->ChannelHeader.oClientString = \ OFFSETOF(type, clientString); \ - MEMCPY(chan->clientString, clientStr, \ + memcpy(chan->clientString, clientStr, \ MINNUM(clientStrLen, \ (u32) (MAX_CLIENTSTRING_LEN - 1))); \ chan->clientString[MINNUM(clientStrLen, \ @@ -846,7 +846,7 @@ static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, x->ChannelHeader.Size = COVER(bytes, 4096); x->ChannelHeader.Type = UltraVnicChannelProtocolGuid; x->ChannelHeader.ZoneGuid = NULL_UUID_LE; - MEMCPY(x->vnic.macaddr, macaddr, MAX_MACADDR_LEN); + memcpy(x->vnic.macaddr, macaddr, MAX_MACADDR_LEN); x->vnic.num_rcv_bufs = num_rcv_bufs; x->vnic.mtu = mtu; x->vnic.zoneGuid = zoneGuid; diff --git a/drivers/staging/unisys/include/commontypes.h b/drivers/staging/unisys/include/commontypes.h index 4311e9f6200f..53ac77053340 100644 --- a/drivers/staging/unisys/include/commontypes.h +++ b/drivers/staging/unisys/include/commontypes.h @@ -31,9 +31,6 @@ typedef u64 GUEST_PHYSICAL_ADDRESS; #define OFFSETOF offsetof #define MEMORYBARRIER mb() -#define MEMCPY(dest, src, len) memcpy(dest, src, len) -#define MEMCPY_TOIO(dest, src, len) memcpy_toio(dest, src, len) -#define MEMCPY_FROMIO(dest, src, len) memcpy_fromio(dest, src, len) #define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \ lin, logCtx) \ -- GitLab From e87cfde4a1e93aa0f0efc5ad7955500c2246f29b Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Sat, 2 Aug 2014 22:03:38 -0400 Subject: [PATCH 0471/9167] staging: unisys: remove MEMORYBARRIER AND VolatileBarrier from commontypes Remove the MEMORYBARRIER and VolatileBarrier() defines from commontypes.h and convert the spots that used this to mb(). Add comments to each use to indicate that the barrier is used to ensure channel synchronization between guests. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/channels/channel.c | 6 +++--- .../staging/unisys/common-spar/include/channels/channel.h | 8 ++++---- drivers/staging/unisys/include/commontypes.h | 4 ---- drivers/staging/unisys/visorchannel/visorchannel_funcs.c | 4 ++-- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/staging/unisys/channels/channel.c b/drivers/staging/unisys/channels/channel.c index ade2fe0da154..b4bdee4b575b 100644 --- a/drivers/staging/unisys/channels/channel.c +++ b/drivers/staging/unisys/channels/channel.c @@ -75,7 +75,7 @@ visor_signal_insert(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal) (head * readl(&pqhdr->SignalSize)); memcpy_toio(psignal, pSignal, readl(&pqhdr->SignalSize)); - VolatileBarrier(); + mb(); /* channel synch */ writel(head, &pqhdr->Head); writeq(readq(&pqhdr->NumSignalsSent) + 1, &pqhdr->NumSignalsSent); @@ -128,7 +128,7 @@ visor_signal_remove(CHANNEL_HEADER __iomem *pChannel, u32 Queue, void *pSignal) (tail * readl(&pqhdr->SignalSize)); memcpy_fromio(pSignal, psource, readl(&pqhdr->SignalSize)); - VolatileBarrier(); + mb(); /* channel synch */ writel(tail, &pqhdr->Tail); writeq(readq(&pqhdr->NumSignalsReceived) + 1, @@ -186,7 +186,7 @@ SignalRemoveAll(pCHANNEL_HEADER pChannel, u32 Queue, void *pSignal) memcpy((char *) pSignal + (pqhdr->SignalSize * signalCount), psource, pqhdr->SignalSize); - VolatileBarrier(); + mb(); /* channel synch */ pqhdr->Tail = tail; signalCount++; diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index 15a8d6b35dac..bc923336fabd 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -157,7 +157,7 @@ ULTRA_CHANNELCLI_STRING(u32 v) PathName_Last_N_Nodes(__FILE__, 4), __LINE__); \ writel(newstate, &((CHANNEL_HEADER __iomem *) \ (pChan))->CliStateOS); \ - MEMORYBARRIER; \ + mb(); /* required for channel synch */ \ } while (0) #define ULTRA_CHANNEL_CLIENT_ACQUIRE_OS(pChan, chanId, logCtx) \ @@ -458,7 +458,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, CHANNELCLI_OWNED, PathName_Last_N_Nodes((u8 *) file, 4), line); writel(CHANNELCLI_OWNED, &pChan->CliStateOS); - MEMORYBARRIER; + mb(); /* required for channel synch */ } if (readl(&pChan->CliStateOS) == CHANNELCLI_OWNED) { if (readb(&pChan->CliErrorOS) != 0) { @@ -502,7 +502,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, return 0; } writel(CHANNELCLI_BUSY, &pChan->CliStateOS); - MEMORYBARRIER; + mb(); /* required for channel synch */ if (readl(&pChan->CliStateBoot) == CHANNELCLI_BUSY) { if ((readb(&pChan->CliErrorOS) & ULTRA_CLIERROROS_THROTTLEMSG_BUSY) == 0) { @@ -521,7 +521,7 @@ ULTRA_channel_client_acquire_os(void __iomem *pChannel, u8 *chanId, } /* reset busy */ writel(CHANNELCLI_ATTACHED, &pChan->CliStateOS); - MEMORYBARRIER; + mb(); /* required for channel synch */ return 0; } if (readb(&pChan->CliErrorOS) != 0) { diff --git a/drivers/staging/unisys/include/commontypes.h b/drivers/staging/unisys/include/commontypes.h index 53ac77053340..34b31ad7b934 100644 --- a/drivers/staging/unisys/include/commontypes.h +++ b/drivers/staging/unisys/include/commontypes.h @@ -30,8 +30,6 @@ typedef u64 GUEST_PHYSICAL_ADDRESS; #define INLINE inline #define OFFSETOF offsetof -#define MEMORYBARRIER mb() - #define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \ lin, logCtx) \ do { \ @@ -63,7 +61,5 @@ typedef u64 GUEST_PHYSICAL_ADDRESS; LineNumber, Str, args...) \ pr_info(Str, ## args) -#define VolatileBarrier() MEMORYBARRIER - #endif diff --git a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c index 62ec9280cb3a..947b23c1e478 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel_funcs.c +++ b/drivers/staging/unisys/visorchannel/visorchannel_funcs.c @@ -424,7 +424,7 @@ visorchannel_signalremove(VISORCHANNEL *channel, u32 queue, void *msg) /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ - MEMORYBARRIER; + mb(); /* required for channel synch */ if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Tail)) { ERRDRV("visor_memregion_write of Tail failed: (status=%d)\n", rc); @@ -477,7 +477,7 @@ visorchannel_signalinsert(VISORCHANNEL *channel, u32 queue, void *msg) /* For each data field in SIGNAL_QUEUE_HEADER that was modified, * update host memory. */ - MEMORYBARRIER; + mb(); /* required for channel synch */ if (!SIG_WRITE_FIELD(channel, queue, &sig_hdr, Head)) { ERRDRV("visor_memregion_write of Head failed: (status=%d)\n", rc); -- GitLab From 2046fcca74148b627577c6324c811c7e894fa45d Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Sat, 2 Aug 2014 22:03:39 -0400 Subject: [PATCH 0472/9167] staging: unisys: remove INLINE define from commontypes There was a macro for INLINE. Delete it and fix the one occurrance of it to just use 'inline' instead, though that function looks awfully big for an inline... Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/channels/iochannel.h | 2 +- drivers/staging/unisys/include/commontypes.h | 1 - 2 files changed, 1 insertion(+), 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 8e81bc93c01d..06f466a51cc1 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -882,7 +882,7 @@ static inline int ULTRA_VNIC_init_channel(ULTRA_IO_CHANNEL_PROTOCOL *x, /* returns next non-zero index on success or zero on failure (i.e. out of * room) */ -static INLINE u16 +static inline u16 add_physinfo_entries(u32 inp_pfn, /* input - specifies the pfn to be used * to add entries */ u16 inp_off, /* input - specifies the off to be used diff --git a/drivers/staging/unisys/include/commontypes.h b/drivers/staging/unisys/include/commontypes.h index 34b31ad7b934..2301984cde7d 100644 --- a/drivers/staging/unisys/include/commontypes.h +++ b/drivers/staging/unisys/include/commontypes.h @@ -27,7 +27,6 @@ typedef u64 GUEST_PHYSICAL_ADDRESS; -#define INLINE inline #define OFFSETOF offsetof #define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \ -- GitLab From af96e9c058ff620b78292945e24a9d044b0d6f97 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Sat, 2 Aug 2014 22:03:40 -0400 Subject: [PATCH 0473/9167] staging: unisys: remove GUEST_PHYSICAL_ADDRESS from commontypes.h The typedef for GUEST_PHYSICAL address is only used in two files, so remove it from commontypes.h and add it to visorchipset/file.c and controlvmchannel.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../unisys/common-spar/include/channels/controlvmchannel.h | 3 +++ drivers/staging/unisys/include/commontypes.h | 2 -- drivers/staging/unisys/visorchipset/file.c | 2 ++ 3 files changed, 5 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 153f57ce908f..7cdce23d0533 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -20,6 +20,9 @@ #include "commontypes.h" #include "channel.h" #include "controlframework.h" + +typedef u64 GUEST_PHYSICAL_ADDRESS; + enum { INVALID_GUEST_FIRMWARE, SAMPLE_GUEST_FIRMWARE, TIANO32_GUEST_FIRMWARE, TIANO64_GUEST_FIRMWARE }; diff --git a/drivers/staging/unisys/include/commontypes.h b/drivers/staging/unisys/include/commontypes.h index 2301984cde7d..fab0c58f8a76 100644 --- a/drivers/staging/unisys/include/commontypes.h +++ b/drivers/staging/unisys/include/commontypes.h @@ -25,8 +25,6 @@ #include #include -typedef u64 GUEST_PHYSICAL_ADDRESS; - #define OFFSETOF offsetof #define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \ diff --git a/drivers/staging/unisys/visorchipset/file.c b/drivers/staging/unisys/visorchipset/file.c index bf2e546d76bf..2f26de2fa8a4 100644 --- a/drivers/staging/unisys/visorchipset/file.c +++ b/drivers/staging/unisys/visorchipset/file.c @@ -28,6 +28,8 @@ #define CURRENT_FILE_PC VISOR_CHIPSET_PC_file_c +typedef u64 GUEST_PHYSICAL_ADDRESS; + static struct cdev Cdev; static VISORCHANNEL **PControlVm_channel; static dev_t MajorDev = -1; /**< indicates major num for device */ -- GitLab From 2e4701ae2cfe5dc45a320a647b498fd9f2527b35 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Sat, 2 Aug 2014 22:03:41 -0400 Subject: [PATCH 0474/9167] staging: unisys: remove OFFSETOF from commontypes The only place OFFSETOF was being used was in iochannel.h. Remove the macro from commontypes.h and replace all uses of it in iochannel.h with offsetof() instead. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/iochannel.h | 36 +++++++++---------- drivers/staging/unisys/include/commontypes.h | 2 -- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 06f466a51cc1..1ab80288fe0f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -711,24 +711,24 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { /* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */ /* define offsets to members of struct uiscmdrsp */ -#define OFFSET_CMDTYPE OFFSETOF(struct uiscmdrsp, cmdtype) -#define OFFSET_SCSI OFFSETOF(struct uiscmdrsp, scsi) -#define OFFSET_NET OFFSETOF(struct uiscmdrsp, net) -#define OFFSET_SCSITASKMGMT OFFSETOF(struct uiscmdrsp, scsitaskmgmt) -#define OFFSET_NEXT OFFSETOF(struct uiscmdrsp, next) +#define OFFSET_CMDTYPE offsetof(struct uiscmdrsp, cmdtype) +#define OFFSET_SCSI offsetof(struct uiscmdrsp, scsi) +#define OFFSET_NET offsetof(struct uiscmdrsp, net) +#define OFFSET_SCSITASKMGMT offsetof(struct uiscmdrsp, scsitaskmgmt) +#define OFFSET_NEXT offsetof(struct uiscmdrsp, next) /* define offsets to members of struct uiscmdrsp_net */ -#define OFFSET_TYPE OFFSETOF(struct uiscmdrsp_net, type) -#define OFFSET_BUF OFFSETOF(struct uiscmdrsp_net, buf) -#define OFFSET_XMT OFFSETOF(struct uiscmdrsp_net, xmt) -#define OFFSET_XMT_DONE_RESULT OFFSETOF(struct uiscmdrsp_net, xmtdone) -#define OFFSET_RCVPOST OFFSETOF(struct uiscmdrsp_net, rcvpost) -#define OFFSET_RCV_DONE_LEN OFFSETOF(struct uiscmdrsp_net, rcv) -#define OFFSET_ENBDIS OFFSETOF(struct uiscmdrsp_net, enbdis) +#define OFFSET_TYPE offsetof(struct uiscmdrsp_net, type) +#define OFFSET_BUF offsetof(struct uiscmdrsp_net, buf) +#define OFFSET_XMT offsetof(struct uiscmdrsp_net, xmt) +#define OFFSET_XMT_DONE_RESULT offsetof(struct uiscmdrsp_net, xmtdone) +#define OFFSET_RCVPOST offsetof(struct uiscmdrsp_net, rcvpost) +#define OFFSET_RCV_DONE_LEN offsetof(struct uiscmdrsp_net, rcv) +#define OFFSET_ENBDIS offsetof(struct uiscmdrsp_net, enbdis) /* define offsets to members of struct net_pkt_rcvpost */ -#define OFFSET_TOTALLEN OFFSETOF(struct net_pkt_rcvpost, totallen) -#define OFFSET_FRAG OFFSETOF(struct net_pkt_rcvpost, frag) +#define OFFSET_TOTALLEN offsetof(struct net_pkt_rcvpost, totallen) +#define OFFSET_FRAG offsetof(struct net_pkt_rcvpost, frag) /* * INLINE functions for initializing and accessing I/O data channels @@ -753,7 +753,7 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { do { \ x->cmdQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \ x->cmdQ.oSignalBase = SIZEOF_PROTOCOL - \ - OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ + offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ x->cmdQ.SignalSize = SIZEOF_CMDRSP; \ x->cmdQ.MaxSignalSlots = \ QSLOTSFROMBYTES(x->ChannelHeader.Size); \ @@ -761,20 +761,20 @@ typedef struct _ULTRA_IO_CHANNEL_PROTOCOL { x->rspQ.Size = QSIZEFROMBYTES(x->ChannelHeader.Size); \ x->rspQ.oSignalBase = \ (SIZEOF_PROTOCOL + x->cmdQ.Size) - \ - OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, rspQ); \ + offsetof(ULTRA_IO_CHANNEL_PROTOCOL, rspQ); \ x->rspQ.SignalSize = SIZEOF_CMDRSP; \ x->rspQ.MaxSignalSlots = \ QSLOTSFROMBYTES(x->ChannelHeader.Size); \ x->rspQ.MaxSignals = x->rspQ.MaxSignalSlots - 1; \ x->ChannelHeader.oChannelSpace = \ - OFFSETOF(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ + offsetof(ULTRA_IO_CHANNEL_PROTOCOL, cmdQ); \ } while (0) #define INIT_CLIENTSTRING(chan, type, clientStr, clientStrLen) \ do { \ if (clientStr) { \ chan->ChannelHeader.oClientString = \ - OFFSETOF(type, clientString); \ + offsetof(type, clientString); \ memcpy(chan->clientString, clientStr, \ MINNUM(clientStrLen, \ (u32) (MAX_CLIENTSTRING_LEN - 1))); \ diff --git a/drivers/staging/unisys/include/commontypes.h b/drivers/staging/unisys/include/commontypes.h index fab0c58f8a76..0ed7f50cd20c 100644 --- a/drivers/staging/unisys/include/commontypes.h +++ b/drivers/staging/unisys/include/commontypes.h @@ -25,8 +25,6 @@ #include #include -#define OFFSETOF offsetof - #define CHANNEL_GUID_MISMATCH(chType, chName, field, expected, actual, fil, \ lin, logCtx) \ do { \ -- GitLab From 15fe5f2ceddc8b3fa3750ca54dacb950606cf8d5 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Sat, 2 Aug 2014 22:03:42 -0400 Subject: [PATCH 0475/9167] staging: unisys: move remaining macros from commontypes.h to channel.h All of the remaining macros in commontypes.h - the CHANNEL_*_MISMATCH macros and UltraLogEvent() - are used only in channel.h. Move the entire set of them to their new home. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 31 +++++++++++++++++++ drivers/staging/unisys/include/commontypes.h | 31 ------------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index bc923336fabd..d861a3fbf9b7 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -50,6 +50,37 @@ #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) + typedef enum { CHANNELSRV_UNINITIALIZED = 0, /* channel is in an undefined state */ CHANNELSRV_READY = 1 /* channel has been initialized by server */ diff --git a/drivers/staging/unisys/include/commontypes.h b/drivers/staging/unisys/include/commontypes.h index 0ed7f50cd20c..eafd83b41cf0 100644 --- a/drivers/staging/unisys/include/commontypes.h +++ b/drivers/staging/unisys/include/commontypes.h @@ -25,36 +25,5 @@ #include #include -#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) - #endif -- GitLab From 1d2def986df26bc8ad96e4a824e149dd5fc0e054 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Sat, 2 Aug 2014 22:03:43 -0400 Subject: [PATCH 0476/9167] staging: unisys: remove commontypes.h Delete commontypes.h, and replace all of the places that #included it with correct #includes for the types used in that file. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/channels/channel.h | 4 +-- .../include/channels/controlframework.h | 2 +- .../include/channels/controlvmchannel.h | 1 - .../include/channels/diagchannel.h | 2 +- .../common-spar/include/channels/iochannel.h | 1 - .../include/channels/vbuschannel.h | 1 - .../common-spar/include/vbusdeviceinfo.h | 2 +- drivers/staging/unisys/include/commontypes.h | 29 ------------------- drivers/staging/unisys/uislib/uislib.c | 3 +- drivers/staging/unisys/uislib/uisutils.c | 3 +- drivers/staging/unisys/virtpci/virtpci.c | 4 ++- .../unisys/visorchannel/visorchannel.h | 1 - 12 files changed, 12 insertions(+), 41 deletions(-) delete mode 100644 drivers/staging/unisys/include/commontypes.h diff --git a/drivers/staging/unisys/common-spar/include/channels/channel.h b/drivers/staging/unisys/common-spar/include/channels/channel.h index d861a3fbf9b7..2004cfe1890d 100644 --- a/drivers/staging/unisys/common-spar/include/channels/channel.h +++ b/drivers/staging/unisys/common-spar/include/channels/channel.h @@ -16,6 +16,8 @@ #ifndef __CHANNEL_H__ #define __CHANNEL_H__ +#include +#include #include /* @@ -30,8 +32,6 @@ */ #define __SUPERVISOR_CHANNEL_H__ -#include "commontypes.h" - #define SIGNATURE_16(A, B) ((A) | (B<<8)) #define SIGNATURE_32(A, B, C, D) \ (SIGNATURE_16(A, B) | (SIGNATURE_16(C, D) << 16)) diff --git a/drivers/staging/unisys/common-spar/include/channels/controlframework.h b/drivers/staging/unisys/common-spar/include/channels/controlframework.h index b0a49e0c37a2..fd4726e754ea 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlframework.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlframework.h @@ -25,7 +25,7 @@ #ifndef _CONTROL_FRAMEWORK_H_ #define _CONTROL_FRAMEWORK_H_ -#include "commontypes.h" +#include #include "channel.h" #define ULTRA_MEMORY_COUNT_Ki 1024 diff --git a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h index 7cdce23d0533..d08c198e0de3 100644 --- a/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/controlvmchannel.h @@ -17,7 +17,6 @@ #define __CONTROLVMCHANNEL_H__ #include -#include "commontypes.h" #include "channel.h" #include "controlframework.h" diff --git a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h index c01649a985c7..9912e51b89b5 100644 --- a/drivers/staging/unisys/common-spar/include/channels/diagchannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/diagchannel.h @@ -33,7 +33,7 @@ #ifndef _DIAG_CHANNEL_H_ #define _DIAG_CHANNEL_H_ -#include "commontypes.h" +#include #include "channel.h" /* {EEA7A573-DB82-447c-8716-EFBEAAAE4858} */ diff --git a/drivers/staging/unisys/common-spar/include/channels/iochannel.h b/drivers/staging/unisys/common-spar/include/channels/iochannel.h index 1ab80288fe0f..ed66c27cd491 100644 --- a/drivers/staging/unisys/common-spar/include/channels/iochannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/iochannel.h @@ -31,7 +31,6 @@ #include -#include "commontypes.h" #include "vmcallinterface.h" #define _ULTRA_CONTROLVM_CHANNEL_INLINE_ diff --git a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h index 8facb51143ae..1231c454176f 100644 --- a/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h +++ b/drivers/staging/unisys/common-spar/include/channels/vbuschannel.h @@ -24,7 +24,6 @@ * the client devices and client drivers for the server end to see. */ #include -#include "commontypes.h" #include "vbusdeviceinfo.h" #include "channel.h" diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h index 5e0d98cd422e..54593c11e70e 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h @@ -16,7 +16,7 @@ #ifndef __VBUSDEVICEINFO_H__ #define __VBUSDEVICEINFO_H__ -#include "commontypes.h" +#include #pragma pack(push, 1) /* both GCC and VC now allow this pragma */ diff --git a/drivers/staging/unisys/include/commontypes.h b/drivers/staging/unisys/include/commontypes.h deleted file mode 100644 index eafd83b41cf0..000000000000 --- a/drivers/staging/unisys/include/commontypes.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2010 - 2013 UNISYS CORPORATION - * 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - */ - -#ifndef _COMMONTYPES_H_ -#define _COMMONTYPES_H_ - -/* define the following to prevent include nesting in kernel header files of - * similar abbreviated content */ -#define _SUPERVISOR_COMMONTYPES_H_ - -#include -#include -#include -#include - -#endif - diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index 63c91cd6fdcc..a3a96ad5e617 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -25,7 +25,8 @@ #include #include -#include "commontypes.h" +#include +#include #include #include "uniklog.h" diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index ee26e009b400..3a59965aa9f9 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -17,7 +17,8 @@ #include #include -#include +#include +#include #include #include #include "uniklog.h" diff --git a/drivers/staging/unisys/virtpci/virtpci.c b/drivers/staging/unisys/virtpci/virtpci.c index d9443a968ddf..261a52f20ba7 100644 --- a/drivers/staging/unisys/virtpci/virtpci.c +++ b/drivers/staging/unisys/virtpci/virtpci.c @@ -24,9 +24,11 @@ #include "uniklog.h" #include "diagnostics/appos_subsystems.h" #include "uisutils.h" -#include "commontypes.h" #include "vbuschannel.h" #include "vbushelper.h" +#include +#include +#include #include #include #include diff --git a/drivers/staging/unisys/visorchannel/visorchannel.h b/drivers/staging/unisys/visorchannel/visorchannel.h index aa17a842381b..9a4d7b6755d1 100644 --- a/drivers/staging/unisys/visorchannel/visorchannel.h +++ b/drivers/staging/unisys/visorchannel/visorchannel.h @@ -20,7 +20,6 @@ #include -#include "commontypes.h" #include "memregion.h" #include "channel.h" #ifndef HOSTADDRESS -- GitLab From fb75fc5c0b461a971ea82b169e65fb4d07b5fa01 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:45 -0400 Subject: [PATCH 0477/9167] staging: unisys: get rid of unused VMMIO types Delete the unused common VMMIO types in timskmod.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index ecf1a6fac7a1..b20fc9dfc4a7 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -71,17 +71,6 @@ #define HOSTADDRESS unsigned long long #endif -typedef long VMMIO; /**< Virtual MMIO address (returned from ioremap), which - * is a virtual address pointer to a memory-mapped region. - * These are declared as "long" instead of u32* to force you to - * use readb()/writeb()/memcpy_fromio()/etc to access them. - * (On x86 we could probably get away with treating them as - * pointers.) - */ -typedef long VMMIO8; /**< #VMMIO pointing to 8-bit data */ -typedef long VMMIO16;/**< #VMMIO pointing to 16-bit data */ -typedef long VMMIO32;/**< #VMMIO pointing to 32-bit data */ - #define LOCKSEM(sem) down_interruptible(sem) #define LOCKSEM_UNINTERRUPTIBLE(sem) down(sem) #define UNLOCKSEM(sem) up(sem) -- GitLab From e5700df5238577e4e570d08a8ee1aa126731dae7 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:46 -0400 Subject: [PATCH 0478/9167] staging: unisys: fix formatting in timskmod.h Fix all whitespace formatting issues in timskmod.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index b20fc9dfc4a7..59144ba3c40b 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -293,6 +293,7 @@ static inline struct cdev *cdev_alloc_init(struct module *owner, const struct file_operations *fops) { struct cdev *cdev = NULL; + cdev = cdev_alloc(); if (!cdev) return NULL; -- GitLab From f2170625b24f6224eec64f591b9360025ccae16f Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:47 -0400 Subject: [PATCH 0479/9167] staging: unisys: get rid of semaphore macros Remove all of the semaphore macros from timskmod.h and switch all uses of those types to the correct function names. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 28 ------------------- drivers/staging/unisys/uislib/uislib.c | 16 +++++------ .../unisys/visorchipset/visorchipset_main.c | 16 +++++------ 3 files changed, 16 insertions(+), 44 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index 59144ba3c40b..8e0ae45d0f9a 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -71,34 +71,6 @@ #define HOSTADDRESS unsigned long long #endif -#define LOCKSEM(sem) down_interruptible(sem) -#define LOCKSEM_UNINTERRUPTIBLE(sem) down(sem) -#define UNLOCKSEM(sem) up(sem) - -/** lock read/write semaphore for reading. - Note that all read/write semaphores are of the "uninterruptible" variety. - @param sem (rw_semaphore *) points to semaphore to lock - */ -#define LOCKREADSEM(sem) down_read(sem) - -/** unlock read/write semaphore for reading. - Note that all read/write semaphores are of the "uninterruptible" variety. - @param sem (rw_semaphore *) points to semaphore to unlock - */ -#define UNLOCKREADSEM(sem) up_read(sem) - -/** lock read/write semaphore for writing. - Note that all read/write semaphores are of the "uninterruptible" variety. - @param sem (rw_semaphore *) points to semaphore to lock - */ -#define LOCKWRITESEM(sem) down_write(sem) - -/** unlock read/write semaphore for writing. - Note that all read/write semaphores are of the "uninterruptible" variety. - @param sem (rw_semaphore *) points to semaphore to unlock - */ -#define UNLOCKWRITESEM(sem) up_write(sem) - #ifdef ENABLE_RETURN_TRACE #define RETTRACE(x) \ do { \ diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c index a3a96ad5e617..4cb3487b58df 100644 --- a/drivers/staging/unisys/uislib/uislib.c +++ b/drivers/staging/unisys/uislib/uislib.c @@ -1362,18 +1362,18 @@ Process_Incoming(void *v) struct device_info *dev = NULL; /* poll each channel for input */ - LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels); + down(&Lock_Polling_Device_Channels); new_tail = NULL; list_for_each_safe(lelt, tmp, &List_Polling_Device_Channels) { int rc = 0; dev = list_entry(lelt, struct device_info, list_polling_device_channels); - LOCKSEM_UNINTERRUPTIBLE(&dev->interrupt_callback_lock); + down(&dev->interrupt_callback_lock); if (dev->interrupt) rc = dev->interrupt(dev->interrupt_context); else continue; - UNLOCKSEM(&dev->interrupt_callback_lock); + up(&dev->interrupt_callback_lock); if (rc) { /* dev->interrupt returned, but there * is still more work to do. @@ -1400,7 +1400,7 @@ Process_Incoming(void *v) tot_moved_to_tail_cnt++; list_move_tail(new_tail, &List_Polling_Device_Channels); } - UNLOCKSEM(&Lock_Polling_Device_Channels); + up(&Lock_Polling_Device_Channels); cur_cycles = get_cycles(); delta_cycles = cur_cycles - old_cycles; old_cycles = cur_cycles; @@ -1470,14 +1470,14 @@ uislib_enable_channel_interrupts(u32 busNo, u32 devNo, (int) (devNo)); return; } - LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels); + down(&Lock_Polling_Device_Channels); Initialize_incoming_thread(); dev->interrupt = interrupt; dev->interrupt_context = interrupt_context; dev->polling = TRUE; list_add_tail(&(dev->list_polling_device_channels), &List_Polling_Device_Channels); - UNLOCKSEM(&Lock_Polling_Device_Channels); + up(&Lock_Polling_Device_Channels); } EXPORT_SYMBOL_GPL(uislib_enable_channel_interrupts); @@ -1494,11 +1494,11 @@ uislib_disable_channel_interrupts(u32 busNo, u32 devNo) (int) (devNo)); return; } - LOCKSEM_UNINTERRUPTIBLE(&Lock_Polling_Device_Channels); + down(&Lock_Polling_Device_Channels); list_del(&dev->list_polling_device_channels); dev->polling = FALSE; dev->interrupt = NULL; - UNLOCKSEM(&Lock_Polling_Device_Channels); + up(&Lock_Polling_Device_Channels); } EXPORT_SYMBOL_GPL(uislib_disable_channel_interrupts); diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c index fe3c0127d255..e860512f1100 100644 --- a/drivers/staging/unisys/visorchipset/visorchipset_main.c +++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c @@ -594,7 +594,7 @@ visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, VISORCHIPSET_BUSDEV_RESPONDERS *responders, ULTRA_VBUS_DEVICEINFO *driverInfo) { - LOCKSEM_UNINTERRUPTIBLE(&NotifierLock); + down(&NotifierLock); if (notifiers == NULL) { memset(&BusDev_Server_Notifiers, 0, sizeof(BusDev_Server_Notifiers)); @@ -609,7 +609,7 @@ visorchipset_register_busdev_server(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, BusDeviceInfo_Init(driverInfo, "chipset", "visorchipset", VERSION, NULL); - UNLOCKSEM(&NotifierLock); + up(&NotifierLock); } EXPORT_SYMBOL_GPL(visorchipset_register_busdev_server); @@ -618,7 +618,7 @@ visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, VISORCHIPSET_BUSDEV_RESPONDERS *responders, ULTRA_VBUS_DEVICEINFO *driverInfo) { - LOCKSEM_UNINTERRUPTIBLE(&NotifierLock); + down(&NotifierLock); if (notifiers == NULL) { memset(&BusDev_Client_Notifiers, 0, sizeof(BusDev_Client_Notifiers)); @@ -632,7 +632,7 @@ visorchipset_register_busdev_client(VISORCHIPSET_BUSDEV_NOTIFIERS *notifiers, if (driverInfo) BusDeviceInfo_Init(driverInfo, "chipset(bolts)", "visorchipset", VERSION, NULL); - UNLOCKSEM(&NotifierLock); + up(&NotifierLock); } EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client); @@ -944,7 +944,7 @@ bus_epilog(u32 busNo, } else pBusInfo->pendingMsgHdr.Id = CONTROLVM_INVALID; - LOCKSEM_UNINTERRUPTIBLE(&NotifierLock); + down(&NotifierLock); if (response == CONTROLVM_RESP_SUCCESS) { switch (cmd) { case CONTROLVM_BUS_CREATE: @@ -989,7 +989,7 @@ bus_epilog(u32 busNo, ; else bus_responder(cmd, busNo, response); - UNLOCKSEM(&NotifierLock); + up(&NotifierLock); } static void @@ -1021,7 +1021,7 @@ device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, } else pDevInfo->pendingMsgHdr.Id = CONTROLVM_INVALID; - LOCKSEM_UNINTERRUPTIBLE(&NotifierLock); + down(&NotifierLock); if (response >= 0) { switch (cmd) { case CONTROLVM_DEVICE_CREATE: @@ -1087,7 +1087,7 @@ device_epilog(u32 busNo, u32 devNo, ULTRA_SEGMENT_STATE state, u32 cmd, ; else device_responder(cmd, busNo, devNo, response); - UNLOCKSEM(&NotifierLock); + up(&NotifierLock); } static void -- GitLab From 52d13a618aa9b84b8ed8b761ca76cec51701afde Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:48 -0400 Subject: [PATCH 0480/9167] staging: unisys: remove unused macros from timskmod.h Several macros in timskmod.h are unused. Remove them. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/timskmod.h | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/drivers/staging/unisys/include/timskmod.h b/drivers/staging/unisys/include/timskmod.h index 8e0ae45d0f9a..e5e4ecd96495 100644 --- a/drivers/staging/unisys/include/timskmod.h +++ b/drivers/staging/unisys/include/timskmod.h @@ -62,8 +62,6 @@ #if !defined SUCCESS #define SUCCESS 0 #endif -#define FAILURE (-1) -#define DRIVERNAMEMAX 50 #define MIN(a, b) (((a) < (b)) ? (a) : (b)) #define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define STRUCTSEQUAL(x, y) (memcmp(&x, &y, sizeof(x)) == 0) @@ -71,18 +69,6 @@ #define HOSTADDRESS unsigned long long #endif -#ifdef ENABLE_RETURN_TRACE -#define RETTRACE(x) \ - do { \ - if (1) { \ - INFODRV("RET 0x%lx in %s", \ - (ulong)(x), __func__); \ - } \ - } while (0) -#else -#define RETTRACE(x) -#endif - /** Try to evaulate the provided expression, and do a RETINT(x) iff * the expression evaluates to < 0. * @param x the expression to try -- GitLab From 746c28e1af51cc6e7c7c6f7bc7d502f6986713a2 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:49 -0400 Subject: [PATCH 0481/9167] staging: unisys: get rid of uiscmpxchg64 Remove the uiscmpxchg64 macro from uisqueue.h and uisqueue.c. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisqueue.h | 15 --------------- drivers/staging/unisys/uislib/uisqueue.c | 6 ++---- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/unisys/include/uisqueue.h b/drivers/staging/unisys/include/uisqueue.h index a2abfa8c82fd..8983407592a9 100644 --- a/drivers/staging/unisys/include/uisqueue.h +++ b/drivers/staging/unisys/include/uisqueue.h @@ -423,19 +423,4 @@ struct guest_msgs { }; -#ifndef __xg -#define __xg(x) ((volatile long *)(x)) -#endif - -/* -* Below code is a copy of Linux kernel's cmpxchg function located at -* this place -* http://tcsxeon:8080/source/xref/00trunk-AppOS-linux/include/asm-x86/cmpxchg_64.h#84 -* Reason for creating our own version of cmpxchg along with -* UISLIB_LOCK_PREFIX is to make the operation atomic even for non SMP -* guests. -*/ - -#define uislibcmpxchg64(p, o, n, s) cmpxchg(p, o, n) - #endif /* __UISQUEUE_H__ */ diff --git a/drivers/staging/unisys/uislib/uisqueue.c b/drivers/staging/unisys/uislib/uisqueue.c index 84eafca5e45c..f52bca1d95b1 100644 --- a/drivers/staging/unisys/uislib/uisqueue.c +++ b/drivers/staging/unisys/uislib/uisqueue.c @@ -43,8 +43,7 @@ uisqueue_InterlockedOr(unsigned long long __iomem *Target, j = readq(Target); do { i = j; - j = uislibcmpxchg64((__force unsigned long long *)Target, - i, i | Set, sizeof(*(Target))); + j = cmpxchg((__force unsigned long long *)Target, i, i | Set); } while (i != j); @@ -62,8 +61,7 @@ uisqueue_InterlockedAnd(unsigned long long __iomem *Target, j = readq(Target); do { i = j; - j = uislibcmpxchg64((__force unsigned long long *)Target, - i, i & Set, sizeof(*(Target))); + j = cmpxchg((__force unsigned long long *)Target, i, i & Set); } while (i != j); -- GitLab From 613cbd9f0048d8220533b98f0924cee07546f240 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:50 -0400 Subject: [PATCH 0482/9167] staging: unisys: fix whitespace in uisutils.h Correct a couple of missing blank lines in uisutils.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/include/uisutils.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/unisys/include/uisutils.h b/drivers/staging/unisys/include/uisutils.h index a1c193c5827e..f1a1b0d2c899 100644 --- a/drivers/staging/unisys/include/uisutils.h +++ b/drivers/staging/unisys/include/uisutils.h @@ -84,6 +84,7 @@ static inline void __iomem * dbg_ioremap_cache(u64 addr, unsigned long size, char *file, int line) { void __iomem *new; + new = ioremap_cache(addr, size); return new; } @@ -94,6 +95,7 @@ static inline void * dbg_ioremap(u64 addr, unsigned long size, char *file, int line) { void *new; + new = ioremap(addr, size); return new; } -- GitLab From 3239c1cc156a1acaaccdf79dc2a9601798dbd109 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:51 -0400 Subject: [PATCH 0483/9167] staging: unisys: fix line lengths in controlvmcompletionstatus.h The controlVM status file had comments going over the 80 character limit. These are moved to the next line and the spacing is fixed. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../include/controlvmcompletionstatus.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/controlvmcompletionstatus.h b/drivers/staging/unisys/common-spar/include/controlvmcompletionstatus.h index db77d6f626a1..f74f5d8c2820 100644 --- a/drivers/staging/unisys/common-spar/include/controlvmcompletionstatus.h +++ b/drivers/staging/unisys/common-spar/include/controlvmcompletionstatus.h @@ -62,14 +62,16 @@ * DEVICE_CREATE, * DEVICE_DESTROY */ /* Unable to invoke VIRTPCI callback */ -#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR 605 /* BUS_CREATE, - * BUS_DESTROY, - * DEVICE_CREATE, - * DEVICE_DESTROY */ +#define CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR 605 + /* BUS_CREATE, + * BUS_DESTROY, + * DEVICE_CREATE, + * DEVICE_DESTROY */ /* VIRTPCI Callback returned error */ -#define CONTROLVM_RESP_ERROR_GENERIC_DRIVER_CALLBACK_ERROR 606 /* SWITCH_ATTACHEXTPORT, - * SWITCH_DETACHEXTPORT - * DEVICE_CONFIGURE */ +#define CONTROLVM_RESP_ERROR_GENERIC_DRIVER_CALLBACK_ERROR 606 + /* SWITCH_ATTACHEXTPORT, + * SWITCH_DETACHEXTPORT + * DEVICE_CONFIGURE */ /* generic device callback returned error */ /* Bus Related------------------------------------------------------[700-799] */ -- GitLab From 3c1a653b90d7b3a681a7e49feef32e3e290b36f0 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:52 -0400 Subject: [PATCH 0484/9167] staging: unisys: fix spacing in iovmcall_gnuc.h There are spacing errors in the functions in iovmcall_gnuc. Fix these. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h b/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h index fe9598c941a6..55437f7e1301 100644 --- a/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h +++ b/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h @@ -19,8 +19,8 @@ __unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx, unsigned long reg_ecx) { unsigned long result = 0; - unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx; + cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx); if (cpuid_ecx & 0x80000000) { __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : @@ -39,8 +39,8 @@ __unisys_extended_vmcall_gnuc(unsigned long long tuple, unsigned long long reg_edx) { unsigned long result = 0; - unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx; + cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx); if (cpuid_ecx & 0x80000000) { __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : -- GitLab From ffe58457492be4bea21d38abf4b84ad3e11abfff Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:53 -0400 Subject: [PATCH 0485/9167] staging: unisys: clean up vmcall functions Clean up the format of the vmcall functions in iovmcall_gnuc.h. These functions are rewritten for clarity and to correct the indention, without changing any functionality. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- .../common-spar/include/iovmcall_gnuc.h | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h b/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h index 55437f7e1301..57dd93e0cc83 100644 --- a/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h +++ b/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h @@ -22,13 +22,11 @@ __unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx, unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx; cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx); - if (cpuid_ecx & 0x80000000) { - __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : - "a"(tuple), "b"(reg_ebx), "c"(reg_ecx) - ); - } else { - result = -1; - } + if (!(cpuid_ecx & 0x80000000)) + return -1; + + __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : + "a"(tuple), "b"(reg_ebx), "c"(reg_ecx)); return result; } @@ -42,12 +40,10 @@ __unisys_extended_vmcall_gnuc(unsigned long long tuple, unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx; cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx); - if (cpuid_ecx & 0x80000000) { - __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : - "a"(tuple), "b"(reg_ebx), "c"(reg_ecx), - "d"(reg_edx)); - } else { - result = -1; - } + if (!(cpuid_ecx & 0x80000000)) + return -1; + + __asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) : + "a"(tuple), "b"(reg_ebx), "c"(reg_ecx), "d"(reg_edx)); return result; - } +} -- GitLab From 11c4eba1ad4174512c8b8a682c3d41f97d286611 Mon Sep 17 00:00:00 2001 From: Benjamin Romer Date: Tue, 5 Aug 2014 14:57:54 -0400 Subject: [PATCH 0486/9167] staging: unisys: fix spacing in vbusdeviceinfo.h There was a missing line between declarations and code in vbusdeviceinfo.h. Signed-off-by: Benjamin Romer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h index 54593c11e70e..3bbdc2bb7ebf 100644 --- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h +++ b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h @@ -54,6 +54,7 @@ vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax) { int chars = 0; int nonprintable_streak = 0; + while (srcmax > 0) { if ((*src >= ' ') && (*src < 0x7f)) { if (nonprintable_streak) { -- GitLab From 1566ac0bc919187bb605403f072fd3ebc58b00a0 Mon Sep 17 00:00:00 2001 From: "Tobenna P. Igwe" Date: Wed, 6 Aug 2014 19:59:42 +0100 Subject: [PATCH 0487/9167] staging: unisys: uislib: Fixed missing blank line coding style issue Fixed coding style issue "Missing a blank line after declarations" detected by the 'checkpatch.pl' script. Signed-off-by: Tobenna P. Igwe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/unisys/uislib/uisutils.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/unisys/uislib/uisutils.c b/drivers/staging/unisys/uislib/uisutils.c index 3a59965aa9f9..423cbc4b72f9 100644 --- a/drivers/staging/unisys/uislib/uisutils.c +++ b/drivers/staging/unisys/uislib/uisutils.c @@ -118,6 +118,7 @@ uisctrl_register_req_handler_ex(uuid_le switchTypeGuid, { ReqHandlerInfo_t *pReqHandlerInfo; int rc = 0; /* assume failure */ + LOGINF("type=%pUL, controlfunc=0x%p.\n", &switchTypeGuid, controlfunc); if (!controlfunc) { @@ -162,6 +163,7 @@ int uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid) { int rc = 0; /* assume failure */ + LOGINF("type=%pUL.\n", &switchTypeGuid); if (ReqHandlerDel(switchTypeGuid) < 0) { LOGERR("failed to remove %pUL from server list\n", @@ -250,6 +252,7 @@ uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx, void *skb_in, if (skb_shinfo(skb)->frag_list) { struct sk_buff *skbinlist; int c; + for (skbinlist = skb_shinfo(skb)->frag_list; skbinlist; skbinlist = skbinlist->next) { @@ -307,6 +310,7 @@ ReqHandlerFind(uuid_le switchTypeGuid) { struct list_head *lelt, *tmp; ReqHandlerInfo_t *entry = NULL; + spin_lock(&ReqHandlerInfo_list_lock); list_for_each_safe(lelt, tmp, &ReqHandlerInfo_list) { entry = list_entry(lelt, ReqHandlerInfo_t, list_link); @@ -325,6 +329,7 @@ ReqHandlerDel(uuid_le switchTypeGuid) struct list_head *lelt, *tmp; ReqHandlerInfo_t *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); -- GitLab From 53bd9a204816a3513c5fa3c6170fe33100bb3f4d Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:38 +0100 Subject: [PATCH 0488/9167] staging: comedi: amplc_pci224: reformat some comments Reformat comments to fit in with the preferred coding style, including the copyright and comedi driver description comments at the start of the file. Also, remove a boiler-plate comment for the comedi device private data structure. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 214 +++++++++--------- 1 file changed, 109 insertions(+), 105 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 45aba1f950fc..72506bf6aa1e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1,102 +1,103 @@ /* - comedi/drivers/amplc_pci224.c - Driver for Amplicon PCI224 and PCI234 AO boards. - - Copyright (C) 2005 MEV Ltd. - - COMEDI - Linux Control and Measurement Device Interface - Copyright (C) 1998,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. + * comedi/drivers/amplc_pci224.c + * Driver for Amplicon PCI224 and PCI234 AO boards. + * + * Copyright (C) 2005 MEV Ltd. + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 1998,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. + */ - 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: amplc_pci224 -Description: Amplicon PCI224, PCI234 -Author: Ian Abbott -Devices: [Amplicon] PCI224 (amplc_pci224 or pci224), - PCI234 (amplc_pci224 or pci234) -Updated: Wed, 22 Oct 2008 12:25:08 +0100 -Status: works, but see caveats - -Supports: - - - ao_insn read/write - - ao_do_cmd mode with the following sources: - - - start_src TRIG_INT TRIG_EXT - - scan_begin_src TRIG_TIMER TRIG_EXT - - convert_src TRIG_NOW - - scan_end_src TRIG_COUNT - - stop_src TRIG_COUNT TRIG_EXT TRIG_NONE - - The channel list must contain at least one channel with no repeated - channels. The scan end count must equal the number of channels in - the channel list. - - There is only one external trigger source so only one of start_src, - scan_begin_src or stop_src may use TRIG_EXT. - -Configuration options - PCI224: - [0] - PCI bus of device (optional). - [1] - PCI slot of device (optional). - If bus/slot is not specified, the first available PCI device - will be used. - [2] - Select available ranges according to jumper LK1. All channels - are set to the same range: - 0=Jumper position 1-2 (factory default), 4 software-selectable - internal voltage references, giving 4 bipolar and 4 unipolar - ranges: - [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V], - [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V]. - 1=Jumper position 2-3, 1 external voltage reference, giving - 1 bipolar and 1 unipolar range: - [-Vext,+Vext], [0,+Vext]. - -Configuration options - PCI234: - [0] - PCI bus of device (optional). - [1] - PCI slot of device (optional). - If bus/slot is not specified, the first available PCI device - will be used. - [2] - Select internal or external voltage reference according to - jumper LK1. This affects all channels: - 0=Jumper position 1-2 (factory default), Vref=5V internal. - 1=Jumper position 2-3, Vref=Vext external. - [3] - Select channel 0 range according to jumper LK2: - 0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref] - (10V bipolar when options[2]=0). - 1=Jumper position 1-2, range [-Vref,+Vref] - (5V bipolar when options[2]=0). - [4] - Select channel 1 range according to jumper LK3: cf. options[3]. - [5] - Select channel 2 range according to jumper LK4: cf. options[3]. - [6] - Select channel 3 range according to jumper LK5: cf. options[3]. - -Passing a zero for an option is the same as leaving it unspecified. - -Caveats: - - 1) All channels on the PCI224 share the same range. Any change to the - range as a result of insn_write or a streaming command will affect - the output voltages of all channels, including those not specified - by the instruction or command. - - 2) For the analog output command, the first scan may be triggered - falsely at the start of acquisition. This occurs when the DAC scan - trigger source is switched from 'none' to 'timer' (scan_begin_src = - TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start - of acquisition and the trigger source is at logic level 1 at the - time of the switch. This is very likely for TRIG_TIMER. For - TRIG_EXT, it depends on the state of the external line and whether - the CR_INVERT flag has been set. The remaining scans are triggered - correctly. -*/ + * Driver: amplc_pci224 + * Description: Amplicon PCI224, PCI234 + * Author: Ian Abbott + * Devices: [Amplicon] PCI224 (amplc_pci224 or pci224), + * PCI234 (amplc_pci224 or pci234) + * Updated: Wed, 22 Oct 2008 12:25:08 +0100 + * Status: works, but see caveats + * + * Supports: + * + * - ao_insn read/write + * - ao_do_cmd mode with the following sources: + * + * - start_src TRIG_INT TRIG_EXT + * - scan_begin_src TRIG_TIMER TRIG_EXT + * - convert_src TRIG_NOW + * - scan_end_src TRIG_COUNT + * - stop_src TRIG_COUNT TRIG_EXT TRIG_NONE + * + * The channel list must contain at least one channel with no repeated + * channels. The scan end count must equal the number of channels in + * the channel list. + * + * There is only one external trigger source so only one of start_src, + * scan_begin_src or stop_src may use TRIG_EXT. + * + * Configuration options - PCI224: + * [0] - PCI bus of device (optional). + * [1] - PCI slot of device (optional). + * If bus/slot is not specified, the first available PCI device + * will be used. + * [2] - Select available ranges according to jumper LK1. All channels + * are set to the same range: + * 0=Jumper position 1-2 (factory default), 4 software-selectable + * internal voltage references, giving 4 bipolar and 4 unipolar + * ranges: + * [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V], + * [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V]. + * 1=Jumper position 2-3, 1 external voltage reference, giving + * 1 bipolar and 1 unipolar range: + * [-Vext,+Vext], [0,+Vext]. + * + * Configuration options - PCI234: + * [0] - PCI bus of device (optional). + * [1] - PCI slot of device (optional). + * If bus/slot is not specified, the first available PCI device + * will be used. + * [2] - Select internal or external voltage reference according to + * jumper LK1. This affects all channels: + * 0=Jumper position 1-2 (factory default), Vref=5V internal. + * 1=Jumper position 2-3, Vref=Vext external. + * [3] - Select channel 0 range according to jumper LK2: + * 0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref] + * (10V bipolar when options[2]=0). + * 1=Jumper position 1-2, range [-Vref,+Vref] + * (5V bipolar when options[2]=0). + * [4] - Select channel 1 range according to jumper LK3: cf. options[3]. + * [5] - Select channel 2 range according to jumper LK4: cf. options[3]. + * [6] - Select channel 3 range according to jumper LK5: cf. options[3]. + * + * Passing a zero for an option is the same as leaving it unspecified. + * + * Caveats: + * + * 1) All channels on the PCI224 share the same range. Any change to the + * range as a result of insn_write or a streaming command will affect + * the output voltages of all channels, including those not specified + * by the instruction or command. + * + * 2) For the analog output command, the first scan may be triggered + * falsely at the start of acquisition. This occurs when the DAC scan + * trigger source is switched from 'none' to 'timer' (scan_begin_src = + * TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start + * of acquisition and the trigger source is at logic level 1 at the + * time of the switch. This is very likely for TRIG_TIMER. For + * TRIG_EXT, it depends on the state of the external line and whether + * the CR_INVERT flag has been set. The remaining scans are triggered + * correctly. + */ #include #include @@ -299,16 +300,20 @@ static const unsigned short hwrange_pci224_external[2] = { PCI224_DACCON_POLAR_UNI, }; -/* The hardware selectable Vref*2 external range for PCI234 - * (option[2] == 1, option[3+n] == 0). */ +/* + * The hardware selectable Vref*2 external range for PCI234 + * (option[2] == 1, option[3+n] == 0). + */ static const struct comedi_lrange range_pci234_ext2 = { 1, { RANGE_ext(-2, 2) } }; -/* The hardware selectable Vref external range for PCI234 - * (option[2] == 1, option[3+n] == 1). */ +/* + * The hardware selectable Vref external range for PCI234 + * (option[2] == 1, option[3+n] == 1). + */ static const struct comedi_lrange range_pci234_ext = { 1, { RANGE_ext(-1, 1) @@ -356,9 +361,6 @@ static const struct pci224_board pci224_boards[] = { }, }; -/* this structure is for data unique to this hardware driver. If - several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device struct. */ struct pci224_private { const unsigned short *hwrange; unsigned long iobase1; @@ -428,8 +430,10 @@ pci224_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s, chan = CR_CHAN(insn->chanspec); range = CR_RANGE(insn->chanspec); - /* Writing a list of values to an AO channel is probably not - * very useful, but that's how the interface is defined. */ + /* + * Writing a list of values to an AO channel is probably not + * very useful, but that's how the interface is defined. + */ for (i = 0; i < insn->n; i++) pci224_ao_set_data(dev, chan, range, data[i]); -- GitLab From 7c40bd48dbae93e7bd8369d8326f8850eff98f73 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:39 +0100 Subject: [PATCH 0489/9167] staging: comedi: amplc_pci224: fix checkpatch line over 80 characters Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 72506bf6aa1e..6a570ef1f5ab 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -565,7 +565,8 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, 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) { + if (cmd->stop_src == TRIG_COUNT && + devpriv->ao_stop_count == 0) { /* FIFO empty at end of counted acquisition. */ s->async->events |= COMEDI_CB_EOA; cfc_handle_events(dev, s); -- GitLab From d0f2c953b692a81acafcb71f35b7cff578099de0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:40 +0100 Subject: [PATCH 0490/9167] staging: comedi: amplc_pci224: blank lines aren't necessary before a close brace '}' Fix checkpatch issues: "CHECK: Blank lines aren't necessary before a close brace '}'". Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 6a570ef1f5ab..e34bc5e76aff 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -557,7 +557,6 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, /* 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). */ @@ -644,7 +643,6 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, trig = PCI224_DACCON_TRIG_EXTN; else trig = PCI224_DACCON_TRIG_EXTP; - } devpriv->daccon = COMBINE(devpriv->daccon, trig, PCI224_DACCON_TRIG_MASK); @@ -908,7 +906,6 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) for (j = 0; j < cmd->chanlist_len; j++) { if (CR_CHAN(cmd->chanlist[j]) < ch) rank++; - } devpriv->ao_scan_order[rank] = i; } @@ -1002,7 +999,6 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, /* Munge the data. */ for (i = 0; i < length; i++) array[i] = (array[i] << shift) - offset; - } /* @@ -1038,11 +1034,9 @@ static irqreturn_t pci224_interrupt(int irq, void *d) pci224_ao_start(dev, s); else if (cmd->stop_src == TRIG_EXT) pci224_ao_stop(dev, s); - } if (valid_intstat & PCI224_INTR_DAC) pci224_ao_handle_fifo(dev, s); - } /* Reenable interrupt sources. */ spin_lock_irqsave(&devpriv->ao_spinlock, flags); -- GitLab From ab2064a5cbd732f5228c718cb7f1afd72ea180da Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:41 +0100 Subject: [PATCH 0491/9167] staging: comedi: amplc_pci224: multiple assignments should be avoided Fix checkpatch issue: "CHECK: multiple assignments should be avoided". Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index e34bc5e76aff..8e5d94abacd4 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1192,11 +1192,12 @@ static int pci224_attach_common(struct comedi_device *dev, /* PCI234 range options. */ const struct comedi_lrange **range_table_list; - s->range_table_list = range_table_list = + range_table_list = kmalloc(sizeof(struct comedi_lrange *) * s->n_chan, GFP_KERNEL); - if (!s->range_table_list) + if (!range_table_list) return -ENOMEM; + s->range_table_list = range_table_list; if (options) { for (n = 2; n < 3 + s->n_chan; n++) { -- GitLab From 71e70e9f6daea58bb5ef03d17ba26c630fcac1d2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:42 +0100 Subject: [PATCH 0492/9167] staging: comedi: amplc_pci224: fix spinlock_t definition without comment Fix checkpatch issue: "CHECK: spinlock_t definition without comment". Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten 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 8e5d94abacd4..dfeb70cc9775 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -365,7 +365,7 @@ struct pci224_private { const unsigned short *hwrange; unsigned long iobase1; unsigned long state; - spinlock_t ao_spinlock; + spinlock_t ao_spinlock; /* spinlock for AO command handling */ unsigned int *ao_readback; unsigned short *ao_scan_vals; unsigned char *ao_scan_order; -- GitLab From 5b18dc660a4e8b3a60d3f2696625b87af40b4d81 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:43 +0100 Subject: [PATCH 0493/9167] staging: comedi: amplc_pci224: add whitespace to pci224_boards[] Add a bit of whitespace to the initializer of `pci224_boards[]` for aesthetic reasons. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index dfeb70cc9775..8ce0f4fa09c3 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -341,24 +341,24 @@ struct pci224_board { static const struct pci224_board pci224_boards[] = { { - .name = "pci224", - .devid = PCI_DEVICE_ID_AMPLICON_PCI224, - .model = pci224_model, - .ao_chans = 16, - .ao_bits = 12, - }, + .name = "pci224", + .devid = PCI_DEVICE_ID_AMPLICON_PCI224, + .model = pci224_model, + .ao_chans = 16, + .ao_bits = 12, + }, { - .name = "pci234", - .devid = PCI_DEVICE_ID_AMPLICON_PCI234, - .model = pci234_model, - .ao_chans = 4, - .ao_bits = 16, - }, + .name = "pci234", + .devid = PCI_DEVICE_ID_AMPLICON_PCI234, + .model = pci234_model, + .ao_chans = 4, + .ao_bits = 16, + }, { - .name = "amplc_pci224", - .devid = PCI_DEVICE_ID_INVALID, - .model = any_model, /* wildcard */ - }, + .name = "amplc_pci224", + .devid = PCI_DEVICE_ID_INVALID, + .model = any_model, /* wildcard */ + }, }; struct pci224_private { -- GitLab From bf6002d898630cc3042f5f727f2ebf0ec4ebabb0 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:44 +0100 Subject: [PATCH 0494/9167] staging: comedi: amplc_pci224: set a more descriptive MODULE_DESCRIPTION() Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten 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 8ce0f4fa09c3..f7862375bbbc 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1362,5 +1362,5 @@ static struct pci_driver amplc_pci224_pci_driver = { module_comedi_pci_driver(amplc_pci224_driver, amplc_pci224_pci_driver); MODULE_AUTHOR("Comedi http://www.comedi.org"); -MODULE_DESCRIPTION("Comedi low-level driver"); +MODULE_DESCRIPTION("Comedi driver for Amplicon PCI224 and PCI234 AO boards"); MODULE_LICENSE("GPL"); -- GitLab From fe3cda6d39bba3368ed9823f78bbd145e3a1416e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:45 +0100 Subject: [PATCH 0495/9167] staging: comedi: amplc_pci224: omit '!= 0' from logical expressions Since anything non-zero is logically "true", don't bother doing "not-equal" comparisons with zero, except when testing for an explicit number 0 (not as a result of bit tests for example). Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index f7862375bbbc..0ac05fb5ac5d 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -759,13 +759,13 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, break; case TRIG_EXT: /* Force to external trigger 0. */ - if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) { + if (cmd->start_arg & ~CR_FLAGS_MASK) { cmd->start_arg = COMBINE(cmd->start_arg, 0, ~CR_FLAGS_MASK); err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ - if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) { + if (cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) { cmd->start_arg = COMBINE(cmd->start_arg, 0, CR_FLAGS_MASK & ~CR_EDGE); err |= -EINVAL; @@ -785,14 +785,14 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, break; case TRIG_EXT: /* Force to external trigger 0. */ - if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) { + if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); err |= -EINVAL; } /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */ - if ((cmd->scan_begin_arg & CR_FLAGS_MASK & - ~(CR_EDGE | CR_INVERT)) != 0) { + if (cmd->scan_begin_arg & CR_FLAGS_MASK & + ~(CR_EDGE | CR_INVERT)) { cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); @@ -810,13 +810,13 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, break; case TRIG_EXT: /* Force to external trigger 0. */ - if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) { + if (cmd->stop_arg & ~CR_FLAGS_MASK) { cmd->stop_arg = COMBINE(cmd->stop_arg, 0, ~CR_FLAGS_MASK); err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ - if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) { + if (cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) { cmd->stop_arg = COMBINE(cmd->stop_arg, 0, CR_FLAGS_MASK & ~CR_EDGE); } @@ -1026,7 +1026,7 @@ static irqreturn_t pci224_interrupt(int irq, void *d) devpriv->intr_running = 1; devpriv->intr_cpuid = THISCPU; spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); - if (valid_intstat != 0) { + if (valid_intstat) { cmd = &s->async->cmd; if (valid_intstat & PCI224_INTR_EXT) { devpriv->intsce &= ~PCI224_INTR_EXT; -- GitLab From e038756110401b6bca6b1091cbcb668fe2741756 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:46 +0100 Subject: [PATCH 0496/9167] staging: comedi: amplc_pci224: remove some unnecessary parentheses Remove some pairs of parentheses that don't really improve readability. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 0ac05fb5ac5d..a7f34547e781 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -396,8 +396,8 @@ pci224_ao_set_data(struct comedi_device *dev, int chan, int range, outw(1 << chan, dev->iobase + PCI224_DACCEN); /* Set range and reset FIFO. */ devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range], - (PCI224_DACCON_POLAR_MASK | - PCI224_DACCON_VREF_MASK)); + PCI224_DACCON_POLAR_MASK | + PCI224_DACCON_VREF_MASK); outw(devpriv->daccon | PCI224_DACCON_FIFORESET, dev->iobase + PCI224_DACCON); /* @@ -685,7 +685,7 @@ static int pci224_ao_check_chanlist(struct comedi_device *dev, __func__); return -EINVAL; } - chan_mask |= (1 << chan); + chan_mask |= 1 << chan; if (range != range0) { dev_dbg(dev->class_dev, @@ -925,13 +925,13 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * N.B. DAC FIFO interrupts are currently disabled. */ devpriv->daccon = COMBINE(devpriv->daccon, - (devpriv-> - hwrange[range] | PCI224_DACCON_TRIG_NONE | - PCI224_DACCON_FIFOINTR_NHALF), - (PCI224_DACCON_POLAR_MASK | - PCI224_DACCON_VREF_MASK | - PCI224_DACCON_TRIG_MASK | - PCI224_DACCON_FIFOINTR_MASK)); + devpriv->hwrange[range] | + PCI224_DACCON_TRIG_NONE | + PCI224_DACCON_FIFOINTR_NHALF, + PCI224_DACCON_POLAR_MASK | + PCI224_DACCON_VREF_MASK | + PCI224_DACCON_TRIG_MASK | + PCI224_DACCON_FIFOINTR_MASK); outw(devpriv->daccon | PCI224_DACCON_FIFORESET, dev->iobase + PCI224_DACCON); @@ -1161,9 +1161,8 @@ static int pci224_attach_common(struct comedi_device *dev, outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON); outw(0, dev->iobase + PCI224_DACCEN); outw(0, dev->iobase + PCI224_FIFOSIZ); - devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI | - PCI224_DACCON_FIFOENAB | - PCI224_DACCON_FIFOINTR_EMPTY); + devpriv->daccon = PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI | + PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY; outw(devpriv->daccon | PCI224_DACCON_FIFORESET, dev->iobase + PCI224_DACCON); -- GitLab From 56eb5cbc5894b206ef9d4b5d3bcc2e1b232e8c22 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:47 +0100 Subject: [PATCH 0497/9167] staging: comedi: amplc_pci224: reduce leading whitespace in a few places Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 53 +++++++++---------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index a7f34547e781..68fc407b1559 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -500,11 +500,10 @@ static void pci224_ao_stop(struct comedi_device *dev, spin_unlock_irqrestore(&devpriv->ao_spinlock, flags); /* Reconfigure DAC for insn_write usage. */ outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */ - devpriv->daccon = COMBINE(devpriv->daccon, - PCI224_DACCON_TRIG_SW | - PCI224_DACCON_FIFOINTR_EMPTY, - PCI224_DACCON_TRIG_MASK | - PCI224_DACCON_FIFOINTR_MASK); + devpriv->daccon = + COMBINE(devpriv->daccon, + PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY, + PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK); outw(devpriv->daccon | PCI224_DACCON_FIFORESET, dev->iobase + PCI224_DACCON); } @@ -644,8 +643,8 @@ static void pci224_ao_handle_fifo(struct comedi_device *dev, else trig = PCI224_DACCON_TRIG_EXTP; } - devpriv->daccon = COMBINE(devpriv->daccon, trig, - PCI224_DACCON_TRIG_MASK); + devpriv->daccon = + COMBINE(devpriv->daccon, trig, PCI224_DACCON_TRIG_MASK); outw(devpriv->daccon, dev->iobase + PCI224_DACCON); } @@ -717,11 +716,11 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT | TRIG_EXT); err |= cfc_check_trigger_src(&cmd->scan_begin_src, - TRIG_EXT | TRIG_TIMER); + TRIG_EXT | TRIG_TIMER); err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); err |= cfc_check_trigger_src(&cmd->stop_src, - TRIG_COUNT | TRIG_EXT | TRIG_NONE); + TRIG_COUNT | TRIG_EXT | TRIG_NONE); if (err) return 1; @@ -760,8 +759,8 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, case TRIG_EXT: /* Force to external trigger 0. */ if (cmd->start_arg & ~CR_FLAGS_MASK) { - cmd->start_arg = COMBINE(cmd->start_arg, 0, - ~CR_FLAGS_MASK); + cmd->start_arg = + COMBINE(cmd->start_arg, 0, ~CR_FLAGS_MASK); err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ @@ -786,16 +785,16 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, case TRIG_EXT: /* Force to external trigger 0. */ if (cmd->scan_begin_arg & ~CR_FLAGS_MASK) { - cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, - ~CR_FLAGS_MASK); + cmd->scan_begin_arg = + COMBINE(cmd->scan_begin_arg, 0, ~CR_FLAGS_MASK); err |= -EINVAL; } /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */ if (cmd->scan_begin_arg & CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)) { - cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0, - CR_FLAGS_MASK & - ~(CR_EDGE | CR_INVERT)); + cmd->scan_begin_arg = + COMBINE(cmd->scan_begin_arg, 0, + CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); err |= -EINVAL; } break; @@ -811,14 +810,14 @@ pci224_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, case TRIG_EXT: /* Force to external trigger 0. */ if (cmd->stop_arg & ~CR_FLAGS_MASK) { - cmd->stop_arg = COMBINE(cmd->stop_arg, 0, - ~CR_FLAGS_MASK); + cmd->stop_arg = + COMBINE(cmd->stop_arg, 0, ~CR_FLAGS_MASK); err |= -EINVAL; } /* The only flag allowed is CR_EDGE, which is ignored. */ if (cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) { - cmd->stop_arg = COMBINE(cmd->stop_arg, 0, - CR_FLAGS_MASK & ~CR_EDGE); + cmd->stop_arg = + COMBINE(cmd->stop_arg, 0, CR_FLAGS_MASK & ~CR_EDGE); } break; case TRIG_NONE: @@ -924,14 +923,12 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * * N.B. DAC FIFO interrupts are currently disabled. */ - devpriv->daccon = COMBINE(devpriv->daccon, - devpriv->hwrange[range] | - PCI224_DACCON_TRIG_NONE | - PCI224_DACCON_FIFOINTR_NHALF, - PCI224_DACCON_POLAR_MASK | - PCI224_DACCON_VREF_MASK | - PCI224_DACCON_TRIG_MASK | - PCI224_DACCON_FIFOINTR_MASK); + devpriv->daccon = + COMBINE(devpriv->daccon, + devpriv->hwrange[range] | PCI224_DACCON_TRIG_NONE | + PCI224_DACCON_FIFOINTR_NHALF, + PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK | + PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK); outw(devpriv->daccon | PCI224_DACCON_FIFORESET, dev->iobase + PCI224_DACCON); -- GitLab From 74f6084336fa651e6e063f50c2cbaa62c3e831be Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:48 +0100 Subject: [PATCH 0498/9167] staging: comedi: amplc_pci224: no need for '&function' Remove the "address-of" operator when the operand is a function. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 68fc407b1559..b8b86abf52a2 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1173,15 +1173,14 @@ static int pci224_attach_common(struct comedi_device *dev, s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; s->n_chan = thisboard->ao_chans; s->maxdata = (1 << thisboard->ao_bits) - 1; - s->insn_write = &pci224_ao_insn_write; - s->insn_read = &pci224_ao_insn_read; + s->insn_write = pci224_ao_insn_write; + s->insn_read = pci224_ao_insn_read; s->len_chanlist = s->n_chan; - dev->write_subdev = s; - s->do_cmd = &pci224_ao_cmd; - s->do_cmdtest = &pci224_ao_cmdtest; - s->cancel = &pci224_ao_cancel; - s->munge = &pci224_ao_munge; + s->do_cmd = pci224_ao_cmd; + s->do_cmdtest = pci224_ao_cmdtest; + s->cancel = pci224_ao_cancel; + s->munge = pci224_ao_munge; /* Sort out channel range options. */ if (thisboard->model == pci234_model) { -- GitLab From c7929e7133daead1b055b4dfceeed5f63ead28ae Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:49 +0100 Subject: [PATCH 0499/9167] staging: comedi: amplc_pci224: remove options to select output ranges When attaching a PCI224 or PCI234 manually via the `COMEDI_DEVCONFIG` ioctl, there are several options the user can supply that describe the state of the hardware jumpers (LK1 for PCI224, LK1 thru LK5 for PCI234). These options control how the driver sets up the AO range tables for the device. Those options are useless when the board is attached automatically via the PCI driver probe function `amplc_pci225_pci_probe()`, `comedi_pci_auto_config()`, and the comedi driver "auto_attach" handler `pci224_auto_attach()`. Rip out the range table selection options and use a single, static range table per board type, containing all the software- and hardware-selectable ranges for that board. The PCI234 used to have a per-channel `range_table_list` rather than an all-channel `range_table`, as the jumpers selected different ranges for all channels. Now that the channels are using a unified range table, use an all-channel `range_table` instead. When checking the channel list for an asynchronous command in `pci224_ao_check_chanlist()` make sure the ranges specified in the list have compatible jumper settings. We don't know how the jumpers are actually set, but we can at least avoid conflicting settings. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 243 ++++++++---------- 1 file changed, 106 insertions(+), 137 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index b8b86abf52a2..fba0198ad7b3 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -24,7 +24,7 @@ * Author: Ian Abbott * Devices: [Amplicon] PCI224 (amplc_pci224 or pci224), * PCI234 (amplc_pci224 or pci234) - * Updated: Wed, 22 Oct 2008 12:25:08 +0100 + * Updated: Wed, 30 Jul 2014 18:08:43 +0000 * Status: works, but see caveats * * Supports: @@ -45,42 +45,48 @@ * There is only one external trigger source so only one of start_src, * scan_begin_src or stop_src may use TRIG_EXT. * - * Configuration options - PCI224: + * Configuration options: * [0] - PCI bus of device (optional). * [1] - PCI slot of device (optional). * If bus/slot is not specified, the first available PCI device * will be used. - * [2] - Select available ranges according to jumper LK1. All channels - * are set to the same range: - * 0=Jumper position 1-2 (factory default), 4 software-selectable - * internal voltage references, giving 4 bipolar and 4 unipolar - * ranges: - * [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V], - * [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V]. - * 1=Jumper position 2-3, 1 external voltage reference, giving - * 1 bipolar and 1 unipolar range: - * [-Vext,+Vext], [0,+Vext]. - * - * Configuration options - PCI234: - * [0] - PCI bus of device (optional). - * [1] - PCI slot of device (optional). - * If bus/slot is not specified, the first available PCI device - * will be used. - * [2] - Select internal or external voltage reference according to - * jumper LK1. This affects all channels: - * 0=Jumper position 1-2 (factory default), Vref=5V internal. - * 1=Jumper position 2-3, Vref=Vext external. - * [3] - Select channel 0 range according to jumper LK2: - * 0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref] - * (10V bipolar when options[2]=0). - * 1=Jumper position 1-2, range [-Vref,+Vref] - * (5V bipolar when options[2]=0). - * [4] - Select channel 1 range according to jumper LK3: cf. options[3]. - * [5] - Select channel 2 range according to jumper LK4: cf. options[3]. - * [6] - Select channel 3 range according to jumper LK5: cf. options[3]. * * Passing a zero for an option is the same as leaving it unspecified. * + * Output range selection - PCI224: + * + * Output ranges on PCI224 are partly software-selectable and partly + * hardware-selectable according to jumper LK1. All channels are set + * to the same range: + * + * - LK1 position 1-2 (factory default) corresponds to the following + * comedi ranges: + * + * 0: [-10V,+10V]; 1: [-5V,+5V]; 2: [-2.5V,+2.5V], 3: [-1.25V,+1.25V], + * 4: [0,+10V], 5: [0,+5V], 6: [0,+2.5V], 7: [0,+1.25V] + * + * - LK1 position 2-3 corresponds to the following Comedi ranges, using + * an external voltage reference: + * + * 0: [-Vext,+Vext], + * 1: [0,+Vext] + * + * Output range selection - PCI234: + * + * Output ranges on PCI234 are hardware-selectable according to jumper + * LK1 which affects all channels, and jumpers LK2, LK3, LK4 and LK5 + * which affect channels 0, 1, 2 and 3 individually. LK1 chooses between + * an internal 5V reference and an external voltage reference (Vext). + * LK2/3/4/5 choose (per channel) to double the reference or not according + * to the following table: + * + * LK1 position LK2/3/4/5 pos Comedi range + * ------------- ------------- -------------- + * 2-3 (factory) 1-2 (factory) 0: [-10V,+10V] + * 2-3 (factory) 2-3 1: [-5V,+5V] + * 1-2 1-2 (factory) 2: [-2*Vext,+2*Vext] + * 1-2 2-3 3: [-Vext,+Vext] + * * Caveats: * * 1) All channels on the PCI224 share the same range. Any change to the @@ -262,9 +268,17 @@ * Range tables. */ -/* The software selectable internal ranges for PCI224 (option[2] == 0). */ -static const struct comedi_lrange range_pci224_internal = { - 8, { +/* + * The ranges for PCI224. + * + * These are partly hardware-selectable by jumper LK1 and partly + * software-selectable. + * + * All channels share the same hardware range. + */ +static const struct comedi_lrange range_pci224 = { + 10, { + /* jumper LK1 in position 1-2 (factory default) */ BIP_RANGE(10), BIP_RANGE(5), BIP_RANGE(2.5), @@ -272,11 +286,15 @@ static const struct comedi_lrange range_pci224_internal = { UNI_RANGE(10), UNI_RANGE(5), UNI_RANGE(2.5), - UNI_RANGE(1.25) + UNI_RANGE(1.25), + /* jumper LK1 in position 2-3 */ + RANGE_ext(-1, 1), /* bipolar [-Vext,+Vext] */ + RANGE_ext(0, 1), /* unipolar [0,+Vext] */ } }; -static const unsigned short hwrange_pci224_internal[8] = { +static const unsigned short hwrange_pci224[10] = { + /* jumper LK1 in position 1-2 (factory default) */ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10, PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5, PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5, @@ -285,44 +303,47 @@ static const unsigned short hwrange_pci224_internal[8] = { PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5, PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5, PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25, -}; - -/* The software selectable external ranges for PCI224 (option[2] == 1). */ -static const struct comedi_lrange range_pci224_external = { - 2, { - RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */ - RANGE_ext(0, 1) /* unipolar [0,+Vref] */ - } -}; - -static const unsigned short hwrange_pci224_external[2] = { + /* jumper LK1 in position 2-3 */ PCI224_DACCON_POLAR_BI, PCI224_DACCON_POLAR_UNI, }; -/* - * The hardware selectable Vref*2 external range for PCI234 - * (option[2] == 1, option[3+n] == 0). - */ -static const struct comedi_lrange range_pci234_ext2 = { - 1, { - RANGE_ext(-2, 2) - } +/* Used to check all channels set to the same range on PCI224. */ +static const unsigned char range_check_pci224[10] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }; /* - * The hardware selectable Vref external range for PCI234 - * (option[2] == 1, option[3+n] == 1). + * The ranges for PCI234. + * + * These are all hardware-selectable by jumper LK1 affecting all channels, + * and jumpers LK2, LK3, LK4 and LK5 affecting channels 0, 1, 2 and 3 + * individually. */ -static const struct comedi_lrange range_pci234_ext = { - 1, { - RANGE_ext(-1, 1) +static const struct comedi_lrange range_pci234 = { + 4, { + /* LK1: 1-2 (fact def), LK2/3/4/5: 2-3 (fac def) */ + BIP_RANGE(10), + /* LK1: 1-2 (fact def), LK2/3/4/5: 1-2 */ + BIP_RANGE(5), + /* LK1: 2-3, LK2/3/4/5: 2-3 (fac def) */ + RANGE_ext(-2, 2), /* bipolar [-2*Vext,+2*Vext] */ + /* LK1: 2-3, LK2/3/4/5: 1-2 */ + RANGE_ext(-1, 1), /* bipolar [-Vext,+Vext] */ } }; -/* This serves for all the PCI234 ranges. */ -static const unsigned short hwrange_pci234[1] = { - PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */ +/* N.B. PCI234 ignores the polarity bit, but software uses it. */ +static const unsigned short hwrange_pci234[4] = { + PCI224_DACCON_POLAR_BI, + PCI224_DACCON_POLAR_BI, + PCI224_DACCON_POLAR_BI, + PCI224_DACCON_POLAR_BI, +}; + +/* Used to check all channels use same LK1 setting on PCI234. */ +static const unsigned char range_check_pci234[4] = { + 0, 0, 1, 1, }; /* @@ -337,6 +358,9 @@ struct pci224_board { enum pci224_model model; unsigned int ao_chans; unsigned int ao_bits; + const struct comedi_lrange *ao_range; + const unsigned short *ao_hwrange; + const unsigned char *ao_range_check; }; static const struct pci224_board pci224_boards[] = { @@ -346,6 +370,9 @@ static const struct pci224_board pci224_boards[] = { .model = pci224_model, .ao_chans = 16, .ao_bits = 12, + .ao_range = &range_pci224, + .ao_hwrange = &hwrange_pci224[0], + .ao_range_check = &range_check_pci224[0], }, { .name = "pci234", @@ -353,6 +380,9 @@ static const struct pci224_board pci224_boards[] = { .model = pci234_model, .ao_chans = 4, .ao_bits = 16, + .ao_range = &range_pci234, + .ao_hwrange = &hwrange_pci234[0], + .ao_range_check = &range_check_pci234[0], }, { .name = "amplc_pci224", @@ -362,7 +392,6 @@ static const struct pci224_board pci224_boards[] = { }; struct pci224_private { - const unsigned short *hwrange; unsigned long iobase1; unsigned long state; spinlock_t ao_spinlock; /* spinlock for AO command handling */ @@ -395,7 +424,7 @@ pci224_ao_set_data(struct comedi_device *dev, int chan, int range, /* Enable the channel. */ outw(1 << chan, dev->iobase + PCI224_DACCEN); /* Set range and reset FIFO. */ - devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range], + devpriv->daccon = COMBINE(devpriv->daccon, thisboard->ao_hwrange[range], PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK); outw(devpriv->daccon | PCI224_DACCON_FIFORESET, @@ -670,13 +699,14 @@ static int pci224_ao_check_chanlist(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_cmd *cmd) { - unsigned int range0 = CR_RANGE(cmd->chanlist[0]); + const struct pci224_board *thisboard = comedi_board(dev); + unsigned int range_check_0; unsigned int chan_mask = 0; int i; + range_check_0 = thisboard->ao_range_check[CR_RANGE(cmd->chanlist[0])]; for (i = 0; i < cmd->chanlist_len; i++) { unsigned int chan = CR_CHAN(cmd->chanlist[i]); - unsigned int range = CR_RANGE(cmd->chanlist[i]); if (chan_mask & (1 << chan)) { dev_dbg(dev->class_dev, @@ -686,9 +716,10 @@ static int pci224_ao_check_chanlist(struct comedi_device *dev, } chan_mask |= 1 << chan; - if (range != range0) { + if (thisboard->ao_range_check[CR_RANGE(cmd->chanlist[i])] != + range_check_0) { dev_dbg(dev->class_dev, - "%s: entries in chanlist must all have the same range index\n", + "%s: entries in chanlist have incompatible ranges\n", __func__); return -EINVAL; } @@ -882,6 +913,7 @@ static void pci224_ao_start_pacer(struct comedi_device *dev, static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { + const struct pci224_board *thisboard = comedi_board(dev); struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; int range; @@ -925,7 +957,7 @@ static int pci224_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) */ devpriv->daccon = COMBINE(devpriv->daccon, - devpriv->hwrange[range] | PCI224_DACCON_TRIG_NONE | + thisboard->ao_hwrange[range] | PCI224_DACCON_TRIG_NONE | PCI224_DACCON_FIFOINTR_NHALF, PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK | PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK); @@ -974,7 +1006,6 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, void *data, unsigned int num_bytes, unsigned int chan_index) { const struct pci224_board *thisboard = comedi_board(dev); - struct pci224_private *devpriv = dev->private; struct comedi_cmd *cmd = &s->async->cmd; unsigned short *array = data; unsigned int length = num_bytes / sizeof(*array); @@ -985,7 +1016,7 @@ pci224_ao_munge(struct comedi_device *dev, struct comedi_subdevice *s, /* The hardware expects 16-bit numbers. */ shift = 16 - thisboard->ao_bits; /* Channels will be all bipolar or all unipolar. */ - if ((devpriv->hwrange[CR_RANGE(cmd->chanlist[0])] & + if ((thisboard->ao_hwrange[CR_RANGE(cmd->chanlist[0])] & PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) { /* Unipolar */ offset = 0; @@ -1108,13 +1139,12 @@ static struct pci_dev *pci224_find_pci_dev(struct comedi_device *dev, * Common part of attach and auto_attach. */ static int pci224_attach_common(struct comedi_device *dev, - struct pci_dev *pci_dev, int *options) + struct pci_dev *pci_dev) { const struct pci224_board *thisboard = comedi_board(dev); struct pci224_private *devpriv = dev->private; struct comedi_subdevice *s; unsigned int irq; - unsigned n; int ret; comedi_set_hw_dev(dev, &pci_dev->dev); @@ -1173,6 +1203,7 @@ static int pci224_attach_common(struct comedi_device *dev, s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; s->n_chan = thisboard->ao_chans; s->maxdata = (1 << thisboard->ao_bits) - 1; + s->range_table = thisboard->ao_range; s->insn_write = pci224_ao_insn_write; s->insn_read = pci224_ao_insn_read; s->len_chanlist = s->n_chan; @@ -1182,61 +1213,6 @@ static int pci224_attach_common(struct comedi_device *dev, s->cancel = pci224_ao_cancel; s->munge = pci224_ao_munge; - /* Sort out channel range options. */ - if (thisboard->model == pci234_model) { - /* PCI234 range options. */ - const struct comedi_lrange **range_table_list; - - range_table_list = - kmalloc(sizeof(struct comedi_lrange *) * s->n_chan, - GFP_KERNEL); - if (!range_table_list) - return -ENOMEM; - s->range_table_list = range_table_list; - - if (options) { - for (n = 2; n < 3 + s->n_chan; n++) { - if (options[n] < 0 || options[n] > 1) { - dev_warn(dev->class_dev, - "warning! bad options[%u]=%d\n", - n, options[n]); - } - } - } - for (n = 0; n < s->n_chan; n++) { - if (n < COMEDI_NDEVCONFOPTS - 3 && options && - options[3 + n] == 1) { - if (options[2] == 1) - range_table_list[n] = &range_pci234_ext; - else - range_table_list[n] = &range_bipolar5; - - } else { - if (options && options[2] == 1) { - range_table_list[n] = - &range_pci234_ext2; - } else { - range_table_list[n] = &range_bipolar10; - } - } - } - devpriv->hwrange = hwrange_pci234; - } else { - /* PCI224 range options. */ - if (options && options[2] == 1) { - s->range_table = &range_pci224_external; - devpriv->hwrange = hwrange_pci224_external; - } else { - if (options && options[2] != 0) { - dev_warn(dev->class_dev, - "warning! bad options[2]=%d\n", - options[2]); - } - s->range_table = &range_pci224_internal; - devpriv->hwrange = hwrange_pci224_internal; - } - } - dev->board_name = thisboard->name; if (irq) { @@ -1268,7 +1244,7 @@ static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (!pci_dev) return -EIO; - return pci224_attach_common(dev, pci_dev, it->options); + return pci224_attach_common(dev, pci_dev); } static int @@ -1296,7 +1272,7 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused) * has been removed. */ pci_dev_get(pci_dev); - return pci224_attach_common(dev, pci_dev, NULL); + return pci224_attach_common(dev, pci_dev); } static void pci224_detach(struct comedi_device *dev) @@ -1306,13 +1282,6 @@ static void pci224_detach(struct comedi_device *dev) if (dev->irq) free_irq(dev->irq, dev); - if (dev->subdevices) { - struct comedi_subdevice *s; - - s = &dev->subdevices[0]; - /* AO subdevice */ - kfree(s->range_table_list); - } if (devpriv) { kfree(devpriv->ao_readback); kfree(devpriv->ao_scan_vals); -- GitLab From 7b2809efb16e4a975666b9b14f3e37edd4b39ad2 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:50 +0100 Subject: [PATCH 0500/9167] staging: comedi: amplc_pci224: remove "legacy" attach mechanism Since the driver no longer supports options in its "legacy" attach mechanism to describe the jumper settings (or any options beyond restricting a PCI search to a particular bus and/or slot), there is no need to retain this mechanism in the driver. Remove the comedi driver "attach" handler `pci224_attach()`, and the now unused `pci224_find_pci_dev()`. Also, remove the "wildcard" entry from the board table `pci224_boards[]` as it is no longer needed. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 82 ++----------------- 1 file changed, 6 insertions(+), 76 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index fba0198ad7b3..0bf5e68410f4 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -22,9 +22,8 @@ * Driver: amplc_pci224 * Description: Amplicon PCI224, PCI234 * Author: Ian Abbott - * Devices: [Amplicon] PCI224 (amplc_pci224 or pci224), - * PCI234 (amplc_pci224 or pci234) - * Updated: Wed, 30 Jul 2014 18:08:43 +0000 + * Devices: [Amplicon] PCI224 (amplc_pci224), PCI234 + * Updated: Thu, 31 Jul 2014 11:08:03 +0000 * Status: works, but see caveats * * Supports: @@ -46,12 +45,10 @@ * scan_begin_src or stop_src may use TRIG_EXT. * * Configuration options: - * [0] - PCI bus of device (optional). - * [1] - PCI slot of device (optional). - * If bus/slot is not specified, the first available PCI device - * will be used. + * none * - * Passing a zero for an option is the same as leaving it unspecified. + * Manual configuration of PCI cards is not supported; they are configured + * automatically. * * Output range selection - PCI224: * @@ -350,7 +347,7 @@ static const unsigned char range_check_pci234[4] = { * Board descriptions. */ -enum pci224_model { any_model, pci224_model, pci234_model }; +enum pci224_model { pci224_model, pci234_model }; struct pci224_board { const char *name; @@ -384,11 +381,6 @@ static const struct pci224_board pci224_boards[] = { .ao_hwrange = &hwrange_pci234[0], .ao_range_check = &range_check_pci234[0], }, - { - .name = "amplc_pci224", - .devid = PCI_DEVICE_ID_INVALID, - .model = any_model, /* wildcard */ - }, }; struct pci224_private { @@ -1092,49 +1084,6 @@ static const struct pci224_board return NULL; } -/* - * This function looks for a PCI device matching the requested board name, - * bus and slot. - */ -static struct pci_dev *pci224_find_pci_dev(struct comedi_device *dev, - struct comedi_devconfig *it) -{ - const struct pci224_board *thisboard = comedi_board(dev); - struct pci_dev *pci_dev = NULL; - int bus = it->options[0]; - int slot = it->options[1]; - - for_each_pci_dev(pci_dev) { - if (bus || slot) { - if (bus != pci_dev->bus->number || - slot != PCI_SLOT(pci_dev->devfn)) - continue; - } - if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON) - continue; - - if (thisboard->model == any_model) { - /* Match any supported model. */ - const struct pci224_board *board_ptr; - - board_ptr = pci224_find_pci_board(pci_dev); - if (board_ptr == NULL) - continue; - /* Change board_ptr to matched board. */ - dev->board_ptr = board_ptr; - } else { - /* Match specific model name. */ - if (thisboard->devid != pci_dev->device) - continue; - } - return pci_dev; - } - dev_err(dev->class_dev, - "No supported board found! (req. bus %d, slot %d)\n", - bus, slot); - return NULL; -} - /* * Common part of attach and auto_attach. */ @@ -1229,24 +1178,6 @@ static int pci224_attach_common(struct comedi_device *dev, return 0; } -static int pci224_attach(struct comedi_device *dev, struct comedi_devconfig *it) -{ - struct pci224_private *devpriv; - struct pci_dev *pci_dev; - - dev_info(dev->class_dev, "attach\n"); - - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - - pci_dev = pci224_find_pci_dev(dev, it); - if (!pci_dev) - return -EIO; - - return pci224_attach_common(dev, pci_dev); -} - static int pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused) { @@ -1295,7 +1226,6 @@ static void pci224_detach(struct comedi_device *dev) static struct comedi_driver amplc_pci224_driver = { .driver_name = "amplc_pci224", .module = THIS_MODULE, - .attach = pci224_attach, .detach = pci224_detach, .auto_attach = pci224_auto_attach, .board_name = &pci224_boards[0].name, -- GitLab From 176835357e7d468987d6ce3663241fac7677b83e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:51 +0100 Subject: [PATCH 0501/9167] staging: comedi: amplc_pci224: no need to manipulate PCI ref count This driver no longer supports a "legacy" attach mechanism that searches for a suitable PCI device and increments it's reference count, but since the common "detach" handler `pci224_detach()` still has a left-over `pci_dev_put()`, a matching `pci_dev_get()` is needed in the "auto_attach" handler `pci224_auto_attach()`. There is no longer any reason to "get" and "put" the PCI device, so those calls can be removed. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 0bf5e68410f4..bcef9e607c2e 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1196,20 +1196,12 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused) "BUG! cannot determine board type!\n"); return -EINVAL; } - /* - * Need to 'get' the PCI device to match the 'put' in pci224_detach(). - * TODO: Remove the pci_dev_get() and matching pci_dev_put() once - * support for manual attachment of PCI devices via pci224_attach() - * has been removed. - */ - pci_dev_get(pci_dev); return pci224_attach_common(dev, pci_dev); } static void pci224_detach(struct comedi_device *dev) { struct pci224_private *devpriv = dev->private; - struct pci_dev *pcidev = comedi_to_pci_dev(dev); if (dev->irq) free_irq(dev->irq, dev); @@ -1219,8 +1211,6 @@ static void pci224_detach(struct comedi_device *dev) kfree(devpriv->ao_scan_order); } comedi_pci_disable(dev); - if (pcidev) - pci_dev_put(pcidev); } static struct comedi_driver amplc_pci224_driver = { -- GitLab From 930771fb905be0e1c09a2fe84c17b578d7a0fdd6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Mon, 4 Aug 2014 12:14:28 +0100 Subject: [PATCH 0502/9167] staging: comedi: amplc_pci224: put board indices in PCI driver_data The `driver_data` member value from the matched entry of the PCI module device table `amplc_pci224_pci_table[]` is passed through to our comedi "auto_attach" handler, `pci224_auto_attach()`. Use that to index directly into our static board data array `pci224_boards[]` instead of calling `pci224_find_pci_board()` to search for the entry matching the PCI device ID. That function can be removed. The `devid` and `model` members of `struct pci224_board` are no longer needed either and can be removed. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 52 +++++++------------ 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index bcef9e607c2e..675bbe896b18 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -351,8 +351,6 @@ enum pci224_model { pci224_model, pci234_model }; struct pci224_board { const char *name; - unsigned short devid; - enum pci224_model model; unsigned int ao_chans; unsigned int ao_bits; const struct comedi_lrange *ao_range; @@ -361,20 +359,16 @@ struct pci224_board { }; static const struct pci224_board pci224_boards[] = { - { + [pci224_model] = { .name = "pci224", - .devid = PCI_DEVICE_ID_AMPLICON_PCI224, - .model = pci224_model, .ao_chans = 16, .ao_bits = 12, .ao_range = &range_pci224, .ao_hwrange = &hwrange_pci224[0], .ao_range_check = &range_check_pci224[0], }, - { + [pci234_model] = { .name = "pci234", - .devid = PCI_DEVICE_ID_AMPLICON_PCI234, - .model = pci234_model, .ao_chans = 4, .ao_bits = 16, .ao_range = &range_pci234, @@ -1070,20 +1064,6 @@ static irqreturn_t pci224_interrupt(int irq, void *d) return IRQ_RETVAL(retval); } -/* - * This function looks for a board matching the supplied PCI device. - */ -static const struct pci224_board -*pci224_find_pci_board(struct pci_dev *pci_dev) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) - if (pci_dev->device == pci224_boards[i].devid) - return &pci224_boards[i]; - return NULL; -} - /* * Common part of attach and auto_attach. */ @@ -1162,8 +1142,6 @@ static int pci224_attach_common(struct comedi_device *dev, s->cancel = pci224_ao_cancel; s->munge = pci224_ao_munge; - dev->board_name = thisboard->name; - if (irq) { ret = request_irq(irq, pci224_interrupt, IRQF_SHARED, dev->board_name, dev); @@ -1179,23 +1157,29 @@ static int pci224_attach_common(struct comedi_device *dev, } static int -pci224_auto_attach(struct comedi_device *dev, unsigned long context_unused) +pci224_auto_attach(struct comedi_device *dev, unsigned long context_model) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); + const struct pci224_board *thisboard = NULL; struct pci224_private *devpriv; - dev_info(dev->class_dev, "attach pci %s\n", pci_name(pci_dev)); + if (context_model < ARRAY_SIZE(pci224_boards)) + thisboard = &pci224_boards[context_model]; + if (!thisboard || !thisboard->name) { + dev_err(dev->class_dev, + "amplc_pci224: BUG! cannot determine board type!\n"); + return -EINVAL; + } + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + + dev_info(dev->class_dev, "amplc_pci224: attach pci %s - %s\n", + pci_name(pci_dev), dev->board_name); devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); if (!devpriv) return -ENOMEM; - dev->board_ptr = pci224_find_pci_board(pci_dev); - if (dev->board_ptr == NULL) { - dev_err(dev->class_dev, - "BUG! cannot determine board type!\n"); - return -EINVAL; - } return pci224_attach_common(dev, pci_dev); } @@ -1231,8 +1215,8 @@ static int amplc_pci224_pci_probe(struct pci_dev *dev, } static const struct pci_device_id amplc_pci224_pci_table[] = { - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224) }, - { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234) }, + { PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224), pci224_model }, + { PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234), pci234_model }, { 0 } }; MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table); -- GitLab From dce75412aa80d0e569d09cc5ef296b52d4c71126 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:53 +0100 Subject: [PATCH 0503/9167] staging: comedi: amplc_pci224: remove PCI_DEVICE_ID_... macros The macros `PCI_DEVICE_ID_AMPLICON_PCI224` and `PCI_DEVICE_ID_AMPLICON_PCI234` are only used in the PCI module device table `amplc_pci224_pci_table[]`. Just expand the macros where they are used and remove them. The macro `PCI_DEVICE_ID_INVALID` is no longer used either, so remove it. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 675bbe896b18..caca0c92b613 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -112,13 +112,6 @@ #include "comedi_fc.h" #include "8253.h" -/* - * PCI IDs. - */ -#define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007 -#define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008 -#define PCI_DEVICE_ID_INVALID 0xffff - /* * PCI224/234 i/o space 1 (PCIBAR2) registers. */ @@ -1215,8 +1208,8 @@ static int amplc_pci224_pci_probe(struct pci_dev *dev, } static const struct pci_device_id amplc_pci224_pci_table[] = { - { PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224), pci224_model }, - { PCI_VDEVICE(AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234), pci234_model }, + { PCI_VDEVICE(AMPLICON, 0x0007), pci224_model }, + { PCI_VDEVICE(AMPLICON, 0x0008), pci234_model }, { 0 } }; MODULE_DEVICE_TABLE(pci, amplc_pci224_pci_table); -- GitLab From fd2bb912e17aee18713504d157bceff7f41fad1e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:54 +0100 Subject: [PATCH 0504/9167] staging: comedi: amplc_pci224: absorb pci224_attach_common() `pci224_attach_common()` is now only called from `pci225_auto_attach()`, so absorb it into that function. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 56 ++++++++----------- 1 file changed, 22 insertions(+), 34 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index caca0c92b613..a01504ac0443 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1057,18 +1057,33 @@ static irqreturn_t pci224_interrupt(int irq, void *d) return IRQ_RETVAL(retval); } -/* - * Common part of attach and auto_attach. - */ -static int pci224_attach_common(struct comedi_device *dev, - struct pci_dev *pci_dev) +static int +pci224_auto_attach(struct comedi_device *dev, unsigned long context_model) { - const struct pci224_board *thisboard = comedi_board(dev); - struct pci224_private *devpriv = dev->private; + struct pci_dev *pci_dev = comedi_to_pci_dev(dev); + const struct pci224_board *thisboard = NULL; + struct pci224_private *devpriv; struct comedi_subdevice *s; unsigned int irq; int ret; + if (context_model < ARRAY_SIZE(pci224_boards)) + thisboard = &pci224_boards[context_model]; + if (!thisboard || !thisboard->name) { + dev_err(dev->class_dev, + "amplc_pci224: BUG! cannot determine board type!\n"); + return -EINVAL; + } + dev->board_ptr = thisboard; + dev->board_name = thisboard->name; + + dev_info(dev->class_dev, "amplc_pci224: attach pci %s - %s\n", + pci_name(pci_dev), dev->board_name); + + devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); + if (!devpriv) + return -ENOMEM; + comedi_set_hw_dev(dev, &pci_dev->dev); ret = comedi_pci_enable(dev); @@ -1149,33 +1164,6 @@ static int pci224_attach_common(struct comedi_device *dev, return 0; } -static int -pci224_auto_attach(struct comedi_device *dev, unsigned long context_model) -{ - struct pci_dev *pci_dev = comedi_to_pci_dev(dev); - const struct pci224_board *thisboard = NULL; - struct pci224_private *devpriv; - - if (context_model < ARRAY_SIZE(pci224_boards)) - thisboard = &pci224_boards[context_model]; - if (!thisboard || !thisboard->name) { - dev_err(dev->class_dev, - "amplc_pci224: BUG! cannot determine board type!\n"); - return -EINVAL; - } - dev->board_ptr = thisboard; - dev->board_name = thisboard->name; - - dev_info(dev->class_dev, "amplc_pci224: attach pci %s - %s\n", - pci_name(pci_dev), dev->board_name); - - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - - return pci224_attach_common(dev, pci_dev); -} - static void pci224_detach(struct comedi_device *dev) { struct pci224_private *devpriv = dev->private; -- GitLab From fe10bdbda634597b4853cd45bc655e1bc8f3d89e Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Thu, 31 Jul 2014 14:47:55 +0100 Subject: [PATCH 0505/9167] staging: comedi: amplc_pci224: no need to comedi_set_hw_dev() here The comedi core module calls `comedi_set_hw_dev()` to associate the hardware `struct device` with the `struct comedi_device` before it calls the comedi driver's "auto_attach" hook `pci224_auto_attach()`. There is no need for `pci224_auto_attach()` to call `comedi_set_hw_dev()` itself, so remove the call. Signed-off-by: Ian Abbott Reviewed-by: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci224.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index a01504ac0443..0b056cfd0136 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c @@ -1084,8 +1084,6 @@ pci224_auto_attach(struct comedi_device *dev, unsigned long context_model) if (!devpriv) return -ENOMEM; - comedi_set_hw_dev(dev, &pci_dev->dev); - ret = comedi_pci_enable(dev); if (ret) return ret; -- GitLab From 76212bf32b92a62d7057159498b7d9475d7bf295 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 1 Aug 2014 13:06:59 -0700 Subject: [PATCH 0506/9167] staging: comedi: amplc_dio200: remove private data The private data in this driver only has one member, 'intr_sd', which is the index to the interrupt subdevice. This member is initialized during the attach of the driver when the sd_intr subdevice is detected in the boadinfo 'layout'. The member is then used in the interrupt handler to get the pointer to the subdevice. This member is not necessary. The comedi_device 'read_subdev' is also initialized during the attach. This can be used in the interrupt handler to get the subdevice pointer. Refactor the code to not require the private data and remove the struct and its allocations. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 5 ---- drivers/staging/comedi/drivers/amplc_dio200.h | 7 ------ .../comedi/drivers/amplc_dio200_common.c | 24 +++++-------------- .../staging/comedi/drivers/amplc_dio200_pci.c | 5 ---- 4 files changed, 6 insertions(+), 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 17d2e20663cb..d605fd95cc50 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -265,16 +265,11 @@ static const struct dio200_board dio200_isa_boards[] = { static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) { const struct dio200_board *thisboard = comedi_board(dev); - struct dio200_private *devpriv; unsigned int irq; int ret; irq = it->options[1]; - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - ret = comedi_request_region(dev, it->options[0], thisboard->mainsize); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index e0afe2cee2d6..b21ed526a960 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -59,13 +59,6 @@ struct dio200_board { unsigned int mainsize; }; -/* - * Comedi device private data. - */ -struct dio200_private { - int intr_sd; -}; - int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, unsigned long req_irq_flags); diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index f0d709e0dafc..775263c1471e 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -574,19 +574,13 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, static irqreturn_t dio200_interrupt(int irq, void *d) { struct comedi_device *dev = d; - struct dio200_private *devpriv = dev->private; - struct comedi_subdevice *s; + struct comedi_subdevice *s = dev->read_subdev; int handled; if (!dev->attached) return IRQ_NONE; - if (devpriv->intr_sd >= 0) { - s = &dev->subdevices[devpriv->intr_sd]; - handled = dio200_handle_read_intr(dev, s); - } else { - handled = 0; - } + handled = dio200_handle_read_intr(dev, s); return IRQ_RETVAL(handled); } @@ -1122,15 +1116,11 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, unsigned long req_irq_flags) { const struct dio200_board *thisboard = comedi_board(dev); - struct dio200_private *devpriv = dev->private; const struct dio200_layout *layout = dio200_board_layout(thisboard); struct comedi_subdevice *s; - int sdx; unsigned int n; int ret; - devpriv->intr_sd = -1; - ret = comedi_alloc_subdevices(dev, layout->n_subdevs); if (ret) return ret; @@ -1154,14 +1144,14 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, break; case sd_intr: /* 'INTERRUPT' subdevice */ - if (irq) { + if (irq && !dev->read_subdev) { ret = dio200_subdev_intr_init(dev, s, DIO200_INT_SCE, layout->sdinfo[n] ); if (ret < 0) return ret; - devpriv->intr_sd = n; + dev->read_subdev = s; } else { s->type = COMEDI_SUBD_UNUSED; } @@ -1176,10 +1166,8 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, break; } } - sdx = devpriv->intr_sd; - if (sdx >= 0 && sdx < dev->n_subdevices) - dev->read_subdev = &dev->subdevices[sdx]; - if (irq) { + + if (irq && dev->read_subdev) { if (request_irq(irq, dio200_interrupt, req_irq_flags, dev->board_name, dev) >= 0) { dev->irq = irq; diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index fbf05687347f..f4170f899487 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -359,7 +359,6 @@ static int dio200_pci_auto_attach(struct comedi_device *dev, { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); const struct dio200_board *thisboard = NULL; - struct dio200_private *devpriv; unsigned int bar; int ret; @@ -373,10 +372,6 @@ static int dio200_pci_auto_attach(struct comedi_device *dev, dev_info(dev->class_dev, "%s: attach pci %s (%s)\n", dev->driver->driver_name, pci_name(pci_dev), dev->board_name); - devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); - if (!devpriv) - return -ENOMEM; - ret = comedi_pci_enable(dev); if (ret) return ret; -- GitLab From 7560e527534570199382ac72278301e9ac82920e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 1 Aug 2014 13:07:00 -0700 Subject: [PATCH 0507/9167] staging: comedi: amplc_dio200: remove 'bustype' from boardinfo This member of the boardinfo 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/amplc_dio200.c | 5 ----- drivers/staging/comedi/drivers/amplc_dio200.h | 3 --- drivers/staging/comedi/drivers/amplc_dio200_pci.c | 5 ----- 3 files changed, 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index d605fd95cc50..f0adead92ba7 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -203,7 +203,6 @@ static const struct dio200_board dio200_isa_boards[] = { { .name = "pc212e", - .bustype = isa_bustype, .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 6, @@ -216,7 +215,6 @@ static const struct dio200_board dio200_isa_boards[] = { }, { .name = "pc214e", - .bustype = isa_bustype, .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 4, @@ -226,7 +224,6 @@ static const struct dio200_board dio200_isa_boards[] = { }, { .name = "pc215e", - .bustype = isa_bustype, .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 5, @@ -238,7 +235,6 @@ static const struct dio200_board dio200_isa_boards[] = { }, { .name = "pc218e", - .bustype = isa_bustype, .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 7, @@ -251,7 +247,6 @@ static const struct dio200_board dio200_isa_boards[] = { }, { .name = "pc272e", - .bustype = isa_bustype, .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 4, diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index b21ed526a960..226ce8438ad1 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -48,12 +48,9 @@ struct dio200_layout { bool has_enhancements:1; /* has enhanced features */ }; -enum dio200_bustype { isa_bustype, pci_bustype }; - struct dio200_board { const char *name; struct dio200_layout layout; - enum dio200_bustype bustype; unsigned char mainbar; unsigned char mainshift; unsigned int mainsize; diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index f4170f899487..e1e62a3fd419 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -243,7 +243,6 @@ enum dio200_pci_model { static const struct dio200_board dio200_pci_boards[] = { [pci215_model] = { .name = "pci215", - .bustype = pci_bustype, .mainbar = 2, .mainsize = DIO200_IO_SIZE, .layout = { @@ -256,7 +255,6 @@ static const struct dio200_board dio200_pci_boards[] = { }, [pci272_model] = { .name = "pci272", - .bustype = pci_bustype, .mainbar = 2, .mainsize = DIO200_IO_SIZE, .layout = { @@ -268,7 +266,6 @@ static const struct dio200_board dio200_pci_boards[] = { }, [pcie215_model] = { .name = "pcie215", - .bustype = pci_bustype, .mainbar = 1, .mainshift = 3, .mainsize = DIO200_PCIE_IO_SIZE, @@ -285,7 +282,6 @@ static const struct dio200_board dio200_pci_boards[] = { }, [pcie236_model] = { .name = "pcie236", - .bustype = pci_bustype, .mainbar = 1, .mainshift = 3, .mainsize = DIO200_PCIE_IO_SIZE, @@ -302,7 +298,6 @@ static const struct dio200_board dio200_pci_boards[] = { }, [pcie296_model] = { .name = "pcie296", - .bustype = pci_bustype, .mainbar = 1, .mainshift = 3, .mainsize = DIO200_PCIE_IO_SIZE, -- GitLab From cf200de92ffd97ee46f6affeb8240448319af8ae Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 1 Aug 2014 13:07:01 -0700 Subject: [PATCH 0508/9167] staging: comedi: amplc_dio200: remove 'mainsize' from ISA boardinfo All the ISA DIO200 boards have an i/o region size of 0x20 (DIO200_IO_SIZE). Remove the boardinfo and open code the size in the comedi_request_region() call. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index f0adead92ba7..6f35c83e4789 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -203,7 +203,6 @@ static const struct dio200_board dio200_isa_boards[] = { { .name = "pc212e", - .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 6, .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254, sd_8254, @@ -215,7 +214,6 @@ static const struct dio200_board dio200_isa_boards[] = { }, { .name = "pc214e", - .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 4, .sdtype = {sd_8255, sd_8255, sd_8254, sd_intr}, @@ -224,7 +222,6 @@ static const struct dio200_board dio200_isa_boards[] = { }, { .name = "pc215e", - .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 5, .sdtype = {sd_8255, sd_8255, sd_8254, sd_8254, sd_intr}, @@ -235,7 +232,6 @@ static const struct dio200_board dio200_isa_boards[] = { }, { .name = "pc218e", - .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 7, .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254, sd_8254, @@ -247,7 +243,6 @@ static const struct dio200_board dio200_isa_boards[] = { }, { .name = "pc272e", - .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 4, .sdtype = {sd_8255, sd_8255, sd_8255, sd_intr}, @@ -259,13 +254,12 @@ static const struct dio200_board dio200_isa_boards[] = { static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - const struct dio200_board *thisboard = comedi_board(dev); unsigned int irq; int ret; irq = it->options[1]; - ret = comedi_request_region(dev, it->options[0], thisboard->mainsize); + ret = comedi_request_region(dev, it->options[0], 0x20); if (ret) return ret; -- GitLab From e2dfb515764dcaf156bd06af998842afe19bd337 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 1 Aug 2014 13:07:02 -0700 Subject: [PATCH 0509/9167] staging: comedi: amplc_dio200_pci: remove 'mainsize' from PCI boardinfo The 'mainsize' member in the boardinfo for the DIO200 PCI boards is only used for a sanity check of the pci_resource_len(). This sanity check is not needed. Remove the sanity check along with the 'mainsize' values in the boardinfo. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.h | 4 ---- drivers/staging/comedi/drivers/amplc_dio200_pci.c | 9 --------- 2 files changed, 13 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index 226ce8438ad1..f8d4d6fbf418 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -23,10 +23,6 @@ #ifndef AMPLC_DIO200_H_INCLUDED #define AMPLC_DIO200_H_INCLUDED -/* 200 series register area sizes */ -#define DIO200_IO_SIZE 0x20 -#define DIO200_PCIE_IO_SIZE 0x4000 - /* * Subdevice types. */ diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index e1e62a3fd419..c69a43176173 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -244,7 +244,6 @@ static const struct dio200_board dio200_pci_boards[] = { [pci215_model] = { .name = "pci215", .mainbar = 2, - .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 5, .sdtype = {sd_8255, sd_8255, sd_8254, sd_8254, sd_intr}, @@ -256,7 +255,6 @@ static const struct dio200_board dio200_pci_boards[] = { [pci272_model] = { .name = "pci272", .mainbar = 2, - .mainsize = DIO200_IO_SIZE, .layout = { .n_subdevs = 4, .sdtype = {sd_8255, sd_8255, sd_8255, sd_intr}, @@ -268,7 +266,6 @@ static const struct dio200_board dio200_pci_boards[] = { .name = "pcie215", .mainbar = 1, .mainshift = 3, - .mainsize = DIO200_PCIE_IO_SIZE, .layout = { .n_subdevs = 8, .sdtype = {sd_8255, sd_none, sd_8255, sd_none, @@ -284,7 +281,6 @@ static const struct dio200_board dio200_pci_boards[] = { .name = "pcie236", .mainbar = 1, .mainshift = 3, - .mainsize = DIO200_PCIE_IO_SIZE, .layout = { .n_subdevs = 8, .sdtype = {sd_8255, sd_none, sd_none, sd_none, @@ -300,7 +296,6 @@ static const struct dio200_board dio200_pci_boards[] = { .name = "pcie296", .mainbar = 1, .mainshift = 3, - .mainsize = DIO200_PCIE_IO_SIZE, .layout = { .n_subdevs = 8, .sdtype = {sd_8255, sd_8255, sd_8255, sd_8255, @@ -372,10 +367,6 @@ static int dio200_pci_auto_attach(struct comedi_device *dev, return ret; bar = thisboard->mainbar; - if (pci_resource_len(pci_dev, bar) < thisboard->mainsize) { - dev_err(dev->class_dev, "error! PCI region size too small!\n"); - return -EINVAL; - } if (pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) { dev->mmio = pci_ioremap_bar(pci_dev, bar); if (!dev->mmio) { -- GitLab From 9e1e2739ef967a3cb60ee73cb70dfdcb0515c8d3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 1 Aug 2014 13:07:03 -0700 Subject: [PATCH 0510/9167] staging: comedi: amplc_dio200.h: remove 'mainsize' from boardinfo This member of the boardinfo is not used by the drivers. Remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index f8d4d6fbf418..e51261b006e1 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -49,7 +49,6 @@ struct dio200_board { struct dio200_layout layout; unsigned char mainbar; unsigned char mainshift; - unsigned int mainsize; }; int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, -- GitLab From acb165135dcf48875e44fe323aa63653785bf01c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Fri, 1 Aug 2014 13:07:04 -0700 Subject: [PATCH 0511/9167] staging: comedi: amplc_dio200: remove unnecessary local variable The local variable 'irq' is not necessary in dio200_attach(). Just pass the it->options[1] value directly. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6f35c83e4789..e99012ee4109 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -254,16 +254,13 @@ static const struct dio200_board dio200_isa_boards[] = { static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) { - unsigned int irq; int ret; - irq = it->options[1]; - ret = comedi_request_region(dev, it->options[0], 0x20); if (ret) return ret; - return amplc_dio200_common_attach(dev, irq, 0); + return amplc_dio200_common_attach(dev, it->options[1], 0); } static void dio200_detach(struct comedi_device *dev) -- GitLab From 9254c8412a4d8286007089f70050ff578f5995eb Mon Sep 17 00:00:00 2001 From: Niklas Svensson Date: Wed, 6 Aug 2014 19:55:10 +0200 Subject: [PATCH 0512/9167] staging: comedi: fixing coding style problems This patch fixes warnings of checkpatch.pl script: CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around devpriv->timer + init_timer(&(devpriv->timer)); CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis + dev_info(dev->class_dev, + "%s: %i microvolt, %li microsecond waveform attached\n", Task of Eudyptula challenge. Signed-off-by: Niklas Svensson Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/comedi_test.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c index 845a67905ca6..7aa23db593bc 100644 --- a/drivers/staging/comedi/drivers/comedi_test.c +++ b/drivers/staging/comedi/drivers/comedi_test.c @@ -415,14 +415,14 @@ static int waveform_attach(struct comedi_device *dev, for (i = 0; i < s->n_chan; i++) devpriv->ao_loopbacks[i] = s->maxdata / 2; - init_timer(&(devpriv->timer)); + init_timer(&devpriv->timer); devpriv->timer.function = waveform_ai_interrupt; devpriv->timer.data = (unsigned long)dev; dev_info(dev->class_dev, - "%s: %i microvolt, %li microsecond waveform attached\n", - dev->board_name, - devpriv->uvolt_amplitude, devpriv->usec_period); + "%s: %i microvolt, %li microsecond waveform attached\n", + dev->board_name, + devpriv->uvolt_amplitude, devpriv->usec_period); return 0; } -- GitLab From a03bb00e50ab4c07107da58a52a0bff7943f360c Mon Sep 17 00:00:00 2001 From: Luca Ellero Date: Thu, 7 Aug 2014 09:10:25 +0200 Subject: [PATCH 0513/9167] staging: comedi: add NI USB-6501 support Enable support for the National Instruments USB-6501 module. The NI USB-6501 is a Full-Speed USB 2.0 (12 Mbit/s) device that provides 24 digital I/O lines channels and one 32-bit counter. This is a preliminary version: GPIO: works counter: doesn't work Signed-off-by: Luca Ellero Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/Kconfig | 11 + drivers/staging/comedi/drivers/Makefile | 1 + drivers/staging/comedi/drivers/ni_usb6501.c | 425 ++++++++++++++++++++ 3 files changed, 437 insertions(+) create mode 100644 drivers/staging/comedi/drivers/ni_usb6501.c diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 36f2c7159250..7d6cebc112dc 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1209,6 +1209,17 @@ config COMEDI_DT9812 To compile this driver as a module, choose M here: the module will be called dt9812. +config COMEDI_NI_USB6501 + tristate "NI USB-6501 support" + ---help--- + Enable support for the National Instruments USB-6501 module. + + The NI USB-6501 is a Full-Speed USB 2.0 (12 Mbit/s) device that + provides 24 digital I/O lines channels and one 32-bit counter. + + To compile this driver as a module, choose M here: the module will be + called ni_usb6501. + config COMEDI_USBDUX tristate "ITL USB-DUX-D support" ---help--- diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 8873d4807a01..87ac79136084 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -125,6 +125,7 @@ obj-$(CONFIG_COMEDI_QUATECH_DAQP_CS) += quatech_daqp_cs.o # Comedi USB drivers obj-$(CONFIG_COMEDI_DT9812) += dt9812.o +obj-$(CONFIG_COMEDI_NI_USB6501) += ni_usb6501.o obj-$(CONFIG_COMEDI_USBDUX) += usbdux.o obj-$(CONFIG_COMEDI_USBDUXFAST) += usbduxfast.o obj-$(CONFIG_COMEDI_USBDUXSIGMA) += usbduxsigma.o diff --git a/drivers/staging/comedi/drivers/ni_usb6501.c b/drivers/staging/comedi/drivers/ni_usb6501.c new file mode 100644 index 000000000000..6a4f965ab79e --- /dev/null +++ b/drivers/staging/comedi/drivers/ni_usb6501.c @@ -0,0 +1,425 @@ +/* + * comedi/drivers/ni_usb6501.c + * Comedi driver for National Instruments USB-6501 + * + * COMEDI - Linux Control and Measurement Device Interface + * Copyright (C) 2014 Luca Ellero + * + * 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: ni_usb6501 + * Description: National Instruments USB-6501 module + * Devices: [National Instruments] USB-6501 (ni_usb6501) + * Author: Luca Ellero + * Updated: 5 Aug 2014 + * Status: works + * + * This driver works, but counter device is not implemented yet. + * + * Configuration Options: + * none + */ + +/* + * NI-6501 - USB PROTOCOL DESCRIPTION + * + * Every command is composed by two USB packets: + * - request (out) + * - response (in) + * + * Every packet is at least 12 bytes long, here is the meaning of + * every field (all values are hex): + * + * byte 0 is always 00 + * byte 1 is always 01 + * byte 2 is always 00 + * byte 3 is the total packet length + * + * byte 4 is always 00 + * byte 5 is is the total packet length - 4 + * byte 6 is always 01 + * byte 7 is the command + * + * byte 8 is 02 (request) or 00 (response) + * byte 9 is 00 (response) or 10 (port request) or 20 (counter request) + * byte 10 is always 00 + * byte 11 is 00 (request) or 02 (response) + * + * + * CMD: 0xE READ_PORT + * REQ: 00 01 00 10 00 0C 01 0E 02 10 00 00 00 03 00 + * RES: 00 01 00 10 00 0C 01 00 00 00 00 02 00 03 00 + + * CMD: 0xF WRITE_PORT + * REQ: 00 01 00 14 00 10 01 0F 02 10 00 00 00 03 00 03 00 00 + * RES: 00 01 00 0C 00 08 01 00 00 00 00 02 + * + * CMD: 0x12 SET_PORT_DIR (0 = input, 1 = output) + * REQ: 00 01 00 18 00 14 01 12 02 10 00 00 + * 00 05 00 05 00 00 00 00 00 + * RES: 00 01 00 0C 00 08 01 00 00 00 00 02 + */ + +#include +#include +#include +#include + +#include "../comedidev.h" + +#define NI6501_TIMEOUT 1000 + +/* Port request packets */ +static const u8 READ_PORT_REQUEST[] = {0x00, 0x01, 0x00, 0x10, + 0x00, 0x0C, 0x01, 0x0E, + 0x02, 0x10, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00}; + +static const u8 WRITE_PORT_REQUEST[] = {0x00, 0x01, 0x00, 0x14, + 0x00, 0x10, 0x01, 0x0F, + 0x02, 0x10, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00}; + +static const u8 SET_PORT_DIR_REQUEST[] = {0x00, 0x01, 0x00, 0x18, + 0x00, 0x14, 0x01, 0x12, + 0x02, 0x10, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00}; + +/* Response packets */ +static const u8 GENERIC_RESPONSE[] = {0x00, 0x01, 0x00, 0x0C, + 0x00, 0x08, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x02}; + +static const u8 READ_PORT_RESPONSE[] = {0x00, 0x01, 0x00, 0x10, + 0x00, 0x0C, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x02, + 0x00, 0x03, 0x00, 0x00}; + +enum commands { + READ_PORT, + WRITE_PORT, + SET_PORT_DIR +}; + +struct ni6501_private { + struct usb_endpoint_descriptor *ep_rx; + struct usb_endpoint_descriptor *ep_tx; + struct semaphore sem; + u8 *usb_rx_buf; + u8 *usb_tx_buf; +}; + +static int ni6501_send_command(struct comedi_device *dev, int command, + const u8 *port, u8 *bitmap) +{ + struct usb_device *usb = comedi_to_usb_dev(dev); + struct ni6501_private *devpriv = dev->private; + int request_size, response_size; + u8 *tx = devpriv->usb_tx_buf; + int ret; + + if (!tx || !port) + return -EINVAL; + + if (command != SET_PORT_DIR && !bitmap) + return -EINVAL; + + down(&devpriv->sem); + + switch (command) { + case READ_PORT: + + request_size = sizeof(READ_PORT_REQUEST); + /* 4 additional bytes for READ_PORT request */ + response_size = sizeof(GENERIC_RESPONSE) + 4; + + memcpy(tx, READ_PORT_REQUEST, request_size); + + tx[14] = port[0]; + + break; + + case WRITE_PORT: + + request_size = sizeof(WRITE_PORT_REQUEST); + response_size = sizeof(GENERIC_RESPONSE); + + memcpy(tx, WRITE_PORT_REQUEST, request_size); + + tx[14] = port[0]; + tx[17] = bitmap[0]; + + break; + + case SET_PORT_DIR: + + request_size = sizeof(SET_PORT_DIR_REQUEST); + response_size = sizeof(GENERIC_RESPONSE); + + memcpy(tx, SET_PORT_DIR_REQUEST, request_size); + + tx[14] = port[0]; + tx[15] = port[1]; + tx[16] = port[2]; + + break; + + default: + ret = -EINVAL; + goto end; + } + + ret = usb_bulk_msg(usb, + usb_sndbulkpipe(usb, + devpriv->ep_tx->bEndpointAddress), + devpriv->usb_tx_buf, + request_size, + NULL, + NI6501_TIMEOUT); + if (ret) + goto end; + + ret = usb_bulk_msg(usb, + usb_rcvbulkpipe(usb, + devpriv->ep_rx->bEndpointAddress), + devpriv->usb_rx_buf, + response_size, + NULL, + NI6501_TIMEOUT); + if (ret) + goto end; + + /* Check if results are valid */ + + if (command == READ_PORT) { + bitmap[0] = devpriv->usb_rx_buf[14]; + /* mask bitmap for comparing */ + devpriv->usb_rx_buf[14] = 0x00; + + if (memcmp(devpriv->usb_rx_buf, READ_PORT_RESPONSE, + sizeof(READ_PORT_RESPONSE))) { + ret = -EINVAL; + } + } else if (memcmp(devpriv->usb_rx_buf, GENERIC_RESPONSE, + sizeof(GENERIC_RESPONSE))) { + ret = -EINVAL; + } +end: + up(&devpriv->sem); + + return ret; +} + +static int ni6501_dio_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + int ret; + u8 port[3]; + + ret = comedi_dio_insn_config(dev, s, insn, data, 0); + if (ret) + return ret; + + port[0] = (s->io_bits) & 0xff; + port[1] = (s->io_bits >> 8) & 0xff; + port[2] = (s->io_bits >> 16) & 0xff; + + ret = ni6501_send_command(dev, SET_PORT_DIR, port, NULL); + if (ret) + return ret; + + return insn->n; +} + +static int ni6501_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + unsigned int mask; + int ret; + u8 port; + u8 bitmap; + + mask = comedi_dio_update_state(s, data); + + for (port = 0; port < 3; port++) { + if (mask & (0xFF << port * 8)) { + bitmap = (s->state >> port * 8) & 0xFF; + ret = ni6501_send_command(dev, WRITE_PORT, + &port, &bitmap); + if (ret) + return ret; + } + } + + data[1] = 0; + + for (port = 0; port < 3; port++) { + ret = ni6501_send_command(dev, READ_PORT, &port, &bitmap); + if (ret) + return ret; + data[1] |= bitmap << port * 8; + } + + return insn->n; +} + +static int ni6501_alloc_usb_buffers(struct comedi_device *dev) +{ + struct ni6501_private *devpriv = dev->private; + size_t size; + + size = le16_to_cpu(devpriv->ep_rx->wMaxPacketSize); + devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL); + if (!devpriv->usb_rx_buf) + return -ENOMEM; + + size = le16_to_cpu(devpriv->ep_tx->wMaxPacketSize); + devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL); + if (!devpriv->usb_tx_buf) { + kfree(devpriv->usb_rx_buf); + return -ENOMEM; + } + + return 0; +} + +static int ni6501_find_endpoints(struct comedi_device *dev) +{ + struct usb_interface *intf = comedi_to_usb_interface(dev); + struct ni6501_private *devpriv = dev->private; + struct usb_host_interface *iface_desc = intf->cur_altsetting; + struct usb_endpoint_descriptor *ep_desc; + int i; + + if (iface_desc->desc.bNumEndpoints != 2) { + dev_err(dev->class_dev, "Wrong number of endpoints\n"); + return -ENODEV; + } + + for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) { + ep_desc = &iface_desc->endpoint[i].desc; + + if (usb_endpoint_is_bulk_in(ep_desc)) { + if (!devpriv->ep_rx) + devpriv->ep_rx = ep_desc; + continue; + } + + if (usb_endpoint_is_bulk_out(ep_desc)) { + if (!devpriv->ep_tx) + devpriv->ep_tx = ep_desc; + continue; + } + } + + if (!devpriv->ep_rx || !devpriv->ep_tx) + return -ENODEV; + + return 0; +} + +static int ni6501_auto_attach(struct comedi_device *dev, + unsigned long context) +{ + struct usb_interface *intf = comedi_to_usb_interface(dev); + struct ni6501_private *devpriv; + struct comedi_subdevice *s; + int ret; + + devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); + if (!devpriv) + return -ENOMEM; + + ret = ni6501_find_endpoints(dev); + if (ret) + return ret; + + ret = ni6501_alloc_usb_buffers(dev); + if (ret) + return ret; + + sema_init(&devpriv->sem, 1); + usb_set_intfdata(intf, devpriv); + + ret = comedi_alloc_subdevices(dev, 1); + if (ret) + return ret; + + /* Digital Input/Output subdevice */ + s = &dev->subdevices[0]; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 24; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = ni6501_dio_insn_bits; + s->insn_config = ni6501_dio_insn_config; + + return 0; +} + +static void ni6501_detach(struct comedi_device *dev) +{ + struct usb_interface *intf = comedi_to_usb_interface(dev); + struct ni6501_private *devpriv = dev->private; + + if (!devpriv) + return; + + down(&devpriv->sem); + + usb_set_intfdata(intf, NULL); + + kfree(devpriv->usb_rx_buf); + kfree(devpriv->usb_tx_buf); + + up(&devpriv->sem); +} + +static struct comedi_driver ni6501_driver = { + .module = THIS_MODULE, + .driver_name = "ni6501", + .auto_attach = ni6501_auto_attach, + .detach = ni6501_detach, +}; + +static int ni6501_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + return comedi_usb_auto_config(intf, &ni6501_driver, id->driver_info); +} + +static const struct usb_device_id ni6501_usb_table[] = { + { USB_DEVICE(0x3923, 0x718a) }, + { } +}; +MODULE_DEVICE_TABLE(usb, ni6501_usb_table); + +static struct usb_driver ni6501_usb_driver = { + .name = "ni6501", + .id_table = ni6501_usb_table, + .probe = ni6501_usb_probe, + .disconnect = comedi_usb_auto_unconfig, +}; +module_comedi_usb_driver(ni6501_driver, ni6501_usb_driver); + +MODULE_AUTHOR("Luca Ellero"); +MODULE_DESCRIPTION("Comedi driver for National Instruments USB-6501"); +MODULE_LICENSE("GPL"); -- GitLab From e2709273e63870721bd0587cdd07000d9619f515 Mon Sep 17 00:00:00 2001 From: Antoine Schweitzer-Chaput Date: Tue, 24 Jun 2014 20:41:38 +0200 Subject: [PATCH 0514/9167] staging: rtl8192u: remove unused define DEBUG_EPROM Also remove the code now unreachable. Signed-off-by: Antoine Schweitzer-Chaput Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 76403864644c..ccf00f7cffc9 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -61,7 +61,6 @@ double __extendsfdf2(float a) #undef DUMP_TX #undef DEBUG_TX_DESC2 #undef RX_DONT_PASS_UL -#undef DEBUG_EPROM #undef DEBUG_RX_VERBOSE #undef DUMMY_RX #undef DEBUG_ZERO_RX @@ -665,15 +664,6 @@ static void tx_timeout(struct net_device *dev) schedule_work(&priv->reset_wq); } - -/* this is only for debug */ -void dump_eprom(struct net_device *dev) -{ - int i; - for (i = 0; i < 63; i++) - RT_TRACE(COMP_EPROM, "EEPROM addr %x : %x", i, eprom_read(dev, i)); -} - void rtl8192_update_msr(struct net_device *dev) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -2869,9 +2859,6 @@ static short rtl8192_init(struct net_device *dev) return -ENOMEM; } -#ifdef DEBUG_EPROM - dump_eprom(dev); -#endif return 0; } -- GitLab From 24de874861267a401815ef955a1112177f79da94 Mon Sep 17 00:00:00 2001 From: Antoine Schweitzer-Chaput Date: Tue, 24 Jun 2014 20:41:39 +0200 Subject: [PATCH 0515/9167] staging: rtl8192u: remove define always set USE_ONE_PIPE Also remove the code previously under #ifndef USE_ONE_PIPE. Signed-off-by: Antoine Schweitzer-Chaput Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/Makefile | 1 - drivers/staging/rtl8192u/r8192U_core.c | 19 ------------------- 2 files changed, 20 deletions(-) diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile index eefc657ce99e..a3a7e3fb5f23 100644 --- a/drivers/staging/rtl8192u/Makefile +++ b/drivers/staging/rtl8192u/Makefile @@ -8,7 +8,6 @@ ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO #ccflags-y += -DUSB_TX_DRIVER_AGGREGATION_ENABLE #ccflags-y += -DUSB_RX_AGGREGATION_SUPPORT -ccflags-y += -DUSE_ONE_PIPE ccflags-y += -Idrivers/staging/rtl8192u/ieee80211 r8192u_usb-y := r8192U_core.o r8180_93cx6.o r8192U_wx.o \ diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index ccf00f7cffc9..17642b75026f 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -1543,15 +1543,6 @@ u16 N_DBPSOfRate(u16 DataRate) return N_DBPS; } -unsigned int txqueue2outpipe(struct r8192_priv *priv, unsigned int tx_queue) -{ - if (tx_queue >= 9) { - RT_TRACE(COMP_ERR, "%s():Unknown queue ID!!!\n", __func__); - return 0x04; - } - return priv->txqueue_to_outpipemap[tx_queue]; -} - short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb) { struct r8192_priv *priv = ieee80211_priv(dev); @@ -1581,12 +1572,7 @@ short rtl819xU_tx_cmd(struct net_device *dev, struct sk_buff *skb) //---------------------------------------------------------------------------- // Fill up USB_OUT_CONTEXT. //---------------------------------------------------------------------------- - // Get index to out pipe from specified QueueID. -#ifndef USE_ONE_PIPE - idx_pipe = txqueue2outpipe(priv, queue_index); -#else idx_pipe = 0x04; -#endif usb_fill_bulk_urb(tx_urb, priv->udev, usb_sndbulkpipe(priv->udev, idx_pipe), skb->data, skb->len, rtl8192_tx_isr, skb); @@ -1915,12 +1901,7 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) //DWORD 2 tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN); } - /* Get index to out pipe from specified QueueID */ -#ifndef USE_ONE_PIPE - idx_pipe = txqueue2outpipe(priv, tcb_desc->queue_index); -#else idx_pipe = 0x5; -#endif /* To submit bulk urb */ usb_fill_bulk_urb(tx_urb, udev, -- GitLab From e3e289658a72075221d01a693c1f76727d67e058 Mon Sep 17 00:00:00 2001 From: Antoine Schweitzer-Chaput Date: Tue, 24 Jun 2014 20:41:40 +0200 Subject: [PATCH 0516/9167] staging: rtl8192u: remove unused define USB_TX_DRIVER_AGGREGATION_ENABLE Also remove the unreachable code. Signed-off-by: Antoine Schweitzer-Chaput Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/Makefile | 1 - drivers/staging/rtl8192u/r8192U_core.c | 250 +------------------------ 2 files changed, 4 insertions(+), 247 deletions(-) diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile index a3a7e3fb5f23..416a05a15559 100644 --- a/drivers/staging/rtl8192u/Makefile +++ b/drivers/staging/rtl8192u/Makefile @@ -6,7 +6,6 @@ ccflags-y += -O2 ccflags-y += -DCONFIG_FORCE_HARD_FLOAT=y ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO -#ccflags-y += -DUSB_TX_DRIVER_AGGREGATION_ENABLE #ccflags-y += -DUSB_RX_AGGREGATION_SUPPORT ccflags-y += -Idrivers/staging/rtl8192u/ieee80211 diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 17642b75026f..fd7a2f3d8041 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -1036,194 +1036,6 @@ static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) void rtl8192_try_wake_queue(struct net_device *dev, int pri); -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE -u16 DrvAggr_PaddingAdd(struct net_device *dev, struct sk_buff *skb) -{ - u16 PaddingNum = 256 - ((skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES) % 256); - return PaddingNum & 0xff; -} - -u8 MRateToHwRate8190Pci(u8 rate); -u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc); -u8 MapHwQueueToFirmwareQueue(u8 QueueID); -struct sk_buff *DrvAggr_Aggregation(struct net_device *dev, struct ieee80211_drv_agg_txb *pSendList) -{ - struct ieee80211_device *ieee = netdev_priv(dev); - struct r8192_priv *priv = ieee80211_priv(dev); - cb_desc *tcb_desc = NULL; - u8 i; - u32 TotalLength; - struct sk_buff *skb; - struct sk_buff *agg_skb; - tx_desc_819x_usb_aggr_subframe *tx_agg_desc = NULL; - tx_fwinfo_819x_usb *tx_fwinfo = NULL; - - // - // Local variable initialization. - // - /* first skb initialization */ - skb = pSendList->tx_agg_frames[0]; - TotalLength = skb->len; - - /* Get the total aggregation length including the padding space and - * sub frame header. - */ - for (i = 1; i < pSendList->nr_drv_agg_frames; i++) { - TotalLength += DrvAggr_PaddingAdd(dev, skb); - skb = pSendList->tx_agg_frames[i]; - TotalLength += (skb->len + TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES); - } - - /* allocate skb to contain the aggregated packets */ - agg_skb = dev_alloc_skb(TotalLength + ieee->tx_headroom); - memset(agg_skb->data, 0, agg_skb->len); - skb_reserve(agg_skb, ieee->tx_headroom); - - /* reserve info for first subframe Tx descriptor to be set in the tx function */ - skb = pSendList->tx_agg_frames[0]; - tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->drv_agg_enable = 1; - tcb_desc->pkt_size = skb->len; - tcb_desc->DrvAggrNum = pSendList->nr_drv_agg_frames; - netdev_dbg(dev, "DrvAggNum = %d\n", tcb_desc->DrvAggrNum); - memcpy(agg_skb->cb, skb->cb, sizeof(skb->cb)); - memcpy(skb_put(agg_skb, skb->len), skb->data, skb->len); - - for (i = 1; i < pSendList->nr_drv_agg_frames; i++) { - /* push the next sub frame to be 256 byte aline */ - skb_put(agg_skb, DrvAggr_PaddingAdd(dev, skb)); - - /* Subframe drv Tx descriptor and firmware info setting */ - skb = pSendList->tx_agg_frames[i]; - tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tx_agg_desc = (tx_desc_819x_usb_aggr_subframe *)skb_tail_pointer(agg_skb); - tx_fwinfo = (tx_fwinfo_819x_usb *)(skb_tail_pointer(agg_skb) + sizeof(tx_desc_819x_usb_aggr_subframe)); - - memset(tx_fwinfo, 0, sizeof(tx_fwinfo_819x_usb)); - /* DWORD 0 */ - tx_fwinfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0; - tx_fwinfo->TxRate = MRateToHwRate8190Pci(tcb_desc->data_rate); - tx_fwinfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur; - tx_fwinfo->Short = QueryIsShort(tx_fwinfo->TxHT, tx_fwinfo->TxRate, tcb_desc); - if (tcb_desc->bAMPDUEnable) { /* AMPDU enabled */ - tx_fwinfo->AllowAggregation = 1; - /* DWORD 1 */ - tx_fwinfo->RxMF = tcb_desc->ampdu_factor; - tx_fwinfo->RxAMD = tcb_desc->ampdu_density&0x07;//ampdudensity - } else { - tx_fwinfo->AllowAggregation = 0; - /* DWORD 1 */ - tx_fwinfo->RxMF = 0; - tx_fwinfo->RxAMD = 0; - } - - /* Protection mode related */ - tx_fwinfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0; - tx_fwinfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0; - tx_fwinfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0; - tx_fwinfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0; - tx_fwinfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate); - tx_fwinfo->RtsSubcarrier = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->RTSSC) : 0; - tx_fwinfo->RtsBandwidth = (tx_fwinfo->RtsHT == 1) ? ((tcb_desc->bRTSBW) ? 1 : 0) : 0; - tx_fwinfo->RtsShort = (tx_fwinfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) : - (tcb_desc->bRTSUseShortGI ? 1 : 0); - - /* Set Bandwidth and sub-channel settings. */ - if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) { - if (tcb_desc->bPacketBW) { - tx_fwinfo->TxBandwidth = 1; - tx_fwinfo->TxSubCarrier = 0; //By SD3's Jerry suggestion, use duplicated mode - } else { - tx_fwinfo->TxBandwidth = 0; - tx_fwinfo->TxSubCarrier = priv->nCur40MhzPrimeSC; - } - } else { - tx_fwinfo->TxBandwidth = 0; - tx_fwinfo->TxSubCarrier = 0; - } - - /* Fill Tx descriptor */ - memset(tx_agg_desc, 0, sizeof(tx_desc_819x_usb_aggr_subframe)); - /* DWORD 0 */ - tx_agg_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8; - /* already raw data, need not to subtract header length */ - tx_agg_desc->PktSize = skb->len & 0xffff; - - /*DWORD 1*/ - tx_agg_desc->SecCAMID = 0; - tx_agg_desc->RATid = tcb_desc->RATRIndex; - tx_agg_desc->NoEnc = 1; - tx_agg_desc->SecType = 0x0; - - if (tcb_desc->bHwSec) { - switch (priv->ieee80211->pairwise_key_type) { - case KEY_TYPE_WEP40: - case KEY_TYPE_WEP104: - tx_agg_desc->SecType = 0x1; - tx_agg_desc->NoEnc = 0; - break; - case KEY_TYPE_TKIP: - tx_agg_desc->SecType = 0x2; - tx_agg_desc->NoEnc = 0; - break; - case KEY_TYPE_CCMP: - tx_agg_desc->SecType = 0x3; - tx_agg_desc->NoEnc = 0; - break; - case KEY_TYPE_NA: - tx_agg_desc->SecType = 0x0; - tx_agg_desc->NoEnc = 1; - break; - } - } - - tx_agg_desc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index); - tx_agg_desc->TxFWInfoSize = sizeof(tx_fwinfo_819x_usb); - - tx_agg_desc->DISFB = tcb_desc->bTxDisableRateFallBack; - tx_agg_desc->USERATE = tcb_desc->bTxUseDriverAssingedRate; - - tx_agg_desc->OWN = 1; - - //DWORD 2 - /* According windows driver, it seems that there no need to fill this field */ - - /* to fill next packet */ - skb_put(agg_skb, TX_PACKET_DRVAGGR_SUBFRAME_SHIFT_BYTES); - memcpy(skb_put(agg_skb, skb->len), skb->data, skb->len); - } - - for (i = 0; i < pSendList->nr_drv_agg_frames; i++) - dev_kfree_skb_any(pSendList->tx_agg_frames[i]); - - return agg_skb; -} - -/* NOTE: - This function return a list of PTCB which is proper to be aggregate with the input TCB. - If no proper TCB is found to do aggregation, SendList will only contain the input TCB. -*/ -u8 DrvAggr_GetAggregatibleList(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_drv_agg_txb *pSendList) -{ - struct ieee80211_device *ieee = netdev_priv(dev); - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - u16 nMaxAggrNum = pHTInfo->UsbTxAggrNum; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 QueueID = tcb_desc->queue_index; - - do { - pSendList->tx_agg_frames[pSendList->nr_drv_agg_frames++] = skb; - if (pSendList->nr_drv_agg_frames >= nMaxAggrNum) - break; - - } while ((skb = skb_dequeue(&ieee->skb_drv_aggQ[QueueID]))); - - RT_TRACE(COMP_AMSDU, "DrvAggr_GetAggregatibleList, nAggrTcbNum = %d \n", pSendList->nr_drv_agg_frames); - return pSendList->nr_drv_agg_frames; -} -#endif - static void rtl8192_tx_isr(struct urb *tx_urb) { struct sk_buff *skb = (struct sk_buff *)tx_urb->context; @@ -1275,37 +1087,6 @@ static void rtl8192_tx_isr(struct urb *tx_urb) return; //modified by david to avoid further processing AMSDU } -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - else if ((skb_queue_len(&priv->ieee80211->skb_drv_aggQ[queue_index]) != 0) && - (!(priv->ieee80211->queue_stop))) { - // Tx Driver Aggregation process - /* The driver will aggregation the packets according to the following stats - * 1. check whether there's tx irq available, for it's a completion return - * function, it should contain enough tx irq; - * 2. check packet type; - * 3. initialize sendlist, check whether the to-be send packet no greater than 1 - * 4. aggregates the packets, and fill firmware info and tx desc into it, etc. - * 5. check whether the packet could be sent, otherwise just insert into wait head - * */ - skb = skb_dequeue(&priv->ieee80211->skb_drv_aggQ[queue_index]); - if (!check_nic_enough_desc(dev, queue_index)) { - skb_queue_head(&(priv->ieee80211->skb_drv_aggQ[queue_index]), skb); - return; - } - - /*TODO*/ - { - struct ieee80211_drv_agg_txb SendList; - - memset(&SendList, 0, sizeof(struct ieee80211_drv_agg_txb)); - if (DrvAggr_GetAggregatibleList(dev, skb, &SendList) > 1) { - skb = DrvAggr_Aggregation(dev, &SendList); - - } - } - priv->ieee80211->softmac_hard_start_xmit(skb, dev); - } -#endif } } @@ -1833,25 +1614,13 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) tx_fwinfo->TxSubCarrier = 0; } -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - if (tcb_desc->drv_agg_enable) - tx_fwinfo->Tx_INFO_RSVD = (tcb_desc->DrvAggrNum & 0x1f) << 1; -#endif /* Fill Tx descriptor */ memset(tx_desc, 0, sizeof(tx_desc_819x_usb)); /* DWORD 0 */ tx_desc->LINIP = 0; tx_desc->CmdInit = 1; tx_desc->Offset = sizeof(tx_fwinfo_819x_usb) + 8; - -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - if (tcb_desc->drv_agg_enable) - tx_desc->PktSize = tcb_desc->pkt_size; - else -#endif - { - tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff; - } + tx_desc->PktSize = (skb->len - TX_PACKET_SHIFT_BYTES) & 0xffff; /*DWORD 1*/ tx_desc->SecCAMID = 0; @@ -1892,15 +1661,8 @@ short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) tx_desc->LastSeg = 1; tx_desc->OWN = 1; -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - if (tcb_desc->drv_agg_enable) { - tx_desc->TxBufferSize = tcb_desc->pkt_size + sizeof(tx_fwinfo_819x_usb); - } else -#endif - { - //DWORD 2 - tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN); - } + /* DWORD 2 */ + tx_desc->TxBufferSize = (u32)(skb->len - USB_HWDESC_HEADER_LEN); idx_pipe = 0x5; /* To submit bulk urb */ @@ -3203,12 +2965,8 @@ static RESET_TYPE TxCheckStuck(struct net_device *dev) for (QueueID = 0; QueueID <= BEACON_QUEUE; QueueID++) { if (QueueID == TXCMD_QUEUE) continue; -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - if ((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_drv_aggQ[QueueID]) == 0)) -#else if ((skb_queue_len(&priv->ieee80211->skb_waitQ[QueueID]) == 0) && (skb_queue_len(&priv->ieee80211->skb_aggQ[QueueID]) == 0)) -#endif - continue; + continue; bCheckFwTxCnt = true; } -- GitLab From a49332ebce02239084dd8c0e83821430b0008152 Mon Sep 17 00:00:00 2001 From: Antoine Schweitzer-Chaput Date: Tue, 24 Jun 2014 20:41:41 +0200 Subject: [PATCH 0517/9167] staging: rtl8192u: remove unused define USB_RX_AGGREGATION_SUPPORT Also remove related unreachable code. Signed-off-by: Antoine Schweitzer-Chaput Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/Makefile | 1 - drivers/staging/rtl8192u/r8192U_core.c | 174 ++----------------------- 2 files changed, 11 insertions(+), 164 deletions(-) diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile index 416a05a15559..703c1505ea5f 100644 --- a/drivers/staging/rtl8192u/Makefile +++ b/drivers/staging/rtl8192u/Makefile @@ -6,7 +6,6 @@ ccflags-y += -O2 ccflags-y += -DCONFIG_FORCE_HARD_FLOAT=y ccflags-y += -DJACKSON_NEW_8187 -DJACKSON_NEW_RX ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO -#ccflags-y += -DUSB_RX_AGGREGATION_SUPPORT ccflags-y += -Idrivers/staging/rtl8192u/ieee80211 r8192u_usb-y := r8192U_core.o r8180_93cx6.o r8192U_wx.o \ diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index fd7a2f3d8041..bd15651930d0 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -715,14 +715,8 @@ static void rtl8192_rx_isr(struct urb *urb); static u32 get_rxpacket_shiftbytes_819xusb(struct ieee80211_rx_stats *pstats) { -#ifdef USB_RX_AGGREGATION_SUPPORT - if (pstats->bisrxaggrsubframe) - return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize - + pstats->RxBufShift + 8); - else -#endif - return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize - + pstats->RxBufShift); + return (sizeof(rx_desc_819x_usb) + pstats->RxDrvInfoSize + + pstats->RxBufShift); } static int rtl8192_rx_initiate(struct net_device *dev) @@ -2796,22 +2790,6 @@ static bool rtl8192_adapter_start(struct net_device *dev) for (i = 0; i < QOS_QUEUE_NUM; i++) write_nic_dword(dev, WDCAPARA_ADD[i], DEFAULT_EDCA); } -#ifdef USB_RX_AGGREGATION_SUPPORT - //3 For usb rx firmware aggregation control - if (priv->ResetProgress == RESET_TYPE_NORESET) { - u32 ulValue; - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) | - (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout); - /* - * If usb rx firmware aggregation is enabled, - * when anyone of three threshold conditions above is reached, - * firmware will send aggregated packet to driver. - */ - write_nic_dword(dev, 0x1a8, ulValue); - priv->bCurrentRxAggrEnable = true; - } -#endif rtl8192_phy_configmac(dev); @@ -4497,30 +4475,16 @@ static void query_rxdesc_status(struct sk_buff *skb, // //Get Rx Descriptor Information // -#ifdef USB_RX_AGGREGATION_SUPPORT - if (bIsRxAggrSubframe) { - rx_desc_819x_usb_aggr_subframe *desc = (rx_desc_819x_usb_aggr_subframe *)skb->data; - stats->Length = desc->Length; - stats->RxDrvInfoSize = desc->RxDrvInfoSize; - stats->RxBufShift = 0; //RxBufShift = 2 in RxDesc, but usb didn't shift bytes in fact. - stats->bICV = desc->ICV; - stats->bCRC = desc->CRC32; - stats->bHwError = stats->bCRC|stats->bICV; - stats->Decrypted = !desc->SWDec;//RTL8190 set this bit to indicate that Hw does not decrypt packet - } else -#endif - { - rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data; + rx_desc_819x_usb *desc = (rx_desc_819x_usb *)skb->data; - stats->Length = desc->Length; - stats->RxDrvInfoSize = desc->RxDrvInfoSize; - stats->RxBufShift = 0; - stats->bICV = desc->ICV; - stats->bCRC = desc->CRC32; - stats->bHwError = stats->bCRC|stats->bICV; - //RTL8190 set this bit to indicate that Hw does not decrypt packet - stats->Decrypted = !desc->SWDec; - } + stats->Length = desc->Length; + stats->RxDrvInfoSize = desc->RxDrvInfoSize; + stats->RxBufShift = 0; + stats->bICV = desc->ICV; + stats->bCRC = desc->CRC32; + stats->bHwError = stats->bCRC|stats->bICV; + /* RTL8190 set this bit to indicate that Hw does not decrypt packet */ + stats->Decrypted = !desc->SWDec; if ((priv->ieee80211->pHTInfo->bCurrentHTSupport == true) && (priv->ieee80211->pairwise_key_type == KEY_TYPE_CCMP)) stats->bHwError = false; @@ -4585,11 +4549,6 @@ static void query_rxdesc_status(struct sk_buff *skb, skb_pull(skb, stats->RxBufShift + stats->RxDrvInfoSize); } -#ifdef USB_RX_AGGREGATION_SUPPORT - /* for the rx aggregated sub frame, the redundant space truly contained in the packet */ - if (bIsRxAggrSubframe) - skb_pull(skb, 8); -#endif /* for debug 2008.5.29 */ //added by vivi, for MP, 20080108 @@ -4599,18 +4558,6 @@ static void query_rxdesc_status(struct sk_buff *skb, } -u32 GetRxPacketShiftBytes819xUsb(struct ieee80211_rx_stats *Status, bool bIsRxAggrSubframe) -{ -#ifdef USB_RX_AGGREGATION_SUPPORT - if (bIsRxAggrSubframe) - return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize - + Status->RxBufShift + 8); - else -#endif - return (sizeof(rx_desc_819x_usb) + Status->RxDrvInfoSize - + Status->RxBufShift); -} - static void rtl8192_rx_nomal(struct sk_buff *skb) { rtl8192_rx_info *info = (struct rtl8192_rx_info *)skb->cb; @@ -4625,42 +4572,13 @@ static void rtl8192_rx_nomal(struct sk_buff *skb) u32 rx_pkt_len = 0; struct ieee80211_hdr_1addr *ieee80211_hdr = NULL; bool unicast_packet = false; -#ifdef USB_RX_AGGREGATION_SUPPORT - struct sk_buff *agg_skb = NULL; - u32 TotalLength = 0; - u32 TempDWord = 0; - u32 PacketLength = 0; - u32 PacketOccupiedLendth = 0; - u8 TempByte = 0; - u32 PacketShiftBytes = 0; - rx_desc_819x_usb_aggr_subframe *RxDescr = NULL; - u8 PaddingBytes = 0; - //add just for testing - u8 testing; - -#endif /* 20 is for ps-poll */ if ((skb->len >= (20 + sizeof(rx_desc_819x_usb))) && (skb->len < RX_URB_SIZE)) { -#ifdef USB_RX_AGGREGATION_SUPPORT - TempByte = *(skb->data + sizeof(rx_desc_819x_usb)); -#endif /* first packet should not contain Rx aggregation header */ query_rxdesc_status(skb, &stats, false); /* TODO */ /* hardware related info */ -#ifdef USB_RX_AGGREGATION_SUPPORT - if (TempByte & BIT0) { - agg_skb = skb; - TotalLength = stats.Length - 4; /*sCrcLng*/ - /* though the head pointer has passed this position */ - TempDWord = *(u32 *)(agg_skb->data - 4); - PacketLength = (u16)(TempDWord & 0x3FFF); /*sCrcLng*/ - skb = dev_alloc_skb(PacketLength); - memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength); - PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, false); - } -#endif /* Process the MPDU received */ skb_trim(skb, skb->len - 4/*sCrcLng*/); @@ -4683,76 +4601,6 @@ static void rtl8192_rx_nomal(struct sk_buff *skb) if (unicast_packet) priv->stats.rxbytesunicast += rx_pkt_len; } -#ifdef USB_RX_AGGREGATION_SUPPORT - testing = 1; - if (TotalLength > 0) { - PacketOccupiedLendth = PacketLength + (PacketShiftBytes + 8); - if ((PacketOccupiedLendth & 0xFF) != 0) - PacketOccupiedLendth = (PacketOccupiedLendth & 0xFFFFFF00) + 256; - PacketOccupiedLendth -= 8; - TempDWord = PacketOccupiedLendth - PacketShiftBytes; /*- PacketLength */ - if (agg_skb->len > TempDWord) - skb_pull(agg_skb, TempDWord); - else - agg_skb->len = 0; - - while (agg_skb->len >= GetRxPacketShiftBytes819xUsb(&stats, true)) { - u8 tmpCRC = 0, tmpICV = 0; - RxDescr = (rx_desc_819x_usb_aggr_subframe *)(agg_skb->data); - tmpCRC = RxDescr->CRC32; - tmpICV = RxDescr->ICV; - memcpy(agg_skb->data, &agg_skb->data[44], 2); - RxDescr->CRC32 = tmpCRC; - RxDescr->ICV = tmpICV; - - memset(&stats, 0, sizeof(struct ieee80211_rx_stats)); - stats.signal = 0; - stats.noise = -98; - stats.rate = 0; - stats.freq = IEEE80211_24GHZ_BAND; - query_rxdesc_status(agg_skb, &stats, true); - PacketLength = stats.Length; - - if (PacketLength > agg_skb->len) - break; - /* Process the MPDU received */ - skb = dev_alloc_skb(PacketLength); - memcpy(skb_put(skb, PacketLength), agg_skb->data, PacketLength); - skb_trim(skb, skb->len - 4/*sCrcLng*/); - - rx_pkt_len = skb->len; - ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data; - unicast_packet = false; - if (is_broadcast_ether_addr(ieee80211_hdr->addr1)) { - //TODO - } else if (is_multicast_ether_addr(ieee80211_hdr->addr1)) { - //TODO - } else { - /* unicast packet */ - unicast_packet = true; - } - if (!ieee80211_rx(priv->ieee80211, skb, &stats)) { - dev_kfree_skb_any(skb); - } else { - priv->stats.rxoktotal++; - if (unicast_packet) - priv->stats.rxbytesunicast += rx_pkt_len; - } - /* should trim the packet which has been copied to target skb */ - skb_pull(agg_skb, PacketLength); - PacketShiftBytes = GetRxPacketShiftBytes819xUsb(&stats, true); - PacketOccupiedLendth = PacketLength + PacketShiftBytes; - if ((PacketOccupiedLendth & 0xFF) != 0) { - PaddingBytes = 256 - (PacketOccupiedLendth & 0xFF); - if (agg_skb->len > PaddingBytes) - skb_pull(agg_skb, PaddingBytes); - else - agg_skb->len = 0; - } - } - dev_kfree_skb(agg_skb); - } -#endif } else { priv->stats.rxurberr++; netdev_dbg(dev, "actual_length: %d\n", skb->len); -- GitLab From 1572f632035194cfb2bf18a50d356faed676aa67 Mon Sep 17 00:00:00 2001 From: Antoine Schweitzer-Chaput Date: Tue, 24 Jun 2014 20:41:42 +0200 Subject: [PATCH 0518/9167] staging: rtl8192u: remove unused define LOOP_TEST Signed-off-by: Antoine Schweitzer-Chaput Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index bd15651930d0..0f5960538ae6 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -56,7 +56,6 @@ double __extendsfdf2(float a) } #endif -#undef LOOP_TEST #undef DUMP_RX #undef DUMP_TX #undef DEBUG_TX_DESC2 @@ -701,13 +700,11 @@ void rtl8192_set_chan(struct net_device *dev, short ch) /* this hack should avoid frame TX during channel setting*/ -#ifndef LOOP_TEST //need to implement rf set channel here WB if (priv->rf_set_chan) priv->rf_set_chan(dev, priv->chan); mdelay(10); -#endif } static void rtl8192_rx_isr(struct urb *urb); -- GitLab From 63d29d5160645260619e6a4359de2a89b41dc263 Mon Sep 17 00:00:00 2001 From: Antoine Schweitzer-Chaput Date: Tue, 24 Jun 2014 20:41:43 +0200 Subject: [PATCH 0519/9167] staging: rtl8192u: remove misc. unused defines Signed-off-by: Antoine Schweitzer-Chaput Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 0f5960538ae6..4f3fa35477df 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -56,27 +56,6 @@ double __extendsfdf2(float a) } #endif -#undef DUMP_RX -#undef DUMP_TX -#undef DEBUG_TX_DESC2 -#undef RX_DONT_PASS_UL -#undef DEBUG_RX_VERBOSE -#undef DUMMY_RX -#undef DEBUG_ZERO_RX -#undef DEBUG_RX_SKB -#undef DEBUG_TX_FRAG -#undef DEBUG_RX_FRAG -#undef DEBUG_TX_FILLDESC -#undef DEBUG_TX -#undef DEBUG_IRQ -#undef DEBUG_RX -#undef DEBUG_RXALLOC -#undef DEBUG_REGISTERS -#undef DEBUG_RING -#undef DEBUG_IRQ_TASKLET -#undef DEBUG_TX_ALLOC -#undef DEBUG_TX_DESC - #define CONFIG_RTL8192_IO_MAP #include -- GitLab From cb418e57d5d65ac8f46b635ff9bce08377826d18 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 3 Aug 2014 15:57:26 -0700 Subject: [PATCH 0520/9167] staging: rtl8192ee: Fix RT_TRACE #define and uses RT_TRACE uses require unnecessary parentheses. Fix the #define and remove the uses. Neaten the RT_TRACE lines and multi-line argument wrapping. dynamic debug can add KBUILD_MODNAME and __func__ so remove those from the #define. Use a single statement pr_debug instead of pr_debug and pr_cont which doesn't support dynamic debug anyway. Miscellaneous grammar and spelling fixes on the RT_TRACE uses. Compile tested only. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192ee/base.c | 76 +++-- drivers/staging/rtl8192ee/btcoexist/rtl_btc.c | 9 +- drivers/staging/rtl8192ee/cam.c | 75 +++-- drivers/staging/rtl8192ee/core.c | 154 +++++----- drivers/staging/rtl8192ee/debug.c | 88 +++--- drivers/staging/rtl8192ee/debug.h | 20 +- drivers/staging/rtl8192ee/efuse.c | 29 +- drivers/staging/rtl8192ee/pci.c | 223 +++++++------- drivers/staging/rtl8192ee/ps.c | 61 ++-- drivers/staging/rtl8192ee/rc.c | 2 +- drivers/staging/rtl8192ee/regd.c | 12 +- drivers/staging/rtl8192ee/rtl8192ee/dm.c | 46 ++- drivers/staging/rtl8192ee/rtl8192ee/fw.c | 128 ++++---- drivers/staging/rtl8192ee/rtl8192ee/hw.c | 180 ++++++----- drivers/staging/rtl8192ee/rtl8192ee/led.c | 16 +- drivers/staging/rtl8192ee/rtl8192ee/phy.c | 279 ++++++++---------- .../staging/rtl8192ee/rtl8192ee/pwrseqcmd.c | 31 +- drivers/staging/rtl8192ee/rtl8192ee/rf.c | 10 +- drivers/staging/rtl8192ee/rtl8192ee/sw.c | 9 +- drivers/staging/rtl8192ee/rtl8192ee/trx.c | 26 +- 20 files changed, 693 insertions(+), 781 deletions(-) diff --git a/drivers/staging/rtl8192ee/base.c b/drivers/staging/rtl8192ee/base.c index f7c3c8bf71a5..2f0fea5010f3 100644 --- a/drivers/staging/rtl8192ee/base.c +++ b/drivers/staging/rtl8192ee/base.c @@ -206,7 +206,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, *highest supported RX rate */ if (rtlpriv->dm.supp_phymode_switch) { - RT_TRACE(COMP_INIT, DBG_EMERG, ("Support phy mode switch\n")); + RT_TRACE(COMP_INIT, DBG_EMERG, "Support phy mode switch\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; @@ -216,7 +216,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, } else { if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { - RT_TRACE(COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n")); + RT_TRACE(COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; @@ -224,7 +224,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { - RT_TRACE(COMP_INIT, DBG_DMESG, ("1T1R\n")); + RT_TRACE(COMP_INIT, DBG_DMESG, "1T1R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0x00; @@ -388,7 +388,7 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; } else { RT_TRACE(COMP_INIT, DBG_EMERG, - ("Err BAND %d\n", rtlhal->current_bandtype)); + "Err BAND %d\n", rtlhal->current_bandtype); } } /* <5> set hw caps */ @@ -556,7 +556,7 @@ int rtl92e_init_core(struct ieee80211_hw *hw) * mac80211 hw in _rtl_init_mac80211. */ if (rtl92e_regd_init(hw, rtl92e_reg_notifier)) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("REGD init failed\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "REGD init failed\n"); return 1; } @@ -952,7 +952,7 @@ bool rtl92e_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) rtlpriv->cfg->ops->check_switch_to_dmdp(hw); } if (ieee80211_is_auth(fc)) { - RT_TRACE(COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + RT_TRACE(COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); rtl92e_ips_nic_on(hw); mac->link_state = MAC80211_LINKING; @@ -987,8 +987,8 @@ bool rtl92e_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) return false; RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG, - ("%s ACT_ADDBAREQ From:%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2)); + "%s ACT_ADDBAREQ From:%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "req\n", skb->data, skb->len); if (!is_tx) { @@ -1004,7 +1004,7 @@ bool rtl92e_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) sta = rtl_find_sta(hw, hdr->addr3); if (sta == NULL) { RT_TRACE((COMP_SEND | COMP_RECV), - DBG_TRACE, ("sta is NULL\n")); + DBG_TRACE, "sta is NULL\n"); rcu_read_unlock(); return true; } @@ -1047,12 +1047,12 @@ bool rtl92e_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) break; case ACT_ADDBARSP: RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG, - ("%s ACT_ADDBARSP From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2)); + "%s ACT_ADDBARSP From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_DELBA: RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG, - ("ACT_ADDBADEL From :%pM\n", hdr->addr2)); + "ACT_ADDBADEL From :%pM\n", hdr->addr2); break; } break; @@ -1094,9 +1094,8 @@ u8 rtl92e_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, * 68 : UDP BOOTP client * 67 : UDP BOOTP server */ - RT_TRACE((COMP_SEND | COMP_RECV), - DBG_DMESG, ("dhcp %s !!\n", - (is_tx) ? "Tx" : "Rx")); + RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG, + "dhcp %s !!\n", is_tx ? "Tx" : "Rx"); if (is_tx) { rtlpriv->ra.is_special_data = true; @@ -1124,7 +1123,7 @@ u8 rtl92e_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, return true; } else if (ETH_P_PAE == ether_type) { RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG, - ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx")); + "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); if (is_tx) { rtlpriv->ra.is_special_data = true; @@ -1165,9 +1164,8 @@ int rtl92e_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - tid_data->seq_number)); + RT_TRACE(COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d seq:%d\n", + sta->addr, tid, tid_data->seq_number); *ssn = tid_data->seq_number; tid_data->agg.agg_state = RTL_AGG_START; @@ -1188,12 +1186,12 @@ int rtl92e_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /* Comparing an array to null is not useful */ /*if (!sta->addr) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; }*/ - RT_TRACE(COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1224,9 +1222,8 @@ int rtl92e_rx_agg_start(struct ieee80211_hw *hw, return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(COMP_RECV, DBG_DMESG, - ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - tid_data->seq_number)); + RT_TRACE(COMP_RECV, DBG_DMESG, "on ra = %pM tid = %d seq:%d\n", + sta->addr, tid, tid_data->seq_number); tid_data->agg.rx_agg_state = RTL_RX_AGG_START; return 0; @@ -1244,12 +1241,12 @@ int rtl92e_rx_agg_stop(struct ieee80211_hw *hw, /* Comparing an array to null is not useful */ /*if (!sta->addr) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; }*/ - RT_TRACE(COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1273,12 +1270,12 @@ int rtl92e_tx_agg_oper(struct ieee80211_hw *hw, /* Comparing an array to null is not useful */ /*if (!sta->addr) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; }*/ - RT_TRACE(COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1454,15 +1451,14 @@ void rtl92e_watchdog_wq_callback(void *data) if ((rtlpriv->link_info.bcn_rx_inperiod + rtlpriv->link_info.num_rx_inperiod) == 0) { rtlpriv->link_info.roam_times++; - RT_TRACE(COMP_ERR, DBG_DMESG, - ("AP off for %d s\n", - (rtlpriv->link_info.roam_times * 2))); + RT_TRACE(COMP_ERR, DBG_DMESG, "AP off for %d s\n", + rtlpriv->link_info.roam_times * 2); /* if we can't recv beacon for 10s, * we should reconnect this AP */ if (rtlpriv->link_info.roam_times >= 5) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("AP off, try to reconnect now\n")); + "AP off, try to reconnect now\n"); rtlpriv->link_info.roam_times = 0; ieee80211_connection_loss( rtlpriv->mac80211.vif); @@ -1793,29 +1789,29 @@ void rtl92e_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) (memcmp(mac->bssid, ap5_6, 3) == 0) || vendor == PEER_ATH) { vendor = PEER_ATH; - RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>ath find\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "=>ath find\n"); } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || (memcmp(mac->bssid, ap4_5, 3) == 0) || (memcmp(mac->bssid, ap4_1, 3) == 0) || (memcmp(mac->bssid, ap4_2, 3) == 0) || (memcmp(mac->bssid, ap4_3, 3) == 0) || vendor == PEER_RAL) { - RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>ral findn\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "=>ral findn\n"); vendor = PEER_RAL; } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || vendor == PEER_CISCO) { vendor = PEER_CISCO; - RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>cisco find\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || (memcmp(mac->bssid, ap3_2, 3) == 0) || (memcmp(mac->bssid, ap3_3, 3) == 0) || vendor == PEER_BROAD) { - RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>broad find\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "=>broad find\n"); vendor = PEER_BROAD; } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || vendor == PEER_MARV) { vendor = PEER_MARV; - RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>marv find\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "=>marv find\n"); } mac->vendor = vendor; diff --git a/drivers/staging/rtl8192ee/btcoexist/rtl_btc.c b/drivers/staging/rtl8192ee/btcoexist/rtl_btc.c index 50c012a4c174..e2e3864c7cb1 100644 --- a/drivers/staging/rtl8192ee/btcoexist/rtl_btc.c +++ b/drivers/staging/rtl8192ee/btcoexist/rtl_btc.c @@ -57,17 +57,14 @@ void rtl92e_btc_init_hal_vars(struct rtl_priv *rtlpriv) u8 bt_exist; u8 bt_type; ant_num = rtl92e_get_hwpg_ant_num(rtlpriv); - RT_TRACE(COMP_INIT, DBG_DMESG, - ("%s, antNum is %d\n", __func__, ant_num)); + RT_TRACE(COMP_INIT, DBG_DMESG, "antNum is %d\n", ant_num); bt_exist = rtl92e_get_hwpg_bt_exist(rtlpriv); - RT_TRACE(COMP_INIT, DBG_DMESG, - ("%s, bt_exist is %d\n", __func__, bt_exist)); + RT_TRACE(COMP_INIT, DBG_DMESG, "bt_exist is %d\n", bt_exist); exhalbtc92e_set_bt_exist(bt_exist); bt_type = rtl92e_get_hwpg_bt_type(rtlpriv); - RT_TRACE(COMP_INIT, DBG_DMESG, - ("%s, bt_type is %d\n", __func__, bt_type)); + RT_TRACE(COMP_INIT, DBG_DMESG, "bt_type is %d\n", bt_type); exhalbtc92e_set_chip_type(bt_type); exhalbtc92e_set_ant_num(BT_COEX_ANT_TYPE_PG, ant_num); diff --git a/drivers/staging/rtl8192ee/cam.c b/drivers/staging/rtl8192ee/cam.c index e32c329da870..26f6f90257de 100644 --- a/drivers/staging/rtl8192ee/cam.c +++ b/drivers/staging/rtl8192ee/cam.c @@ -62,14 +62,12 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(COMP_SEC, DBG_LOUD, - ("WRITE %x: %x\n", - rtlpriv->cfg->maps[WCAMI], target_content)); - RT_TRACE(COMP_SEC, DBG_LOUD, - ("The Key ID is %d\n", entry_no)); - RT_TRACE(COMP_SEC, DBG_LOUD, - ("WRITE %x: %x\n", - rtlpriv->cfg->maps[RWCAM], target_command)); + RT_TRACE(COMP_SEC, DBG_LOUD, "WRITE %x: %x\n", + rtlpriv->cfg->maps[WCAMI], target_content); + RT_TRACE(COMP_SEC, DBG_LOUD, "The Key ID is %d\n", + entry_no); + RT_TRACE(COMP_SEC, DBG_LOUD, "WRITE %x: %x\n", + rtlpriv->cfg->maps[RWCAM], target_command); } else if (entry_i == 1) { target_content = (u32) (*(mac_addr + 5)) << 24 | (u32) (*(mac_addr + 4)) << 16 | @@ -81,10 +79,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(COMP_SEC, DBG_LOUD, - ("WRITE A4: %x\n", target_content)); - RT_TRACE(COMP_SEC, DBG_LOUD, - ("WRITE A0: %x\n", target_command)); + RT_TRACE(COMP_SEC, DBG_LOUD, "WRITE A4: %x\n", + target_content); + RT_TRACE(COMP_SEC, DBG_LOUD, "WRITE A0: %x\n", + target_command); } else { target_content = (u32) (*(key_cont_128 + (entry_i * 4 - 8) + 3)) << @@ -99,15 +97,14 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, target_command); udelay(100); - RT_TRACE(COMP_SEC, DBG_LOUD, - ("WRITE A4: %x\n", target_content)); - RT_TRACE(COMP_SEC, DBG_LOUD, - ("WRITE A0: %x\n", target_command)); + RT_TRACE(COMP_SEC, DBG_LOUD, "WRITE A4: %x\n", + target_content); + RT_TRACE(COMP_SEC, DBG_LOUD, "WRITE A0: %x\n", + target_command); } } - RT_TRACE(COMP_SEC, DBG_LOUD, - ("after set key, usconfig:%x\n", us_config)); + RT_TRACE(COMP_SEC, DBG_LOUD, "after set key, usconfig:%x\n", us_config); } u8 stg_rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, @@ -118,13 +115,11 @@ u8 stg_rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(COMP_SEC, DBG_DMESG, - ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", - ul_entry_idx, ul_key_id, ul_enc_alg, - ul_default_key, mac_addr)); + "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", + ul_entry_idx, ul_key_id, ul_enc_alg, ul_default_key, mac_addr); if (ul_key_id == TOTAL_CAM_ENTRY) { - RT_TRACE(COMP_ERR, DBG_WARNING, - ("ulKeyId exceed!\n")); + RT_TRACE(COMP_ERR, DBG_WARNING, "ulKeyId exceed!\n"); return 0; } @@ -136,7 +131,7 @@ u8 stg_rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, (u8 *)key_content, us_config); - RT_TRACE(COMP_SEC, DBG_DMESG, ("end\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "end\n"); return 1; } @@ -148,7 +143,7 @@ int stg_rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u32 ul_command; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id)); + RT_TRACE(COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); ul_command = ul_key_id * CAM_CONTENT_COUNT; ul_command = ul_command | BIT(31) | BIT(16); @@ -157,10 +152,10 @@ int stg_rtl_cam_delete_one_entry(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(COMP_SEC, DBG_DMESG, - ("stg_rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0)); + "stg_rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0); RT_TRACE(COMP_SEC, DBG_DMESG, - ("stg_rtl_cam_delete_one_entry(): WRITE A0: %x\n", - ul_command)); + "stg_rtl_cam_delete_one_entry(): WRITE A0: %x\n", + ul_command); return 0; } EXPORT_SYMBOL(stg_rtl_cam_delete_one_entry); @@ -210,9 +205,9 @@ void stg_rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(COMP_SEC, DBG_DMESG, - ("stg_rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content)); + "stg_rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content); RT_TRACE(COMP_SEC, DBG_DMESG, - ("stg_rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command)); + "stg_rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command); } EXPORT_SYMBOL(stg_rtl_cam_mark_invalid); @@ -259,11 +254,11 @@ void stg_rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(COMP_SEC, DBG_LOUD, - ("stg_rtl_cam_empty_entry(): WRITE A4: %x\n", - ul_content)); + "stg_rtl_cam_empty_entry(): WRITE A4: %x\n", + ul_content); RT_TRACE(COMP_SEC, DBG_LOUD, - ("stg_rtl_cam_empty_entry(): WRITE A0: %x\n", - ul_command)); + "stg_rtl_cam_empty_entry(): WRITE A0: %x\n", + ul_command); } } EXPORT_SYMBOL(stg_rtl_cam_empty_entry); @@ -276,8 +271,7 @@ u8 stg_rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) u8 i, *addr; if (!sta_addr) { - RT_TRACE(COMP_SEC, DBG_EMERG, - ("sta_addr is NULL\n")); + RT_TRACE(COMP_SEC, DBG_EMERG, "sta_addr is NULL\n"); return TOTAL_CAM_ENTRY; } /* Does STA already exist? */ @@ -290,8 +284,8 @@ u8 stg_rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) { if ((bitmap & BIT(0)) == 0) { RT_TRACE(COMP_SEC, DBG_EMERG, - ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", - rtlpriv->sec.hwsec_cam_bitmap, entry_idx)); + "-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", + rtlpriv->sec.hwsec_cam_bitmap, entry_idx); rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx; memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx], sta_addr, ETH_ALEN); @@ -310,14 +304,13 @@ void stg_rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) u8 i, *addr; if (NULL == sta_addr) { - RT_TRACE(COMP_SEC, DBG_EMERG, - ("sta_addr is NULL.\n")); + RT_TRACE(COMP_SEC, DBG_EMERG, "sta_addr is NULL\n"); return; } if (is_zero_ether_addr(sta_addr)) { RT_TRACE(COMP_SEC, DBG_EMERG, - ("sta_addr is 00:00:00:00:00:00.\n")); + "sta_addr is 00:00:00:00:00:00\n"); return; } /* Does STA already exist? */ diff --git a/drivers/staging/rtl8192ee/core.c b/drivers/staging/rtl8192ee/core.c index 7f6accd59986..71aa241b170b 100644 --- a/drivers/staging/rtl8192ee/core.c +++ b/drivers/staging/rtl8192ee/core.c @@ -124,7 +124,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, if (mac->vif) { RT_TRACE(COMP_ERR, DBG_WARNING, - ("vif has been set!! mac->vif = 0x%p\n", mac->vif)); + "vif has been set!! mac->vif = 0x%p\n", mac->vif); return -EOPNOTSUPP; } @@ -140,15 +140,14 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_STATION: if (mac->beacon_enabled == 1) { RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_STATION\n")); + "NL80211_IFTYPE_STATION\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, rtlpriv->cfg->maps[RTL_IBSS_INT_MASKS]); } break; case NL80211_IFTYPE_ADHOC: - RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_ADHOC\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "NL80211_IFTYPE_ADHOC\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) @@ -162,8 +161,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, mac->p2p = P2P_ROLE_GO; /*fall through*/ case NL80211_IFTYPE_AP: - RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_AP\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "NL80211_IFTYPE_AP\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -176,7 +174,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_MESH_POINT: RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_MESH_POINT\n")); + "NL80211_IFTYPE_MESH_POINT\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -189,7 +187,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; default: RT_TRACE(COMP_ERR, DBG_EMERG, - ("operation mode %d is not support!\n", vif->type)); + "operation mode %d is not support!\n", vif->type); err = -EOPNOTSUPP; goto out; } @@ -200,8 +198,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, #endif if (mac->p2p) { - RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("p2p role %x\n", vif->type)); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "p2p role %x\n", vif->type); mac->basic_rates = 0xff0;/*disable cck rate for p2p*/ rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, (u8 *)(&mac->basic_rates)); @@ -262,8 +259,7 @@ static int rtl_op_change_interface(struct ieee80211_hw *hw, vif->type = new_type; vif->p2p = p2p; ret = rtl_op_add_interface(hw, vif); - RT_TRACE(COMP_MAC80211, DBG_LOUD, - (" p2p %x\n", p2p)); + RT_TRACE(COMP_MAC80211, DBG_LOUD, " p2p %x\n", p2p); return ret; } @@ -336,7 +332,7 @@ static void _rtl_add_wowlan_patterns(struct ieee80211_hw *hw, memset(mask, 0, MAX_WOL_BIT_MASK_SIZE); if (patterns[i].pattern_len > MAX_WOL_PATTERN_SIZE) { RT_TRACE(COMP_POWER, DBG_WARNING, - ("Pattern[%d] is too long\n", i)); + "Pattern[%d] is too long\n", i); continue; } pattern_os = patterns[i].pattern; @@ -414,8 +410,8 @@ static void _rtl_add_wowlan_patterns(struct ieee80211_hw *hw, "pattern to hw\n", content, len); /* 3. calculate crc */ rtl_pattern.crc = _calculate_wol_pattern_crc(content, len); - RT_TRACE(COMP_POWER, DBG_TRACE, - ("CRC_Remainder = 0x%x", rtl_pattern.crc)); + RT_TRACE(COMP_POWER, DBG_TRACE, "CRC_Remainder = 0x%x\n", + rtl_pattern.crc); /* 4. write crc & mask_for_hw to hw */ rtlpriv->cfg->ops->add_wowlan_pattern(hw, &rtl_pattern, i); @@ -431,7 +427,7 @@ static int rtl_op_suspend(struct ieee80211_hw *hw, struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct timeval ts; - RT_TRACE(COMP_POWER, DBG_DMESG, ("\n")); + RT_TRACE(COMP_POWER, DBG_DMESG, "\n"); if (WARN_ON(!wow)) return -EINVAL; @@ -458,7 +454,7 @@ static int rtl_op_resume(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct timeval ts; - RT_TRACE(COMP_POWER, DBG_DMESG, ("\n")); + RT_TRACE(COMP_POWER, DBG_DMESG, "\n"); rtlhal->driver_is_goingto_unload = false; rtlhal->b_enter_pnp_sleep = false; rtlhal->b_wake_from_pnp_sleep = true; @@ -491,7 +487,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&rtlpriv->locks.conf_mutex); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /* BIT(2) */ RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n")); + "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); } /*For IPS */ @@ -534,8 +530,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", - hw->conf.long_frame_max_tx_count)); + "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", + hw->conf.long_frame_max_tx_count); mac->retry_long = hw->conf.long_frame_max_tx_count; mac->retry_short = hw->conf.long_frame_max_tx_count; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, @@ -650,7 +646,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) mac->bw_40 = false; mac->bw_80 = false; RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not processed\n")); + "switch case not processed\n"); break; } } @@ -700,12 +696,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]; RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("Enable receive multicast frame.\n")); + "Enable receive multicast frame\n"); } else { mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]); RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("Disable receive multicast frame.\n")); + "Disable receive multicast frame\n"); } } @@ -713,11 +709,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_FCSFAIL) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("Enable receive FCS error frame.\n")); + "Enable receive FCS error frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("Disable receive FCS error frame.\n")); + "Disable receive FCS error frame\n"); } } @@ -740,11 +736,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("Enable receive control frame.\n")); + "Enable receive control frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("Disable receive control frame.\n")); + "Disable receive control frame\n"); } } @@ -752,11 +748,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_OTHER_BSS) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("Enable receive other BSS's frame.\n")); + "Enable receive other BSS's frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("Disable receive other BSS's frame.\n")); + "Disable receive other BSS's frame\n"); } } } @@ -798,8 +794,8 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, sta->supp_rates[0] &= 0xfffffff0; ether_addr_copy(sta_entry->mac_addr, sta->addr); - RT_TRACE(COMP_MAC80211, DBG_DMESG, - ("Add sta addr is %pM\n", sta->addr)); + RT_TRACE(COMP_MAC80211, DBG_DMESG, "Add sta addr is %pM\n", + sta->addr); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); } @@ -813,8 +809,8 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_sta_info *sta_entry; if (sta) { - RT_TRACE(COMP_MAC80211, DBG_DMESG, - ("Remove sta addr is %pM\n", sta->addr)); + RT_TRACE(COMP_MAC80211, DBG_DMESG, "Remove sta addr is %pM\n", + sta->addr); sta_entry = (struct rtl_sta_info *)sta->drv_priv; sta_entry->wireless_mode = 0; sta_entry->ratr_index = 0; @@ -862,7 +858,7 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, if (queue >= AC_MAX) { RT_TRACE(COMP_ERR, DBG_WARNING, - ("queue number %d is incorrect!\n", queue)); + "queue number %d is incorrect!\n", queue); return -EINVAL; } @@ -895,7 +891,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, bss_conf->enable_beacon)) { if (mac->beacon_enabled == 0) { RT_TRACE(COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_BEACON_ENABLED\n")); + "BSS_CHANGED_BEACON_ENABLED\n"); /*start hw beacon interrupt. */ /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ @@ -912,7 +908,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, !bss_conf->enable_beacon) { if (mac->beacon_enabled == 1) { RT_TRACE(COMP_MAC80211, DBG_DMESG, - ("ADHOC DISABLE BEACON\n")); + "ADHOC DISABLE BEACON\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, @@ -922,7 +918,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON_INT) { RT_TRACE(COMP_BEACON, DBG_TRACE, - ("BSS_CHANGED_BEACON_INT\n")); + "BSS_CHANGED_BEACON_INT\n"); mac->beacon_interval = bss_conf->beacon_int; rtlpriv->cfg->ops->set_bcn_intv(hw); } @@ -965,7 +961,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (vif->type == NL80211_IFTYPE_STATION && sta) rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); RT_TRACE(COMP_EASY_CONCURRENT, DBG_LOUD, - ("send PS STATIC frame\n")); + "send PS STATIC frame\n"); if (rtlpriv->dm.supp_phymode_switch) { if (sta->ht_cap.ht_supported) stg_rtl_send_smps_action(hw, sta, @@ -1003,7 +999,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, (u8 *)(&keep_alive)); RT_TRACE(COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_ASSOC\n")); + "BSS_CHANGED_ASSOC\n"); } else { mstatus = RT_MEDIA_DISCONNECT; @@ -1021,7 +1017,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->check_switch_to_dmdp(hw); } RT_TRACE(COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_UN_ASSOC\n")); + "BSS_CHANGED_UN_ASSOC\n"); } rtlpriv->cfg->ops->set_network_type(hw, vif->type); /* For FW LPS: @@ -1039,14 +1035,14 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ERP_CTS_PROT) { RT_TRACE(COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_ERP_CTS_PROT\n")); + "BSS_CHANGED_ERP_CTS_PROT\n"); mac->use_cts_protect = bss_conf->use_cts_prot; } if (changed & BSS_CHANGED_ERP_PREAMBLE) { RT_TRACE(COMP_MAC80211, DBG_LOUD, - ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", - bss_conf->use_short_preamble)); + "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", + bss_conf->use_short_preamble); mac->short_preamble = bss_conf->use_short_preamble; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, @@ -1054,8 +1050,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_ERP_SLOT) { - RT_TRACE(COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_ERP_SLOT\n")); + RT_TRACE(COMP_MAC80211, DBG_TRACE, "BSS_CHANGED_ERP_SLOT\n"); if (bss_conf->use_short_slot) mac->slot_time = RTL_SLOT_TIME_9; @@ -1069,8 +1064,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_HT) { struct ieee80211_sta *sta = NULL; - RT_TRACE(COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_HT\n")); + RT_TRACE(COMP_MAC80211, DBG_TRACE, "BSS_CHANGED_HT\n"); rcu_read_lock(); sta = ieee80211_find_sta(vif, (u8 *)bss_conf->bssid); @@ -1101,8 +1095,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, (u8 *)bss_conf->bssid); - RT_TRACE(COMP_MAC80211, DBG_DMESG, - ("bssid: %pM\n", bss_conf->bssid)); + RT_TRACE(COMP_MAC80211, DBG_DMESG, "bssid: %pM\n", + bss_conf->bssid); mac->vendor = PEER_UNKNOWN; memcpy(mac->bssid, bss_conf->bssid, 6); @@ -1231,34 +1225,34 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_TX_START: RT_TRACE(COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); return rtl92e_tx_agg_start(hw, vif, sta, tid, ssn); break; case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: RT_TRACE(COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); return rtl92e_tx_agg_stop(hw, vif, sta, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: RT_TRACE(COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); rtl92e_tx_agg_oper(hw, sta, tid); break; case IEEE80211_AMPDU_RX_START: RT_TRACE(COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid)); + "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); return rtl92e_rx_agg_start(hw, sta, tid); break; case IEEE80211_AMPDU_RX_STOP: RT_TRACE(COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid)); + "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); return rtl92e_rx_agg_stop(hw, sta, tid); break; default: RT_TRACE(COMP_ERR, DBG_EMERG, - ("IEEE80211_AMPDU_ERR!!!!:\n")); + "IEEE80211_AMPDU_ERR!!!!:\n"); return -EOPNOTSUPP; } return 0; @@ -1269,7 +1263,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(COMP_MAC80211, DBG_LOUD, ("\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = true; if (rtlpriv->link_info.b_higher_busytraffic) { mac->skip_scan = true; @@ -1303,7 +1297,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(COMP_MAC80211, DBG_LOUD, ("\n")); + RT_TRACE(COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = false; mac->skip_scan = false; if (rtlpriv->link_info.b_higher_busytraffic) @@ -1345,8 +1339,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(COMP_ERR, DBG_WARNING, - ("not open hw encryption\n")); + RT_TRACE(COMP_ERR, DBG_WARNING, "not open hw encryption\n"); return -ENOSPC; /*User disabled HW-crypto */ } /* To support IBSS, use sw-crypto for GTK */ @@ -1355,9 +1348,9 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) return -ENOSPC; RT_TRACE(COMP_SEC, DBG_DMESG, - ("%s hardware based encryption for keyidx: %d, mac: %pM\n", - cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, - sta ? sta->addr : bcast_addr)); + "%s hardware based encryption for keyidx: %d, mac: %pM\n", + cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, + sta ? sta->addr : bcast_addr); rtlpriv->sec.being_setkey = true; rtl92e_ips_nic_on(hw); mutex_lock(&rtlpriv->locks.conf_mutex); @@ -1366,32 +1359,31 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: key_type = WEP40_ENCRYPTION; - RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "alg:WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: - RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:WEP104\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "alg:WEP104\n"); key_type = WEP104_ENCRYPTION; break; case WLAN_CIPHER_SUITE_TKIP: key_type = TKIP_ENCRYPTION; - RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "alg:TKIP\n"); break; case WLAN_CIPHER_SUITE_CCMP: key_type = AESCCMP_ENCRYPTION; - RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "alg:CCMP\n"); break; case WLAN_CIPHER_SUITE_AES_CMAC: /* HW don't support CMAC encryption, * use software CMAC encryption */ key_type = AESCMAC_ENCRYPTION; - RT_TRACE(COMP_SEC, DBG_DMESG, ("alg:CMAC\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "alg:CMAC\n"); RT_TRACE(COMP_SEC, DBG_DMESG, - ("HW don't support CMAC encrypiton, use software CMAC encryption\n")); + "HW don't support CMAC encrypiton, use software CMAC encryption\n"); err = -EOPNOTSUPP; goto out_unlock; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("alg_err:%x!!!!:\n", key->cipher)); + RT_TRACE(COMP_ERR, DBG_EMERG, "alg_err:%x!!!!:\n", key->cipher); goto out_unlock; } if (key_type == WEP40_ENCRYPTION || @@ -1434,8 +1426,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wep_only = true; rtlpriv->sec.pairwise_enc_algorithm = key_type; RT_TRACE(COMP_SEC, DBG_DMESG, - ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", - key_type)); + "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", + key_type); rtlpriv->cfg->ops->enable_hw_sec(hw); } } @@ -1444,7 +1436,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, case SET_KEY: if (wep_only) { RT_TRACE(COMP_SEC, DBG_DMESG, - ("set WEP(group/pairwise) key\n")); + "set WEP(group/pairwise) key\n"); /* Pairwise key with an assigned MAC address. */ rtlpriv->sec.pairwise_enc_algorithm = key_type; rtlpriv->sec.group_enc_algorithm = key_type; @@ -1454,8 +1446,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, rtlpriv->sec.key_len[key_idx] = key->keylen; eth_zero_addr(mac_addr); } else if (group_key) { /* group key */ - RT_TRACE(COMP_SEC, DBG_DMESG, - ("set group key\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "set group key\n"); /* group key */ rtlpriv->sec.group_enc_algorithm = key_type; /*set local buf about group key. */ @@ -1464,8 +1455,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, rtlpriv->sec.key_len[key_idx] = key->keylen; ether_addr_copy(mac_addr, bcast_addr); } else { /* pairwise key */ - RT_TRACE(COMP_SEC, DBG_DMESG, - ("set pairwise key\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "set pairwise key\n"); if (!sta) { RT_ASSERT(false, ("pairwise key without mac_addr\n")); @@ -1497,8 +1487,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; break; case DISABLE_KEY: - RT_TRACE(COMP_SEC, DBG_DMESG, - ("disable key delete one entry\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "disable key delete one entry\n"); /*set local buf about wep key. */ if (vif->type == NL80211_IFTYPE_AP || vif->type == NL80211_IFTYPE_MESH_POINT) { @@ -1516,8 +1505,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, stg_rtl_cam_delete_one_entry(hw, mac_addr, key_idx); break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("cmd_err:%x!!!!:\n", cmd)); + RT_TRACE(COMP_ERR, DBG_EMERG, "cmd_err:%x!!!!:\n", cmd); } out_unlock: mutex_unlock(&rtlpriv->locks.conf_mutex); @@ -1546,8 +1534,8 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) rtlpriv->rfkill.rfkill_state = radio_state; RT_TRACE(COMP_RF, DBG_DMESG, - (KERN_INFO "wireless radio switch turned %s\n", - radio_state ? "on" : "off")); + "wireless radio switch turned %s\n", + radio_state ? "on" : "off"); blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; wiphy_rfkill_set_hw_state(hw->wiphy, blocked); diff --git a/drivers/staging/rtl8192ee/debug.c b/drivers/staging/rtl8192ee/debug.c index feec3948585d..d32730c34744 100644 --- a/drivers/staging/rtl8192ee/debug.c +++ b/drivers/staging/rtl8192ee/debug.c @@ -779,9 +779,9 @@ void rtl_proc_add_one(struct ieee80211_hw *hw) rtlpriv->dbg.proc_dir = proc_mkdir(rtlpriv->dbg.proc_name, proc_topdir); if (!rtlpriv->dbg.proc_dir) { RT_TRACE(COMP_INIT, DBG_EMERG, - ("Unable to init /proc/net/%s/%s\n", + "Unable to init /proc/net/%s/%s\n", rtlpriv->cfg->name, - rtlpriv->dbg.proc_name)); + rtlpriv->dbg.proc_name); return; } @@ -789,148 +789,148 @@ void rtl_proc_add_one(struct ieee80211_hw *hw) rtlpriv->dbg.proc_dir, &file_ops_mac_0, hw); if (!entry) RT_TRACE(COMP_INIT, DBG_EMERG, - ("Unable to initialize /proc/net/%s/%s/mac-0\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/mac-0\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("mac-1", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_mac_1, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/mac-1\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/mac-1\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("mac-2", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_mac_2, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/mac-2\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/mac-2\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("mac-3", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_mac_3, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/mac-3\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/mac-3\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("mac-4", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_mac_4, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/mac-4\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/mac-4\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("mac-5", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_mac_5, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/mac-5\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/mac-5\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("mac-6", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_mac_6, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/mac-6\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/mac-6\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("mac-7", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_mac_7, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/mac-7\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/mac-7\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("bb-8", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_bb_8, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/bb-8\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/bb-8\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("bb-9", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_bb_9, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/bb-9\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/bb-9\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("bb-a", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_bb_a, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/bb-a\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/bb-a\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("bb-b", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_bb_b, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/bb-b\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/bb-b\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("bb-c", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_bb_c, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/bb-c\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/bb-c\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("bb-d", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_bb_d, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/bb-d\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/bb-d\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("bb-e", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_bb_e, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/bb-e\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/bb-e\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("bb-f", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_bb_f, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/bb-f\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/bb-f\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("rf-a", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_rf_a, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/rf-a\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/rf-a\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("rf-b", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_rf_b, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/rf-b\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/rf-b\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("cam-1", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_cam_1, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/cam-1\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/cam-1\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("cam-2", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_cam_2, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/cam-2\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/cam-2\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); entry = proc_create_data("cam-3", S_IFREG | S_IRUGO, rtlpriv->dbg.proc_dir, &file_ops_cam_3, hw); if (!entry) RT_TRACE(COMP_INIT, COMP_ERR, - ("Unable to initialize /proc/net/%s/%s/cam-3\n", - rtlpriv->cfg->name, rtlpriv->dbg.proc_name)); + "Unable to initialize /proc/net/%s/%s/cam-3\n", + rtlpriv->cfg->name, rtlpriv->dbg.proc_name); } void rtl_proc_remove_one(struct ieee80211_hw *hw) diff --git a/drivers/staging/rtl8192ee/debug.h b/drivers/staging/rtl8192ee/debug.h index 093128d1f368..26857b727d17 100644 --- a/drivers/staging/rtl8192ee/debug.h +++ b/drivers/staging/rtl8192ee/debug.h @@ -171,17 +171,15 @@ enum dbgp_flag_e { } \ } while (0) -#define RT_TRACE(comp, level, fmt)\ - do { \ - if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ - ((level) <= rtlpriv->dbg.global_debuglevel))) {\ - pr_debug("%s-%d:%s():<%lx> ", \ - KBUILD_MODNAME, \ - rtlpriv->rtlhal.interfaceindex, __func__, \ - in_interrupt()); \ - pr_cont fmt; \ - } \ - } while (0) +#define RT_TRACE(comp, level, fmt, ...) \ +do { \ + if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ + ((level) <= rtlpriv->dbg.global_debuglevel))) { \ + pr_debug("%d:<%lx> " fmt, \ + rtlpriv->rtlhal.interfaceindex, \ + in_interrupt(), ##__VA_ARGS__); \ + } \ +} while (0) #define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...) \ do { \ diff --git a/drivers/staging/rtl8192ee/efuse.c b/drivers/staging/rtl8192ee/efuse.c index 3fae18369831..ba39f104b943 100644 --- a/drivers/staging/rtl8192ee/efuse.c +++ b/drivers/staging/rtl8192ee/efuse.c @@ -151,8 +151,7 @@ void efuse92e_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) const u32 efuse_real_content_len = rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; - RT_TRACE(COMP_EFUSE, DBG_LOUD, - ("Addr=%x Data =%x\n", address, value)); + RT_TRACE(COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", address, value); if (address < efuse_real_content_len) { rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); @@ -242,8 +241,8 @@ void read92e_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { RT_TRACE(COMP_EFUSE, DBG_LOUD, - ("read92e_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n", - _offset, _size_byte)); + "read92e_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n", + _offset, _size_byte); return; } @@ -411,8 +410,8 @@ bool efuse92e_shadow_update_chk(struct ieee80211_hw *hw) bresult = false; RT_TRACE(COMP_EFUSE, DBG_LOUD, - ("efuse92e_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", - totalbytes, hdr_num, words_need, efuse_used)); + "efuse92e_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", + totalbytes, hdr_num, words_need, efuse_used); return bresult; } @@ -448,7 +447,7 @@ bool efuse92e_shadow_update(struct ieee80211_hw *hw) u8 word_en = 0x0F; u8 first_pg = false; - RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n")); + RT_TRACE(COMP_EFUSE, DBG_LOUD, "\n"); if (!efuse92e_shadow_update_chk(hw)) { efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); @@ -456,8 +455,7 @@ bool efuse92e_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(COMP_EFUSE, DBG_LOUD, - ("efuse out of capacity!!\n")); + RT_TRACE(COMP_EFUSE, DBG_LOUD, "efuse out of capacity!!\n"); return false; } efuse_power_switch(hw, true, true); @@ -494,7 +492,7 @@ bool efuse92e_shadow_update(struct ieee80211_hw *hw) if (!efuse_pg_packet_write(hw, (u8) offset, word_en, tmpdata)) { RT_TRACE(COMP_ERR, DBG_WARNING, - ("PG section(%#x) fail!!\n", offset)); + "PG section(%#x) fail!!\n", offset); break; } } @@ -507,7 +505,7 @@ bool efuse92e_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(COMP_EFUSE, DBG_LOUD, ("\n")); + RT_TRACE(COMP_EFUSE, DBG_LOUD, "\n"); return true; } @@ -640,8 +638,7 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) u8 tmpidx = 0; bool bresult; - RT_TRACE(COMP_EFUSE, DBG_LOUD, - ("Addr = %x Data=%x\n", addr, data)); + RT_TRACE(COMP_EFUSE, DBG_LOUD, "Addr = %x Data=%x\n", addr, data); rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); @@ -1021,7 +1018,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (efuse_addr >= (EFUSE_MAX_SIZE - rtlpriv->cfg->maps[EFUSE_OOB_PROTECT_BYTES_LEN])) { RT_TRACE(COMP_EFUSE, DBG_LOUD, - ("efuse_addr(%#x) Out of size!!\n", efuse_addr)); + "efuse_addr(%#x) Out of size!!\n", efuse_addr); } return true; @@ -1061,8 +1058,8 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, u8 tmpdata[8]; memset(tmpdata, 0xff, PGPKT_DATA_SIZE); - RT_TRACE(COMP_EFUSE, DBG_LOUD, - ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr)); + RT_TRACE(COMP_EFUSE, DBG_LOUD, "word_en = %x efuse_addr=%x\n", + word_en, efuse_addr); if (!(word_en & BIT(0))) { tmpaddr = start_addr; diff --git a/drivers/staging/rtl8192ee/pci.c b/drivers/staging/rtl8192ee/pci.c index 0215aef1eacc..4b895b3cea0b 100644 --- a/drivers/staging/rtl8192ee/pci.c +++ b/drivers/staging/rtl8192ee/pci.c @@ -164,8 +164,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) } break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "switch case not process\n"); break; } @@ -228,8 +227,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) return; if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { - RT_TRACE(COMP_POWER, DBG_TRACE, - ("PCI(Bridge) UNKNOWN.\n")); + RT_TRACE(COMP_POWER, DBG_TRACE, "PCI(Bridge) UNKNOWN\n"); return; } @@ -284,8 +282,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) return; if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { - RT_TRACE(COMP_POWER, DBG_TRACE, - ("PCI(Bridge) UNKNOWN.\n")); + RT_TRACE(COMP_POWER, DBG_TRACE, "PCI(Bridge) UNKNOWN\n"); return; } @@ -303,9 +300,9 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, u_pcibridge_aspmsetting); RT_TRACE(COMP_INIT, DBG_LOUD, - ("PlatformEnableASPM(): Write reg[%x] = %x\n", - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), - u_pcibridge_aspmsetting)); + "PlatformEnableASPM(): Write reg[%x] = %x\n", + pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10, + u_pcibridge_aspmsetting); udelay(50); @@ -371,11 +368,11 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, tpcipriv = (struct rtl_pci_priv *)tpriv->priv; RT_TRACE(COMP_INIT, DBG_LOUD, - ("pcipriv->ndis_adapter.funcnumber %x\n", - pcipriv->ndis_adapter.funcnumber)); + "pcipriv->ndis_adapter.funcnumber %x\n", + pcipriv->ndis_adapter.funcnumber); RT_TRACE(COMP_INIT, DBG_LOUD, - ("tpcipriv->ndis_adapter.funcnumber %x\n", - tpcipriv->ndis_adapter.funcnumber)); + "tpcipriv->ndis_adapter.funcnumber %x\n", + tpcipriv->ndis_adapter.funcnumber); if ((pcipriv->ndis_adapter.busnumber == tpcipriv->ndis_adapter.busnumber) && @@ -389,8 +386,7 @@ static bool rtl_pci_check_buddy_priv(struct ieee80211_hw *hw, } } - RT_TRACE(COMP_INIT, DBG_LOUD, - ("find_buddy_priv %d\n", find_buddy_priv)); + RT_TRACE(COMP_INIT, DBG_LOUD, "find_buddy_priv %d\n", find_buddy_priv); if (find_buddy_priv) *buddy_priv = tpriv; @@ -431,9 +427,8 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev, pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg); pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg; - RT_TRACE(COMP_INIT, DBG_TRACE, - ("Link Control Register =%x\n", - pcipriv->ndis_adapter.linkctrl_reg)); + RT_TRACE(COMP_INIT, DBG_TRACE, "Link Control Register = %x\n", + pcipriv->ndis_adapter.linkctrl_reg); pci_read_config_byte(pdev, 0x98, &tmp); tmp |= BIT(4); @@ -601,10 +596,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) skb_pull(skb, EM_HDR_LEN); RT_TRACE((COMP_INTR | COMP_SEND), DBG_TRACE, - ("new ring->idx:%d, free: skb_queue_len:%d, free: seq:%d\n", - ring->idx, - skb_queue_len(&ring->queue), - *(u16 *)(skb->data + 22))); + "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%d\n", + ring->idx, + skb_queue_len(&ring->queue), + *(u16 *)(skb->data + 22)); if (prio == TXCMD_QUEUE) { dev_kfree_skb(skb); @@ -649,9 +644,8 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) if ((ring->entries - skb_queue_len(&ring->queue)) == 2) { RT_TRACE(COMP_ERR, DBG_LOUD, - ("more desc left, wake skb_queue@%d,ring->idx = %d, skb_queue_len = 0x%d\n", - prio, ring->idx, - skb_queue_len(&ring->queue))); + "more desc left, wake skb_queue@%d,ring->idx = %d, skb_queue_len = 0x%d\n", + prio, ring->idx, skb_queue_len(&ring->queue)); ieee80211_wake_queue(hw, skb_get_queue_mapping (skb)); @@ -972,59 +966,59 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) goto done; /*<1> beacon related */ if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) - RT_TRACE(COMP_INTR, DBG_TRACE, ("beacon ok interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "beacon ok interrupt!\n"); if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) - RT_TRACE(COMP_INTR, DBG_TRACE, ("beacon err interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "beacon err interrupt!\n"); if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) - RT_TRACE(COMP_INTR, DBG_TRACE, ("beacon interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) { RT_TRACE(COMP_INTR, DBG_TRACE, - ("prepare beacon for interrupt!\n")); + "prepare beacon for interrupt!\n"); tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); } /*<2> tx related */ if (unlikely(intb & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) - RT_TRACE(COMP_ERR, DBG_TRACE, ("IMR_TXFOVW!\n")); + RT_TRACE(COMP_ERR, DBG_TRACE, "IMR_TXFOVW!\n"); if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { - RT_TRACE(COMP_INTR, DBG_TRACE, ("Manage ok interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "Manage ok interrupt!\n"); _rtl_pci_tx_isr(hw, MGNT_QUEUE); } if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { - RT_TRACE(COMP_INTR, DBG_TRACE, ("HIGH_QUEUE ok interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "HIGH_QUEUE ok interrupt!\n"); _rtl_pci_tx_isr(hw, HIGH_QUEUE); } if (inta & rtlpriv->cfg->maps[RTL_IMR_BKDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(COMP_INTR, DBG_TRACE, ("BK Tx OK interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "BK Tx OK interrupt!\n"); _rtl_pci_tx_isr(hw, BK_QUEUE); } if (inta & rtlpriv->cfg->maps[RTL_IMR_BEDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(COMP_INTR, DBG_TRACE, ("BE TX OK interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "BE TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, BE_QUEUE); } if (inta & rtlpriv->cfg->maps[RTL_IMR_VIDOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(COMP_INTR, DBG_TRACE, ("VI TX OK interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "VI TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VI_QUEUE); } if (inta & rtlpriv->cfg->maps[RTL_IMR_VODOK]) { rtlpriv->link_info.num_tx_inperiod++; - RT_TRACE(COMP_INTR, DBG_TRACE, ("Vo TX OK interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "Vo TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VO_QUEUE); } @@ -1033,25 +1027,25 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(COMP_INTR, DBG_TRACE, - ("CMD TX OK interrupt!\n")); + "CMD TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, TXCMD_QUEUE); } } /*<3> rx related */ if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { - RT_TRACE(COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { RT_TRACE(COMP_ERR, DBG_WARNING, - ("rx descriptor unavailable!\n")); + "rx descriptor unavailable!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(intb & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { - RT_TRACE(COMP_ERR, DBG_WARNING, ("rx overflow !\n")); + RT_TRACE(COMP_ERR, DBG_WARNING, "rx overflow !\n"); _rtl_pci_rx_interrupt(hw); } @@ -1059,7 +1053,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723AE) { if (inta & rtlpriv->cfg->maps[RTL_IMR_C2HCMD]) { RT_TRACE(COMP_INTR, DBG_TRACE, - ("firmware interrupt!\n")); + "firmware interrupt!\n"); queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.fwevt_wq, 0); } @@ -1073,8 +1067,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) if (rtlhal->hw_type == HARDWARE_TYPE_RTL8188EE || rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) { if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_HSISR_IND])) { - RT_TRACE(COMP_INTR, DBG_TRACE, - ("hsisr interrupt!\n")); + RT_TRACE(COMP_INTR, DBG_TRACE, "hsisr interrupt!\n"); _rtl_pci_hs_interrupt(hw); } } @@ -1230,8 +1223,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, &buffer_desc_dma); if (!buffer_desc || (unsigned long)buffer_desc & 0xFF) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Cannot allocate TX ring (prio = %d)\n", - prio)); + "Cannot allocate TX ring (prio = %d)\n", + prio); return -ENOMEM; } @@ -1248,7 +1241,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, &desc_dma); if (!desc || (unsigned long)desc & 0xFF) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Cannot allocate TX ring (prio = %d)\n", prio)); + "Cannot allocate TX ring (prio = %d)\n", prio); return -ENOMEM; } @@ -1258,8 +1251,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, rtlpci->tx_ring[prio].idx = 0; rtlpci->tx_ring[prio].entries = entries; skb_queue_head_init(&rtlpci->tx_ring[prio].queue); - RT_TRACE(COMP_INIT, DBG_LOUD, - ("queue:%d, ring_addr:%p\n", prio, desc)); + RT_TRACE(COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", prio, desc); /* init every desc in this ring */ if (!rtlpriv->use_new_trx_flow) { @@ -1293,7 +1285,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) if (!rtlpci->rx_ring[rxring_idx].buffer_desc || (unsigned long)rtlpci->rx_ring[rxring_idx].buffer_desc & 0xFF) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Cannot allocate RX ring\n")); + "Cannot allocate RX ring\n"); return -ENOMEM; } @@ -1317,7 +1309,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw, int rxring_idx) if (!rtlpci->rx_ring[rxring_idx].desc || (unsigned long)rtlpci->rx_ring[rxring_idx].desc & 0xFF) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Cannot allocate RX ring\n")); + "Cannot allocate RX ring\n"); return -ENOMEM; } @@ -1628,9 +1620,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, if ((own == 1) && (hw_queue != BEACON_QUEUE)) { RT_TRACE(COMP_ERR, DBG_WARNING, - ("No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue))); + "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); @@ -1670,9 +1662,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && hw_queue != BEACON_QUEUE) { RT_TRACE(COMP_ERR, DBG_LOUD, - ("less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue))); + "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); } @@ -1745,7 +1737,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) err = _rtl_pci_init_trx_ring(hw); if (err) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("tx ring initialization failed")); + "tx ring initialization failed\n"); return err; } @@ -1759,7 +1751,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); int err = 0; - RT_TRACE(COMP_INIT, DBG_DMESG, (" rtl_pci_start\n")); + RT_TRACE(COMP_INIT, DBG_DMESG, " rtl_pci_start\n"); rtl92e_pci_reset_trx_ring(hw); rtlpriv->rtlhal.driver_is_goingto_unload = false; @@ -1771,12 +1763,12 @@ static int rtl_pci_start(struct ieee80211_hw *hw) err = rtlpriv->cfg->ops->hw_init(hw); if (err) { RT_TRACE(COMP_INIT, DBG_DMESG, - ("Failed to config hardware err %x!\n" , err)); + "Failed to config hardware err %x!\n" , err); return err; } rtlpriv->cfg->ops->enable_interrupt(hw); - RT_TRACE(COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); rtl92e_init_rx_config(hw); @@ -1787,7 +1779,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) rtlpriv->rtlhal.up_first_time = false; - RT_TRACE(COMP_INIT, DBG_DMESG, ("rtl_pci_start OK\n")); + RT_TRACE(COMP_INIT, DBG_DMESG, "rtl_pci_start OK\n"); return 0; } @@ -1863,67 +1855,67 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, switch (revisionid) { case RTL_PCI_REVISION_ID_8192PCIE: RT_TRACE(COMP_INIT, DBG_DMESG, - ("8192E is found but not supported now-vid/did=%x/%x\n", - venderid, deviceid)); + "8192E is found but not supported now-vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; return false; break; case RTL_PCI_REVISION_ID_8192SE: RT_TRACE(COMP_INIT, DBG_DMESG, - ("8192SE is found - vid/did=%x/%x\n", - venderid, deviceid)); + "8192SE is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; default: RT_TRACE(COMP_ERR, DBG_WARNING, - ("Err: Unknown device - vid/did=%x/%x\n", - venderid, deviceid)); + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; } } else if (deviceid == RTL_PCI_8723AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE; RT_TRACE(COMP_INIT, DBG_DMESG, - ("8723AE PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid)); + "8723AE PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192CET_DID || deviceid == RTL_PCI_8192CE_DID || deviceid == RTL_PCI_8191CE_DID || deviceid == RTL_PCI_8188CE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; RT_TRACE(COMP_INIT, DBG_DMESG, - ("8192C PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid)); + "8192C PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192DE_DID || deviceid == RTL_PCI_8192DE_DID2) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; RT_TRACE(COMP_INIT, DBG_DMESG, - ("8192D PCI-E is found - vid/did=%x/%x\n", - venderid, deviceid)); + "8192D PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8188EE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8188EE; - RT_TRACE(COMP_INIT , DBG_LOUD, - ("Find adapter, Hardware type is 8188EE\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8188EE\n"); } else if (deviceid == RTL_PCI_8723BE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8723BE; - RT_TRACE(COMP_INIT , DBG_LOUD, - ("Find adapter, Hardware type is 8723BE\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8723BE\n"); } else if (deviceid == RTL_PCI_8192EE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192EE; - RT_TRACE(COMP_INIT , DBG_LOUD, - ("Find adapter, Hardware type is 8192EE\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8192EE\n"); } else if (deviceid == RTL_PCI_8821AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8821AE; - RT_TRACE(COMP_INIT , DBG_LOUD, - ("Find adapter, Hardware type is 8821AE\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8821AE\n"); } else if (deviceid == RTL_PCI_8812AE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8812AE; - RT_TRACE(COMP_INIT , DBG_LOUD, - ("Find adapter, Hardware type is 8812AE\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, + "Find adapter, Hardware type is 8812AE\n"); } else { RT_TRACE(COMP_ERR, DBG_WARNING, - ("Err: Unknown device - vid/did=%x/%x\n", - venderid, deviceid)); + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; } @@ -1932,17 +1924,17 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (revisionid == 0 || revisionid == 1) { if (revisionid == 0) { RT_TRACE(COMP_INIT, DBG_LOUD, - ("Find 92DE MAC0.\n")); + "Find 92DE MAC0\n"); rtlhal->interfaceindex = 0; } else if (revisionid == 1) { RT_TRACE(COMP_INIT, DBG_LOUD, - ("Find 92DE MAC1.\n")); + "Find 92DE MAC1\n"); rtlhal->interfaceindex = 1; } } else { RT_TRACE(COMP_INIT, DBG_LOUD, - ("Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", - venderid, deviceid, revisionid)); + "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", + venderid, deviceid, revisionid); rtlhal->interfaceindex = 0; } } @@ -1968,8 +1960,8 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { pcipriv->ndis_adapter.pcibridge_vendor = tmp; RT_TRACE(COMP_INIT, DBG_DMESG, - ("Pci Bridge Vendor is found index: %d\n", - tmp)); + "Pci Bridge Vendor is found index: %d\n", + tmp); break; } } @@ -2002,21 +1994,21 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, } RT_TRACE(COMP_INIT, DBG_DMESG, - ("pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", - pcipriv->ndis_adapter.busnumber, - pcipriv->ndis_adapter.devnumber, - pcipriv->ndis_adapter.funcnumber, - pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg)); + "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.busnumber, + pcipriv->ndis_adapter.devnumber, + pcipriv->ndis_adapter.funcnumber, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); RT_TRACE(COMP_INIT, DBG_DMESG, - ("pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", - pcipriv->ndis_adapter.pcibridge_busnum, - pcipriv->ndis_adapter.pcibridge_devnum, + "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, pcipriv->ndis_adapter.pcibridge_funcnum, - pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], - pcipriv->ndis_adapter.pcibridge_pciehdr_offset, - pcipriv->ndis_adapter.pcibridge_linkctrlreg, - pcipriv->ndis_adapter.amd_l1_patch)); + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], + pcipriv->ndis_adapter.pcibridge_pciehdr_offset, + pcipriv->ndis_adapter.pcibridge_linkctrlreg, + pcipriv->ndis_adapter.amd_l1_patch); rtl_pci_parse_configuration(pdev, hw); list_add_tail(&rtlpriv->list, &rtlpriv->glb_var->glb_priv_list); @@ -2042,7 +2034,7 @@ static int rtl_pci_intr_mode_msi(struct ieee80211_hw *hw) rtlpci->using_msi = true; - RT_TRACE(COMP_INIT|COMP_INTR, DBG_DMESG, ("MSI Interrupt Mode!\n")); + RT_TRACE(COMP_INIT|COMP_INTR, DBG_DMESG, "MSI Interrupt Mode!\n"); return 0; } @@ -2059,8 +2051,7 @@ static int rtl_pci_intr_mode_legacy(struct ieee80211_hw *hw) return ret; rtlpci->using_msi = false; - RT_TRACE(COMP_INIT|COMP_INTR, DBG_DMESG, - ("Pin-based Interrupt Mode!\n")); + RT_TRACE(COMP_INIT|COMP_INTR, DBG_DMESG, "Pin-based Interrupt Mode!\n"); return 0; } @@ -2166,9 +2157,8 @@ int stg_rtl_pci_probe(struct pci_dev *pdev, } RT_TRACE(COMP_INIT, DBG_DMESG, - ("mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", - pmem_start, pmem_len, pmem_flags, - rtlpriv->io.pci_mem_start)); + "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, rtlpriv->io.pci_mem_start); /* Disable Clk Request */ pci_write_config_byte(pdev, 0x81, 0); @@ -2192,7 +2182,7 @@ int stg_rtl_pci_probe(struct pci_dev *pdev, rtlpriv->cfg->ops->read_eeprom_info(hw); if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("Can't init_sw_vars.\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); goto fail3; } @@ -2205,21 +2195,20 @@ int stg_rtl_pci_probe(struct pci_dev *pdev, err = rtl92e_init_core(hw); if (err) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); + "Can't allocate sw for mac80211\n"); goto fail3; } /* Init PCI sw */ err = !rtl_pci_init(hw, pdev); if (err) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("Failed to init PCI.\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Failed to init PCI\n"); goto fail3; } err = ieee80211_register_hw(hw); if (err) { - RT_TRACE(COMP_ERR, DBG_EMERG, - ("Can't register mac80211 hw.\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Can't register mac80211 hw\n"); goto fail3; } else { rtlpriv->mac80211.mac80211_registered = 1; @@ -2227,7 +2216,7 @@ int stg_rtl_pci_probe(struct pci_dev *pdev, /* the wiphy must have been registed to * cfg80211 prior to regulatory_hint */ if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) - RT_TRACE(COMP_ERR, DBG_WARNING, ("regulatory_hint fail\n")); + RT_TRACE(COMP_ERR, DBG_WARNING, "regulatory_hint fail\n"); /* add for prov */ rtl_proc_add_one(hw); @@ -2239,8 +2228,8 @@ int stg_rtl_pci_probe(struct pci_dev *pdev, err = rtl_pci_intr_mode_decide(hw); if (err) { RT_TRACE(COMP_INIT, DBG_DMESG, - ("%s: failed to register IRQ handler\n", - wiphy_name(hw->wiphy))); + "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); goto fail3; } else { rtlpci->irq_alloc = 1; diff --git a/drivers/staging/rtl8192ee/ps.c b/drivers/staging/rtl8192ee/ps.c index 90c3fc2e62b6..1a547b31321a 100644 --- a/drivers/staging/rtl8192ee/ps.c +++ b/drivers/staging/rtl8192ee/ps.c @@ -40,7 +40,7 @@ bool stg_rtl_ps_enable_nic(struct ieee80211_hw *hw) rtlpriv->intf_ops->reset_trx_ring(hw); if (is_hal_stop(rtlhal)) - RT_TRACE(COMP_ERR, DBG_WARNING, ("Driver is already down!\n")); + RT_TRACE(COMP_ERR, DBG_WARNING, "Driver is already down!\n"); /*<2> Enable Adapter */ rtlpriv->cfg->ops->hw_init(hw); @@ -101,8 +101,8 @@ bool stg_rtl_ps_set_rf_state(struct ieee80211_hw *hw, spin_unlock(&rtlpriv->locks.rf_ps_lock); RT_TRACE(COMP_ERR, DBG_WARNING, - ("RF Change in progress! Wait to set..state_toset(%d)\n", - state_toset)); + "RF Change in progress! Wait to set..state_toset(%d)\n", + state_toset); /* Set RF after the previous action is done. */ while (ppsc->rfchange_inprogress) { @@ -151,7 +151,7 @@ bool stg_rtl_ps_set_rf_state(struct ieee80211_hw *hw, b_actionallowed = true; break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, ("switch case not process\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "switch case not process\n"); break; } @@ -212,7 +212,7 @@ void rtl92e_ips_nic_off_wq_callback(void *data) enum rf_pwrstate rtstate; if (mac->opmode != NL80211_IFTYPE_STATION) { - RT_TRACE(COMP_ERR, DBG_WARNING, ("not station return\n")); + RT_TRACE(COMP_ERR, DBG_WARNING, "not station return\n"); return; } @@ -249,7 +249,7 @@ void rtl92e_ips_nic_off_wq_callback(void *data) (mac->link_state == MAC80211_NOLINK) && !mac->act_scanning) { RT_TRACE(COMP_RF, DBG_LOUD, - ("IPSEnter(): Turn off RF.\n")); + "IPSEnter(): Turn off RF\n"); ppsc->inactive_pwrstate = ERFOFF; ppsc->b_in_powersavemode = true; @@ -326,7 +326,7 @@ static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) if (ps_timediff < 2000) { RT_TRACE(COMP_POWER, DBG_LOUD, - ("Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n")); + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); return false; } @@ -372,8 +372,8 @@ void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) if ((ppsc->b_fwctrl_lps) && ppsc->report_linked) { if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(COMP_RF, DBG_DMESG, - ("FW LPS leave ps_mode:%x\n", - FW_PS_ACTIVE_MODE)); + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); enter_fwlps = false; ppsc->pwr_mode = FW_PS_ACTIVE_MODE; ppsc->smart_ps = 0; @@ -387,8 +387,8 @@ void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) } else { if (rtl_get_fwlps_doze(hw)) { RT_TRACE(COMP_RF, DBG_DMESG, - ("FW LPS enter ps_mode:%x\n", - ppsc->fwctrl_psmode)); + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); if (rtlpriv->cfg->ops->get_btc_status()) rtlpriv->btcoexist.btc_ops->btc_lps_notify(rtlpriv, rt_psmode); enter_fwlps = true; @@ -439,7 +439,7 @@ void rtl92e_lps_enter(struct ieee80211_hw *hw) if (mac->cnt_after_linked >= 2) { if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(COMP_POWER, DBG_LOUD, - ("Enter 802.11 power save mode...\n")); + "Enter 802.11 power save mode...\n"); rtl_lps_set_psmode(hw, EAUTOPS); } @@ -469,7 +469,7 @@ void rtl92e_lps_leave(struct ieee80211_hw *hw) } RT_TRACE(COMP_POWER, DBG_LOUD, - ("Busy Traffic,Leave 802.11 power save..\n")); + "Busy Traffic,Leave 802.11 power save..\n"); rtl_lps_set_psmode(hw, EACTIVE); } @@ -555,8 +555,8 @@ void rtl92e_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) &rtlpriv->works.ps_work, MSECS(5)); } else { RT_TRACE(COMP_POWER, DBG_DMESG, - ("u_bufferd: %x, m_buffered: %x\n", - u_buffed, m_buffed)); + "u_bufferd: %x, m_buffered: %x\n", + u_buffed, m_buffed); } } @@ -653,8 +653,8 @@ void rtl92e_swlps_rf_sleep(struct ieee80211_hw *hw) * sleep = dtim_period, that meaons, we should * awake before every dtim */ RT_TRACE(COMP_POWER, DBG_DMESG, - ("dtim_counter:%x will sleep :%d beacon_intv\n", - rtlpriv->psc.dtim_counter, sleep_intv)); + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); /* we tested that 40ms is enough for sw & hw sw delay */ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, @@ -731,8 +731,8 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, find_p2p_ps_ie = true; if ((noa_len - 2) % 13 != 0) { RT_TRACE(COMP_INIT, DBG_LOUD, - ("P2P notice of absence: invalid length%d\n", - noa_len)); + "P2P notice of absence: invalid length%d\n", + noa_len); return; } else { noa_num = (noa_len - 2) / 13; @@ -740,8 +740,7 @@ static void rtl_p2p_noa_ie(struct ieee80211_hw *hw, void *data, noa_index = ie[3]; if (rtlpriv->psc.p2p_ps_info.p2p_ps_mode == P2P_PS_NONE || noa_index != p2pinfo->noa_index) { - RT_TRACE(COMP_FW, DBG_LOUD, - ("update NOA ie.\n")); + RT_TRACE(COMP_FW, DBG_LOUD, "update NOA ie\n"); p2pinfo->noa_index = noa_index; p2pinfo->opp_ps = (ie[4] >> 7); p2pinfo->ctwindow = ie[4] & 0x7F; @@ -815,7 +814,7 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, return; find_p2p_ie = true; - RT_TRACE(COMP_FW, DBG_LOUD, ("action frame find P2P IE.\n")); + RT_TRACE(COMP_FW, DBG_LOUD, "action frame find P2P IE.\n"); /*to find noa ie*/ while (ie + 1 < end) { noa_len = READEF2BYTE((__le16 *)&ie[1]); @@ -823,14 +822,14 @@ static void rtl_p2p_action_ie(struct ieee80211_hw *hw, void *data, return; if (ie[0] == 12) { - RT_TRACE(COMP_FW, DBG_LOUD, ("find NOA IE\n")); + RT_TRACE(COMP_FW, DBG_LOUD, "find NOA IE\n"); RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_LOUD, "noa ie ", ie, noa_len); find_p2p_ps_ie = true; if ((noa_len - 2) % 13 != 0) { RT_TRACE(COMP_FW, DBG_LOUD, - ("P2P notice of absence: invalid length%d\n", - noa_len)); + "P2P notice of absence: invalid length%d\n", + noa_len); return; } else { noa_num = (noa_len - 2) / 13; @@ -887,7 +886,7 @@ void rtl92e_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) struct rtl_ps_ctl *rtlps = rtl_psc(rtl_priv(hw)); struct rtl_p2p_ps_info *p2pinfo = &(rtlpriv->psc.p2p_ps_info); - RT_TRACE(COMP_FW, DBG_LOUD, ("p2p state %x\n", p2p_ps_state)); + RT_TRACE(COMP_FW, DBG_LOUD, "p2p state %x\n", p2p_ps_state); switch (p2p_ps_state) { case P2P_PS_DISABLE: p2pinfo->p2p_ps_state = p2p_ps_state; @@ -939,17 +938,17 @@ void rtl92e_p2p_ps_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) default: break; } - RT_TRACE(COMP_FW, DBG_LOUD, (" ctwindow %x oppps %x\n", - p2pinfo->ctwindow , p2pinfo->opp_ps)); + RT_TRACE(COMP_FW, DBG_LOUD, " ctwindow %x oppps %x\n", + p2pinfo->ctwindow , p2pinfo->opp_ps); RT_TRACE(COMP_FW, DBG_LOUD, - ("count %x duration %x index %x interval %x start time %x noa num %x\n", + "count %x duration %x index %x interval %x start time %x noa num %x\n", p2pinfo->noa_count_type[0], p2pinfo->noa_duration[0], p2pinfo->noa_index, p2pinfo->noa_interval[0], p2pinfo->noa_start_time[0], - p2pinfo->noa_num)); - RT_TRACE(COMP_FW, DBG_LOUD, ("end\n")); + p2pinfo->noa_num); + RT_TRACE(COMP_FW, DBG_LOUD, "end\n"); } void rtl92e_p2p_info(struct ieee80211_hw *hw, void *data, unsigned int len) diff --git a/drivers/staging/rtl8192ee/rc.c b/drivers/staging/rtl8192ee/rc.c index c4c34ddcf8cd..31146a56fa28 100644 --- a/drivers/staging/rtl8192ee/rc.c +++ b/drivers/staging/rtl8192ee/rc.c @@ -250,7 +250,7 @@ static void *rtl_rate_alloc_sta(void *ppriv, rate_priv = kzalloc(sizeof(*rate_priv), gfp); if (!rate_priv) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Unable to allocate private rc structure\n")); + "Unable to allocate private rc structure\n"); return NULL; } diff --git a/drivers/staging/rtl8192ee/regd.c b/drivers/staging/rtl8192ee/regd.c index 7272fae68ec6..58b1d9f4717a 100644 --- a/drivers/staging/rtl8192ee/regd.c +++ b/drivers/staging/rtl8192ee/regd.c @@ -407,12 +407,12 @@ int rtl92e_regd_init(struct ieee80211_hw *hw, rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan; RT_TRACE(COMP_REGD, DBG_TRACE, - (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", - rtlpriv->regd.country_code)); + KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", + rtlpriv->regd.country_code); if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { RT_TRACE(COMP_REGD, DBG_DMESG, - ("rtl: EEPROM indicates invalid contry code world wide 13 should be used\n")); + "rtl: EEPROM indicates invalid contry code world wide 13 should be used\n"); rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; } @@ -428,8 +428,8 @@ int rtl92e_regd_init(struct ieee80211_hw *hw, } RT_TRACE(COMP_REGD, DBG_TRACE, - (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n", - rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1])); + KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); _rtl92e_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); @@ -442,7 +442,7 @@ void rtl92e_reg_notifier(struct wiphy *wiphy, struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(COMP_REGD, DBG_LOUD, ("\n")); + RT_TRACE(COMP_REGD, DBG_LOUD, "\n"); _rtl92e_reg_notifier_apply(wiphy, request, &rtlpriv->regd); } diff --git a/drivers/staging/rtl8192ee/rtl8192ee/dm.c b/drivers/staging/rtl8192ee/rtl8192ee/dm.c index 41c2d98e81db..64254c4070f7 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/dm.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/dm.c @@ -256,16 +256,15 @@ static void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) RT_TRACE(COMP_DIG, DBG_TRACE, - ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); RT_TRACE(COMP_DIG, DBG_TRACE, - ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); } static void rtl92ee_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) @@ -341,7 +340,7 @@ static void rtl92ee_dm_dig(struct ieee80211_hw *hw) } else { dm_dig.rx_gain_range_max = dm_dig_max; dig_dynamic_min = dm_dig_min; - RT_TRACE(COMP_DIG, DBG_LOUD, ("no link\n")); + RT_TRACE(COMP_DIG, DBG_LOUD, "no link\n"); } if (rtlpriv->falsealm_cnt.cnt_all > 10000) { @@ -496,7 +495,7 @@ static void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw *hw) (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { rtl_dm_dig->min_undecorated_pwdb_for_dm = 0; RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD, - ("Not connected to any\n")); + "Not connected to any\n"); } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_AP || @@ -504,24 +503,24 @@ static void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw *hw) rtl_dm_dig->min_undecorated_pwdb_for_dm = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb); } else { rtl_dm_dig->min_undecorated_pwdb_for_dm = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD, - ("STA Default Port PWDB = 0x%x\n", - rtl_dm_dig->min_undecorated_pwdb_for_dm)); + "STA Default Port PWDB = 0x%x\n", + rtl_dm_dig->min_undecorated_pwdb_for_dm); } } else { rtl_dm_dig->min_undecorated_pwdb_for_dm = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(COMP_BB_POWERSAVING, DBG_LOUD, - ("AP Ext Port or disconnet PWDB = 0x%x\n", - rtl_dm_dig->min_undecorated_pwdb_for_dm)); + "AP Ext Port or disconnet PWDB = 0x%x\n", + rtl_dm_dig->min_undecorated_pwdb_for_dm); } - RT_TRACE(COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n", - rtl_dm_dig->min_undecorated_pwdb_for_dm)); + RT_TRACE(COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", + rtl_dm_dig->min_undecorated_pwdb_for_dm); } static void rtl92ee_dm_check_rssi_monitor(struct ieee80211_hw *hw) @@ -842,8 +841,7 @@ static void rtl92ee_dm_dynamic_atc_switch(struct ieee80211_hw *hw) if (rtlpriv->cfg->ops->get_btc_status()) { if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) { RT_TRACE(COMP_BT_COEXIST, DBG_LOUD, - ("odm_DynamicATCSwitch(): " - "Disable CFO tracking for BT!!\n")); + "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n"); return; } } @@ -1003,7 +1001,8 @@ static bool _rtl92ee_dm_ra_state_check(struct ieee80211_hw *hw, default: RT_TRACE(COMP_RATR, DBG_DMESG, - ("wrong rssi level setting %d !", *ratr_state)); + "wrong rssi level setting %d !\n", + *ratr_state); break; } @@ -1032,14 +1031,13 @@ static void rtl92ee_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) struct ieee80211_sta *sta = NULL; if (is_hal_stop(rtlhal)) { - RT_TRACE(COMP_RATE, DBG_LOUD, - ("driver is going to unload\n")); + RT_TRACE(COMP_RATE, DBG_LOUD, "driver is going to unload\n"); return; } if (!rtlpriv->dm.b_useramask) { RT_TRACE(COMP_RATE, DBG_LOUD, - ("driver does not control rate adaptive mask\n")); + "driver does not control rate adaptive mask\n"); return; } diff --git a/drivers/staging/rtl8192ee/rtl8192ee/fw.c b/drivers/staging/rtl8192ee/rtl8192ee/fw.c index ea6cafa80f48..5b98c50c0644 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/fw.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/fw.c @@ -115,7 +115,7 @@ static void _rtl92ee_write_fw(struct ieee80211_hw *hw, u32 pageNums, remainSize; u32 page, offset; - RT_TRACE(COMP_FW, DBG_LOUD , ("FW size is %d bytes,\n", size)); + RT_TRACE(COMP_FW, DBG_LOUD , "FW size is %d bytes\n", size); _rtl92ee_fill_dummy(bufferPtr, &size); @@ -124,7 +124,7 @@ static void _rtl92ee_write_fw(struct ieee80211_hw *hw, if (pageNums > 8) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 8\n")); + "Page numbers should not greater then 8\n"); } for (page = 0; page < pageNums; page++) { @@ -157,13 +157,13 @@ static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw) if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); + "chksum report faill ! REG_MCUFWDL:0x%08x\n", + value32); goto exit; } RT_TRACE(COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32); value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); value32 |= MCUFWDL_RDY; @@ -176,9 +176,9 @@ static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw) do { value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); if (value32 & WINTINI_RDY) { - RT_TRACE(COMP_FW, DBG_LOUD , - ("Polling FW ready success!! REG_MCUFWDL:" - "0x%08x. count = %d\n", value32, counter)); + RT_TRACE(COMP_FW, DBG_LOUD, + "Polling FW ready success!! REG_MCUFWDL:0x%08x. count = %d\n", + value32, counter); err = 0; goto exit; } @@ -188,8 +188,8 @@ static int _rtl92ee_fw_free_to_go(struct ieee80211_hw *hw) } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); RT_TRACE(COMP_ERR, DBG_EMERG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n", - value32, counter)); + "Polling FW ready fail!! REG_MCUFWDL:0x%08x. count = %d\n", + value32, counter); exit: return err; @@ -213,21 +213,20 @@ int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw) rtlhal->fw_subversion = pfwheader->subversion; pfwdata = (u8 *) rtlhal->pfirmware; fwsize = rtlhal->fwsize; - RT_TRACE(COMP_FW, DBG_DMESG, - ("normal Firmware SIZE %d\n" , fwsize)); + RT_TRACE(COMP_FW, DBG_DMESG, "normal Firmware SIZE %d\n", fwsize); if (IS_FW_HEADER_EXIST(pfwheader)) { RT_TRACE(COMP_FW, DBG_DMESG, - ("Firmware Version(%d), Signature(%#x), Size(%d)\n", - pfwheader->version, pfwheader->signature, - (int)sizeof(struct rtl92c_firmware_header))); + "Firmware Version(%d), Signature(%#x), Size(%d)\n", + pfwheader->version, pfwheader->signature, + (int)sizeof(struct rtl92c_firmware_header)); pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); fwsize = fwsize - sizeof(struct rtl92c_firmware_header); } else { RT_TRACE(COMP_FW, DBG_DMESG, - ("Firmware no Header, Signature(%#x)\n", - pfwheader->signature)); + "Firmware no Header, Signature(%#x)\n", + pfwheader->signature); } if (rtlhal->b_mac_func_enable) { @@ -243,10 +242,9 @@ int rtl92ee_download_fw(struct ieee80211_hw *hw, bool buse_wake_on_wlan_fw) err = _rtl92ee_fw_free_to_go(hw); if (err) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Firmware is not ready to run!\n")); + "Firmware is not ready to run!\n"); } else { - RT_TRACE(COMP_FW, DBG_LOUD , - ("Firmware is ready to run!\n")); + RT_TRACE(COMP_FW, DBG_LOUD, "Firmware is ready to run!\n"); } return 0; @@ -284,13 +282,12 @@ static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, if (ppsc->dot11_psmode != EACTIVE || ppsc->inactive_pwrstate == ERFOFF) { - RT_TRACE(COMP_CMD, DBG_LOUD , - ("FillH2CCommand8192E(): " - "Return because RF is off!!!\n")); + RT_TRACE(COMP_CMD, DBG_LOUD, + "FillH2CCommand8192E(): Return because RF is off!!!\n"); return; } - RT_TRACE(COMP_CMD, DBG_LOUD , ("come in\n")); + RT_TRACE(COMP_CMD, DBG_LOUD, "come in\n"); /* 1. Prevent race condition in setting H2C cmd. * (copy from MgntActSet_RF_State().) @@ -299,16 +296,16 @@ static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); if (rtlhal->b_h2c_setinprogress) { RT_TRACE(COMP_CMD, DBG_LOUD , - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); + "H2C set in progress! Wait to set..element_id(%d)\n", + element_id); while (rtlhal->b_h2c_setinprogress) { spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); h2c_waitcounter++; - RT_TRACE(COMP_CMD, DBG_LOUD , - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); + RT_TRACE(COMP_CMD, DBG_LOUD, + "Wait 100 us (%d times)...\n", + h2c_waitcounter); udelay(100); if (h2c_waitcounter > 1000) @@ -329,8 +326,7 @@ static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, /*wait_writeh2c_limmit--; if (wait_writeh2c_limmit == 0) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); + "Write H2C fail because no trigger for FW INT!\n"); break; } */ @@ -355,7 +351,7 @@ static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, break; default: RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -377,19 +373,18 @@ static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, while (!isfw_read) { wait_h2c_limmit--; if (wait_h2c_limmit == 0) { - RT_TRACE(COMP_CMD, DBG_LOUD , - ("Wating too long for FW" - "read clear HMEBox(%d)!!!\n", - boxnum)); + RT_TRACE(COMP_CMD, DBG_LOUD, + "Wating too long for FW read clear HMEBox(%d)!!!\n", + boxnum); break; } udelay(10); isfw_read = _rtl92ee_check_fw_read_last_h2c(hw, boxnum); u1b_tmp = rtl_read_byte(rtlpriv, 0x130); - RT_TRACE(COMP_CMD, DBG_LOUD , - ("Wating for FW read clear HMEBox(%d)!!! 0x130 = %2x\n", - boxnum, u1b_tmp)); + RT_TRACE(COMP_CMD, DBG_LOUD, + "Waiting for FW read clear HMEBox(%d)!!! 0x130 = %2x\n", + boxnum, u1b_tmp); } } @@ -397,17 +392,17 @@ static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, H2C cmd, break and give up this H2C. */ if (!isfw_read) { RT_TRACE(COMP_CMD, DBG_LOUD , - ("Write H2C reg BOX[%d] fail, Fw don't read.\n", - boxnum)); + "Write H2C reg BOX[%d] fail, Fw doesn't read\n", + boxnum); break; } /* 4. Fill the H2C cmd into box */ memset(boxcontent, 0, sizeof(boxcontent)); memset(boxextcontent, 0, sizeof(boxextcontent)); boxcontent[0] = element_id; - RT_TRACE(COMP_CMD, DBG_LOUD , - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); + RT_TRACE(COMP_CMD, DBG_LOUD, + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); switch (cmd_len) { case 1: @@ -444,7 +439,7 @@ static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, break; default: RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -454,16 +449,15 @@ static void _rtl92ee_fill_h2c_command(struct ieee80211_hw *hw, u8 element_id, if (rtlhal->last_hmeboxnum == 4) rtlhal->last_hmeboxnum = 0; - RT_TRACE(COMP_CMD, DBG_LOUD , - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); + RT_TRACE(COMP_CMD, DBG_LOUD, "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); } spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); rtlhal->b_h2c_setinprogress = false; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - RT_TRACE(COMP_CMD, DBG_LOUD , ("go out\n")); + RT_TRACE(COMP_CMD, DBG_LOUD, "go out\n"); } void rtl92ee_fill_h2c_cmd(struct ieee80211_hw *hw, @@ -504,8 +498,8 @@ void rtl92ee_firmware_selfreset(struct ieee80211_hw *hw) u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp | BIT(2))); - RT_TRACE(COMP_INIT, DBG_LOUD , - (" _8051Reset92E(): 8051 reset success .\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, + " _8051Reset92E(): 8051 reset success\n"); } void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) @@ -514,7 +508,7 @@ void rtl92ee_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) u8 u1_h2c_set_pwrmode[H2C_92E_PWEMODE_LENGTH] = { 0 }; struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); u8 rlbm , power_state = 0; - RT_TRACE(COMP_POWER, DBG_LOUD , ("FW LPS mode = %d\n", mode)); + RT_TRACE(COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, ((mode) ? 1 : 0)); rlbm = 0;/*YJ, temp, 120316. FW now not support RLBM = 2.*/ @@ -776,15 +770,15 @@ void rtl92ee_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) b_dlok = true; if (b_dlok) { - RT_TRACE(COMP_POWER, DBG_LOUD , - ("Set RSVD page location to Fw.\n")); + RT_TRACE(COMP_POWER, DBG_LOUD, + "Set RSVD page location to Fw\n"); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD , "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3); rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else RT_TRACE(COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); + "Set RSVD page location to Fw FAIL!!!!!!\n"); } /*Shoud check FW support p2p or not.*/ @@ -809,11 +803,11 @@ void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) switch (p2p_ps_state) { case P2P_PS_DISABLE: - RT_TRACE(COMP_FW, DBG_LOUD , ("P2P_PS_DISABLE\n")); + RT_TRACE(COMP_FW, DBG_LOUD, "P2P_PS_DISABLE\n"); memset(p2p_ps_offload, 0, 1); break; case P2P_PS_ENABLE: - RT_TRACE(COMP_FW, DBG_LOUD , ("P2P_PS_ENABLE\n")); + RT_TRACE(COMP_FW, DBG_LOUD, "P2P_PS_ENABLE\n"); /* update CTWindow value. */ if (p2pinfo->ctwindow > 0) { p2p_ps_offload->CTWindow_En = 1; @@ -864,11 +858,11 @@ void rtl92ee_set_p2p_ps_offload_cmd(struct ieee80211_hw *hw, u8 p2p_ps_state) } break; case P2P_PS_SCAN: - RT_TRACE(COMP_FW, DBG_LOUD , ("P2P_PS_SCAN\n")); + RT_TRACE(COMP_FW, DBG_LOUD, "P2P_PS_SCAN\n"); p2p_ps_offload->discovery = 1; break; case P2P_PS_SCAN_DONE: - RT_TRACE(COMP_FW, DBG_LOUD , ("P2P_PS_SCAN_DONE\n")); + RT_TRACE(COMP_FW, DBG_LOUD, "P2P_PS_SCAN_DONE\n"); p2p_ps_offload->discovery = 0; p2pinfo->p2p_ps_state = P2P_PS_ENABLE; break; @@ -897,28 +891,28 @@ static void _rtl92ee_c2h_content_parsing(struct ieee80211_hw *hw, u8 c2h_cmd_id, switch (c2h_cmd_id) { case C2H_8192E_DBG: - RT_TRACE(COMP_FW, DBG_TRACE , ("[C2H], C2H_8723BE_DBG!!\n")); + RT_TRACE(COMP_FW, DBG_TRACE, "[C2H], C2H_8723BE_DBG!!\n"); break; case C2H_8192E_TXBF: - RT_TRACE(COMP_FW, DBG_TRACE , ("[C2H], C2H_8192E_TXBF!!\n")); + RT_TRACE(COMP_FW, DBG_TRACE, "[C2H], C2H_8192E_TXBF!!\n"); break; case C2H_8192E_TX_REPORT: - RT_TRACE(COMP_FW, DBG_TRACE , ("[C2H], C2H_8723BE_TX_REPORT!\n")); + RT_TRACE(COMP_FW, DBG_TRACE, "[C2H], C2H_8723BE_TX_REPORT!\n"); break; case C2H_8192E_BT_INFO: - RT_TRACE(COMP_FW, DBG_TRACE , ("[C2H], C2H_8723BE_BT_INFO!!\n")); + RT_TRACE(COMP_FW, DBG_TRACE, "[C2H], C2H_8723BE_BT_INFO!!\n"); rtlpriv->btcoexist.btc_ops->btc_btinfo_notify(rtlpriv, tmp_buf, c2h_cmd_len); break; case C2H_8192E_BT_MP: - RT_TRACE(COMP_FW, DBG_TRACE, ("[C2H], C2H_8723BE_BT_MP!!\n")); + RT_TRACE(COMP_FW, DBG_TRACE, "[C2H], C2H_8723BE_BT_MP!!\n"); break; case C2H_8192E_RA_RPT: _rtl92ee_c2h_ra_report_handler(hw, tmp_buf, c2h_cmd_len); break; default: RT_TRACE(COMP_FW, DBG_TRACE, - ("[C2H], Unkown packet!! CmdId(%#X)!\n", c2h_cmd_id)); + "[C2H], Unkown packet!! CmdId(%#X)!\n", c2h_cmd_id); break; } } @@ -935,8 +929,8 @@ void rtl92ee_c2h_packet_handler(struct ieee80211_hw *hw, u8 *buffer, u8 len) tmp_buf = buffer + 2; RT_TRACE(COMP_FW, DBG_TRACE, - ("[C2H packet], c2hCmdId = 0x%x, c2hCmdSeq = 0x%x, c2hCmdLen =%d\n", - c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len)); + "[C2H packet], c2hCmdId = 0x%x, c2hCmdSeq = 0x%x, c2hCmdLen =%d\n", + c2h_cmd_id, c2h_cmd_seq, c2h_cmd_len); RT_PRINT_DATA(rtlpriv, COMP_FW, DBG_TRACE, "[C2H packet], Content Hex:\n", tmp_buf, c2h_cmd_len); diff --git a/drivers/staging/rtl8192ee/rtl8192ee/hw.c b/drivers/staging/rtl8192ee/rtl8192ee/hw.c index 26af119e2ca4..780f6179c0d6 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/hw.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/hw.c @@ -161,8 +161,8 @@ static void _rtl92ee_set_fw_clock_on(struct ieee80211_hw *hw, rtl_write_word(rtlpriv , isr_regaddr, 0x0100); rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_92E; RT_TRACE(COMP_POWER, DBG_LOUD, - ("Receive CPWM INT!!! PSState = %X\n", - rtlhal->fw_ps_state)); + "Receive CPWM INT!!! PSState = %X\n", + rtlhal->fw_ps_state); } } @@ -357,8 +357,8 @@ void rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } default: - RT_TRACE(COMP_ERR, DBG_LOUD, - ("switch case not process %x\n", variable)); + RT_TRACE(COMP_ERR, DBG_LOUD, "switch case not processed %x\n", + variable); break; } } @@ -430,7 +430,7 @@ static void _rtl92ee_download_rsvd_page(struct ieee80211_hw *hw) } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5); if (!(bcnvalid_reg & BIT(0))) - RT_TRACE(COMP_INIT, DBG_LOUD, ("Download RSVD page failed!\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "Download RSVD page failed!\n"); /* Enable Bcn */ _rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0); @@ -488,8 +488,7 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) case HW_VAR_SLOT_TIME:{ u8 e_aci; - RT_TRACE(COMP_MLME, DBG_TRACE, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + RT_TRACE(COMP_MLME, DBG_TRACE, "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, REG_SLOT, val[0]); @@ -533,7 +532,7 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) reg[i]); } RT_TRACE(COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR:%#x\n", fac)); + "Set HW_VAR_AMPDU_FACTOR:%#x\n", fac); } break; } case HW_VAR_AC_PARAM:{ @@ -565,8 +564,8 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -582,14 +581,14 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(COMP_ERR, DBG_LOUD, - ("switch case not process \n")); + "switch case not processed\n"); break; } } RT_TRACE(COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", - acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } case HW_VAR_RCR:{ @@ -689,8 +688,8 @@ void rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl92ee_fill_h2c_cmd(hw, H2C_92E_KEEP_ALIVE_CTRL, 2, array); break; } default: - RT_TRACE(COMP_ERR, DBG_LOUD, - ("switch case not process %x\n", variable)); + RT_TRACE(COMP_ERR, DBG_LOUD, "switch case not processed %x\n", + variable); break; } } @@ -795,7 +794,7 @@ static bool _rtl92ee_init_mac(struct ieee80211_hw *hw) if (!rtl92e_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, Rtl8192E_NIC_ENABLE_FLOW)) { RT_TRACE(COMP_INIT, DBG_LOUD, - ("init MAC Fail as rtl92e_hal_pwrseqcmdparsing\n")); + "init MAC Fail as rtl92e_hal_pwrseqcmdparsing\n"); return false; } @@ -818,8 +817,7 @@ static bool _rtl92ee_init_mac(struct ieee80211_hw *hw) if (!rtlhal->b_mac_func_enable) { if (_rtl92ee_llt_table_init(hw) == false) { - RT_TRACE(COMP_INIT, DBG_LOUD, - ("LLT table init fail \n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "LLT table init fail\n"); return false; } } @@ -1112,12 +1110,12 @@ void rtl92ee_enable_hw_security_config(struct ieee80211_hw *hw) u8 tmp; RT_TRACE(COMP_INIT, DBG_DMESG, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(COMP_SEC, DBG_DMESG, ("not open hw encryption\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "not open hw encryption\n"); return; } @@ -1133,8 +1131,7 @@ void rtl92ee_enable_hw_security_config(struct ieee80211_hw *hw) tmp = rtl_read_byte(rtlpriv, REG_CR + 1); rtl_write_byte(rtlpriv, REG_CR + 1, tmp | BIT(1)); - RT_TRACE(COMP_SEC, DBG_DMESG, - ("The SECR-value %x \n", sec_reg_value)); + RT_TRACE(COMP_SEC, DBG_DMESG, "The SECR-value %x\n", sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); @@ -1152,7 +1149,7 @@ int rtl92ee_hw_init(struct ieee80211_hw *hw) u8 tmp_u1b , u1byte; u32 tmp_u4b; - RT_TRACE(COMP_INIT , DBG_LOUD , (" Rtl8192EE hw init\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, " Rtl8192EE hw init\n"); rtlpriv->rtlhal.being_init_adapter = true; rtlpriv->intf_ops->disable_aspm(hw); @@ -1180,7 +1177,7 @@ int rtl92ee_hw_init(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, 0x65, 1); } if (rtstatus != true) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Init MAC failed\n"); err = 1; return err; } @@ -1189,7 +1186,7 @@ int rtl92ee_hw_init(struct ieee80211_hw *hw) err = rtl92ee_download_fw(hw , false); if (err) { RT_TRACE(COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW without FW now..\n")); + "Failed to download FW. Init HW without FW now..\n"); err = 1; rtlhal->bfw_ready = false; return err; @@ -1267,12 +1264,12 @@ int rtl92ee_hw_init(struct ieee80211_hw *hw) stg_efuse_one_byte_read(hw, 0x1FA, &tmp_u1b); if (!(tmp_u1b & BIT(0))) { rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); - RT_TRACE(COMP_INIT, DBG_LOUD, ("PA BIAS path A\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "PA BIAS path A\n"); } if ((!(tmp_u1b & BIT(1))) && (rtlphy->rf_type == RF_2T2R)) { rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); - RT_TRACE(COMP_INIT, DBG_LOUD, ("PA BIAS path B\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "PA BIAS path B\n"); } rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128)); @@ -1287,7 +1284,7 @@ int rtl92ee_hw_init(struct ieee80211_hw *hw) rtl_write_dword(rtlpriv, 0x4fc, 0); - RT_TRACE(COMP_INIT , DBG_LOUD , ("end of Rtl8192EE hw init %x\n" , err)); + RT_TRACE(COMP_INIT, DBG_LOUD, "end of Rtl8192EE hw init %x\n", err); return 0; } @@ -1306,9 +1303,8 @@ static enum version_8192e _rtl92ee_read_chip_version(struct ieee80211_hw *hw) else version = (enum version_8192e) VERSION_NORMAL_CHIP_2T2R_8192E; - RT_TRACE(COMP_INIT, DBG_LOUD, - ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? - "RF_2T2R" : "RF_1T1R")); + RT_TRACE(COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); return version; } @@ -1326,29 +1322,26 @@ static int _rtl92ee_set_media_status(struct ieee80211_hw *hw, case NL80211_IFTYPE_UNSPECIFIED: mode = MSR_NOLINK; RT_TRACE(COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_MESH_POINT: mode = MSR_ADHOC; - RT_TRACE(COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + RT_TRACE(COMP_INIT, DBG_TRACE, "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: mode = MSR_INFRA; ledaction = LED_CTL_LINK; - RT_TRACE(COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + RT_TRACE(COMP_INIT, DBG_TRACE, "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: mode = MSR_AP; ledaction = LED_CTL_LINK; - RT_TRACE(COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + RT_TRACE(COMP_INIT, DBG_TRACE, "Set Network type to AP!\n"); break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + RT_TRACE(COMP_ERR, DBG_EMERG, "Network type %d not support!\n", + type); return 1; break; } @@ -1372,8 +1365,8 @@ static int _rtl92ee_set_media_status(struct ieee80211_hw *hw, _rtl92ee_disable_bcn_sub_func(hw); } else { RT_TRACE(COMP_ERR, DBG_WARNING, - ("Set HW_VAR_MEDIA_STATUS: " - "No such media status(%x).\n", mode)); + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + mode); } rtl_write_byte(rtlpriv, (MSR), bt_msr | mode); @@ -1494,7 +1487,7 @@ static void _rtl92ee_poweroff_adapter(struct ieee80211_hw *hw) u8 u1b_tmp; rtlhal->b_mac_func_enable = false; - RT_TRACE(COMP_INIT , DBG_LOUD , ("POWER OFF adapter \n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "POWER OFF adapter\n"); /* Run LPS WL RFOFF flow */ rtl92e_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, @@ -1534,7 +1527,7 @@ void rtl92ee_card_disable(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); enum nl80211_iftype opmode; - RT_TRACE(COMP_INIT , DBG_LOUD , ("RTL8192ee card disable\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "RTL8192ee card disable\n"); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); @@ -1593,8 +1586,7 @@ void rtl92ee_set_beacon_interval(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u16 bcn_interval = mac->beacon_interval; - RT_TRACE(COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + RT_TRACE(COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", bcn_interval); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); } @@ -1604,8 +1596,8 @@ void rtl92ee_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; @@ -1672,14 +1664,14 @@ static void _rtl8192ee_read_power_value_fromprom(struct ieee80211_hw *hw, u32 rf, addr = EEPROM_TX_PWR_INX, group, i = 0; RT_TRACE(COMP_INIT, DBG_LOUD, - ("hal_ReadPowerValueFromPROM92E(): PROMContent[0x%x]= 0x%x\n", - (addr + 1), hwinfo[addr + 1])); + "hal_ReadPowerValueFromPROM92E(): PROMContent[0x%x]= 0x%x\n", + (addr + 1), hwinfo[addr + 1]); if (0xFF == hwinfo[addr+1]) /*YJ, add, 120316*/ autoload_fail = true; if (autoload_fail) { RT_TRACE(COMP_INIT, DBG_LOUD, - ("auto load fail : Use Default value!\n")); + "auto load fail : Use Default value!\n"); for (rf = 0 ; rf < MAX_RF_PATH ; rf++) { /* 2.4G default value */ for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { @@ -1999,11 +1991,11 @@ static void _rtl92ee_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); return; } else { RT_TRACE(COMP_ERR, DBG_EMERG, - ("boot from neither eeprom nor efuse, check it !!")); + "boot from neither eeprom nor efuse, check it !!\n"); return; } @@ -2012,11 +2004,11 @@ static void _rtl92ee_read_adapter_info(struct ieee80211_hw *hw) eeprom_id = *((u16 *) &hwinfo[0]); if (eeprom_id != RTL8192E_EEPROM_ID) { - RT_TRACE(COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + RT_TRACE(COMP_ERR, DBG_WARNING, "EEPROM ID(%#x) is invalid!!\n", + eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -2027,22 +2019,22 @@ static void _rtl92ee_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_did = *(u16 *) &hwinfo[EEPROM_DID]; rtlefuse->eeprom_svid = *(u16 *) &hwinfo[EEPROM_SVID]; rtlefuse->eeprom_smid = *(u16 *) &hwinfo[EEPROM_SMID]; - RT_TRACE(COMP_INIT, DBG_LOUD, ("EEPROMId = 0x%4x\n", eeprom_id)); - RT_TRACE(COMP_INIT, DBG_LOUD, - ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); - RT_TRACE(COMP_INIT, DBG_LOUD, - ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); - RT_TRACE(COMP_INIT, DBG_LOUD, - ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); - RT_TRACE(COMP_INIT, DBG_LOUD, - ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); + RT_TRACE(COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id); + RT_TRACE(COMP_INIT, DBG_LOUD, "EEPROM VID = 0x%4x\n", + rtlefuse->eeprom_vid); + RT_TRACE(COMP_INIT, DBG_LOUD, "EEPROM DID = 0x%4x\n", + rtlefuse->eeprom_did); + RT_TRACE(COMP_INIT, DBG_LOUD, "EEPROM SVID = 0x%4x\n", + rtlefuse->eeprom_svid); + RT_TRACE(COMP_INIT, DBG_LOUD, "EEPROM SMID = 0x%4x\n", + rtlefuse->eeprom_smid); /*customer ID*/ rtlefuse->eeprom_oemid = *(u8 *) &hwinfo[EEPROM_CUSTOMER_ID]; if (rtlefuse->eeprom_oemid == 0xFF) rtlefuse->eeprom_oemid = 0; - RT_TRACE(COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + RT_TRACE(COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", + rtlefuse->eeprom_oemid); /*EEPROM version*/ rtlefuse->eeprom_version = *(u8 *) &hwinfo[EEPROM_VERSION]; /*mac address*/ @@ -2051,8 +2043,7 @@ static void _rtl92ee_read_adapter_info(struct ieee80211_hw *hw) *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; } - RT_TRACE(COMP_INIT, DBG_DMESG, - ("dev_addr: %pM\n", rtlefuse->dev_addr)); + RT_TRACE(COMP_INIT, DBG_DMESG, "dev_addr: %pM\n", rtlefuse->dev_addr); /*channel plan */ rtlefuse->eeprom_channelplan = *(u8 *) &hwinfo[EEPROM_CHANNELPLAN]; /* set channel paln to world wide 13 */ @@ -2106,8 +2097,8 @@ static void _rtl92ee_hal_customized_behavior(struct ieee80211_hw *hw) pcipriv->ledctl.bled_opendrain = true; - RT_TRACE(COMP_INIT, DBG_DMESG, - ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); + RT_TRACE(COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", + rtlhal->oem_id); } void rtl92ee_read_eeprom_info(struct ieee80211_hw *hw) @@ -2124,22 +2115,22 @@ void rtl92ee_read_eeprom_info(struct ieee80211_hw *hw) else rtlpriv->dm.brfpath_rxenable[0] = rtlpriv->dm.brfpath_rxenable[1] = true; - RT_TRACE(COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", - rtlhal->version)); + RT_TRACE(COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); if (tmp_u1b & BIT(4)) { - RT_TRACE(COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92ee_read_adapter_info(hw); } else { - RT_TRACE(COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); } _rtl92ee_hal_customized_behavior(hw); @@ -2295,8 +2286,7 @@ static void rtl92ee_update_hal_rate_mask(struct ieee80211_hw *hw, ratr_index = _rtl92ee_mrate_idx_to_arfr_id(hw, ratr_index); sta_entry->ratr_index = ratr_index; - RT_TRACE(COMP_RATR, DBG_DMESG, - ("ratr_bitmap :%x\n", ratr_bitmap)); + RT_TRACE(COMP_RATR, DBG_DMESG, "ratr_bitmap:%x\n", ratr_bitmap); *(u32 *) &rate_mask = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28); rate_mask[0] = macid; @@ -2307,10 +2297,10 @@ static void rtl92ee_update_hal_rate_mask(struct ieee80211_hw *hw, rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16); rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24); RT_TRACE(COMP_RATR, DBG_DMESG, - ("Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n", - ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1], - rate_mask[2], rate_mask[3], rate_mask[4], - rate_mask[5], rate_mask[6])); + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1], + rate_mask[2], rate_mask[3], rate_mask[4], + rate_mask[5], rate_mask[6]); rtl92ee_fill_h2c_cmd(hw, H2C_92E_RA_MASK, 7, rate_mask); _rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0); } @@ -2372,7 +2362,7 @@ void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { stg_rtl_cam_mark_invalid(hw, cam_offset + idx); @@ -2401,7 +2391,7 @@ void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, break; default: RT_TRACE(COMP_ERR, DBG_LOUD, - ("switch case not process \n")); + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2420,7 +2410,7 @@ void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(COMP_SEC, DBG_EMERG, - ("Can not find free hw security cam entry\n")); + "Can not find free hw security cam entry\n"); return; } } else { @@ -2434,17 +2424,17 @@ void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_MESH_POINT) stg_rtl_cam_del_entry(hw, p_macaddr); stg_rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { - RT_TRACE(COMP_SEC, DBG_DMESG, ("add one entry\n")); + RT_TRACE(COMP_SEC, DBG_DMESG, "add one entry\n"); if (is_pairwise) { RT_TRACE(COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); stg_rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -2452,7 +2442,7 @@ void rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, rtlpriv->sec.key_buf[key_index]); } else { RT_TRACE(COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { stg_rtl_cam_add_one_entry(hw, @@ -2539,6 +2529,6 @@ void rtl92ee_allow_all_destaddr(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); RT_TRACE(COMP_TURBO | COMP_INIT, DBG_LOUD, - ("receive_config = 0x%08X, write_into_reg =%d\n", - rtlpci->receive_config, write_into_reg)); + "receive_config = 0x%08X, write_into_reg =%d\n", + rtlpci->receive_config, write_into_reg); } diff --git a/drivers/staging/rtl8192ee/rtl8192ee/led.c b/drivers/staging/rtl8192ee/rtl8192ee/led.c index 3b459c93a843..aa471bb2de73 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/led.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/led.c @@ -41,8 +41,8 @@ void rtl92ee_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u32 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(COMP_LED, DBG_LOUD, "LedAddr:%X ledpin =%d\n", + REG_LEDCFG2, pled->ledpin); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -55,8 +55,7 @@ void rtl92ee_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) case LED_PIN_LED1: break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "switch case not processed\n"); break; } pled->b_ledon = true; @@ -67,8 +66,8 @@ void rtl92ee_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_priv *rtlpriv = rtl_priv(hw); u32 ledcfg; - RT_TRACE(COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin =%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(COMP_LED, DBG_LOUD, "LedAddr:%X ledpin =%d\n", + REG_LEDCFG2, pled->ledpin); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -81,8 +80,7 @@ void rtl92ee_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) case LED_PIN_LED1: break; default: - RT_TRACE(COMP_ERR, DBG_LOUD, - ("switch case not process\n")); + RT_TRACE(COMP_ERR, DBG_LOUD, "switch case not processed\n"); break; } pled->b_ledon = false; @@ -129,6 +127,6 @@ void rtl92ee_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(COMP_LED, DBG_TRACE, ("ledaction %d,\n", ledaction)); + RT_TRACE(COMP_LED, DBG_TRACE, "ledaction %d\n", ledaction); _rtl92ee_sw_led_control(hw, ledaction); } diff --git a/drivers/staging/rtl8192ee/rtl8192ee/phy.c b/drivers/staging/rtl8192ee/rtl8192ee/phy.c index beef284615e5..1c5c0e8ffd29 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/phy.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/phy.c @@ -65,15 +65,14 @@ u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) struct rtl_priv *rtlpriv = rtl_priv(hw); u32 returnvalue, originalvalue, bitshift; - RT_TRACE(COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask)); + RT_TRACE(COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(COMP_RF, DBG_TRACE, - ("BBR MASK = 0x%x Addr[0x%x]= 0x%x\n", - bitmask, regaddr, originalvalue)); + RT_TRACE(COMP_RF, DBG_TRACE, "BBR MASK = 0x%x Addr[0x%x]= 0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; } @@ -84,9 +83,8 @@ void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 originalvalue, bitshift; - RT_TRACE(COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x)\n", - regaddr, bitmask, data)); + RT_TRACE(COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); @@ -96,9 +94,8 @@ void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x)\n", - regaddr, bitmask, data)); + RT_TRACE(COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, @@ -109,8 +106,8 @@ u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, unsigned long flags; RT_TRACE(COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); @@ -122,8 +119,8 @@ u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); RT_TRACE(COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -137,8 +134,8 @@ void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw, unsigned long flags; RT_TRACE(COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - addr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + addr, bitmask, data, rfpath); spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); @@ -153,8 +150,8 @@ void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw, spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); RT_TRACE(COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - addr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + addr, bitmask, data, rfpath); } static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, @@ -171,7 +168,7 @@ static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, offset &= 0xff; newoffset = offset; if (RT_CANNOT_IO(hw)) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("return all one\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "return all one\n"); return 0xFFFFFFFF; } tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); @@ -199,9 +196,8 @@ static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, else retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); - RT_TRACE(COMP_RF, DBG_TRACE, - ("RFR-%d Addr[0x%x]= 0x%x\n", - rfpath, pphyreg->rflssi_readback, retvalue)); + RT_TRACE(COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]= 0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } @@ -216,16 +212,15 @@ static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; if (RT_CANNOT_IO(hw)) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("stop\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "stop\n"); return; } offset &= 0xff; newoffset = offset; data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(COMP_RF, DBG_TRACE, - ("RFW-%d Addr[0x%x]= 0x%x\n", rfpath, - pphyreg->rf3wire_offset, data_and_addr)); + RT_TRACE(COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]= 0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask) @@ -423,7 +418,7 @@ static void _rtl92ee_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &(rtlpriv->phy); if (path > RF90_PATH_D) { - RT_TRACE(COMP_INIT, DBG_LOUD, ("Invalid Rf Path %d\n", path)); + RT_TRACE(COMP_INIT, DBG_LOUD, "Invalid Rf Path %d\n", path); return; } if (band == BAND_ON_2_4G) { @@ -442,12 +437,12 @@ static void _rtl92ee_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, break; default: RT_TRACE(COMP_INIT, DBG_LOUD, - ("Invalid RateSection %d in 2.4G, Rf %d,%dTx\n", - rate_section, path, txnum)); + "Invalid RateSection %d in 2.4G, Rf %d,%dTx\n", + rate_section, path, txnum); break; }; } else { - RT_TRACE(COMP_INIT, DBG_LOUD, ("Invalid Band %d\n", band)); + RT_TRACE(COMP_INIT, DBG_LOUD, "Invalid Band %d\n", band); } } @@ -458,7 +453,7 @@ static u8 _rtl92ee_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, u8 band struct rtl_phy *rtlphy = &(rtlpriv->phy); u8 value = 0; if (path > RF90_PATH_D) { - RT_TRACE(COMP_INIT, DBG_LOUD, ("Invalid Rf Path %d\n", path)); + RT_TRACE(COMP_INIT, DBG_LOUD, "Invalid Rf Path %d\n", path); return 0; } if (band == BAND_ON_2_4G) { @@ -477,12 +472,12 @@ static u8 _rtl92ee_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, u8 band break; default: RT_TRACE(COMP_INIT, DBG_LOUD, - ("Invalid RateSection %d in 2.4G, Rf %d,%dTx\n", - rate_section, path, txnum)); + "Invalid RateSection %d in 2.4G, Rf %d,%dTx\n", + rate_section, path, txnum); break; }; } else { - RT_TRACE(COMP_INIT, DBG_LOUD, ("Invalid Band %d()\n", band)); + RT_TRACE(COMP_INIT, DBG_LOUD, "Invalid Band %d()\n", band); } return value; } @@ -608,7 +603,7 @@ static void _rtl92ee_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_ 0, 3, base); } RT_TRACE(COMP_POWER, DBG_TRACE, - ("<== _rtl92ee_phy_convert_txpower_dbm_to_relative_value()\n")); + "<== _rtl92ee_phy_convert_txpower_dbm_to_relative_value()\n"); } static void _rtl92ee_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw) @@ -627,7 +622,7 @@ static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw) rtstatus = _rtl92ee_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); if (!rtstatus) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n"); return false; } @@ -639,13 +634,13 @@ static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw) } _rtl92ee_phy_txpower_by_rate_configuration(hw); if (!rtstatus) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + RT_TRACE(COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n"); return false; } rtstatus = _rtl92ee_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); if (!rtstatus) { - RT_TRACE(COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); return false; } rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw, @@ -662,11 +657,11 @@ static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(COMP_INIT, DBG_TRACE, ("Read Rtl8192EMACPHY_Array\n")); + RT_TRACE(COMP_INIT, DBG_TRACE, "Read Rtl8192EMACPHY_Array\n"); arraylength = RTL8192EE_MAC_ARRAY_LEN; ptrarray = RTL8192EE_MAC_ARRAY; - RT_TRACE(COMP_INIT, DBG_LOUD, - ("Img:RTL8192EE_MAC_ARRAY LEN %d\n" , arraylength)); + RT_TRACE(COMP_INIT, DBG_LOUD, "Img:RTL8192EE_MAC_ARRAY LEN %d\n", + arraylength); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); return true; @@ -773,9 +768,9 @@ static bool _rtl92ee_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, } } RT_TRACE(COMP_INIT, DBG_TRACE, - ("The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n", + "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n", array[i], - array[i + 1])); + array[i + 1]); } } return true; @@ -853,16 +848,16 @@ static void _rtl92ee_store_tx_power_by_rate(struct ieee80211_hw *hw, u8 section = _rtl92ee_get_rate_section_index(regaddr); if (band != BAND_ON_2_4G && band != BAND_ON_5G) { - RT_TRACE(FPHY, PHY_TXPWR, ("Invalid Band %d\n", band)); + RT_TRACE(FPHY, PHY_TXPWR, "Invalid Band %d\n", band); return; } if (rfpath > MAX_RF_PATH - 1) { - RT_TRACE(FPHY, PHY_TXPWR, ("Invalid RfPath %d\n", rfpath)); + RT_TRACE(FPHY, PHY_TXPWR, "Invalid RfPath %d\n", rfpath); return; } if (txnum > MAX_RF_PATH - 1) { - RT_TRACE(FPHY, PHY_TXPWR, ("Invalid TxNum %d\n", txnum)); + RT_TRACE(FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum); return; } @@ -898,7 +893,7 @@ static bool _rtl92ee_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } } else { RT_TRACE(COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -924,8 +919,8 @@ bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, len = RTL8192EE_RADIOA_ARRAY_LEN; array = RTL8192EE_RADIOA_ARRAY; RT_TRACE(COMP_INIT, DBG_LOUD, - ("Radio_A:RTL8192EE_RADIOA_ARRAY %d\n" , len)); - RT_TRACE(COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath)); + "Radio_A:RTL8192EE_RADIOA_ARRAY %d\n", len); + RT_TRACE(COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); for (i = 0; i < len; i = i + 2) { v1 = array[i]; v2 = array[i+1]; @@ -968,8 +963,8 @@ bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, len = RTL8192EE_RADIOB_ARRAY_LEN; array = RTL8192EE_RADIOB_ARRAY; RT_TRACE(COMP_INIT, DBG_LOUD, - ("Radio_A:RTL8192EE_RADIOB_ARRAY %d\n" , len)); - RT_TRACE(COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath)); + "Radio_A:RTL8192EE_RADIOB_ARRAY %d\n", len); + RT_TRACE(COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); for (i = 0; i < len; i = i + 2) { v1 = array[i]; v2 = array[i+1]; @@ -1008,12 +1003,10 @@ bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, } break; case RF90_PATH_C: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "switch case not processed\n"); break; case RF90_PATH_D: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "switch case not processed\n"); break; } return true; @@ -1034,20 +1027,19 @@ void rtl92ee_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); RT_TRACE(COMP_INIT, DBG_TRACE, - ("Default initial gain (c50 = 0x%x, c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + "Default initial gain (c50 = 0x%x, c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, MASKDWORD); - RT_TRACE(COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + RT_TRACE(COMP_INIT, DBG_TRACE, "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } static void _rtl92ee_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) @@ -1313,8 +1305,7 @@ static u8 _rtl92ee_get_txpower_index(struct ieee80211_hw *hw, if (channel < 1 || channel > 14) { index = 0; - RT_TRACE(COMP_POWER_TRACKING, DBG_DMESG, - ("Illegal channel!!\n")); + RT_TRACE(COMP_POWER_TRACKING, DBG_DMESG, "Illegal channel!!\n"); } if (IS_CCK_RATE(rate)) @@ -1472,7 +1463,7 @@ static void _rtl92ee_set_txpower_index(struct ieee80211_hw *hw, u8 pwr_idx, MASKBYTE3, pwr_idx); break; default: - RT_TRACE(COMP_POWER, DBG_LOUD, ("Invalid Rate!!\n")); + RT_TRACE(COMP_POWER, DBG_LOUD, "Invalid Rate!!\n"); break; } } else if (rfpath == RF90_PATH_B) { @@ -1590,11 +1581,11 @@ static void _rtl92ee_set_txpower_index(struct ieee80211_hw *hw, u8 pwr_idx, MASKBYTE3, pwr_idx); break; default: - RT_TRACE(COMP_POWER, DBG_LOUD, ("Invalid Rate!!\n")); + RT_TRACE(COMP_POWER, DBG_LOUD, "Invalid Rate!!\n"); break; } } else { - RT_TRACE(COMP_POWER, DBG_LOUD, ("Invalid RFPath!!\n")); + RT_TRACE(COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n"); } } @@ -1652,8 +1643,7 @@ static void rtl92ee_phy_set_txpower_index_by_rate_section(struct ieee80211_hw *h rtlphy->current_chan_bw, channel, ht_rates2t, 8); } else - RT_TRACE(FPHY, PHY_TXPWR, - ("Invalid RateSection %d\n", section)); + RT_TRACE(FPHY, PHY_TXPWR, "Invalid RateSection %d\n", section); } void rtl92ee_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) @@ -1724,7 +1714,7 @@ void rtl92ee_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) break; default: RT_TRACE(COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); + "Unknown Scan Backup operation\n"); break; } } @@ -1739,10 +1729,8 @@ void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw) u8 reg_bw_opmode; u8 reg_prsr_rsc; - RT_TRACE(COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(COMP_SCAN, DBG_TRACE, "Switch to %sMHz bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? "20" : "40"); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; @@ -1765,8 +1753,8 @@ void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + RT_TRACE(COMP_ERR, DBG_EMERG, "unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); break; } @@ -1790,13 +1778,13 @@ void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw) HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + RT_TRACE(COMP_ERR, DBG_EMERG, "unknown bandwidth: %#X\n", + rtlphy->current_chan_bw); break; } rtl92ee_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(COMP_SCAN, DBG_LOUD, ("\n")); + RT_TRACE(COMP_SCAN, DBG_LOUD, "\n"); } void rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw, @@ -1814,7 +1802,7 @@ void rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw, rtl92ee_phy_set_bw_mode_callback(hw); } else { RT_TRACE(COMP_ERR, DBG_WARNING, - ("false driver sleep or unload\n")); + "false driver sleep or unload\n"); rtlphy->set_bwmode_inprogress = false; rtlphy->current_chan_bw = tmp_bw; } @@ -1827,8 +1815,8 @@ void rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); u32 delay; - RT_TRACE(COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); + RT_TRACE(COMP_SCAN, DBG_TRACE, "switch to channel%d\n", + rtlphy->current_channel); if (is_hal_stop(rtlhal)) return; do { @@ -1846,7 +1834,7 @@ void rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw) } break; } while (true); - RT_TRACE(COMP_SCAN, DBG_TRACE, ("\n")); + RT_TRACE(COMP_SCAN, DBG_TRACE, "\n"); } u8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw) @@ -1867,12 +1855,12 @@ u8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw) if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { rtl92ee_phy_sw_chnl_callback(hw); RT_TRACE(COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false schdule workitem current channel %d\n", - rtlphy->current_channel)); + "sw_chnl_inprogress false schedule workitem current channel %d\n", + rtlphy->current_channel); rtlphy->sw_chnl_inprogress = false; } else { RT_TRACE(COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or unload\n")); + "sw_chnl_inprogress false driver sleep or unload\n"); rtlphy->sw_chnl_inprogress = false; } return 1; @@ -1933,8 +1921,7 @@ static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(COMP_ERR, DBG_EMERG, - ("Invalid 'stage' = %d, Check it!\n" , - *stage)); + "Invalid 'stage' = %d, Check it!\n", *stage); return true; break; } @@ -1979,7 +1966,7 @@ static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -2325,7 +2312,7 @@ static u8 _rtl92ee_phy_path_b_rx_iqk(struct ieee80211_hw *hw, bool config_pathb) (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) result |= 0x02; else - RT_TRACE(COMP_RF, DBG_LOUD, ("Path B Rx IQK fail!!\n")); + RT_TRACE(COMP_RF, DBG_LOUD, "Path B Rx IQK fail!!\n"); return result; } @@ -2637,7 +2624,7 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, if (patha_ok == 0x01) { RT_TRACE(COMP_RF, DBG_LOUD, - ("Path A Tx IQK Success!!\n")); + "Path A Tx IQK Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, RTx_Power_Before_IQK_A, MASKDWORD) & 0x3FF0000) @@ -2648,8 +2635,8 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, break; } else { RT_TRACE(COMP_RF, DBG_LOUD, - ("Path A Tx IQK Fail!!, ret = 0x%x\n", - patha_ok)); + "Path A Tx IQK Fail!!, ret = 0x%x\n", + patha_ok); } } @@ -2658,7 +2645,7 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, if (patha_ok == 0x03) { RT_TRACE(COMP_RF, DBG_LOUD, - ("Path A Rx IQK Success!!\n")); + "Path A Rx IQK Success!!\n"); result[t][2] = (rtl_get_bbreg(hw, RRx_Power_Before_IQK_A_2, MASKDWORD) & 0x3FF0000) @@ -2670,13 +2657,13 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, break; } else { RT_TRACE(COMP_RF, DBG_LOUD, - ("Path A Rx IQK Fail!!, ret = 0x%x\n", - patha_ok)); + "Path A Rx IQK Fail!!, ret = 0x%x\n", + patha_ok); } } if (0x00 == patha_ok) - RT_TRACE(COMP_RF, DBG_LOUD, ("Path A IQK failed!!, ret = 0\n")); + RT_TRACE(COMP_RF, DBG_LOUD, "Path A IQK failed!!, ret = 0\n"); if (is2t) { _rtl92ee_phy_path_a_standby(hw); @@ -2692,7 +2679,7 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, pathb_ok = _rtl92ee_phy_path_b_iqk(hw); if (pathb_ok == 0x01) { RT_TRACE(COMP_RF, DBG_LOUD, - ("Path B Tx IQK Success!!\n")); + "Path B Tx IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, RTx_Power_Before_IQK_B, MASKDWORD) & 0x3FF0000) @@ -2704,8 +2691,8 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, break; } else { RT_TRACE(COMP_RF, DBG_LOUD, - ("Path B Tx IQK Fail!!, ret = 0x%x\n", - pathb_ok)); + "Path B Tx IQK Fail!!, ret = 0x%x\n", + pathb_ok); } } @@ -2713,7 +2700,7 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, pathb_ok = _rtl92ee_phy_path_b_rx_iqk(hw, is2t); if (pathb_ok == 0x03) { RT_TRACE(COMP_RF, DBG_LOUD, - ("Path B Rx IQK Success!!\n")); + "Path B Rx IQK Success!!\n"); result[t][6] = (rtl_get_bbreg(hw, RRx_Power_Before_IQK_B_2, MASKDWORD) & 0x3FF0000) @@ -2725,18 +2712,18 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, break; } else { RT_TRACE(COMP_RF, DBG_LOUD, - ("Path B Rx IQK Fail!!, ret = 0x%x\n", - pathb_ok)); + "Path B Rx IQK Fail!!, ret = 0x%x\n", + pathb_ok); } } if (0x00 == pathb_ok) RT_TRACE(COMP_RF, DBG_LOUD, - ("Path B IQK failed!!, ret = 0\n")); + "Path B IQK failed!!, ret = 0\n"); } /* Back to BB mode, load original value */ RT_TRACE(COMP_RF, DBG_LOUD, - ("IQK:Back to BB mode, load original value!\n")); + "IQK:Back to BB mode, load original value!\n"); rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0); if (t != 0) { @@ -2765,7 +2752,7 @@ static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTx_IQK_Tone_A, MASKDWORD, 0x01008c00); rtl_set_bbreg(hw, RRx_IQK_Tone_A, MASKDWORD, 0x01008c00); } - RT_TRACE(COMP_RF, DBG_LOUD, ("_rtl92ee_phy_iq_calibrate() <==\n")); + RT_TRACE(COMP_RF, DBG_LOUD, "_rtl92ee_phy_iq_calibrate() <==\n"); } static void _rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) @@ -2811,7 +2798,7 @@ static void _rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) } else { rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); } - RT_TRACE(COMP_INIT , DBG_LOUD , ("\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "\n"); } static void _rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, @@ -2820,7 +2807,7 @@ static void _rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - RT_TRACE(COMP_INIT , DBG_LOUD , ("\n")); + RT_TRACE(COMP_INIT, DBG_LOUD, "\n"); if (is_hal_stop(rtlhal)) { u8 u1btmp; @@ -3059,24 +3046,23 @@ bool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) struct rtl_phy *rtlphy = &(rtlpriv->phy); bool b_postprocessing = false; - RT_TRACE(COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); + RT_TRACE(COMP_CMD, DBG_TRACE, "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); do { switch (iotype) { case IO_CMD_RESUME_DM_BY_SCAN: RT_TRACE(COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); + "[IO CMD] Resume DM after scan\n"); b_postprocessing = true; break; case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: RT_TRACE(COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); + "[IO CMD] Pause DM before scan\n"); b_postprocessing = true; break; default: RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } while (false); @@ -3087,7 +3073,7 @@ bool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) return false; } rtl92ee_phy_set_io(hw); - RT_TRACE(COMP_CMD, DBG_TRACE, ("IO Type(%#x)\n", iotype)); + RT_TRACE(COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); return true; } @@ -3097,13 +3083,13 @@ static void rtl92ee_phy_set_io(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); RT_TRACE(COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: rtl92ee_dm_write_dig(hw , rtlphy->initgain_backup.xaagccore1); rtl92ee_dm_write_cck_cca_thres(hw, rtlphy->initgain_backup.cca); - RT_TRACE(COMP_CMD, DBG_TRACE , ("no set txpower\n")); + RT_TRACE(COMP_CMD, DBG_TRACE, "no set txpower\n"); rtl92ee_phy_set_txpower_level(hw, rtlphy->current_channel); break; case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: @@ -3114,13 +3100,11 @@ static void rtl92ee_phy_set_io(struct ieee80211_hw *hw) rtl92ee_dm_write_cck_cca_thres(hw, 0x40); break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "switch case not processed\n"); break; } rtlphy->set_io_inprogress = false; - RT_TRACE(COMP_CMD, DBG_TRACE, - ("(%#x)\n", rtlphy->current_io_type)); + RT_TRACE(COMP_CMD, DBG_TRACE, "(%#x)\n", rtlphy->current_io_type); } static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw) @@ -3166,15 +3150,15 @@ static bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw, do { init_count++; RT_TRACE(COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = stg_rtl_ps_enable_nic(hw); } while (!rtstatus && (init_count < 10)); RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(COMP_RF, DBG_DMESG, - ("Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies))); + "Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); ppsc->last_awake_jiffies = jiffies; rtl92ee_phy_set_rf_on(hw); } @@ -3192,26 +3176,26 @@ static bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); stg_rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -3235,31 +3219,28 @@ static bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", - (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } - RT_TRACE(COMP_RF, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + RT_TRACE(COMP_RF, DBG_DMESG, "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); ppsc->last_sleep_jiffies = jiffies; _rtl92ee_phy_set_rf_sleep(hw); break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "switch case not processed\n"); bresult = false; break; } diff --git a/drivers/staging/rtl8192ee/rtl8192ee/pwrseqcmd.c b/drivers/staging/rtl8192ee/rtl8192ee/pwrseqcmd.c index efb00f622361..d55234678d6b 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/pwrseqcmd.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/pwrseqcmd.c @@ -51,15 +51,15 @@ bool rtl92e_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, do { pwr_cfg_cmd = pwrcfgcmd[ary_idx]; RT_TRACE(COMP_INIT, DBG_TRACE, - ("offset(%#x), cut_msk(%#x), fab_msk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", - GET_PWR_CFG_OFFSET(pwr_cfg_cmd), - GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd), - GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd), - GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd), - GET_PWR_CFG_BASE(pwr_cfg_cmd), - GET_PWR_CFG_CMD(pwr_cfg_cmd), - GET_PWR_CFG_MASK(pwr_cfg_cmd), - GET_PWR_CFG_VALUE(pwr_cfg_cmd))); + "offset(%#x), cut_msk(%#x), fab_msk(%#x), interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", + GET_PWR_CFG_OFFSET(pwr_cfg_cmd), + GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd), + GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd), + GET_PWR_CFG_INTF_MASK(pwr_cfg_cmd), + GET_PWR_CFG_BASE(pwr_cfg_cmd), + GET_PWR_CFG_CMD(pwr_cfg_cmd), + GET_PWR_CFG_MASK(pwr_cfg_cmd), + GET_PWR_CFG_VALUE(pwr_cfg_cmd)); if ((GET_PWR_CFG_FAB_MASK(pwr_cfg_cmd)&fab_version) && (GET_PWR_CFG_CUT_MASK(pwr_cfg_cmd)&cut_version) && @@ -67,12 +67,12 @@ bool rtl92e_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, switch (GET_PWR_CFG_CMD(pwr_cfg_cmd)) { case PWR_CMD_READ: RT_TRACE(COMP_INIT, DBG_TRACE, - ("PWR_CMD_READ\n")); + "PWR_CMD_READ\n"); break; case PWR_CMD_WRITE: RT_TRACE(COMP_INIT, DBG_TRACE, - ("PWR_CMD_WRITE\n")); + "PWR_CMD_WRITE\n"); offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd); /*Read the value from system register*/ @@ -87,7 +87,7 @@ bool rtl92e_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, case PWR_CMD_POLLING: RT_TRACE(COMP_INIT, DBG_TRACE, - ("PWR_CMD_POLLING\n")); + "PWR_CMD_POLLING\n"); b_polling_bit = false; offset = GET_PWR_CFG_OFFSET(pwr_cfg_cmd); @@ -104,7 +104,7 @@ bool rtl92e_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, if (polling_count++ > max_polling_cnt) { RT_TRACE(COMP_INIT, DBG_LOUD, - ("polling fail\n")); + "polling fail\n"); return false; } } while (!b_polling_bit); @@ -113,7 +113,7 @@ bool rtl92e_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, case PWR_CMD_DELAY: RT_TRACE(COMP_INIT, DBG_TRACE, - ("PWR_CMD_DELAY\n")); + "PWR_CMD_DELAY\n"); if (GET_PWR_CFG_VALUE(pwr_cfg_cmd) == PWRSEQ_DELAY_US) udelay(GET_PWR_CFG_OFFSET(pwr_cfg_cmd)); @@ -122,8 +122,7 @@ bool rtl92e_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, break; case PWR_CMD_END: - RT_TRACE(COMP_INIT, DBG_TRACE, - ("PWR_CMD_END\n")); + RT_TRACE(COMP_INIT, DBG_TRACE, "PWR_CMD_END\n"); return true; break; diff --git a/drivers/staging/rtl8192ee/rtl8192ee/rf.c b/drivers/staging/rtl8192ee/rtl8192ee/rf.c index 4f5a49ebca10..5dcb9116db1d 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/rf.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/rf.c @@ -55,8 +55,8 @@ void rtl92ee_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) rtlphy->rfreg_chnlval[0]); break; default: - RT_TRACE(COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + RT_TRACE(COMP_ERR, DBG_EMERG, "unknown bandwidth: %#X\n", + bandwidth); break; } } @@ -139,12 +139,12 @@ static bool _rtl92ee_phy_rf6052_config_parafile(struct ieee80211_hw *hw) break; } if (!rtstatus) { - RT_TRACE(COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + RT_TRACE(COMP_INIT, DBG_TRACE, "Radio[%d] Fail!!\n", + rfpath); return false; } } - RT_TRACE(COMP_INIT, DBG_TRACE, ("\n")); + RT_TRACE(COMP_INIT, DBG_TRACE, "\n"); return rtstatus; } diff --git a/drivers/staging/rtl8192ee/rtl8192ee/sw.c b/drivers/staging/rtl8192ee/rtl8192ee/sw.c index f9c5729e2cd9..74f402d701ce 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/sw.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/sw.c @@ -171,8 +171,7 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw) /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vmalloc(0x8000); if (!rtlpriv->rtlhal.pfirmware) { - RT_TRACE(COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Can't alloc buffer for fw\n"); return 1; } @@ -180,13 +179,11 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw) err = request_firmware(&firmware, fw_name, rtlpriv->io.dev); if (err) { - RT_TRACE(COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Failed to request firmware!\n"); return 1; } if (firmware->size > 0x8000) { - RT_TRACE(COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + RT_TRACE(COMP_ERR, DBG_EMERG, "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/staging/rtl8192ee/rtl8192ee/trx.c b/drivers/staging/rtl8192ee/rtl8192ee/trx.c index 1190c8bdb0d3..71f1b9f394bc 100644 --- a/drivers/staging/rtl8192ee/rtl8192ee/trx.c +++ b/drivers/staging/rtl8192ee/rtl8192ee/trx.c @@ -531,9 +531,9 @@ bool rtl92ee_rx_query_desc(struct ieee80211_hw *hw, else status->wake_match = 0; if (status->wake_match) - RT_TRACE(COMP_RXDESC , DBG_LOUD, - ("GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch =%d\n", - status->wake_match)); + RT_TRACE(COMP_RXDESC, DBG_LOUD, + "GGGGGGGGGGGGGet Wakeup Packet!! WakeMatch =%d\n", + status->wake_match); rx_status->freq = hw->conf.chandef.chan->center_freq; rx_status->band = hw->conf.chandef.chan->band; @@ -645,8 +645,8 @@ u16 rtl92ee_rx_desc_buff_remained_cnt(struct ieee80211_hw *hw , u8 queue_index) if (write_point != rtlpci->rx_ring[queue_index].next_rx_rp) { RT_TRACE(COMP_RXDESC, DBG_DMESG, - ("!!!write point is 0x%x, reg 0x3B4 value is 0x%x\n", - write_point, tmp_4byte)); + "!!!write point is 0x%x, reg 0x3B4 value is 0x%x\n", + write_point, tmp_4byte); tmp_4byte = rtl_read_dword(rtlpriv, REG_RXQ_TXBD_IDX); read_point = (u16)((tmp_4byte>>16) & 0x7ff); write_point = (u16)(tmp_4byte & 0x7ff); @@ -868,8 +868,7 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw, mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { - RT_TRACE(COMP_SEND, DBG_TRACE, - ("DMA mapping error")); + RT_TRACE(COMP_SEND, DBG_TRACE, "DMA mapping error\n"); return; } if (pbd_desc_tx != NULL) @@ -887,8 +886,8 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw, USB_HWDESC_HEADER_LEN + EM_HDR_LEN); if (ptcb_desc->empkt_num) { RT_TRACE(COMP_SEND, DBG_TRACE, - ("Insert 8 byte.pTcb->EMPktNum:%d\n", - ptcb_desc->empkt_num)); + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); _rtl92ee_insert_emcontent(ptcb_desc, (u8 *)(skb->data)); } @@ -990,7 +989,7 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(pdesc, 1); SET_TX_DESC_HTC(pdesc, 1); } @@ -1013,7 +1012,7 @@ void rtl92ee_tx_fill_desc(struct ieee80211_hw *hw, is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { SET_TX_DESC_BMC(pdesc, 1); } - RT_TRACE(COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(COMP_SEND, DBG_TRACE, "\n"); } void rtl92ee_tx_fill_cmddesc(struct ieee80211_hw *hw, @@ -1032,8 +1031,7 @@ void rtl92ee_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 txdesc_len = 40; if (pci_dma_mapping_error(rtlpci->pdev, mapping)) { - RT_TRACE(COMP_SEND, DBG_TRACE, - ("DMA mapping error")); + RT_TRACE(COMP_SEND, DBG_TRACE, "DMA mapping error\n"); return; } CLEAR_PCI_TX_DESC_CONTENT(pdesc, txdesc_len); @@ -1278,7 +1276,7 @@ u32 rtl92ee_rx_command_packet(struct ieee80211_hw *hw, result = 1; break; default: - RT_TRACE(COMP_RECV, DBG_TRACE, ("No this packet type!!\n")); + RT_TRACE(COMP_RECV, DBG_TRACE, "No this packet type!!\n"); break; } -- GitLab From 0e107b9f3979fdeef3b5366c24317d0c3a5bf490 Mon Sep 17 00:00:00 2001 From: Adrian Remonda Date: Tue, 5 Aug 2014 00:30:17 +0200 Subject: [PATCH 0521/9167] Staging: rtl8188eu: Missing a blank line after declarations. This is a patch to the rtl8188e_xmit.c file that fixes up a missing blank line warning found by the checkpatch.pl tool. Signed-off-by: Adrian Remonda Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c index 7ecbcf731ea9..7a4f754d86df 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_xmit.c @@ -64,6 +64,7 @@ void _dbg_dump_tx_info(struct adapter *padapter, int frame_tag, { u8 dmp_txpkt; bool dump_txdesc = false; + rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(dmp_txpkt)); if (dmp_txpkt == 1) {/* dump txdesc for data frame */ -- GitLab From 742728f97a99b9125dfeea37744f27ab72d74e9d Mon Sep 17 00:00:00 2001 From: Fernando Apesteguia Date: Tue, 5 Aug 2014 21:10:19 +0200 Subject: [PATCH 0522/9167] staging: rtl8192u: remove unused function. Remove ComputeTxTime since it is not used. Signed-off-by: Fernando Apesteguia Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 4f3fa35477df..bd8a497af06e 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -1227,28 +1227,6 @@ inline u8 rtl8192_IsWirelessBMode(u16 rate) u16 N_DBPSOfRate(u16 DataRate); -u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame, - u8 bShortPreamble) -{ - u16 FrameTime; - u16 N_DBPS; - u16 Ceiling; - - if (rtl8192_IsWirelessBMode(DataRate)) { - if (bManagementFrame || !bShortPreamble || DataRate == 10) /* long preamble */ - FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10))); - else // Short preamble - FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10))); - if ((FrameLength*8 % (DataRate/10)) != 0) /* Get the Ceilling */ - FrameTime++; - } else { //802.11g DSSS-OFDM PLCP length field calculation. - N_DBPS = N_DBPSOfRate(DataRate); - Ceiling = (16 + 8*FrameLength + 6) / N_DBPS - + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0); - FrameTime = (u16)(16 + 4 + 4*Ceiling + 6); - } - return FrameTime; -} u16 N_DBPSOfRate(u16 DataRate) { -- GitLab From ca4e82966635d0b43cf668db036c0b9e9cc67b7c Mon Sep 17 00:00:00 2001 From: Tom Wales Date: Sun, 3 Aug 2014 20:41:44 +0100 Subject: [PATCH 0523/9167] Staging: lustre: checkpatch: remove blank spaces Remove spaces between the function names and open paranthesis and use the kernel coding style. Signed-off-by: Tom Wales Signed-off-by: Greg Kroah-Hartman --- .../lustre/lustre/obdclass/llog_swab.c | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/llog_swab.c b/drivers/staging/lustre/lustre/obdclass/llog_swab.c index b3247fb7a35a..bfac8387021e 100644 --- a/drivers/staging/lustre/lustre/obdclass/llog_swab.c +++ b/drivers/staging/lustre/lustre/obdclass/llog_swab.c @@ -61,9 +61,9 @@ static void print_llogd_body(struct llogd_body *d) void lustre_swab_lu_fid(struct lu_fid *fid) { - __swab64s (&fid->f_seq); - __swab32s (&fid->f_oid); - __swab32s (&fid->f_ver); + __swab64s(&fid->f_seq); + __swab32s(&fid->f_oid); + __swab32s(&fid->f_ver); } EXPORT_SYMBOL(lustre_swab_lu_fid); @@ -82,47 +82,47 @@ void lustre_swab_llog_id(struct llog_logid *log_id) { __swab64s(&log_id->lgl_oi.oi.oi_id); __swab64s(&log_id->lgl_oi.oi.oi_seq); - __swab32s(&log_id->lgl_ogen); + __swab32s(&log_id->lgl_ogen); } EXPORT_SYMBOL(lustre_swab_llog_id); -void lustre_swab_llogd_body (struct llogd_body *d) +void lustre_swab_llogd_body(struct llogd_body *d) { print_llogd_body(d); lustre_swab_llog_id(&d->lgd_logid); - __swab32s (&d->lgd_ctxt_idx); - __swab32s (&d->lgd_llh_flags); - __swab32s (&d->lgd_index); - __swab32s (&d->lgd_saved_index); - __swab32s (&d->lgd_len); - __swab64s (&d->lgd_cur_offset); + __swab32s(&d->lgd_ctxt_idx); + __swab32s(&d->lgd_llh_flags); + __swab32s(&d->lgd_index); + __swab32s(&d->lgd_saved_index); + __swab32s(&d->lgd_len); + __swab64s(&d->lgd_cur_offset); print_llogd_body(d); } EXPORT_SYMBOL(lustre_swab_llogd_body); -void lustre_swab_llogd_conn_body (struct llogd_conn_body *d) +void lustre_swab_llogd_conn_body(struct llogd_conn_body *d) { - __swab64s (&d->lgdc_gen.mnt_cnt); - __swab64s (&d->lgdc_gen.conn_cnt); + __swab64s(&d->lgdc_gen.mnt_cnt); + __swab64s(&d->lgdc_gen.conn_cnt); lustre_swab_llog_id(&d->lgdc_logid); - __swab32s (&d->lgdc_ctxt_idx); + __swab32s(&d->lgdc_ctxt_idx); } EXPORT_SYMBOL(lustre_swab_llogd_conn_body); void lustre_swab_ll_fid(struct ll_fid *fid) { - __swab64s (&fid->id); - __swab32s (&fid->generation); - __swab32s (&fid->f_type); + __swab64s(&fid->id); + __swab32s(&fid->generation); + __swab32s(&fid->f_type); } EXPORT_SYMBOL(lustre_swab_ll_fid); void lustre_swab_lu_seq_range(struct lu_seq_range *range) { - __swab64s (&range->lsr_start); - __swab64s (&range->lsr_end); - __swab32s (&range->lsr_index); - __swab32s (&range->lsr_flags); + __swab64s(&range->lsr_start); + __swab64s(&range->lsr_end); + __swab32s(&range->lsr_index); + __swab32s(&range->lsr_flags); } EXPORT_SYMBOL(lustre_swab_lu_seq_range); @@ -168,7 +168,7 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec) } case CHANGELOG_REC: { - struct llog_changelog_rec *cr = (struct llog_changelog_rec*)rec; + struct llog_changelog_rec *cr = (struct llog_changelog_rec *)rec; __swab16s(&cr->cr.cr_namelen); __swab16s(&cr->cr.cr_flags); @@ -193,7 +193,7 @@ void lustre_swab_llog_rec(struct llog_rec_hdr *rec) case CHANGELOG_USER_REC: { struct llog_changelog_user_rec *cur = - (struct llog_changelog_user_rec*)rec; + (struct llog_changelog_user_rec *)rec; __swab32s(&cur->cur_id); __swab64s(&cur->cur_endrec); @@ -294,7 +294,7 @@ static void print_llog_hdr(struct llog_log_hdr *h) CDEBUG(D_OTHER, "\tllh_tail.lrt_len: %#x\n", h->llh_tail.lrt_len); } -void lustre_swab_llog_hdr (struct llog_log_hdr *h) +void lustre_swab_llog_hdr(struct llog_log_hdr *h) { print_llog_hdr(h); @@ -367,7 +367,7 @@ struct cfg_marker32 { void lustre_swab_cfg_marker(struct cfg_marker *marker, int swab, int size) { - struct cfg_marker32 *cm32 = (struct cfg_marker32*)marker; + struct cfg_marker32 *cm32 = (struct cfg_marker32 *)marker; if (swab) { __swab32s(&marker->cm_step); -- GitLab From 714340db24b8b34dd9befc87db0e8c51040a4a7f Mon Sep 17 00:00:00 2001 From: Benedict Boerger Date: Fri, 8 Aug 2014 18:26:22 +0200 Subject: [PATCH 0524/9167] drivers: staging: lustre: fix sparse warnings / delete unused function drivers: staging: lustre: fix sparse warning: symbol XYZ was not declared. Should it be static? This was done by declaring them static. This could be done because the functions were used only in this file. Deleted the function lnet_print_text_bufs because it were unused. Compiled without an error. Done to complete a eudyptula task. Signed-off-by: Benedict Boerger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/config.c | 57 +++++++++-------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index 7c8b9476bfbb..ede664bfb748 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -47,7 +47,7 @@ static int lnet_tbnob; /* track text buf allocation */ #define LNET_MAX_TEXTBUF_NOB (64<<10) /* bound allocation */ #define LNET_SINGLE_TEXTBUF_NOB (4<<10) -void +static void lnet_syntax(char *name, char *str, int offset, int width) { static char dots[LNET_SINGLE_TEXTBUF_NOB]; @@ -64,7 +64,7 @@ lnet_syntax(char *name, char *str, int offset, int width) (width < 1) ? 0 : width - 1, dashes); } -int +static int lnet_issep(char c) { switch (c) { @@ -77,7 +77,7 @@ lnet_issep(char c) } } -int +static int lnet_net_unique(__u32 net, struct list_head *nilist) { struct list_head *tmp; @@ -108,7 +108,7 @@ lnet_ni_free(struct lnet_ni *ni) LIBCFS_FREE(ni, sizeof(*ni)); } -lnet_ni_t * +static lnet_ni_t * lnet_ni_alloc(__u32 net, struct cfs_expr_list *el, struct list_head *nilist) { struct lnet_tx_queue *tq; @@ -365,7 +365,7 @@ lnet_parse_networks(struct list_head *nilist, char *networks) return -EINVAL; } -lnet_text_buf_t * +static lnet_text_buf_t * lnet_new_text_buf(int str_len) { lnet_text_buf_t *ltb; @@ -394,14 +394,14 @@ lnet_new_text_buf(int str_len) return ltb; } -void +static void lnet_free_text_buf(lnet_text_buf_t *ltb) { lnet_tbnob -= ltb->ltb_size; LIBCFS_FREE(ltb, ltb->ltb_size); } -void +static void lnet_free_text_bufs(struct list_head *tbs) { lnet_text_buf_t *ltb; @@ -414,22 +414,7 @@ lnet_free_text_bufs(struct list_head *tbs) } } -void -lnet_print_text_bufs(struct list_head *tbs) -{ - struct list_head *tmp; - lnet_text_buf_t *ltb; - - list_for_each(tmp, tbs) { - ltb = list_entry(tmp, lnet_text_buf_t, ltb_list); - - CDEBUG(D_WARNING, "%s\n", ltb->ltb_text); - } - - CDEBUG(D_WARNING, "%d allocated\n", lnet_tbnob); -} - -int +static int lnet_str2tbs_sep(struct list_head *tbs, char *str) { struct list_head pending; @@ -487,7 +472,7 @@ lnet_str2tbs_sep(struct list_head *tbs, char *str) return 0; } -int +static int lnet_expand1tb(struct list_head *list, char *str, char *sep1, char *sep2, char *item, int itemlen) @@ -512,7 +497,7 @@ lnet_expand1tb(struct list_head *list, return 0; } -int +static int lnet_str2tbs_expand(struct list_head *tbs, char *str) { char num[16]; @@ -592,7 +577,7 @@ lnet_str2tbs_expand(struct list_head *tbs, char *str) return -1; } -int +static int lnet_parse_hops(char *str, unsigned int *hops) { int len = strlen(str); @@ -605,7 +590,7 @@ lnet_parse_hops(char *str, unsigned int *hops) #define LNET_PRIORITY_SEPARATOR (':') -int +static int lnet_parse_priority(char *str, unsigned int *priority, char **token) { int nob; @@ -635,7 +620,7 @@ lnet_parse_priority(char *str, unsigned int *priority, char **token) return 0; } -int +static int lnet_parse_route(char *str, int *im_a_router) { /* static scratch buffer OK (single threaded) */ @@ -778,7 +763,7 @@ lnet_parse_route(char *str, int *im_a_router) return myrc; } -int +static int lnet_parse_route_tbs(struct list_head *tbs, int *im_a_router) { lnet_text_buf_t *ltb; @@ -819,7 +804,7 @@ lnet_parse_routes(char *routes, int *im_a_router) return rc; } -int +static int lnet_match_network_token(char *token, int len, __u32 *ipaddrs, int nip) { LIST_HEAD(list); @@ -838,7 +823,7 @@ lnet_match_network_token(char *token, int len, __u32 *ipaddrs, int nip) return rc; } -int +static int lnet_match_network_tokens(char *net_entry, __u32 *ipaddrs, int nip) { static char tokens[LNET_SINGLE_TEXTBUF_NOB]; @@ -895,7 +880,7 @@ lnet_match_network_tokens(char *net_entry, __u32 *ipaddrs, int nip) return 1; } -__u32 +static __u32 lnet_netspec2net(char *netspec) { char *bracket = strchr(netspec, '('); @@ -912,7 +897,7 @@ lnet_netspec2net(char *netspec) return net; } -int +static int lnet_splitnets(char *source, struct list_head *nets) { int offset = 0; @@ -992,7 +977,7 @@ lnet_splitnets(char *source, struct list_head *nets) } } -int +static int lnet_match_networks(char **networksp, char *ip2nets, __u32 *ipaddrs, int nip) { static char networks[LNET_SINGLE_TEXTBUF_NOB]; @@ -1112,13 +1097,13 @@ lnet_match_networks(char **networksp, char *ip2nets, __u32 *ipaddrs, int nip) return count; } -void +static void lnet_ipaddr_free_enumeration(__u32 *ipaddrs, int nip) { LIBCFS_FREE(ipaddrs, nip * sizeof(*ipaddrs)); } -int +static int lnet_ipaddr_enumerate(__u32 **ipaddrsp) { int up; -- GitLab From 967544a65cf5d70b2d2ff069349eeca0cbf9e0b1 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Sun, 3 Aug 2014 17:21:06 -0700 Subject: [PATCH 0525/9167] staging: rtl8821ae: fix %d confusingly prefixed with 0x in format strings Signed-off-by: Hans Wennborg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8821ae/pci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/rtl8821ae/pci.c b/drivers/staging/rtl8821ae/pci.c index 26d7b2fc852a..b8187887d85f 100644 --- a/drivers/staging/rtl8821ae/pci.c +++ b/drivers/staging/rtl8821ae/pci.c @@ -662,7 +662,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) RT_TRACE(COMP_ERR, DBG_LOUD, ("more desc left, wake" "skb_queue@%d,ring->idx = %d," - "skb_queue_len = 0x%d\n", + "skb_queue_len = 0x%x\n", prio, ring->idx, skb_queue_len(&ring->queue))); @@ -1650,7 +1650,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, if ((own == 1) && (hw_queue != BEACON_QUEUE)) { RT_TRACE(COMP_ERR, DBG_WARNING, ("No more TX desc@%d, ring->idx = %d," - "idx = %d, skb_queue_len = 0x%d\n", + "idx = %d, skb_queue_len = 0x%x\n", hw_queue, ring->idx, idx, skb_queue_len(&ring->queue))); @@ -1695,7 +1695,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, RT_TRACE(COMP_ERR, DBG_LOUD, ("less desc left, stop skb_queue@%d, " "ring->idx = %d," - "idx = %d, skb_queue_len = 0x%d\n", + "idx = %d, skb_queue_len = 0x%x\n", hw_queue, ring->idx, idx, skb_queue_len(&ring->queue))); -- GitLab From 5a3101884571e6a1aaf307620178f7532f3284ad Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Sun, 3 Aug 2014 17:20:49 -0700 Subject: [PATCH 0526/9167] staging: nokia_h4p: fix %d confusingly prefixed with 0x in format string Signed-off-by: Hans Wennborg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nokia_h4p/nokia_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/nokia_h4p/nokia_core.c b/drivers/staging/nokia_h4p/nokia_core.c index 775e1d043230..240da0c4ee72 100644 --- a/drivers/staging/nokia_h4p/nokia_core.c +++ b/drivers/staging/nokia_h4p/nokia_core.c @@ -1113,7 +1113,7 @@ static int hci_h4p_probe(struct platform_device *pdev) GPIOF_OUT_INIT_LOW, "bt_wakeup"); if (err < 0) { - dev_err(info->dev, "Cannot get GPIO line 0x%d", + dev_err(info->dev, "Cannot get GPIO line 0x%x", info->bt_wakeup_gpio); return err; } -- GitLab From 9fca4f70edbdf7052458b21545d860637c41f863 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Mon, 4 Aug 2014 14:54:47 +0200 Subject: [PATCH 0527/9167] staging: ozwpan: Add module parameter description Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozmain.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozmain.c b/drivers/staging/ozwpan/ozmain.c index d1a5b7a2c16d..7d6ef4cadf1a 100644 --- a/drivers/staging/ozwpan/ozmain.c +++ b/drivers/staging/ozwpan/ozmain.c @@ -25,6 +25,9 @@ unsigned int oz_dbg_mask = OZ_DEFAULT_DBG_MASK; * netcards. Bindings can be added later using an IOCTL. */ static char *g_net_dev = ""; +module_param(g_net_dev, charp, S_IRUGO); +MODULE_PARM_DESC(g_net_dev, "The device(s) to bind to; " + "'*' means all, '' (empty string; default) means none."); /* * Context: process @@ -48,7 +51,6 @@ static void __exit ozwpan_exit(void) oz_cdev_deregister(); } -module_param(g_net_dev, charp, S_IRUGO); module_init(ozwpan_init); module_exit(ozwpan_exit); -- GitLab From c24dd2e2cdd22ce7ae2c54a15ee585689d611e3e Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Mon, 4 Aug 2014 14:54:48 +0200 Subject: [PATCH 0528/9167] staging: ozwpan: Fix typo in typedef Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozproto.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ozwpan/ozproto.h b/drivers/staging/ozwpan/ozproto.h index cb38e02c968e..378b7377a7a4 100644 --- a/drivers/staging/ozwpan/ozproto.h +++ b/drivers/staging/ozwpan/ozproto.h @@ -34,7 +34,7 @@ typedef void (*oz_app_term_fn_t)(void); typedef int (*oz_app_start_fn_t)(struct oz_pd *pd, int resume); typedef void (*oz_app_stop_fn_t)(struct oz_pd *pd, int pause); typedef void (*oz_app_rx_fn_t)(struct oz_pd *pd, struct oz_elt *elt); -typedef int (*oz_app_hearbeat_fn_t)(struct oz_pd *pd); +typedef int (*oz_app_heartbeat_fn_t)(struct oz_pd *pd); typedef void (*oz_app_farewell_fn_t)(struct oz_pd *pd, u8 ep_num, u8 *data, u8 len); @@ -44,7 +44,7 @@ struct oz_app_if { oz_app_start_fn_t start; oz_app_stop_fn_t stop; oz_app_rx_fn_t rx; - oz_app_hearbeat_fn_t heartbeat; + oz_app_heartbeat_fn_t heartbeat; oz_app_farewell_fn_t farewell; int app_id; }; -- GitLab From 3f8fd6d85fa9b826282043b9a67604eff8725033 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Mon, 4 Aug 2014 14:54:49 +0200 Subject: [PATCH 0529/9167] staging: ozwpan: Remove unused OZ_MAX_TIMER_POOL_SIZE OZ_MAX_TIMER_POOL_SIZE is not used anywhere; remove it. Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozproto.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index 110205599190..4aebe16810a7 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -29,8 +29,6 @@ #define OZ_DO_STOP 1 #define OZ_DO_SLEEP 2 -#define OZ_MAX_TIMER_POOL_SIZE 16 - struct oz_binding { struct packet_type ptype; char name[OZ_MAX_BINDING_LEN]; -- GitLab From 4abc48d140e75bb07143287f3be3fa858b8e10f5 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Mon, 4 Aug 2014 14:54:50 +0200 Subject: [PATCH 0530/9167] staging: ozwpan: Remove redundant initialization Member 'ops' has already been initialized by calling cdev_init(). Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozcdev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index 10c0a96ce8bb..f82e12cd26d8 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -360,7 +360,6 @@ int oz_cdev_register(void) MAJOR(g_cdev.devnum), MINOR(g_cdev.devnum)); cdev_init(&g_cdev.cdev, &oz_fops); g_cdev.cdev.owner = THIS_MODULE; - g_cdev.cdev.ops = &oz_fops; spin_lock_init(&g_cdev.lock); init_waitqueue_head(&g_cdev.rdq); err = cdev_add(&g_cdev.cdev, g_cdev.devnum, 1); -- GitLab From a7ae725c9295d9076c889bbb75f83cd8e053bfb6 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Mon, 4 Aug 2014 14:54:51 +0200 Subject: [PATCH 0531/9167] staging: ozwpan: Remove dead code No need to return a value from elt_buf_init(). Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozeltbuf.c | 3 +-- drivers/staging/ozwpan/ozeltbuf.h | 2 +- drivers/staging/ozwpan/ozpd.c | 5 +---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/ozwpan/ozeltbuf.c b/drivers/staging/ozwpan/ozeltbuf.c index bd560c67fc8c..f6e64817fb16 100644 --- a/drivers/staging/ozwpan/ozeltbuf.c +++ b/drivers/staging/ozwpan/ozeltbuf.c @@ -16,7 +16,7 @@ /* * Context: softirq-serialized */ -int oz_elt_buf_init(struct oz_elt_buf *buf) +void oz_elt_buf_init(struct oz_elt_buf *buf) { memset(buf, 0, sizeof(struct oz_elt_buf)); INIT_LIST_HEAD(&buf->stream_list); @@ -24,7 +24,6 @@ int oz_elt_buf_init(struct oz_elt_buf *buf) INIT_LIST_HEAD(&buf->isoc_list); buf->max_free_elts = 32; spin_lock_init(&buf->lock); - return 0; } /* diff --git a/drivers/staging/ozwpan/ozeltbuf.h b/drivers/staging/ozwpan/ozeltbuf.h index 03c12f57b9bb..384643272a43 100644 --- a/drivers/staging/ozwpan/ozeltbuf.h +++ b/drivers/staging/ozwpan/ozeltbuf.h @@ -50,7 +50,7 @@ struct oz_elt_buf { u8 tx_seq_num[OZ_NB_APPS]; }; -int oz_elt_buf_init(struct oz_elt_buf *buf); +void oz_elt_buf_init(struct oz_elt_buf *buf); void oz_elt_buf_term(struct oz_elt_buf *buf); struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf); void oz_elt_info_free(struct oz_elt_buf *buf, struct oz_elt_info *ei); diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 10f1b3ac8832..a27c6030e2f2 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -175,10 +175,7 @@ struct oz_pd *oz_pd_alloc(const u8 *mac_addr) oz_pd_set_state(pd, OZ_PD_S_IDLE); pd->max_tx_size = OZ_MAX_TX_SIZE; ether_addr_copy(pd->mac_addr, mac_addr); - if (0 != oz_elt_buf_init(&pd->elt_buff)) { - kfree(pd); - pd = NULL; - } + oz_elt_buf_init(&pd->elt_buff); spin_lock_init(&pd->tx_frame_lock); INIT_LIST_HEAD(&pd->tx_queue); INIT_LIST_HEAD(&pd->farewell_list); -- GitLab From a9686e786896297f9f1d74a2cac4ffccc7b3e50e Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Mon, 4 Aug 2014 14:54:52 +0200 Subject: [PATCH 0532/9167] staging: ozwpan: Simplify app interface Simplify the somewhat overcomplicated application interface; improves readability and saves a bunch of lines. Use designated struct initializers for clarity. Signed-off-by: Christoph Jaeger Reviewed-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozcdev.c | 30 +++--- drivers/staging/ozwpan/ozpd.c | 151 ++++++++-------------------- drivers/staging/ozwpan/ozpd.h | 4 +- drivers/staging/ozwpan/ozproto.c | 2 +- drivers/staging/ozwpan/ozproto.h | 1 - drivers/staging/ozwpan/ozprotocol.h | 2 - drivers/staging/ozwpan/ozusbsvc.c | 30 +++--- drivers/staging/ozwpan/ozusbsvc1.c | 12 +-- 8 files changed, 82 insertions(+), 150 deletions(-) diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index f82e12cd26d8..c73d3969a6b2 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c @@ -49,11 +49,11 @@ static struct oz_serial_ctx *oz_cdev_claim_ctx(struct oz_pd *pd) { struct oz_serial_ctx *ctx; - spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); - ctx = (struct oz_serial_ctx *)pd->app_ctx[OZ_APPID_SERIAL-1]; + spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL]); + ctx = (struct oz_serial_ctx *) pd->app_ctx[OZ_APPID_SERIAL]; if (ctx) atomic_inc(&ctx->ref_count); - spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); + spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL]); return ctx; } @@ -182,8 +182,8 @@ static ssize_t oz_cdev_write(struct file *filp, const char __user *buf, app_hdr->app_id = OZ_APPID_SERIAL; if (copy_from_user(app_hdr+1, buf, count)) goto out; - spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); - ctx = (struct oz_serial_ctx *)pd->app_ctx[OZ_APPID_SERIAL-1]; + spin_lock_bh(&pd->app_lock[OZ_APPID_USB]); + ctx = (struct oz_serial_ctx *) pd->app_ctx[OZ_APPID_SERIAL]; if (ctx) { app_hdr->elt_seq_num = ctx->tx_seq_num++; if (ctx->tx_seq_num == 0) @@ -193,7 +193,7 @@ static ssize_t oz_cdev_write(struct file *filp, const char __user *buf, ei = NULL; spin_unlock(&eb->lock); } - spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); + spin_unlock_bh(&pd->app_lock[OZ_APPID_USB]); out: if (ei) { count = 0; @@ -436,14 +436,14 @@ int oz_cdev_start(struct oz_pd *pd, int resume) return -ENOMEM; atomic_set(&ctx->ref_count, 1); ctx->tx_seq_num = 1; - spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); - old_ctx = pd->app_ctx[OZ_APPID_SERIAL-1]; + spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL]); + old_ctx = pd->app_ctx[OZ_APPID_SERIAL]; if (old_ctx) { - spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); + spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL]); kfree(ctx); } else { - pd->app_ctx[OZ_APPID_SERIAL-1] = ctx; - spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); + pd->app_ctx[OZ_APPID_SERIAL] = ctx; + spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL]); } spin_lock(&g_cdev.lock); if ((g_cdev.active_pd == NULL) && @@ -468,10 +468,10 @@ void oz_cdev_stop(struct oz_pd *pd, int pause) oz_dbg(ON, "Serial service paused\n"); return; } - spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); - ctx = (struct oz_serial_ctx *)pd->app_ctx[OZ_APPID_SERIAL-1]; - pd->app_ctx[OZ_APPID_SERIAL-1] = NULL; - spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL-1]); + spin_lock_bh(&pd->app_lock[OZ_APPID_SERIAL]); + ctx = (struct oz_serial_ctx *) pd->app_ctx[OZ_APPID_SERIAL]; + pd->app_ctx[OZ_APPID_SERIAL] = NULL; + spin_unlock_bh(&pd->app_lock[OZ_APPID_SERIAL]); if (ctx) oz_cdev_release_ctx(ctx); spin_lock(&g_cdev.lock); diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index a27c6030e2f2..6c4b13fad786 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -32,11 +32,6 @@ static void oz_retire_frame(struct oz_pd *pd, struct oz_tx_frame *f); static void oz_isoc_stream_free(struct oz_isoc_stream *st); static int oz_send_next_queued_frame(struct oz_pd *pd, int more_data); static void oz_isoc_destructor(struct sk_buff *skb); -static int oz_def_app_init(void); -static void oz_def_app_term(void); -static int oz_def_app_start(struct oz_pd *pd, int resume); -static void oz_def_app_stop(struct oz_pd *pd, int pause); -static void oz_def_app_rx(struct oz_pd *pd, struct oz_elt *elt); /* * Counts the uncompleted isoc frames submitted to netcard. @@ -45,80 +40,25 @@ static atomic_t g_submitted_isoc = ATOMIC_INIT(0); /* Application handler functions. */ -static const struct oz_app_if g_app_if[OZ_APPID_MAX] = { - {oz_usb_init, - oz_usb_term, - oz_usb_start, - oz_usb_stop, - oz_usb_rx, - oz_usb_heartbeat, - oz_usb_farewell, - OZ_APPID_USB}, - - {oz_def_app_init, - oz_def_app_term, - oz_def_app_start, - oz_def_app_stop, - oz_def_app_rx, - NULL, - NULL, - OZ_APPID_UNUSED1}, - - {oz_def_app_init, - oz_def_app_term, - oz_def_app_start, - oz_def_app_stop, - oz_def_app_rx, - NULL, - NULL, - OZ_APPID_UNUSED2}, - - {oz_cdev_init, - oz_cdev_term, - oz_cdev_start, - oz_cdev_stop, - oz_cdev_rx, - NULL, - NULL, - OZ_APPID_SERIAL}, +static const struct oz_app_if g_app_if[OZ_NB_APPS] = { + [OZ_APPID_USB] = { + .init = oz_usb_init, + .term = oz_usb_term, + .start = oz_usb_start, + .stop = oz_usb_stop, + .rx = oz_usb_rx, + .heartbeat = oz_usb_heartbeat, + .farewell = oz_usb_farewell, + }, + [OZ_APPID_SERIAL] = { + .init = oz_cdev_init, + .term = oz_cdev_term, + .start = oz_cdev_start, + .stop = oz_cdev_stop, + .rx = oz_cdev_rx, + }, }; -/* - * Context: process - */ -static int oz_def_app_init(void) -{ - return 0; -} - -/* - * Context: process - */ -static void oz_def_app_term(void) -{ -} - -/* - * Context: softirq - */ -static int oz_def_app_start(struct oz_pd *pd, int resume) -{ - return 0; -} - -/* - * Context: softirq - */ -static void oz_def_app_stop(struct oz_pd *pd, int pause) -{ -} - -/* - * Context: softirq - */ -static void oz_def_app_rx(struct oz_pd *pd, struct oz_elt *elt) -{ -} /* * Context: softirq or process @@ -169,7 +109,7 @@ struct oz_pd *oz_pd_alloc(const u8 *mac_addr) if (pd) { int i; atomic_set(&pd->ref_count, 2); - for (i = 0; i < OZ_APPID_MAX; i++) + for (i = 0; i < OZ_NB_APPS; i++) spin_lock_init(&pd->app_lock[i]); pd->last_rx_pkt_num = 0xffffffff; oz_pd_set_state(pd, OZ_PD_S_IDLE); @@ -269,23 +209,21 @@ void oz_pd_destroy(struct oz_pd *pd) */ int oz_services_start(struct oz_pd *pd, u16 apps, int resume) { - const struct oz_app_if *ai; - int rc = 0; + int i, rc = 0; oz_pd_dbg(pd, ON, "%s: (0x%x) resume(%d)\n", __func__, apps, resume); - for (ai = g_app_if; ai < &g_app_if[OZ_APPID_MAX]; ai++) { - if (apps & (1<app_id)) { - if (ai->start(pd, resume)) { + for (i = 0; i < OZ_NB_APPS; i++) { + if (g_app_if[i].start && (apps & (1 << i))) { + if (g_app_if[i].start(pd, resume)) { rc = -1; oz_pd_dbg(pd, ON, - "Unable to start service %d\n", - ai->app_id); + "Unable to start service %d\n", i); break; } spin_lock_bh(&g_polling_lock); - pd->total_apps |= (1<app_id); + pd->total_apps |= (1 << i); if (resume) - pd->paused_apps &= ~(1<app_id); + pd->paused_apps &= ~(1 << i); spin_unlock_bh(&g_polling_lock); } } @@ -297,20 +235,20 @@ int oz_services_start(struct oz_pd *pd, u16 apps, int resume) */ void oz_services_stop(struct oz_pd *pd, u16 apps, int pause) { - const struct oz_app_if *ai; + int i; oz_pd_dbg(pd, ON, "%s: (0x%x) pause(%d)\n", __func__, apps, pause); - for (ai = g_app_if; ai < &g_app_if[OZ_APPID_MAX]; ai++) { - if (apps & (1<app_id)) { + for (i = 0; i < OZ_NB_APPS; i++) { + if (g_app_if[i].stop && (apps & (1 << i))) { spin_lock_bh(&g_polling_lock); if (pause) { - pd->paused_apps |= (1<app_id); + pd->paused_apps |= (1 << i); } else { - pd->total_apps &= ~(1<app_id); - pd->paused_apps &= ~(1<app_id); + pd->total_apps &= ~(1 << i); + pd->paused_apps &= ~(1 << i); } spin_unlock_bh(&g_polling_lock); - ai->stop(pd, pause); + g_app_if[i].stop(pd, pause); } } } @@ -320,12 +258,11 @@ void oz_services_stop(struct oz_pd *pd, u16 apps, int pause) */ void oz_pd_heartbeat(struct oz_pd *pd, u16 apps) { - const struct oz_app_if *ai; - int more = 0; + int i, more = 0; - for (ai = g_app_if; ai < &g_app_if[OZ_APPID_MAX]; ai++) { - if (ai->heartbeat && (apps & (1<app_id))) { - if (ai->heartbeat(pd)) + for (i = 0; i < OZ_NB_APPS; i++) { + if (g_app_if[i].heartbeat && (apps & (1 << i))) { + if (g_app_if[i].heartbeat(pd)) more = 1; } } @@ -957,9 +894,10 @@ void oz_apps_init(void) { int i; - for (i = 0; i < OZ_APPID_MAX; i++) + for (i = 0; i < OZ_NB_APPS; i++) { if (g_app_if[i].init) g_app_if[i].init(); + } } /* @@ -970,9 +908,10 @@ void oz_apps_term(void) int i; /* Terminate all the apps. */ - for (i = 0; i < OZ_APPID_MAX; i++) + for (i = 0; i < OZ_NB_APPS; i++) { if (g_app_if[i].term) g_app_if[i].term(); + } } /* @@ -980,12 +919,8 @@ void oz_apps_term(void) */ void oz_handle_app_elt(struct oz_pd *pd, u8 app_id, struct oz_elt *elt) { - const struct oz_app_if *ai; - - if (app_id == 0 || app_id > OZ_APPID_MAX) - return; - ai = &g_app_if[app_id-1]; - ai->rx(pd, elt); + if (app_id < OZ_NB_APPS && g_app_if[app_id].rx) + g_app_if[app_id].rx(pd, elt); } /* @@ -994,7 +929,7 @@ void oz_handle_app_elt(struct oz_pd *pd, u8 app_id, struct oz_elt *elt) void oz_pd_indicate_farewells(struct oz_pd *pd) { struct oz_farewell *f; - const struct oz_app_if *ai = &g_app_if[OZ_APPID_USB-1]; + const struct oz_app_if *ai = &g_app_if[OZ_APPID_USB]; while (1) { spin_lock_bh(&g_polling_lock); diff --git a/drivers/staging/ozwpan/ozpd.h b/drivers/staging/ozwpan/ozpd.h index ad5fe7a6e619..3b3b3ce9f9e4 100644 --- a/drivers/staging/ozwpan/ozpd.h +++ b/drivers/staging/ozwpan/ozpd.h @@ -81,8 +81,8 @@ struct oz_pd { unsigned long presleep; unsigned long keep_alive; struct oz_elt_buf elt_buff; - void *app_ctx[OZ_APPID_MAX]; - spinlock_t app_lock[OZ_APPID_MAX]; + void *app_ctx[OZ_NB_APPS]; + spinlock_t app_lock[OZ_NB_APPS]; int max_tx_size; u8 mode; u8 ms_per_isoc; diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index 4aebe16810a7..549fe7ff1eee 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -614,7 +614,7 @@ struct oz_pd *oz_pd_find(const u8 *mac_addr) */ void oz_app_enable(int app_id, int enable) { - if (app_id <= OZ_APPID_MAX) { + if (app_id < OZ_NB_APPS) { spin_lock_bh(&g_polling_lock); if (enable) g_apps |= (1<app_lock[OZ_APPID_USB-1]); - old_ctx = pd->app_ctx[OZ_APPID_USB-1]; + spin_lock_bh(&pd->app_lock[OZ_APPID_USB]); + old_ctx = pd->app_ctx[OZ_APPID_USB]; if (old_ctx == NULL) - pd->app_ctx[OZ_APPID_USB-1] = usb_ctx; - oz_usb_get(pd->app_ctx[OZ_APPID_USB-1]); - spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); + pd->app_ctx[OZ_APPID_USB] = usb_ctx; + oz_usb_get(pd->app_ctx[OZ_APPID_USB]); + spin_unlock_bh(&pd->app_lock[OZ_APPID_USB]); if (old_ctx) { oz_dbg(ON, "Already have USB context\n"); kfree(usb_ctx); @@ -99,9 +99,9 @@ int oz_usb_start(struct oz_pd *pd, int resume) usb_ctx->hport = oz_hcd_pd_arrived(usb_ctx); if (usb_ctx->hport == NULL) { oz_dbg(ON, "USB hub returned null port\n"); - spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); - pd->app_ctx[OZ_APPID_USB-1] = NULL; - spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); + spin_lock_bh(&pd->app_lock[OZ_APPID_USB]); + pd->app_ctx[OZ_APPID_USB] = NULL; + spin_unlock_bh(&pd->app_lock[OZ_APPID_USB]); oz_usb_put(usb_ctx); rc = -1; } @@ -122,10 +122,10 @@ void oz_usb_stop(struct oz_pd *pd, int pause) oz_dbg(ON, "USB service paused\n"); return; } - spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); - usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB-1]; - pd->app_ctx[OZ_APPID_USB-1] = NULL; - spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); + spin_lock_bh(&pd->app_lock[OZ_APPID_USB]); + usb_ctx = (struct oz_usb_ctx *) pd->app_ctx[OZ_APPID_USB]; + pd->app_ctx[OZ_APPID_USB] = NULL; + spin_unlock_bh(&pd->app_lock[OZ_APPID_USB]); if (usb_ctx) { struct timespec ts, now; getnstimeofday(&ts); @@ -187,11 +187,11 @@ int oz_usb_heartbeat(struct oz_pd *pd) struct oz_usb_ctx *usb_ctx; int rc = 0; - spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); - usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB-1]; + spin_lock_bh(&pd->app_lock[OZ_APPID_USB]); + usb_ctx = (struct oz_usb_ctx *) pd->app_ctx[OZ_APPID_USB]; if (usb_ctx) oz_usb_get(usb_ctx); - spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); + spin_unlock_bh(&pd->app_lock[OZ_APPID_USB]); if (usb_ctx == NULL) return rc; if (usb_ctx->stopped) diff --git a/drivers/staging/ozwpan/ozusbsvc1.c b/drivers/staging/ozwpan/ozusbsvc1.c index f32d01427f77..12bb236174dc 100644 --- a/drivers/staging/ozwpan/ozusbsvc1.c +++ b/drivers/staging/ozwpan/ozusbsvc1.c @@ -364,11 +364,11 @@ void oz_usb_rx(struct oz_pd *pd, struct oz_elt *elt) struct oz_usb_hdr *usb_hdr = (struct oz_usb_hdr *)(elt + 1); struct oz_usb_ctx *usb_ctx; - spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); - usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB-1]; + spin_lock_bh(&pd->app_lock[OZ_APPID_USB]); + usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB]; if (usb_ctx) oz_usb_get(usb_ctx); - spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); + spin_unlock_bh(&pd->app_lock[OZ_APPID_USB]); if (usb_ctx == NULL) return; /* Context has gone so nothing to do. */ if (usb_ctx->stopped) @@ -434,11 +434,11 @@ void oz_usb_farewell(struct oz_pd *pd, u8 ep_num, u8 *data, u8 len) { struct oz_usb_ctx *usb_ctx; - spin_lock_bh(&pd->app_lock[OZ_APPID_USB-1]); - usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB-1]; + spin_lock_bh(&pd->app_lock[OZ_APPID_USB]); + usb_ctx = (struct oz_usb_ctx *)pd->app_ctx[OZ_APPID_USB]; if (usb_ctx) oz_usb_get(usb_ctx); - spin_unlock_bh(&pd->app_lock[OZ_APPID_USB-1]); + spin_unlock_bh(&pd->app_lock[OZ_APPID_USB]); if (usb_ctx == NULL) return; /* Context has gone so nothing to do. */ if (!usb_ctx->stopped) { -- GitLab From 9e6fbdde1219bdd3875e72c6278beebf241bd416 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Fri, 8 Aug 2014 07:59:24 +0200 Subject: [PATCH 0533/9167] staging: ozwpan: Use slab cache for oz_urb_link allocation Use a slab cache rather than rolling our own free list. Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozhcd.c | 70 ++++++---------------------------- 1 file changed, 12 insertions(+), 58 deletions(-) diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 30bd9286d47d..1142f574a3e5 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -45,10 +45,6 @@ */ #define OZ_PLAT_DEV_NAME "ozwpan" -/* Maximum number of free urb links that can be kept in the pool. - */ -#define OZ_MAX_LINK_POOL_SIZE 16 - /* Get endpoint object from the containing link. */ #define ep_from_link(__e) container_of((__e), struct oz_endpoint, link) @@ -75,6 +71,8 @@ struct oz_urb_link { unsigned submit_counter; }; +static struct kmem_cache *oz_urb_link_cache; + /* Holds state information about a USB endpoint. */ #define OZ_EP_BUFFER_SIZE_ISOC (1024 * 24) @@ -198,9 +196,6 @@ static struct platform_device *g_plat_dev; static struct oz_hcd *g_ozhcd; static DEFINE_SPINLOCK(g_hcdlock); /* Guards g_ozhcd. */ static const char g_hcd_name[] = "Ozmo WPAN"; -static struct list_head *g_link_pool; -static int g_link_pool_size; -static DEFINE_SPINLOCK(g_link_lock); static DEFINE_SPINLOCK(g_tasklet_lock); static struct tasklet_struct g_urb_process_tasklet; static struct tasklet_struct g_urb_cancel_tasklet; @@ -265,68 +260,22 @@ static int oz_get_port_from_addr(struct oz_hcd *ozhcd, u8 bus_addr) } /* - * Allocates an urb link, first trying the pool but going to heap if empty. * Context: any */ static struct oz_urb_link *oz_alloc_urb_link(void) { - struct oz_urb_link *urbl = NULL; - unsigned long irq_state; - - spin_lock_irqsave(&g_link_lock, irq_state); - if (g_link_pool) { - urbl = container_of(g_link_pool, struct oz_urb_link, link); - g_link_pool = urbl->link.next; - --g_link_pool_size; - } - spin_unlock_irqrestore(&g_link_lock, irq_state); - if (urbl == NULL) - urbl = kmalloc(sizeof(struct oz_urb_link), GFP_ATOMIC); - return urbl; + return kmem_cache_alloc(oz_urb_link_cache, GFP_ATOMIC); } /* - * Frees an urb link by putting it in the pool if there is enough space or - * deallocating it to heap otherwise. * Context: any */ static void oz_free_urb_link(struct oz_urb_link *urbl) { - if (urbl) { - unsigned long irq_state; - - spin_lock_irqsave(&g_link_lock, irq_state); - if (g_link_pool_size < OZ_MAX_LINK_POOL_SIZE) { - urbl->link.next = g_link_pool; - g_link_pool = &urbl->link; - urbl = NULL; - g_link_pool_size++; - } - spin_unlock_irqrestore(&g_link_lock, irq_state); - kfree(urbl); - } -} - -/* - * Deallocates all the urb links in the pool. - * Context: unknown - */ -static void oz_empty_link_pool(void) -{ - struct list_head *e; - unsigned long irq_state; + if (!urbl) + return; - spin_lock_irqsave(&g_link_lock, irq_state); - e = g_link_pool; - g_link_pool = NULL; - g_link_pool_size = 0; - spin_unlock_irqrestore(&g_link_lock, irq_state); - while (e) { - struct oz_urb_link *urbl = - container_of(e, struct oz_urb_link, link); - e = e->next; - kfree(urbl); - } + kmem_cache_free(oz_urb_link_cache, urbl); } /* @@ -2311,7 +2260,6 @@ static int oz_plat_remove(struct platform_device *dev) oz_dbg(ON, "Removing hcd\n"); usb_remove_hcd(hcd); usb_put_hcd(hcd); - oz_empty_link_pool(); return 0; } @@ -2341,6 +2289,11 @@ int oz_hcd_init(void) if (usb_disabled()) return -ENODEV; + + oz_urb_link_cache = KMEM_CACHE(oz_urb_link, 0); + if (!oz_urb_link_cache) + return -ENOMEM; + tasklet_init(&g_urb_process_tasklet, oz_urb_process_tasklet, 0); tasklet_init(&g_urb_cancel_tasklet, oz_urb_cancel_tasklet, 0); err = platform_driver_register(&g_oz_plat_drv); @@ -2380,4 +2333,5 @@ void oz_hcd_term(void) platform_device_unregister(g_plat_dev); platform_driver_unregister(&g_oz_plat_drv); oz_dbg(ON, "Pending urbs:%d\n", atomic_read(&g_pending_urbs)); + kmem_cache_destroy(oz_urb_link_cache); } -- GitLab From 2b8b61aaef59751fe85c1b2df51a848a6c50d202 Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Fri, 8 Aug 2014 08:00:42 +0200 Subject: [PATCH 0534/9167] staging: ozwpan: Use slab cache for oz_elt_info allocation Use a slab cache rather than rolling our own free list. Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozeltbuf.c | 68 ++----------------------------- drivers/staging/ozwpan/ozeltbuf.h | 5 --- drivers/staging/ozwpan/ozpd.c | 2 - drivers/staging/ozwpan/ozpd.h | 2 + drivers/staging/ozwpan/ozproto.c | 9 ++++ drivers/staging/ozwpan/ozproto.h | 2 + 6 files changed, 16 insertions(+), 72 deletions(-) diff --git a/drivers/staging/ozwpan/ozeltbuf.c b/drivers/staging/ozwpan/ozeltbuf.c index f6e64817fb16..389ab1ab62fe 100644 --- a/drivers/staging/ozwpan/ozeltbuf.c +++ b/drivers/staging/ozwpan/ozeltbuf.c @@ -10,9 +10,6 @@ #include "ozeltbuf.h" #include "ozpd.h" -#define OZ_ELT_INFO_MAGIC_USED 0x35791057 -#define OZ_ELT_INFO_MAGIC_FREE 0x78940102 - /* * Context: softirq-serialized */ @@ -22,7 +19,6 @@ void oz_elt_buf_init(struct oz_elt_buf *buf) INIT_LIST_HEAD(&buf->stream_list); INIT_LIST_HEAD(&buf->order_list); INIT_LIST_HEAD(&buf->isoc_list); - buf->max_free_elts = 32; spin_lock_init(&buf->lock); } @@ -49,14 +45,6 @@ void oz_elt_buf_term(struct oz_elt_buf *buf) kfree(ei); } } - /* Free any elelment in the pool. */ - while (buf->elt_pool) { - struct oz_elt_info *ei = - container_of(buf->elt_pool, struct oz_elt_info, link); - buf->elt_pool = buf->elt_pool->next; - kfree(ei); - } - buf->free_elts = 0; } /* @@ -66,27 +54,8 @@ struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf) { struct oz_elt_info *ei; - spin_lock_bh(&buf->lock); - if (buf->free_elts && buf->elt_pool) { - ei = container_of(buf->elt_pool, struct oz_elt_info, link); - buf->elt_pool = ei->link.next; - buf->free_elts--; - spin_unlock_bh(&buf->lock); - if (ei->magic != OZ_ELT_INFO_MAGIC_FREE) { - oz_dbg(ON, "%s: ei with bad magic: 0x%x\n", - __func__, ei->magic); - } - } else { - spin_unlock_bh(&buf->lock); - ei = kmalloc(sizeof(struct oz_elt_info), GFP_ATOMIC); - } + ei = kmem_cache_zalloc(oz_elt_info_cache, GFP_ATOMIC); if (ei) { - ei->flags = 0; - ei->app_id = 0; - ei->callback = NULL; - ei->context = 0; - ei->stream = NULL; - ei->magic = OZ_ELT_INFO_MAGIC_USED; INIT_LIST_HEAD(&ei->link); INIT_LIST_HEAD(&ei->link_order); } @@ -99,17 +68,8 @@ struct oz_elt_info *oz_elt_info_alloc(struct oz_elt_buf *buf) */ void oz_elt_info_free(struct oz_elt_buf *buf, struct oz_elt_info *ei) { - if (ei) { - if (ei->magic == OZ_ELT_INFO_MAGIC_USED) { - buf->free_elts++; - ei->link.next = buf->elt_pool; - buf->elt_pool = &ei->link; - ei->magic = OZ_ELT_INFO_MAGIC_FREE; - } else { - oz_dbg(ON, "%s: bad magic ei: %p magic: 0x%x\n", - __func__, ei, ei->magic); - } - } + if (ei) + kmem_cache_free(oz_elt_info_cache, ei); } /*------------------------------------------------------------------------------ @@ -313,25 +273,3 @@ int oz_are_elts_available(struct oz_elt_buf *buf) { return buf->order_list.next != &buf->order_list; } - -void oz_trim_elt_pool(struct oz_elt_buf *buf) -{ - struct list_head *free = NULL; - struct list_head *e; - - spin_lock_bh(&buf->lock); - while (buf->free_elts > buf->max_free_elts) { - e = buf->elt_pool; - buf->elt_pool = e->next; - e->next = free; - free = e; - buf->free_elts--; - } - spin_unlock_bh(&buf->lock); - while (free) { - struct oz_elt_info *ei = - container_of(free, struct oz_elt_info, link); - free = free->next; - kfree(ei); - } -} diff --git a/drivers/staging/ozwpan/ozeltbuf.h b/drivers/staging/ozwpan/ozeltbuf.h index 384643272a43..f09f5fe3ffbe 100644 --- a/drivers/staging/ozwpan/ozeltbuf.h +++ b/drivers/staging/ozwpan/ozeltbuf.h @@ -34,7 +34,6 @@ struct oz_elt_info { struct oz_elt_stream *stream; u8 data[sizeof(struct oz_elt) + OZ_MAX_ELT_PAYLOAD]; int length; - unsigned magic; }; /* Flags values */ #define OZ_EI_F_MARKED 0x1 @@ -44,9 +43,6 @@ struct oz_elt_buf { struct list_head stream_list; struct list_head order_list; struct list_head isoc_list; - struct list_head *elt_pool; - int free_elts; - int max_free_elts; u8 tx_seq_num[OZ_NB_APPS]; }; @@ -64,7 +60,6 @@ int oz_queue_elt_info(struct oz_elt_buf *buf, u8 isoc, u8 id, int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len, unsigned max_len, struct list_head *list); int oz_are_elts_available(struct oz_elt_buf *buf); -void oz_trim_elt_pool(struct oz_elt_buf *buf); #endif /* _OZELTBUF_H */ diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index 6c4b13fad786..c6fddb8182ee 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -504,8 +504,6 @@ static void oz_retire_frame(struct oz_pd *pd, struct oz_tx_frame *f) spin_unlock_bh(&pd->elt_buff.lock); } oz_tx_frame_free(pd, f); - if (pd->elt_buff.free_elts > pd->elt_buff.max_free_elts) - oz_trim_elt_pool(&pd->elt_buff); } /* diff --git a/drivers/staging/ozwpan/ozpd.h b/drivers/staging/ozwpan/ozpd.h index 3b3b3ce9f9e4..43a26ea8c9ad 100644 --- a/drivers/staging/ozwpan/ozpd.h +++ b/drivers/staging/ozwpan/ozpd.h @@ -130,4 +130,6 @@ void oz_handle_app_elt(struct oz_pd *pd, u8 app_id, struct oz_elt *elt); void oz_apps_init(void); void oz_apps_term(void); +extern struct kmem_cache *oz_elt_info_cache; + #endif /* Sentry */ diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index 549fe7ff1eee..b592e96a8445 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "ozdbg.h" #include "ozprotocol.h" #include "ozeltbuf.h" @@ -51,6 +52,8 @@ static u8 g_session_id; static u16 g_apps = 0x1; static int g_processing_rx; +struct kmem_cache *oz_elt_info_cache; + /* * Context: softirq-serialized */ @@ -479,6 +482,8 @@ void oz_protocol_term(void) } spin_unlock_bh(&g_polling_lock); oz_dbg(ON, "Protocol stopped\n"); + + kmem_cache_destroy(oz_elt_info_cache); } /* @@ -762,6 +767,10 @@ static char *oz_get_next_device_name(char *s, char *dname, int max_size) */ int oz_protocol_init(char *devs) { + oz_elt_info_cache = KMEM_CACHE(oz_elt_info, 0); + if (!oz_elt_info_cache) + return -ENOMEM; + skb_queue_head_init(&g_rx_queue); if (devs[0] == '*') { oz_binding_add(NULL); diff --git a/drivers/staging/ozwpan/ozproto.h b/drivers/staging/ozwpan/ozproto.h index f1d30c467e80..b0f7459dff45 100644 --- a/drivers/staging/ozwpan/ozproto.h +++ b/drivers/staging/ozwpan/ozproto.h @@ -65,4 +65,6 @@ enum hrtimer_restart oz_pd_timeout_event(struct hrtimer *timer); int oz_get_pd_status_list(char *pd_list, int max_count); int oz_get_binding_list(char *buf, int max_if); +extern struct kmem_cache *oz_elt_info_cache; + #endif /* _OZPROTO_H */ -- GitLab From 50222db4b03ac8f3259c6d39bbd585ed3358f70f Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Fri, 8 Aug 2014 08:01:09 +0200 Subject: [PATCH 0535/9167] staging: ozwpan: Use slab cache for oz_tx_frame allocation Use a slab cache rather than rolling our own free list. Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozpd.c | 41 +++++--------------------------- drivers/staging/ozwpan/ozpd.h | 3 +-- drivers/staging/ozwpan/ozproto.c | 8 +++++++ drivers/staging/ozwpan/ozproto.h | 1 + 4 files changed, 16 insertions(+), 37 deletions(-) diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index c6fddb8182ee..e849d8a5fb85 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -21,8 +21,6 @@ #include #include -#define OZ_MAX_TX_POOL_SIZE 6 - static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd); static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f); static void oz_tx_isoc_free(struct oz_pd *pd, struct oz_tx_frame *f); @@ -177,13 +175,6 @@ static void oz_pd_free(struct work_struct *work) e = e->next; kfree(fwell); } - /* Deallocate all frames in tx pool. - */ - while (pd->tx_pool) { - e = pd->tx_pool; - pd->tx_pool = e->next; - kfree(container_of(e, struct oz_tx_frame, link)); - } if (pd->net_dev) dev_put(pd->net_dev); kfree(pd); @@ -333,17 +324,9 @@ int oz_pd_sleep(struct oz_pd *pd) */ static struct oz_tx_frame *oz_tx_frame_alloc(struct oz_pd *pd) { - struct oz_tx_frame *f = NULL; + struct oz_tx_frame *f; - spin_lock_bh(&pd->tx_frame_lock); - if (pd->tx_pool) { - f = container_of(pd->tx_pool, struct oz_tx_frame, link); - pd->tx_pool = pd->tx_pool->next; - pd->tx_pool_count--; - } - spin_unlock_bh(&pd->tx_frame_lock); - if (f == NULL) - f = kmalloc(sizeof(struct oz_tx_frame), GFP_ATOMIC); + f = kmem_cache_alloc(oz_tx_frame_cache, GFP_ATOMIC); if (f) { f->total_size = sizeof(struct oz_hdr); INIT_LIST_HEAD(&f->link); @@ -359,13 +342,9 @@ static void oz_tx_isoc_free(struct oz_pd *pd, struct oz_tx_frame *f) { pd->nb_queued_isoc_frames--; list_del_init(&f->link); - if (pd->tx_pool_count < OZ_MAX_TX_POOL_SIZE) { - f->link.next = pd->tx_pool; - pd->tx_pool = &f->link; - pd->tx_pool_count++; - } else { - kfree(f); - } + + kmem_cache_free(oz_tx_frame_cache, f); + oz_dbg(TX_FRAMES, "Releasing ISOC Frame isoc_nb= %d\n", pd->nb_queued_isoc_frames); } @@ -375,15 +354,7 @@ static void oz_tx_isoc_free(struct oz_pd *pd, struct oz_tx_frame *f) */ static void oz_tx_frame_free(struct oz_pd *pd, struct oz_tx_frame *f) { - spin_lock_bh(&pd->tx_frame_lock); - if (pd->tx_pool_count < OZ_MAX_TX_POOL_SIZE) { - f->link.next = pd->tx_pool; - pd->tx_pool = &f->link; - pd->tx_pool_count++; - f = NULL; - } - spin_unlock_bh(&pd->tx_frame_lock); - kfree(f); + kmem_cache_free(oz_tx_frame_cache, f); } /* diff --git a/drivers/staging/ozwpan/ozpd.h b/drivers/staging/ozwpan/ozpd.h index 43a26ea8c9ad..212fab0d807a 100644 --- a/drivers/staging/ozwpan/ozpd.h +++ b/drivers/staging/ozwpan/ozpd.h @@ -90,8 +90,6 @@ struct oz_pd { unsigned max_stream_buffering; int nb_queued_frames; int nb_queued_isoc_frames; - struct list_head *tx_pool; - int tx_pool_count; spinlock_t tx_frame_lock; struct list_head *last_sent_frame; struct list_head tx_queue; @@ -131,5 +129,6 @@ void oz_apps_init(void); void oz_apps_term(void); extern struct kmem_cache *oz_elt_info_cache; +extern struct kmem_cache *oz_tx_frame_cache; #endif /* Sentry */ diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index b592e96a8445..db6ef99e9dc4 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -53,6 +53,7 @@ static u16 g_apps = 0x1; static int g_processing_rx; struct kmem_cache *oz_elt_info_cache; +struct kmem_cache *oz_tx_frame_cache; /* * Context: softirq-serialized @@ -483,6 +484,7 @@ void oz_protocol_term(void) spin_unlock_bh(&g_polling_lock); oz_dbg(ON, "Protocol stopped\n"); + kmem_cache_destroy(oz_tx_frame_cache); kmem_cache_destroy(oz_elt_info_cache); } @@ -771,6 +773,12 @@ int oz_protocol_init(char *devs) if (!oz_elt_info_cache) return -ENOMEM; + oz_tx_frame_cache = KMEM_CACHE(oz_tx_frame, 0); + if (!oz_tx_frame_cache) { + kmem_cache_destroy(oz_elt_info_cache); + return -ENOMEM; + } + skb_queue_head_init(&g_rx_queue); if (devs[0] == '*') { oz_binding_add(NULL); diff --git a/drivers/staging/ozwpan/ozproto.h b/drivers/staging/ozwpan/ozproto.h index b0f7459dff45..73cc69bd30a6 100644 --- a/drivers/staging/ozwpan/ozproto.h +++ b/drivers/staging/ozwpan/ozproto.h @@ -66,5 +66,6 @@ int oz_get_pd_status_list(char *pd_list, int max_count); int oz_get_binding_list(char *buf, int max_if); extern struct kmem_cache *oz_elt_info_cache; +extern struct kmem_cache *oz_tx_frame_cache; #endif /* _OZPROTO_H */ -- GitLab From a87c38090ea95d36925fefc5cb3d475416f3796c Mon Sep 17 00:00:00 2001 From: Christoph Jaeger Date: Mon, 4 Aug 2014 14:54:56 +0200 Subject: [PATCH 0536/9167] staging: ozwpan: Use list helpers Make use of the various list helper functions to improve readability. Signed-off-by: Christoph Jaeger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ozwpan/ozeltbuf.c | 60 +++++------------ drivers/staging/ozwpan/ozhcd.c | 96 +++++++++------------------ drivers/staging/ozwpan/ozpd.c | 106 ++++++++++-------------------- drivers/staging/ozwpan/ozproto.c | 15 ++--- 4 files changed, 88 insertions(+), 189 deletions(-) diff --git a/drivers/staging/ozwpan/ozeltbuf.c b/drivers/staging/ozwpan/ozeltbuf.c index 389ab1ab62fe..400cc75279b0 100644 --- a/drivers/staging/ozwpan/ozeltbuf.c +++ b/drivers/staging/ozwpan/ozeltbuf.c @@ -27,24 +27,12 @@ void oz_elt_buf_init(struct oz_elt_buf *buf) */ void oz_elt_buf_term(struct oz_elt_buf *buf) { - struct list_head *e; - int i; + struct oz_elt_info *ei, *n; - /* Free any elements in the order or isoc lists. */ - for (i = 0; i < 2; i++) { - struct list_head *list; - if (i) - list = &buf->order_list; - else - list = &buf->isoc_list; - e = list->next; - while (e != list) { - struct oz_elt_info *ei = - container_of(e, struct oz_elt_info, link_order); - e = e->next; - kfree(ei); - } - } + list_for_each_entry_safe(ei, n, &buf->isoc_list, link_order) + kfree(ei); + list_for_each_entry_safe(ei, n, &buf->order_list, link_order) + kfree(ei); } /* @@ -77,16 +65,11 @@ void oz_elt_info_free(struct oz_elt_buf *buf, struct oz_elt_info *ei) */ void oz_elt_info_free_chain(struct oz_elt_buf *buf, struct list_head *list) { - struct list_head *e; + struct oz_elt_info *ei, *n; - e = list->next; spin_lock_bh(&buf->lock); - while (e != list) { - struct oz_elt_info *ei; - ei = container_of(e, struct oz_elt_info, link); - e = e->next; + list_for_each_entry_safe(ei, n, list->next, link) oz_elt_info_free(buf, ei); - } spin_unlock_bh(&buf->lock); } @@ -111,14 +94,13 @@ int oz_elt_stream_create(struct oz_elt_buf *buf, u8 id, int max_buf_count) int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id) { - struct list_head *e; + struct list_head *e, *n; struct oz_elt_stream *st = NULL; oz_dbg(ON, "%s: (0x%x)\n", __func__, id); spin_lock_bh(&buf->lock); - e = buf->stream_list.next; - while (e != &buf->stream_list) { - st = container_of(e, struct oz_elt_stream, link); + list_for_each(e, &buf->stream_list) { + st = list_entry(e, struct oz_elt_stream, link); if (st->id == id) { list_del(e); break; @@ -129,11 +111,9 @@ int oz_elt_stream_delete(struct oz_elt_buf *buf, u8 id) spin_unlock_bh(&buf->lock); return -1; } - e = st->elt_list.next; - while (e != &st->elt_list) { + list_for_each_safe(e, n, &st->elt_list) { struct oz_elt_info *ei = - container_of(e, struct oz_elt_info, link); - e = e->next; + list_entry(e, struct oz_elt_info, link); list_del_init(&ei->link); list_del_init(&ei->link_order); st->buf_count -= ei->length; @@ -173,7 +153,7 @@ int oz_queue_elt_info(struct oz_elt_buf *buf, u8 isoc, u8 id, if (id) { list_for_each(e, &buf->stream_list) { - st = container_of(e, struct oz_elt_stream, link); + st = list_entry(e, struct oz_elt_stream, link); if (st->id == id) break; } @@ -228,22 +208,18 @@ int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len, unsigned max_len, struct list_head *list) { int count = 0; - struct list_head *e; struct list_head *el; - struct oz_elt_info *ei; + struct oz_elt_info *ei, *n; spin_lock_bh(&buf->lock); if (isoc) el = &buf->isoc_list; else el = &buf->order_list; - e = el->next; - while (e != el) { - struct oz_app_hdr *app_hdr; - ei = container_of(e, struct oz_elt_info, link_order); - e = e->next; + + list_for_each_entry_safe(ei, n, el, link_order) { if ((*len + ei->length) <= max_len) { - app_hdr = (struct oz_app_hdr *) + struct oz_app_hdr *app_hdr = (struct oz_app_hdr *) &ei->data[sizeof(struct oz_elt)]; app_hdr->elt_seq_num = buf->tx_seq_num[ei->app_id]++; if (buf->tx_seq_num[ei->app_id] == 0) @@ -271,5 +247,5 @@ int oz_select_elts_for_tx(struct oz_elt_buf *buf, u8 isoc, unsigned *len, int oz_are_elts_available(struct oz_elt_buf *buf) { - return buf->order_list.next != &buf->order_list; + return !list_empty(&buf->order_list); } diff --git a/drivers/staging/ozwpan/ozhcd.c b/drivers/staging/ozwpan/ozhcd.c index 1142f574a3e5..b30c4d87c25e 100644 --- a/drivers/staging/ozwpan/ozhcd.c +++ b/drivers/staging/ozwpan/ozhcd.c @@ -45,10 +45,6 @@ */ #define OZ_PLAT_DEV_NAME "ozwpan" -/* Get endpoint object from the containing link. - */ -#define ep_from_link(__e) container_of((__e), struct oz_endpoint, link) - /*EP0 timeout before ep0 request is again added to TX queue. (13*8 = 98mSec) */ #define EP0_TIMEOUT_COUNTER 13 @@ -308,12 +304,10 @@ static struct oz_urb_link *oz_uncancel_urb(struct oz_hcd *ozhcd, struct urb *urb) { struct oz_urb_link *urbl; - struct list_head *e; - list_for_each(e, &ozhcd->urb_cancel_list) { - urbl = container_of(e, struct oz_urb_link, link); + list_for_each_entry(urbl, &ozhcd->urb_cancel_list, link) { if (urb == urbl->urb) { - list_del_init(e); + list_del_init(&urbl->link); return urbl; } } @@ -372,10 +366,9 @@ static void oz_complete_urb(struct usb_hcd *hcd, struct urb *urb, static void oz_ep_free(struct oz_port *port, struct oz_endpoint *ep) { if (port) { - struct list_head list; + LIST_HEAD(list); struct oz_hcd *ozhcd = port->ozhcd; - INIT_LIST_HEAD(&list); if (ep->flags & OZ_F_EP_HAVE_STREAM) oz_usb_stream_delete(port->hpd, ep->ep_num); /* Transfer URBs to the orphanage while we hold the lock. */ @@ -521,7 +514,7 @@ static int oz_dequeue_ep_urb(struct oz_port *port, u8 ep_addr, int in_dir, struct list_head *e; list_for_each(e, &ep->urb_list) { - urbl = container_of(e, struct oz_urb_link, link); + urbl = list_entry(e, struct oz_urb_link, link); if (urbl->urb == urb) { list_del_init(e); break; @@ -553,7 +546,7 @@ static struct urb *oz_find_urb_by_id(struct oz_port *port, int ep_ix, struct list_head *e; list_for_each(e, &ep->urb_list) { - urbl = container_of(e, struct oz_urb_link, link); + urbl = list_entry(e, struct oz_urb_link, link); if (urbl->req_id == req_id) { urb = urbl->urb; list_del_init(e); @@ -1046,21 +1039,17 @@ int oz_hcd_heartbeat(void *hport) int rc = 0; struct oz_port *port = (struct oz_port *)hport; struct oz_hcd *ozhcd = port->ozhcd; - struct oz_urb_link *urbl; - struct list_head xfr_list; - struct list_head *e; - struct list_head *n; + struct oz_urb_link *urbl, *n; + LIST_HEAD(xfr_list); struct urb *urb; struct oz_endpoint *ep; struct timespec ts, delta; getrawmonotonic(&ts); - INIT_LIST_HEAD(&xfr_list); /* Check the OUT isoc endpoints to see if any URB data can be sent. */ spin_lock_bh(&ozhcd->hcd_lock); - list_for_each(e, &port->isoc_out_ep) { - ep = ep_from_link(e); + list_for_each_entry(ep, &port->isoc_out_ep, link) { if (ep->credit < 0) continue; delta = timespec_sub(ts, ep->timestamp); @@ -1083,10 +1072,9 @@ int oz_hcd_heartbeat(void *hport) spin_unlock_bh(&ozhcd->hcd_lock); /* Send to PD and complete URBs. */ - list_for_each_safe(e, n, &xfr_list) { - urbl = container_of(e, struct oz_urb_link, link); + list_for_each_entry_safe(urbl, n, &xfr_list, link) { urb = urbl->urb; - list_del_init(e); + list_del_init(&urbl->link); urb->error_count = 0; urb->start_frame = oz_usb_get_frame_number(); oz_usb_send_isoc(port->hpd, urbl->ep_num, urb); @@ -1096,9 +1084,7 @@ int oz_hcd_heartbeat(void *hport) /* Check the IN isoc endpoints to see if any URBs can be completed. */ spin_lock_bh(&ozhcd->hcd_lock); - list_for_each(e, &port->isoc_in_ep) { - struct oz_endpoint *ep = ep_from_link(e); - + list_for_each_entry(ep, &port->isoc_in_ep, link) { if (ep->flags & OZ_F_EP_BUFFERING) { if (ep->buffered_units >= OZ_IN_BUFFERING_UNITS) { ep->flags &= ~OZ_F_EP_BUFFERING; @@ -1111,10 +1097,7 @@ int oz_hcd_heartbeat(void *hport) delta = timespec_sub(ts, ep->timestamp); ep->credit += div_u64(timespec_to_ns(&delta), NSEC_PER_MSEC); ep->timestamp = ts; - while (!list_empty(&ep->urb_list)) { - struct oz_urb_link *urbl = - list_first_entry(&ep->urb_list, - struct oz_urb_link, link); + list_for_each_entry_safe(urbl, n, &ep->urb_list, link) { struct urb *urb = urbl->urb; int len = 0; int copy_len; @@ -1161,10 +1144,9 @@ int oz_hcd_heartbeat(void *hport) spin_unlock_bh(&ozhcd->hcd_lock); /* Complete the filled URBs. */ - list_for_each_safe(e, n, &xfr_list) { - urbl = container_of(e, struct oz_urb_link, link); + list_for_each_entry_safe(urbl, n, &xfr_list, link) { urb = urbl->urb; - list_del_init(e); + list_del_init(&urbl->link); oz_free_urb_link(urbl); oz_complete_urb(port->ozhcd->hcd, urb, 0); } @@ -1173,15 +1155,11 @@ int oz_hcd_heartbeat(void *hport) */ ep = port->out_ep[0]; if (ep) { - struct list_head *e; - struct list_head *n; - spin_lock_bh(&ozhcd->hcd_lock); - list_for_each_safe(e, n, &ep->urb_list) { - urbl = container_of(e, struct oz_urb_link, link); + list_for_each_entry_safe(urbl, n, &ep->urb_list, link) { if (urbl->submit_counter > EP0_TIMEOUT_COUNTER) { oz_dbg(ON, "Request 0x%p timeout\n", urbl->urb); - list_move_tail(e, &xfr_list); + list_move_tail(&urbl->link, &xfr_list); urbl->submit_counter = 0; } else { urbl->submit_counter++; @@ -1190,10 +1168,7 @@ int oz_hcd_heartbeat(void *hport) if (!list_empty(&ep->urb_list)) rc = 1; spin_unlock_bh(&ozhcd->hcd_lock); - e = xfr_list.next; - while (e != &xfr_list) { - urbl = container_of(e, struct oz_urb_link, link); - e = e->next; + list_for_each_entry_safe(urbl, n, &xfr_list, link) { oz_dbg(ON, "Resending request to PD\n"); oz_process_ep0_urb(ozhcd, urbl->urb, GFP_ATOMIC); oz_free_urb_link(urbl); @@ -1292,12 +1267,12 @@ static void oz_clean_endpoints_for_interface(struct usb_hcd *hcd, struct oz_hcd *ozhcd = port->ozhcd; unsigned mask; int i; - struct list_head ep_list; + LIST_HEAD(ep_list); + struct oz_endpoint *ep, *n; oz_dbg(ON, "Deleting endpoints for interface %d\n", if_ix); if (if_ix >= port->num_iface) return; - INIT_LIST_HEAD(&ep_list); spin_lock_bh(&ozhcd->hcd_lock); mask = port->iface[if_ix].ep_mask; port->iface[if_ix].ep_mask = 0; @@ -1321,9 +1296,7 @@ static void oz_clean_endpoints_for_interface(struct usb_hcd *hcd, } } spin_unlock_bh(&ozhcd->hcd_lock); - while (!list_empty(&ep_list)) { - struct oz_endpoint *ep = - list_first_entry(&ep_list, struct oz_endpoint, link); + list_for_each_entry_safe(ep, n, &ep_list, link) { list_del_init(&ep->link); oz_ep_free(port, ep); } @@ -1594,6 +1567,7 @@ static void oz_urb_process_tasklet(unsigned long unused) unsigned long irq_state; struct urb *urb; struct oz_hcd *ozhcd = oz_hcd_claim(); + struct oz_urb_link *urbl, *n; int rc = 0; if (ozhcd == NULL) @@ -1603,10 +1577,7 @@ static void oz_urb_process_tasklet(unsigned long unused) * appropriately while removing urbs. */ spin_lock_irqsave(&g_tasklet_lock, irq_state); - while (!list_empty(&ozhcd->urb_pending_list)) { - struct oz_urb_link *urbl = - list_first_entry(&ozhcd->urb_pending_list, - struct oz_urb_link, link); + list_for_each_entry_safe(urbl, n, &ozhcd->urb_pending_list, link) { list_del_init(&urbl->link); spin_unlock_irqrestore(&g_tasklet_lock, irq_state); urb = urbl->urb; @@ -1651,7 +1622,7 @@ static void oz_urb_cancel(struct oz_port *port, u8 ep_num, struct urb *urb) */ spin_lock_irqsave(&g_tasklet_lock, irq_state); list_for_each(e, &ozhcd->urb_cancel_list) { - urbl = container_of(e, struct oz_urb_link, link); + urbl = list_entry(e, struct oz_urb_link, link); if (urb == urbl->urb) { list_del_init(e); spin_unlock_irqrestore(&g_tasklet_lock, irq_state); @@ -1665,7 +1636,7 @@ static void oz_urb_cancel(struct oz_port *port, u8 ep_num, struct urb *urb) */ spin_lock_irqsave(&ozhcd->hcd_lock, irq_state); list_for_each(e, &ozhcd->orphanage) { - urbl = container_of(e, struct oz_urb_link, link); + urbl = list_entry(e, struct oz_urb_link, link); if (urbl->urb == urb) { list_del(e); oz_dbg(ON, "Found urb in orphanage\n"); @@ -1695,15 +1666,13 @@ static void oz_urb_cancel_tasklet(unsigned long unused) { unsigned long irq_state; struct urb *urb; + struct oz_urb_link *urbl, *n; struct oz_hcd *ozhcd = oz_hcd_claim(); if (ozhcd == NULL) return; spin_lock_irqsave(&g_tasklet_lock, irq_state); - while (!list_empty(&ozhcd->urb_cancel_list)) { - struct oz_urb_link *urbl = - list_first_entry(&ozhcd->urb_cancel_list, - struct oz_urb_link, link); + list_for_each_entry_safe(urbl, n, &ozhcd->urb_cancel_list, link) { list_del_init(&urbl->link); spin_unlock_irqrestore(&g_tasklet_lock, irq_state); urb = urbl->urb; @@ -1722,11 +1691,9 @@ static void oz_urb_cancel_tasklet(unsigned long unused) static void oz_hcd_clear_orphanage(struct oz_hcd *ozhcd, int status) { if (ozhcd) { - struct oz_urb_link *urbl; + struct oz_urb_link *urbl, *n; - while (!list_empty(&ozhcd->orphanage)) { - urbl = list_first_entry(&ozhcd->orphanage, - struct oz_urb_link, link); + list_for_each_entry_safe(urbl, n, &ozhcd->orphanage, link) { list_del(&urbl->link); oz_complete_urb(ozhcd->hcd, urbl->urb, status); oz_free_urb_link(urbl); @@ -1824,14 +1791,13 @@ static struct oz_urb_link *oz_remove_urb(struct oz_endpoint *ep, struct urb *urb) { struct oz_urb_link *urbl; - struct list_head *e; if (unlikely(ep == NULL)) return NULL; - list_for_each(e, &ep->urb_list) { - urbl = container_of(e, struct oz_urb_link, link); + + list_for_each_entry(urbl, &ep->urb_list, link) { if (urbl->urb == urb) { - list_del_init(e); + list_del_init(&urbl->link); if (usb_pipeisoc(urb->pipe)) { ep->credit -= urb->number_of_packets; if (ep->credit < 0) diff --git a/drivers/staging/ozwpan/ozpd.c b/drivers/staging/ozwpan/ozpd.c index e849d8a5fb85..772641011a44 100644 --- a/drivers/staging/ozwpan/ozpd.c +++ b/drivers/staging/ozwpan/ozpd.c @@ -137,10 +137,7 @@ struct oz_pd *oz_pd_alloc(const u8 *mac_addr) */ static void oz_pd_free(struct work_struct *work) { - struct list_head *e; - struct oz_tx_frame *f; - struct oz_isoc_stream *st; - struct oz_farewell *fwell; + struct list_head *e, *n; struct oz_pd *pd; oz_pd_dbg(pd, ON, "Destroying PD\n"); @@ -148,33 +145,24 @@ static void oz_pd_free(struct work_struct *work) /*Disable timer tasklets*/ tasklet_kill(&pd->heartbeat_tasklet); tasklet_kill(&pd->timeout_tasklet); - /* Delete any streams. - */ - e = pd->stream_list.next; - while (e != &pd->stream_list) { - st = container_of(e, struct oz_isoc_stream, link); - e = e->next; - oz_isoc_stream_free(st); - } - /* Free any queued tx frames. - */ - e = pd->tx_queue.next; - while (e != &pd->tx_queue) { - f = container_of(e, struct oz_tx_frame, link); - e = e->next; + + /* Free streams, queued tx frames and farewells. */ + + list_for_each_safe(e, n, &pd->stream_list) + oz_isoc_stream_free(list_entry(e, struct oz_isoc_stream, link)); + + list_for_each_safe(e, n, &pd->tx_queue) { + struct oz_tx_frame *f = list_entry(e, struct oz_tx_frame, link); if (f->skb != NULL) kfree_skb(f->skb); oz_retire_frame(pd, f); } + oz_elt_buf_term(&pd->elt_buff); - /* Free any farewells. - */ - e = pd->farewell_list.next; - while (e != &pd->farewell_list) { - fwell = container_of(e, struct oz_farewell, link); - e = e->next; - kfree(fwell); - } + + list_for_each_safe(e, n, &pd->farewell_list) + kfree(list_entry(e, struct oz_farewell, link)); + if (pd->net_dev) dev_put(pd->net_dev); kfree(pd); @@ -418,7 +406,7 @@ static struct sk_buff *oz_build_frame(struct oz_pd *pd, struct oz_tx_frame *f) struct net_device *dev = pd->net_dev; struct oz_hdr *oz_hdr; struct oz_elt *elt; - struct list_head *e; + struct oz_elt_info *ei; /* Allocate skb with enough space for the lower layers as well * as the space we need. @@ -443,9 +431,7 @@ static struct sk_buff *oz_build_frame(struct oz_pd *pd, struct oz_tx_frame *f) /* Copy the elements into the frame body. */ elt = (struct oz_elt *)(oz_hdr+1); - for (e = f->elt_list.next; e != &f->elt_list; e = e->next) { - struct oz_elt_info *ei; - ei = container_of(e, struct oz_elt_info, link); + list_for_each_entry(ei, &f->elt_list, link) { memcpy(elt, ei->data, ei->length); elt = oz_next_elt(elt); } @@ -460,13 +446,9 @@ static struct sk_buff *oz_build_frame(struct oz_pd *pd, struct oz_tx_frame *f) */ static void oz_retire_frame(struct oz_pd *pd, struct oz_tx_frame *f) { - struct list_head *e; - struct oz_elt_info *ei; + struct oz_elt_info *ei, *n; - e = f->elt_list.next; - while (e != &f->elt_list) { - ei = container_of(e, struct oz_elt_info, link); - e = e->next; + list_for_each_entry_safe(ei, n, &f->elt_list, link) { list_del_init(&ei->link); if (ei->callback) ei->callback(pd, ei->context); @@ -492,7 +474,7 @@ static int oz_send_next_queued_frame(struct oz_pd *pd, int more_data) spin_unlock(&pd->tx_frame_lock); return -1; } - f = container_of(e, struct oz_tx_frame, link); + f = list_entry(e, struct oz_tx_frame, link); if (f->skb != NULL) { skb = f->skb; @@ -580,15 +562,13 @@ static int oz_send_isoc_frame(struct oz_pd *pd) struct net_device *dev = pd->net_dev; struct oz_hdr *oz_hdr; struct oz_elt *elt; - struct list_head *e; - struct list_head list; + struct oz_elt_info *ei; + LIST_HEAD(list); int total_size = sizeof(struct oz_hdr); - INIT_LIST_HEAD(&list); - oz_select_elts_for_tx(&pd->elt_buff, 1, &total_size, pd->max_tx_size, &list); - if (list.next == &list) + if (list_empty(&list)) return 0; skb = alloc_skb(total_size + OZ_ALLOCATED_SPACE(dev), GFP_ATOMIC); if (skb == NULL) { @@ -610,9 +590,7 @@ static int oz_send_isoc_frame(struct oz_pd *pd) oz_hdr->last_pkt_num = pd->trigger_pkt_num & OZ_LAST_PN_MASK; elt = (struct oz_elt *)(oz_hdr+1); - for (e = list.next; e != &list; e = e->next) { - struct oz_elt_info *ei; - ei = container_of(e, struct oz_elt_info, link); + list_for_each_entry(ei, &list, link) { memcpy(elt, ei->data, ei->length); elt = oz_next_elt(elt); } @@ -626,41 +604,30 @@ static int oz_send_isoc_frame(struct oz_pd *pd) */ void oz_retire_tx_frames(struct oz_pd *pd, u8 lpn) { - struct list_head *e; - struct oz_tx_frame *f; - struct list_head *first = NULL; - struct list_head *last = NULL; + struct oz_tx_frame *f, *tmp = NULL; u8 diff; u32 pkt_num; + LIST_HEAD(list); + spin_lock(&pd->tx_frame_lock); - e = pd->tx_queue.next; - while (e != &pd->tx_queue) { - f = container_of(e, struct oz_tx_frame, link); + list_for_each_entry(f, &pd->tx_queue, link) { pkt_num = le32_to_cpu(get_unaligned(&f->hdr.pkt_num)); diff = (lpn - (pkt_num & OZ_LAST_PN_MASK)) & OZ_LAST_PN_MASK; if ((diff > OZ_LAST_PN_HALF_CYCLE) || (pkt_num == 0)) break; oz_dbg(TX_FRAMES, "Releasing pkt_num= %u, nb= %d\n", pkt_num, pd->nb_queued_frames); - if (first == NULL) - first = e; - last = e; - e = e->next; + tmp = f; pd->nb_queued_frames--; } - if (first) { - last->next->prev = &pd->tx_queue; - pd->tx_queue.next = last->next; - last->next = NULL; - } + if (tmp) + list_cut_position(&list, &pd->tx_queue, &tmp->link); pd->last_sent_frame = &pd->tx_queue; spin_unlock(&pd->tx_frame_lock); - while (first) { - f = container_of(first, struct oz_tx_frame, link); - first = first->next; + + list_for_each_entry_safe(f, tmp, &list, link) oz_retire_frame(pd, f); - } } /* @@ -669,11 +636,9 @@ void oz_retire_tx_frames(struct oz_pd *pd, u8 lpn) */ static struct oz_isoc_stream *pd_stream_find(struct oz_pd *pd, u8 ep_num) { - struct list_head *e; struct oz_isoc_stream *st; - list_for_each(e, &pd->stream_list) { - st = container_of(e, struct oz_isoc_stream, link); + list_for_each_entry(st, &pd->stream_list, link) { if (st->ep_num == ep_num) return st; } @@ -810,14 +775,11 @@ int oz_send_isoc_unit(struct oz_pd *pd, u8 ep_num, const u8 *data, int len) struct oz_tx_frame *isoc_unit = NULL; int nb = pd->nb_queued_isoc_frames; if (nb >= pd->isoc_latency) { - struct list_head *e; struct oz_tx_frame *f; oz_dbg(TX_FRAMES, "Dropping ISOC Unit nb= %d\n", nb); spin_lock(&pd->tx_frame_lock); - list_for_each(e, &pd->tx_queue) { - f = container_of(e, struct oz_tx_frame, - link); + list_for_each_entry(f, &pd->tx_queue, link) { if (f->skb != NULL) { oz_tx_isoc_free(pd, f); break; diff --git a/drivers/staging/ozwpan/ozproto.c b/drivers/staging/ozwpan/ozproto.c index db6ef99e9dc4..af3da3ebabc2 100644 --- a/drivers/staging/ozwpan/ozproto.c +++ b/drivers/staging/ozwpan/ozproto.c @@ -185,7 +185,7 @@ static struct oz_pd *oz_connect_req(struct oz_pd *cur_pd, struct oz_elt *elt, getnstimeofday(&pd->last_rx_timestamp); spin_lock_bh(&g_polling_lock); list_for_each(e, &g_pd_list) { - pd2 = container_of(e, struct oz_pd, link); + pd2 = list_entry(e, struct oz_pd, link); if (ether_addr_equal(pd2->mac_addr, pd_addr)) { free_pd = pd; pd = pd2; @@ -601,13 +601,11 @@ void oz_pd_request_heartbeat(struct oz_pd *pd) struct oz_pd *oz_pd_find(const u8 *mac_addr) { struct oz_pd *pd; - struct list_head *e; spin_lock_bh(&g_polling_lock); - list_for_each(e, &g_pd_list) { - pd = container_of(e, struct oz_pd, link); + list_for_each_entry(pd, &g_pd_list, link) { if (ether_addr_equal(pd->mac_addr, mac_addr)) { - atomic_inc(&pd->ref_count); + oz_pd_get(pd); spin_unlock_bh(&g_polling_lock); return pd; } @@ -700,11 +698,10 @@ void oz_binding_add(const char *net_dev) */ static void pd_stop_all_for_device(struct net_device *net_dev) { - struct list_head h; + LIST_HEAD(h); struct oz_pd *pd; struct oz_pd *n; - INIT_LIST_HEAD(&h); spin_lock_bh(&g_polling_lock); list_for_each_entry_safe(pd, n, &g_pd_list, link) { if (pd->net_dev == net_dev) { @@ -799,14 +796,12 @@ int oz_protocol_init(char *devs) int oz_get_pd_list(struct oz_mac_addr *addr, int max_count) { struct oz_pd *pd; - struct list_head *e; int count = 0; spin_lock_bh(&g_polling_lock); - list_for_each(e, &g_pd_list) { + list_for_each_entry(pd, &g_pd_list, link) { if (count >= max_count) break; - pd = container_of(e, struct oz_pd, link); ether_addr_copy((u8 *)&addr[count++], pd->mac_addr); } spin_unlock_bh(&g_polling_lock); -- GitLab From ddf5a2c1cb62a2ce4e6d9104998df2d3eae8923e Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 8 Aug 2014 12:07:50 +0200 Subject: [PATCH 0537/9167] imx-drm: imx-drm-core: 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: Greg Kroah-Hartman --- drivers/staging/imx-drm/imx-drm-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 6b22106534d8..1852300412b4 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -471,8 +471,7 @@ int imx_drm_encoder_parse_of(struct drm_device *drm, crtc_mask |= mask; } - if (ep) - of_node_put(ep); + of_node_put(ep); if (i == 0) return -ENOENT; -- GitLab From 63bc516402c615250ef9e88905b8c78a04fbacdb Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Mon, 4 Aug 2014 21:07:07 +0200 Subject: [PATCH 0538/9167] staging: imx-drm: fix a blank line coding style issue Add missing blank lines after declaration. Signed-off-by: Quentin Lambert Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/imx-drm-core.c | 2 ++ drivers/staging/imx-drm/imx-tve.c | 2 ++ drivers/staging/imx-drm/parallel-display.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 1852300412b4..4289cc8963e4 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -427,6 +427,7 @@ static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm, for (i = 0; i < MAX_CRTC; i++) { struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i]; + if (imx_drm_crtc && imx_drm_crtc->port == port) return drm_crtc_mask(imx_drm_crtc->crtc); } @@ -438,6 +439,7 @@ static struct device_node *imx_drm_of_get_next_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; } diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index c628fcdc22ae..31fe7cfe5d35 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c @@ -133,6 +133,7 @@ static void tve_lock(void *__tve) __acquires(&tve->lock) { struct imx_tve *tve = __tve; + spin_lock(&tve->lock); } @@ -140,6 +141,7 @@ static void tve_unlock(void *__tve) __releases(&tve->lock) { struct imx_tve *tve = __tve; + spin_unlock(&tve->lock); } diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c index 4ca61afdf622..1998846ff21d 100644 --- a/drivers/staging/imx-drm/parallel-display.c +++ b/drivers/staging/imx-drm/parallel-display.c @@ -70,6 +70,7 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) if (imxpd->mode_valid) { struct drm_display_mode *mode = drm_mode_create(connector->dev); + if (!mode) return -EINVAL; drm_mode_copy(mode, &imxpd->mode); @@ -80,6 +81,7 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) if (np) { struct drm_display_mode *mode = drm_mode_create(connector->dev); + if (!mode) return -EINVAL; of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE); -- GitLab From 69b8b22489f5edf1fde0d6958ab3881068701e6d Mon Sep 17 00:00:00 2001 From: Fabio Falzoi Date: Tue, 5 Aug 2014 23:24:17 +0200 Subject: [PATCH 0539/9167] Staging: rts5208: Use dev_dbg and print_hex_dump_bytes to dump memory Use dev_dbg with %*ph format specifier and print_hex_dump_bytes to dump memory instead of relying on custom macro. Signed-off-by: Fabio Falzoi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/ms.c | 5 +++-- drivers/staging/rts5208/rtsx_chip.c | 6 ++++-- drivers/staging/rts5208/rtsx_scsi.c | 7 +++---- drivers/staging/rts5208/sd.c | 6 +++--- drivers/staging/rts5208/trace.h | 8 -------- 5 files changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/staging/rts5208/ms.c b/drivers/staging/rts5208/ms.c index 390b1f83ebc2..db8e22166db8 100644 --- a/drivers/staging/rts5208/ms.c +++ b/drivers/staging/rts5208/ms.c @@ -305,7 +305,8 @@ static int ms_read_bytes(struct rtsx_chip *chip, if ((tpc == PRO_READ_SHORT_DATA) && (data_len == 8)) { dev_dbg(rtsx_dev(chip), "Read format progress:\n"); - RTSX_DUMP(ptr, cnt); + print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, ptr, + cnt); } return STATUS_SUCCESS; @@ -1913,7 +1914,7 @@ static int reset_ms(struct rtsx_chip *chip) ptr = rtsx_get_cmd_data(chip); dev_dbg(rtsx_dev(chip), "Boot block data:\n"); - RTSX_DUMP(ptr, 16); + dev_dbg(rtsx_dev(chip), "%*ph\n", 16, ptr); /* Block ID error * HEADER_ID0, HEADER_ID1 diff --git a/drivers/staging/rts5208/rtsx_chip.c b/drivers/staging/rts5208/rtsx_chip.c index fe98309b7de6..1db534aeb12d 100644 --- a/drivers/staging/rts5208/rtsx_chip.c +++ b/drivers/staging/rts5208/rtsx_chip.c @@ -1309,8 +1309,10 @@ int rtsx_write_cfg_seq(struct rtsx_chip *chip, u8 func, u16 addr, u8 *buf, } } - RTSX_DUMP(mask, dw_len * 4); - RTSX_DUMP(data, dw_len * 4); + print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, mask, + dw_len * 4); + print_hex_dump_bytes(KBUILD_MODNAME ": ", DUMP_PREFIX_NONE, data, + dw_len * 4); for (i = 0; i < dw_len; i++) { retval = rtsx_write_cfg_dw(chip, func, aligned_addr + i * 4, diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index 5f5f512714e5..7e6c7c043a52 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -39,7 +39,7 @@ void scsi_show_command(struct rtsx_chip *chip) { struct scsi_cmnd *srb = chip->srb; char *what = NULL; - int i, unknown_cmd = 0; + int unknown_cmd = 0, len; switch (srb->cmnd[0]) { case TEST_UNIT_READY: @@ -319,9 +319,8 @@ void scsi_show_command(struct rtsx_chip *chip) what, srb->cmd_len); if (unknown_cmd) { - for (i = 0; i < srb->cmd_len && i < 16; i++) - dev_dbg(rtsx_dev(chip), " %02x", srb->cmnd[i]); - dev_dbg(rtsx_dev(chip), "\n"); + len = min_t(unsigned short, srb->cmd_len, 16); + dev_dbg(rtsx_dev(chip), "%*ph\n", len, srb->cmnd); } } diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index c79bea808698..06c96d52c15d 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -427,7 +427,7 @@ static int sd_check_csd(struct rtsx_chip *chip, char check_wp) memcpy(sd_card->raw_csd, rsp + 1, 15); dev_dbg(rtsx_dev(chip), "CSD Response:\n"); - RTSX_DUMP(sd_card->raw_csd, 16); + dev_dbg(rtsx_dev(chip), "%*ph\n", 16, sd_card->raw_csd); csd_ver = (rsp[1] & 0xc0) >> 6; dev_dbg(rtsx_dev(chip), "csd_ver = %d\n", csd_ver); @@ -1060,7 +1060,7 @@ static int sd_check_switch_mode(struct rtsx_chip *chip, u8 mode, TRACE_RET(chip, STATUS_FAIL); } - RTSX_DUMP(buf, 64); + dev_dbg(rtsx_dev(chip), "%*ph\n", 64, buf); if (func_group == NO_ARGUMENT) { sd_card->func_group1_mask = buf[0x0D]; @@ -2119,7 +2119,7 @@ static int sd_check_wp_state(struct rtsx_chip *chip) } dev_dbg(rtsx_dev(chip), "ACMD13:\n"); - RTSX_DUMP(buf, 64); + dev_dbg(rtsx_dev(chip), "%*ph\n", 64, buf); sd_card_type = ((u16)buf[2] << 8) | buf[3]; dev_dbg(rtsx_dev(chip), "sd_card_type = 0x%04x\n", sd_card_type); diff --git a/drivers/staging/rts5208/trace.h b/drivers/staging/rts5208/trace.h index fbb304a54acc..a9ab4077b283 100644 --- a/drivers/staging/rts5208/trace.h +++ b/drivers/staging/rts5208/trace.h @@ -84,12 +84,4 @@ static inline char *filename(char *path) #define TRACE_GOTO(chip, label) goto label #endif -#ifdef CONFIG_RTS5208_DEBUG -#define RTSX_DUMP(buf, buf_len) \ - print_hex_dump(KERN_DEBUG, KBUILD_MODNAME ": ", \ - DUMP_PREFIX_NONE, 16, 1, (buf), (buf_len), false) -#else -#define RTSX_DUMP(buf, buf_len) -#endif - #endif /* __REALTEK_RTSX_TRACE_H */ -- GitLab From a855861d57890d8433b158e72bba7c31b8b2fff7 Mon Sep 17 00:00:00 2001 From: Fabio Falzoi Date: Tue, 5 Aug 2014 23:24:18 +0200 Subject: [PATCH 0540/9167] Staging: rts5208: Remove CONFIG_RTS5208_DEBUG option CONFIG_RTS5208_DEBUG is no more needed, we rely on dynamic debug config options instead. Signed-off-by: Fabio Falzoi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rts5208/Kconfig | 7 ------- drivers/staging/rts5208/sd.c | 5 +---- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/staging/rts5208/Kconfig b/drivers/staging/rts5208/Kconfig index 055655cecaf7..05c990f654a4 100644 --- a/drivers/staging/rts5208/Kconfig +++ b/drivers/staging/rts5208/Kconfig @@ -6,10 +6,3 @@ config RTS5208 PCI-E card reader rts5208/rts5288. If this driver is compiled as a module, it will be named rts5208. - -config RTS5208_DEBUG - bool "Realtek PCI-E Card Reader RTS5208/5288 verbose debug" - depends on RTS5208 - help - Say Y here in order to have the rts5208 code generate - verbose debugging messages. diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index 06c96d52c15d..21c3b3cd61f2 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -812,12 +812,10 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) PHASE_NOT_RESET); RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); } else { -#ifdef CONFIG_RTS5208_DEBUG rtsx_read_register(chip, SD_VP_CTL, &val); dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val); rtsx_read_register(chip, SD_DCMPS_CTL, &val); dev_dbg(rtsx_dev(chip), "SD_DCMPS_CTL: 0x%x\n", val); -#endif if (ddr_rx) { RTSX_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, @@ -863,12 +861,11 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) return STATUS_SUCCESS; Fail: -#ifdef CONFIG_RTS5208_DEBUG rtsx_read_register(chip, SD_VP_CTL, &val); dev_dbg(rtsx_dev(chip), "SD_VP_CTL: 0x%x\n", val); rtsx_read_register(chip, SD_DCMPS_CTL, &val); dev_dbg(rtsx_dev(chip), "SD_DCMPS_CTL: 0x%x\n", val); -#endif + rtsx_write_register(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); rtsx_write_register(chip, SD_VP_CTL, PHASE_CHANGE, 0); wait_timeout(10); -- GitLab From 0d0e9d9e777fcfcd50cb45299048e68edcd54ca4 Mon Sep 17 00:00:00 2001 From: Quentin Lambert Date: Mon, 4 Aug 2014 21:10:24 +0200 Subject: [PATCH 0541/9167] staging: slicoss: fix a blank line coding style issue Add 2 missing blank lines after declaration. Signed-off-by: Quentin Lambert Signed-off-by: Greg Kroah-Hartman --- drivers/staging/slicoss/slicoss.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c index f35fa3dfe22c..841facee3bc2 100644 --- a/drivers/staging/slicoss/slicoss.c +++ b/drivers/staging/slicoss/slicoss.c @@ -2455,6 +2455,7 @@ static void slic_entry_remove(struct pci_dev *pcidev) adapter->allocated = 0; if (!card->adapters_allocated) { struct sliccard *curr_card = slic_global.slic_card; + if (curr_card == card) { slic_global.slic_card = card->next; } else { @@ -2551,6 +2552,7 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) case SIOCSLICTRACEDUMP: { u32 value; + DBG_IOCTL("slic_ioctl SIOCSLIC_TRACE_DUMP\n"); if (copy_from_user(data, rq->ifr_data, 28)) { -- GitLab From 41cb65c4854e14f12b1cbb8215e509d8ad4d0c88 Mon Sep 17 00:00:00 2001 From: A Raghavendra Rao Date: Thu, 7 Aug 2014 14:10:39 +0530 Subject: [PATCH 0542/9167] Staging: wlan-ng: fix sparse warning in prism2fw.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix the following sparse warning : In file included from drivers/staging/wlan-ng/prism2usb.c:5:0: drivers/staging/wlan-ng/prism2fw.c: In function ‘read_cardpda.constprop.43’: drivers/staging/wlan-ng/prism2fw.c:792:1: warning: the frame size of 1068 bytes is larger than 1024 bytes [-Wframe-larger-than=] The variable to 'struct p80211msg_p2req_readpda' was previously being created on the stack, which inturn exeeded the frame size limit, resulting in a sparse warning. This patch alloctes the memory to the structure dynamically and the operations are left unchanged. Signed-off-by: A Raghavendra Rao Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2fw.c | 33 +++++++++++++++++------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 42c14b0b6833..3f5f7cc105f8 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -764,30 +764,35 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, static int read_cardpda(struct pda *pda, wlandevice_t *wlandev) { int result = 0; - struct p80211msg_p2req_readpda msg; + struct p80211msg_p2req_readpda *msg; + + msg = kzalloc(sizeof(*msg), GFP_KERNEL); + if (!msg) + return -ENOMEM; /* set up the msg */ - msg.msgcode = DIDmsg_p2req_readpda; - msg.msglen = sizeof(msg); - strcpy(msg.devname, wlandev->name); - msg.pda.did = DIDmsg_p2req_readpda_pda; - msg.pda.len = HFA384x_PDA_LEN_MAX; - msg.pda.status = P80211ENUM_msgitem_status_no_value; - msg.resultcode.did = DIDmsg_p2req_readpda_resultcode; - msg.resultcode.len = sizeof(u32); - msg.resultcode.status = P80211ENUM_msgitem_status_no_value; - - if (prism2mgmt_readpda(wlandev, &msg) != 0) { + msg->msgcode = DIDmsg_p2req_readpda; + msg->msglen = sizeof(msg); + strcpy(msg->devname, wlandev->name); + msg->pda.did = DIDmsg_p2req_readpda_pda; + msg->pda.len = HFA384x_PDA_LEN_MAX; + msg->pda.status = P80211ENUM_msgitem_status_no_value; + msg->resultcode.did = DIDmsg_p2req_readpda_resultcode; + msg->resultcode.len = sizeof(u32); + msg->resultcode.status = P80211ENUM_msgitem_status_no_value; + + if (prism2mgmt_readpda(wlandev, msg) != 0) { /* prism2mgmt_readpda prints an errno if appropriate */ result = -1; - } else if (msg.resultcode.data == P80211ENUM_resultcode_success) { - memcpy(pda->buf, msg.pda.data, HFA384x_PDA_LEN_MAX); + } else if (msg->resultcode.data == P80211ENUM_resultcode_success) { + memcpy(pda->buf, msg->pda.data, HFA384x_PDA_LEN_MAX); result = mkpdrlist(pda); } else { /* resultcode must've been something other than success */ result = -1; } + kfree(msg); return result; } -- GitLab From d14b71231e78645008c3e2edee5496b4722d4d62 Mon Sep 17 00:00:00 2001 From: Lars Hamre Date: Thu, 7 Aug 2014 21:21:42 -0400 Subject: [PATCH 0543/9167] Staging: nokia_h4p: removed unnecessary return statement in nokia_fw.c This is a patch to the nokia_fw.c file that removes an unnecessary return statement found by the checkpatch.pl tool Signed-off-by: Lars Hamre Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nokia_h4p/nokia_fw.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/nokia_h4p/nokia_fw.c b/drivers/staging/nokia_h4p/nokia_fw.c index 14ba2193efb6..18953aed5a29 100644 --- a/drivers/staging/nokia_h4p/nokia_fw.c +++ b/drivers/staging/nokia_h4p/nokia_fw.c @@ -197,8 +197,6 @@ void hci_h4p_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb) dev_err(info->dev, "Don't know how to parse fw event\n"); info->fw_error = -EINVAL; } - - return; } MODULE_FIRMWARE(FW_NAME_TI1271_PRELE); -- GitLab From 1e8810026b96f5ecaa551e1963c4fbc71d976d85 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Tue, 12 Aug 2014 08:08:37 +0200 Subject: [PATCH 0544/9167] staging: dgnc: Fix externs should be avoided in the .c files This commit fixes the following checkpatch warnings: WARNING: externs should be avoided in .c files #80: FILE: drivers/staging/dgnc/dgnc_driver.c:80: +int dgnc_init_module(void); #81: FILE: drivers/staging/dgnc/dgnc_driver.c:81: +void dgnc_cleanup_module(void); This was caused by putting the declarations for module init and module exit fucntions on the top of the file. The fix removes these declarations plus it also corrects the type of the init/exit functions. Due to the dependency between init and exit functions the dgnc_cleanup_module had to be put first. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 84 ++++++++++++++---------------- 1 file changed, 39 insertions(+), 45 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 764613b2f4b4..2c2abf848326 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -76,12 +76,6 @@ static void dgnc_remove_one(struct pci_dev *dev); static int dgnc_probe1(struct pci_dev *pdev, int card_type); static void dgnc_do_remap(struct dgnc_board *brd); -/* Driver load/unload functions */ -int dgnc_init_module(void); -void dgnc_cleanup_module(void); - -module_init(dgnc_init_module); -module_exit(dgnc_cleanup_module); /* @@ -199,13 +193,49 @@ char *dgnc_driver_state_text[] = { * ************************************************************************/ +/* + * dgnc_cleanup_module() + * + * Module unload. This is where it all ends. + */ +static void dgnc_cleanup_module(void) +{ + int i; + ulong lock_flags; + + DGNC_LOCK(dgnc_poll_lock, lock_flags); + dgnc_poll_stop = 1; + DGNC_UNLOCK(dgnc_poll_lock, lock_flags); + + /* Turn off poller right away. */ + del_timer_sync(&dgnc_poll_timer); + + dgnc_remove_driver_sysfiles(&dgnc_driver); + + if (dgnc_Major_Control_Registered) { + device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); + class_destroy(dgnc_class); + unregister_chrdev(dgnc_Major, "dgnc"); + } + + for (i = 0; i < dgnc_NumBoards; ++i) { + dgnc_remove_ports_sysfiles(dgnc_Board[i]); + dgnc_tty_uninit(dgnc_Board[i]); + dgnc_cleanup_board(dgnc_Board[i]); + } + + dgnc_tty_post_uninit(); + + if (dgnc_NumBoards) + pci_unregister_driver(&dgnc_driver); +} /* * init_module() * * Module load. This is where it all starts. */ -int dgnc_init_module(void) +static int __init dgnc_init_module(void) { int rc = 0; @@ -243,6 +273,8 @@ int dgnc_init_module(void) return rc; } +module_init(dgnc_init_module); +module_exit(dgnc_cleanup_module); /* * Start of driver. @@ -354,44 +386,6 @@ static void dgnc_remove_one(struct pci_dev *dev) /* Do Nothing */ } -/* - * dgnc_cleanup_module() - * - * Module unload. This is where it all ends. - */ -void dgnc_cleanup_module(void) -{ - int i; - ulong lock_flags; - - DGNC_LOCK(dgnc_poll_lock, lock_flags); - dgnc_poll_stop = 1; - DGNC_UNLOCK(dgnc_poll_lock, lock_flags); - - /* Turn off poller right away. */ - del_timer_sync(&dgnc_poll_timer); - - dgnc_remove_driver_sysfiles(&dgnc_driver); - - if (dgnc_Major_Control_Registered) { - device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); - class_destroy(dgnc_class); - unregister_chrdev(dgnc_Major, "dgnc"); - } - - for (i = 0; i < dgnc_NumBoards; ++i) { - dgnc_remove_ports_sysfiles(dgnc_Board[i]); - dgnc_tty_uninit(dgnc_Board[i]); - dgnc_cleanup_board(dgnc_Board[i]); - } - - dgnc_tty_post_uninit(); - - if (dgnc_NumBoards) - pci_unregister_driver(&dgnc_driver); -} - - /* * dgnc_cleanup_board() * -- GitLab From 338fd80f9da7772ff3b957adb7ae1ed4615c484c Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 14:21:20 +0200 Subject: [PATCH 0545/9167] staging: dgnc: Fix no spaces before tabs checkpath warning This commit corrects the 'no space before tabs' checkpath warning. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 2c2abf848326..ec7dcb02f3c2 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -57,7 +57,7 @@ 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."); +PARM_INT(trcbuf_size, 0x100000, 0644, "Debugging trace buffer size."); /************************************************************************** * @@ -83,7 +83,7 @@ static void dgnc_do_remap(struct dgnc_board *brd); */ static const struct file_operations dgnc_BoardFops = { .owner = THIS_MODULE, - .unlocked_ioctl = dgnc_mgmt_ioctl, + .unlocked_ioctl = dgnc_mgmt_ioctl, .open = dgnc_mgmt_open, .release = dgnc_mgmt_close }; @@ -111,7 +111,7 @@ static struct class *dgnc_class; /* * Poller stuff */ -static DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ +static DEFINE_SPINLOCK(dgnc_poll_lock); /* Poll scheduling lock */ static ulong dgnc_poll_time; /* Time of next poll */ static uint dgnc_poll_stop; /* Used to tell poller to stop */ static struct timer_list dgnc_poll_timer; -- GitLab From ea6e9dea2e72a7abd146a2c5bab726b27f34b36c Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 14:21:21 +0200 Subject: [PATCH 0546/9167] staging: dgnc: Fix frame size is larger than 1024B This comit fixes the following sparse warnign: drivers/staging/dgnc/dgnc_tty.c:572:1: warning: the frame size of 1060 bytes is larger than 1024 bytes [-Wframe-larger-than=] This was caused by having buffer as an automatic variable. This commit moves it from the stack to the heap. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_tty.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index c712b431f969..2dc78f79ec49 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -471,13 +471,18 @@ void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int int nbuf; int i; int tmpbuflen; - char tmpbuf[TMPBUFLEN]; - char *p = tmpbuf; + char *tmpbuf; + char *p; int too_much_data; + tmpbuf = kzalloc(TMPBUFLEN, GFP_KERNEL); + if (!tmpbuf) + return; + p = tmpbuf; + /* Leave if sniff not open */ if (!(ch->ch_sniff_flags & SNIFF_OPEN)) - return; + goto exit; do_gettimeofday(&tv); @@ -524,7 +529,7 @@ void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int * function was probably called by the interrupt/timer routines! */ if (n == 0) - return; + goto exit; /* * Copy as much data as will fit. @@ -569,6 +574,9 @@ void dgnc_sniff_nowait_nolock(struct channel_t *ch, uchar *text, uchar *buf, int } } while (too_much_data); + +exit: + kfree(tmpbuf); } -- GitLab From bbecbacbed32db649c10d1d4e0a6045b4f4d4750 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 14:21:22 +0200 Subject: [PATCH 0547/9167] staging: dgnc: Remove unnecessary functions from dgnc_driver.c This commit slightly cleans up the dgnc_driver.c file. The changes include removing one-line proxy functions as they were not needed. Additionaly the pci 'remove' function is deleted because it was no need for it. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index ec7dcb02f3c2..96108e2ee69f 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -70,14 +70,9 @@ static void dgnc_init_globals(void); static int dgnc_found_board(struct pci_dev *pdev, int id); static void dgnc_cleanup_board(struct dgnc_board *brd); static void dgnc_poll_handler(ulong dummy); -static int dgnc_init_pci(void); static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent); -static void dgnc_remove_one(struct pci_dev *dev); -static int dgnc_probe1(struct pci_dev *pdev, int card_type); static void dgnc_do_remap(struct dgnc_board *brd); - - /* * File operations permitted on Control/Management major. */ @@ -170,7 +165,6 @@ static struct pci_driver dgnc_driver = { .name = "dgnc", .probe = dgnc_init_one, .id_table = dgnc_pci_tbl, - .remove = dgnc_remove_one, }; @@ -252,7 +246,7 @@ static int __init dgnc_init_module(void) /* * Find and configure all the cards */ - rc = dgnc_init_pci(); + rc = pci_register_driver(&dgnc_driver); /* * If something went wrong in the scan, bail out of driver. @@ -346,15 +340,6 @@ static int dgnc_start(void) return rc; } -/* - * Register pci driver, and return how many boards we have. - */ -static int dgnc_init_pci(void) -{ - return pci_register_driver(&dgnc_driver); -} - - /* returns count (>= 0), or negative on error */ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -366,7 +351,7 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc < 0) { rc = -EIO; } else { - rc = dgnc_probe1(pdev, ent->driver_data); + rc = dgnc_found_board(pdev, ent->driver_data); if (rc == 0) { dgnc_NumBoards++; DPR_INIT(("Incrementing numboards to %d\n", dgnc_NumBoards)); @@ -375,17 +360,6 @@ static int dgnc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return rc; } -static int dgnc_probe1(struct pci_dev *pdev, int card_type) -{ - return dgnc_found_board(pdev, card_type); -} - - -static void dgnc_remove_one(struct pci_dev *dev) -{ - /* Do Nothing */ -} - /* * dgnc_cleanup_board() * -- GitLab From 9a633d00d14129b5865502a0f45c160f523b446f Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 14:21:23 +0200 Subject: [PATCH 0548/9167] staging: dgnc: Move utility functions out of dgnc_driver.c This commit moves the utility functions out of dgnc_driver.c file and puts them in the new dgnc_utils.{c,h} files. The accompanying changes adjust the existing code to work with this design. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/Makefile | 3 +- drivers/staging/dgnc/dgnc_driver.c | 74 ------------------------------ drivers/staging/dgnc/dgnc_driver.h | 10 ---- drivers/staging/dgnc/dgnc_tty.c | 1 + drivers/staging/dgnc/dgnc_utils.c | 70 ++++++++++++++++++++++++++++ drivers/staging/dgnc/dgnc_utils.h | 7 +++ 6 files changed, 80 insertions(+), 85 deletions(-) create mode 100644 drivers/staging/dgnc/dgnc_utils.c create mode 100644 drivers/staging/dgnc/dgnc_utils.h diff --git a/drivers/staging/dgnc/Makefile b/drivers/staging/dgnc/Makefile index 733434f63700..b69f7b6b1143 100644 --- a/drivers/staging/dgnc/Makefile +++ b/drivers/staging/dgnc/Makefile @@ -4,4 +4,5 @@ obj-$(CONFIG_DGNC) += dgnc.o dgnc-objs := dgnc_cls.o dgnc_driver.o\ dgnc_mgmt.o dgnc_neo.o\ - dgnc_tty.o dgnc_sysfs.o + dgnc_tty.o dgnc_sysfs.o\ + dgnc_utils.o diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 96108e2ee69f..561571c318da 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -821,77 +821,3 @@ static void dgnc_init_globals(void) init_timer(&dgnc_poll_timer); } - -/************************************************************************ - * - * Utility functions - * - ************************************************************************/ - -/* - * dgnc_ms_sleep() - * - * Put the driver to sleep for x ms's - * - * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal. - */ -int dgnc_ms_sleep(ulong ms) -{ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout((ms * HZ) / 1000); - return signal_pending(current); -} - - - -/* - * dgnc_ioctl_name() : Returns a text version of each ioctl value. - */ -char *dgnc_ioctl_name(int cmd) -{ - switch (cmd) { - - case TCGETA: return "TCGETA"; - case TCGETS: return "TCGETS"; - case TCSETA: return "TCSETA"; - case TCSETS: return "TCSETS"; - case TCSETAW: return "TCSETAW"; - case TCSETSW: return "TCSETSW"; - case TCSETAF: return "TCSETAF"; - case TCSETSF: return "TCSETSF"; - case TCSBRK: return "TCSBRK"; - case TCXONC: return "TCXONC"; - case TCFLSH: return "TCFLSH"; - case TIOCGSID: return "TIOCGSID"; - - case TIOCGETD: return "TIOCGETD"; - case TIOCSETD: return "TIOCSETD"; - case TIOCGWINSZ: return "TIOCGWINSZ"; - case TIOCSWINSZ: return "TIOCSWINSZ"; - - case TIOCMGET: return "TIOCMGET"; - case TIOCMSET: return "TIOCMSET"; - case TIOCMBIS: return "TIOCMBIS"; - case TIOCMBIC: return "TIOCMBIC"; - - /* from digi.h */ - case DIGI_SETA: return "DIGI_SETA"; - case DIGI_SETAW: return "DIGI_SETAW"; - case DIGI_SETAF: return "DIGI_SETAF"; - case DIGI_SETFLOW: return "DIGI_SETFLOW"; - case DIGI_SETAFLOW: return "DIGI_SETAFLOW"; - case DIGI_GETFLOW: return "DIGI_GETFLOW"; - case DIGI_GETAFLOW: return "DIGI_GETAFLOW"; - case DIGI_GETA: return "DIGI_GETA"; - case DIGI_GEDELAY: return "DIGI_GEDELAY"; - case DIGI_SEDELAY: return "DIGI_SEDELAY"; - case DIGI_GETCUSTOMBAUD: return "DIGI_GETCUSTOMBAUD"; - case DIGI_SETCUSTOMBAUD: return "DIGI_SETCUSTOMBAUD"; - case TIOCMODG: return "TIOCMODG"; - case TIOCMODS: return "TIOCMODS"; - case TIOCSDTR: return "TIOCSDTR"; - case TIOCCDTR: return "TIOCCDTR"; - - default: return "unknown"; - } -} diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index 58b5aa7b68ed..eae04940062c 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -481,16 +481,6 @@ struct channel_t { wait_queue_head_t ch_sniff_wait; }; - -/************************************************************************* - * - * Prototypes for non-static functions used in more than one module - * - *************************************************************************/ - -extern int dgnc_ms_sleep(ulong ms); -extern char *dgnc_ioctl_name(int cmd); - /* * Our Global Variables. */ diff --git a/drivers/staging/dgnc/dgnc_tty.c b/drivers/staging/dgnc/dgnc_tty.c index 2dc78f79ec49..281491a75e76 100644 --- a/drivers/staging/dgnc/dgnc_tty.c +++ b/drivers/staging/dgnc/dgnc_tty.c @@ -57,6 +57,7 @@ #include "dgnc_cls.h" #include "dpacompat.h" #include "dgnc_sysfs.h" +#include "dgnc_utils.h" #define init_MUTEX(sem) sema_init(sem, 1) #define DECLARE_MUTEX(name) \ diff --git a/drivers/staging/dgnc/dgnc_utils.c b/drivers/staging/dgnc/dgnc_utils.c new file mode 100644 index 000000000000..61efc13ec160 --- /dev/null +++ b/drivers/staging/dgnc/dgnc_utils.c @@ -0,0 +1,70 @@ +#include +#include +#include "dgnc_utils.h" +#include "digi.h" + +/* + * dgnc_ms_sleep() + * + * Put the driver to sleep for x ms's + * + * Returns 0 if timed out, !0 (showing signal) if interrupted by a signal. + */ +int dgnc_ms_sleep(ulong ms) +{ + current->state = TASK_INTERRUPTIBLE; + schedule_timeout((ms * HZ) / 1000); + return signal_pending(current); +} + +/* + * dgnc_ioctl_name() : Returns a text version of each ioctl value. + */ +char *dgnc_ioctl_name(int cmd) +{ + switch (cmd) { + + case TCGETA: return "TCGETA"; + case TCGETS: return "TCGETS"; + case TCSETA: return "TCSETA"; + case TCSETS: return "TCSETS"; + case TCSETAW: return "TCSETAW"; + case TCSETSW: return "TCSETSW"; + case TCSETAF: return "TCSETAF"; + case TCSETSF: return "TCSETSF"; + case TCSBRK: return "TCSBRK"; + case TCXONC: return "TCXONC"; + case TCFLSH: return "TCFLSH"; + case TIOCGSID: return "TIOCGSID"; + + case TIOCGETD: return "TIOCGETD"; + case TIOCSETD: return "TIOCSETD"; + case TIOCGWINSZ: return "TIOCGWINSZ"; + case TIOCSWINSZ: return "TIOCSWINSZ"; + + case TIOCMGET: return "TIOCMGET"; + case TIOCMSET: return "TIOCMSET"; + case TIOCMBIS: return "TIOCMBIS"; + case TIOCMBIC: return "TIOCMBIC"; + + /* from digi.h */ + case DIGI_SETA: return "DIGI_SETA"; + case DIGI_SETAW: return "DIGI_SETAW"; + case DIGI_SETAF: return "DIGI_SETAF"; + case DIGI_SETFLOW: return "DIGI_SETFLOW"; + case DIGI_SETAFLOW: return "DIGI_SETAFLOW"; + case DIGI_GETFLOW: return "DIGI_GETFLOW"; + case DIGI_GETAFLOW: return "DIGI_GETAFLOW"; + case DIGI_GETA: return "DIGI_GETA"; + case DIGI_GEDELAY: return "DIGI_GEDELAY"; + case DIGI_SEDELAY: return "DIGI_SEDELAY"; + case DIGI_GETCUSTOMBAUD: return "DIGI_GETCUSTOMBAUD"; + case DIGI_SETCUSTOMBAUD: return "DIGI_SETCUSTOMBAUD"; + case TIOCMODG: return "TIOCMODG"; + case TIOCMODS: return "TIOCMODS"; + case TIOCSDTR: return "TIOCSDTR"; + case TIOCCDTR: return "TIOCCDTR"; + + default: return "unknown"; + } +} diff --git a/drivers/staging/dgnc/dgnc_utils.h b/drivers/staging/dgnc/dgnc_utils.h new file mode 100644 index 000000000000..cebf60163a26 --- /dev/null +++ b/drivers/staging/dgnc/dgnc_utils.h @@ -0,0 +1,7 @@ +#ifndef __DGNC_UTILS_H +#define __DGNC_UTILS_H + +int dgnc_ms_sleep(ulong ms); +char *dgnc_ioctl_name(int cmd); + +#endif -- GitLab From 92ded48cc3f09b8f6bdf56348b9318f9badd28fe Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 15:40:11 +0200 Subject: [PATCH 0549/9167] staging: dgnc: Siplify the dgnc_start function This commit slightly simplifies the sgnc_start() function by rearranging it. As a result the indentation level is reduced. This is not the functional change. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 91 +++++++++++++++--------------- 1 file changed, 44 insertions(+), 47 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 561571c318da..7bbe98080edf 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -278,64 +278,60 @@ static int dgnc_start(void) int rc = 0; unsigned long flags; - if (dgnc_driver_start == FALSE) { - - dgnc_driver_start = TRUE; - - /* make sure that the globals are init'd before we do anything else */ - dgnc_init_globals(); + if (dgnc_driver_start == TRUE) + return rc; + dgnc_driver_start = TRUE; - dgnc_NumBoards = 0; + /* 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")); + 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 + * before any of the boards are init'ed. + */ + if (!dgnc_Major_Control_Registered) { /* - * Register our base character device into the kernel. - * This allows the download daemon to connect to the downld device - * before any of the boards are init'ed. + * Register management/dpa devices */ - if (!dgnc_Major_Control_Registered) { - /* - * Register management/dpa devices - */ - rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); - if (rc <= 0) { - APR(("Can't register dgnc driver device (%d)\n", rc)); - rc = -ENXIO; - return rc; - } - dgnc_Major = rc; - - dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); - device_create(dgnc_class, NULL, - MKDEV(dgnc_Major, 0), - NULL, "dgnc_mgmt"); - dgnc_Major_Control_Registered = TRUE; + rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); + if (rc <= 0) { + APR(("Can't register dgnc driver device (%d)\n", rc)); + return -ENXIO; } + dgnc_Major = rc; - /* - * Init any global tty stuff. - */ - rc = dgnc_tty_preinit(); + dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); + device_create(dgnc_class, NULL, + MKDEV(dgnc_Major, 0), + NULL, "dgnc_mgmt"); + dgnc_Major_Control_Registered = TRUE; + } - if (rc < 0) { - APR(("tty preinit - not enough memory (%d)\n", rc)); - return rc; - } + /* + * Init any global tty stuff. + */ + rc = dgnc_tty_preinit(); - /* Start the poller */ - DGNC_LOCK(dgnc_poll_lock, flags); - init_timer(&dgnc_poll_timer); - dgnc_poll_timer.function = dgnc_poll_handler; - dgnc_poll_timer.data = 0; - dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick); - dgnc_poll_timer.expires = dgnc_poll_time; - DGNC_UNLOCK(dgnc_poll_lock, flags); + if (rc < 0) { + APR(("tty preinit - not enough memory (%d)\n", rc)); + return rc; + } - add_timer(&dgnc_poll_timer); + /* Start the poller */ + DGNC_LOCK(dgnc_poll_lock, flags); + init_timer(&dgnc_poll_timer); + dgnc_poll_timer.function = dgnc_poll_handler; + dgnc_poll_timer.data = 0; + dgnc_poll_time = jiffies + dgnc_jiffies_from_ms(dgnc_poll_tick); + dgnc_poll_timer.expires = dgnc_poll_time; + DGNC_UNLOCK(dgnc_poll_lock, flags); - dgnc_driver_state = DRIVER_READY; - } + add_timer(&dgnc_poll_timer); + + dgnc_driver_state = DRIVER_READY; return rc; } @@ -814,6 +810,7 @@ static void dgnc_init_globals(void) dgnc_rawreadok = rawreadok; dgnc_trcbuf_size = trcbuf_size; dgnc_debug = debug; + dgnc_NumBoards = 0; for (i = 0; i < MAXBOARDS; i++) dgnc_Board[i] = NULL; -- GitLab From 98b3bcc05fa7efaf6a9a1420ce4a0fc6c9031b36 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 14:21:25 +0200 Subject: [PATCH 0550/9167] staging: dgnc: Update the TODO file It turned out that the TODO file contained the invalid information as some of the work has already been done. This commit updates it with the current status of what is left to be done. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/TODO | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/dgnc/TODO b/drivers/staging/dgnc/TODO index 1ff2d1874aa2..d2828c7936c8 100644 --- a/drivers/staging/dgnc/TODO +++ b/drivers/staging/dgnc/TODO @@ -1,9 +1,4 @@ -* remove kzalloc casts * checkpatch fixes -* sparse fixes -* fix use of sizeof(). Example replace sizeof(struct board_t) - with sizeof(*brd) and remove sizeof(char) -* change name of board_t to dgnc_board * split two assignments into the two assignments on two lines; don't use two equals signs * remove unecessary comments -- GitLab From 9dfe5670e1ceeda7378a6f4234cca6820fd5af46 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 21:01:22 +0200 Subject: [PATCH 0551/9167] staging: dgnc: Fix included header from 'asm' This commit fixes the checkpatch warning: drivers/staging/dgnc/dgnc_neo.c:37: WARNING: Use #include instead of Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 68ff1161e677..d58aaa067f4d 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -34,7 +34,7 @@ #include /* For jiffies, task states */ #include /* For tasklet and interrupt structs/defines */ #include /* For udelay */ -#include /* For read[bwl]/write[bwl] */ +#include /* For read[bwl]/write[bwl] */ #include /* For struct async_serial */ #include /* For the various UART offsets */ -- GitLab From 1eba3dba7463cddd254605b5372ee38ceb45fa30 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 21:01:23 +0200 Subject: [PATCH 0552/9167] staging: dgnc: Fix missing blank line after declarations This commit deals with the checkapth warnings 'missing line after declarations' in the dgnc_neo.c file. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index d58aaa067f4d..79684a355530 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -397,6 +397,7 @@ static inline void neo_clear_break(struct channel_t *ch, int force) if (time_after_eq(jiffies, ch->ch_stop_sending_break) || force) { uchar temp = readb(&ch->ch_neo_uart->lcr); + writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); neo_pci_posting_flush(ch->ch_bd); ch->ch_flags &= ~(CH_BREAK_SENDING); @@ -1138,6 +1139,7 @@ static irqreturn_t neo_intr(int irq, void *voidbrd) static void neo_disable_receiver(struct channel_t *ch) { uchar tmp = readb(&ch->ch_neo_uart->ier); + tmp &= ~(UART_IER_RDI); writeb(tmp, &ch->ch_neo_uart->ier); neo_pci_posting_flush(ch->ch_bd); @@ -1152,6 +1154,7 @@ static void neo_disable_receiver(struct channel_t *ch) static void neo_enable_receiver(struct channel_t *ch) { uchar tmp = readb(&ch->ch_neo_uart->ier); + tmp |= (UART_IER_RDI); writeb(tmp, &ch->ch_neo_uart->ier); neo_pci_posting_flush(ch->ch_bd); @@ -1324,6 +1327,7 @@ static void neo_copy_data_from_uart_to_queue(struct channel_t *ch) */ if (linestatus & error_mask) { uchar discard; + linestatus = 0; memcpy_fromio(&discard, &ch->ch_neo_uart->txrxburst, 1); continue; @@ -1822,6 +1826,7 @@ static void neo_send_break(struct channel_t *ch, int msecs) if (msecs == 0) { if (ch->ch_flags & CH_BREAK_SENDING) { uchar temp = readb(&ch->ch_neo_uart->lcr); + writeb((temp & ~UART_LCR_SBC), &ch->ch_neo_uart->lcr); neo_pci_posting_flush(ch->ch_bd); ch->ch_flags &= ~(CH_BREAK_SENDING); @@ -1841,6 +1846,7 @@ static void neo_send_break(struct channel_t *ch, int msecs) /* Tell the UART to start sending the break */ if (!(ch->ch_flags & CH_BREAK_SENDING)) { uchar temp = readb(&ch->ch_neo_uart->lcr); + writeb((temp | UART_LCR_SBC), &ch->ch_neo_uart->lcr); neo_pci_posting_flush(ch->ch_bd); ch->ch_flags |= (CH_BREAK_SENDING); -- GitLab From 5ef33f38cb148ad0fb4a7c8860d8e1c7ebe16bdb Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 21:01:24 +0200 Subject: [PATCH 0553/9167] staging: dgnc: Fix that open brace { should be on the previous line This commit fixes the following checkpath error in dgnc_neo.c file: 'that open brace { should be on the previous line' Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index 79684a355530..e6aeda3dae93 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1846,7 +1846,7 @@ static void neo_send_break(struct channel_t *ch, int msecs) /* Tell the UART to start sending the break */ if (!(ch->ch_flags & CH_BREAK_SENDING)) { uchar temp = readb(&ch->ch_neo_uart->lcr); - + writeb((temp | UART_LCR_SBC), &ch->ch_neo_uart->lcr); neo_pci_posting_flush(ch->ch_bd); ch->ch_flags |= (CH_BREAK_SENDING); @@ -1935,8 +1935,8 @@ static void neo_vpd(struct dgnc_board *brd) if (((brd->vpd[0x08] != 0x82) /* long resource name tag */ && (brd->vpd[0x10] != 0x82)) /* long resource name tag (PCI-66 files)*/ - || (brd->vpd[0x7F] != 0x78)) /* small resource end tag */ - { + || (brd->vpd[0x7F] != 0x78)) { /* small resource end tag */ + memset(brd->vpd, '\0', NEO_VPD_IMAGESIZE); } else { /* Search for the serial number */ -- GitLab From 13d1773ace622802e99f2aae577f30eab444eb55 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 21:01:25 +0200 Subject: [PATCH 0554/9167] staging: dgnc: Fix braces {} are not necessary for single statement blocks This commit fixes the following checkpath warning in dgnc_neo.c file: 'braces {} are not necessary for single statement blocks' Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index e6aeda3dae93..b4198e0d5f0c 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1804,9 +1804,8 @@ static uint neo_get_uart_bytes_left(struct channel_t *ch) /* Determine whether the Transmitter is empty or not */ if (!(lsr & UART_LSR_TEMT)) { - if (ch->ch_flags & CH_TX_FIFO_EMPTY) { + if (ch->ch_flags & CH_TX_FIFO_EMPTY) tasklet_schedule(&ch->ch_bd->helper_tasklet); - } left = 1; } else { ch->ch_flags |= (CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); -- GitLab From e9b69997e74a88b388a6272a81e5133688683705 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 21:01:26 +0200 Subject: [PATCH 0555/9167] staging: dgnc: Remove 'volatile' modifier where it is not needed This commit fixes the checkpath warning about misused 'volatile' modifier. In this case the 'volatile' was not needed as it was used for regular automatic variable. Thos commit removes the 'volatile'. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_neo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/dgnc/dgnc_neo.c b/drivers/staging/dgnc/dgnc_neo.c index b4198e0d5f0c..86a1cd79daee 100644 --- a/drivers/staging/dgnc/dgnc_neo.c +++ b/drivers/staging/dgnc/dgnc_neo.c @@ -1640,7 +1640,7 @@ static void neo_copy_data_from_queue_to_uart(struct channel_t *ch) static void neo_parse_modem(struct channel_t *ch, uchar signals) { - volatile uchar msignals = signals; + uchar msignals = signals; if (!ch || ch->magic != DGNC_CHANNEL_MAGIC) return; -- GitLab From 8aa5d0d825715db571be47b02ca8b176f70cb1da Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 22:17:09 +0200 Subject: [PATCH 0556/9167] staging: dgnc: Fix missing blank line after declarations This commit fixes the missing blank lines after declarations checkpath warnings found in dgnc_cls.c file. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_cls.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index cfa8384c0077..0d3ca7cec8fc 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -390,6 +390,7 @@ static inline void cls_clear_break(struct channel_t *ch, int force) if (ch->ch_flags & CH_BREAK_SENDING) { if (time_after(jiffies, ch->ch_stop_sending_break) || force) { uchar temp = readb(&ch->ch_cls_uart->lcr); + writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr); ch->ch_flags &= ~(CH_BREAK_SENDING); ch->ch_stop_sending_break = 0; @@ -866,6 +867,7 @@ static irqreturn_t cls_intr(int irq, void *voidbrd) static void cls_disable_receiver(struct channel_t *ch) { uchar tmp = readb(&ch->ch_cls_uart->ier); + tmp &= ~(UART_IER_RDI); writeb(tmp, &ch->ch_cls_uart->ier); } @@ -874,6 +876,7 @@ static void cls_disable_receiver(struct channel_t *ch) static void cls_enable_receiver(struct channel_t *ch) { uchar tmp = readb(&ch->ch_cls_uart->ier); + tmp |= (UART_IER_RDI); writeb(tmp, &ch->ch_cls_uart->ier); } @@ -920,6 +923,7 @@ static void cls_copy_data_from_uart_to_queue(struct channel_t *ch) */ if (linestatus & error_mask) { uchar discard; + linestatus = 0; discard = readb(&ch->ch_cls_uart->txrx); continue; @@ -1157,6 +1161,7 @@ static void cls_parse_modem(struct channel_t *ch, uchar signals) DGNC_LOCK(ch->ch_lock, lock_flags); if (ch->ch_digi.digi_flags & DIGI_ALTPIN) { uchar mswap = signals; + if (mswap & UART_MSR_DDCD) { msignals &= ~UART_MSR_DDCD; msignals |= UART_MSR_DDSR; @@ -1356,6 +1361,7 @@ static void cls_send_break(struct channel_t *ch, int msecs) /* Turn break off, and unset some variables */ if (ch->ch_flags & CH_BREAK_SENDING) { uchar temp = readb(&ch->ch_cls_uart->lcr); + writeb((temp & ~UART_LCR_SBC), &ch->ch_cls_uart->lcr); ch->ch_flags &= ~(CH_BREAK_SENDING); ch->ch_stop_sending_break = 0; @@ -1375,6 +1381,7 @@ static void cls_send_break(struct channel_t *ch, int msecs) /* Tell the UART to start sending the break */ if (!(ch->ch_flags & CH_BREAK_SENDING)) { uchar temp = readb(&ch->ch_cls_uart->lcr); + writeb((temp | UART_LCR_SBC), &ch->ch_cls_uart->lcr); ch->ch_flags |= (CH_BREAK_SENDING); DPR_IOCTL(( -- GitLab From d6365fe50ebff17a5beccefed0c19d7dd847f076 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Wed, 6 Aug 2014 22:17:10 +0200 Subject: [PATCH 0557/9167] staging: dgnc: Remove unnecessary 'return' statement This commit fixes the checkpath warning 'void function return statements are not generally useful' caused by the 'return' at the end of 'void' function. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_cls.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_cls.c b/drivers/staging/dgnc/dgnc_cls.c index 0d3ca7cec8fc..fe099c651d32 100644 --- a/drivers/staging/dgnc/dgnc_cls.c +++ b/drivers/staging/dgnc/dgnc_cls.c @@ -1138,8 +1138,6 @@ static void cls_copy_data_from_queue_to_uart(struct channel_t *ch) ch->ch_flags &= ~(CH_TX_FIFO_EMPTY | CH_TX_FIFO_LWM); DGNC_UNLOCK(ch->ch_lock, lock_flags); - - return; } -- GitLab From c5081c548eafb115645d9fc60703641d4597b589 Mon Sep 17 00:00:00 2001 From: Andreas Schlick Date: Thu, 7 Aug 2014 19:20:49 +0200 Subject: [PATCH 0558/9167] staging: rtl8723au: Move open braces to the previous line. Correct coding style errors in rtw_efuse.c. checkpatch.pl reported: ERROR: that open brace { should be on the previous line Signed-off-by: Andreas Schlick Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_efuse.c | 33 ++++++++-------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c index fe092c5defa6..0bec1316af56 100644 --- a/drivers/staging/rtl8723au/core/rtw_efuse.c +++ b/drivers/staging/rtl8723au/core/rtw_efuse.c @@ -157,8 +157,7 @@ ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf) retry = 0; value32 = rtl8723au_read32(Adapter, EFUSE_CTRL); /* while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) */ - while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000)) - { + while (!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000)) { value32 = rtl8723au_read32(Adapter, EFUSE_CTRL); retry++; } @@ -285,8 +284,7 @@ EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address) TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen); - if (Address < contentLen) /* E-fuse 512Byte */ - { + if (Address < contentLen) { /* E-fuse 512Byte */ /* Write E-fuse Register address bit0~7 */ temp = Address & 0xFF; rtl8723au_write8(Adapter, EFUSE_CTRL+1, temp); @@ -302,12 +300,10 @@ EFUSE_Read1Byte23a(struct rtw_adapter *Adapter, u16 Address) /* Wait Write-ready (0x30[31]= 1) */ Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); - while(!(Bytetemp & 0x80)) - { + while (!(Bytetemp & 0x80)) { Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); k++; - if (k == 1000) - { + if (k == 1000) { k = 0; break; } @@ -357,8 +353,7 @@ EFUSE_Write1Byte( TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&contentLen); - if (Address < contentLen) /* E-fuse 512Byte */ - { + if (Address < contentLen) { /* E-fuse 512Byte */ rtl8723au_write8(Adapter, EFUSE_CTRL, Value); /* Write E-fuse Register address bit0~7 */ @@ -377,12 +372,10 @@ EFUSE_Write1Byte( /* Wait Write-ready (0x30[31]= 0) */ Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); - while(Bytetemp & 0x80) - { + while (Bytetemp & 0x80) { Bytetemp = rtl8723au_read8(Adapter, EFUSE_CTRL+3); k++; - if (k == 100) - { + if (k == 100) { k = 0; break; } @@ -472,23 +465,19 @@ efuse_WordEnableDataRead23a(u8 word_en, u8 *sourdata, u8 *targetdata) { - if (!(word_en&BIT(0))) - { + if (!(word_en&BIT(0))) { targetdata[0] = sourdata[0]; targetdata[1] = sourdata[1]; } - if (!(word_en&BIT(1))) - { + if (!(word_en&BIT(1))) { targetdata[2] = sourdata[2]; targetdata[3] = sourdata[3]; } - if (!(word_en&BIT(2))) - { + if (!(word_en&BIT(2))) { targetdata[4] = sourdata[4]; targetdata[5] = sourdata[5]; } - if (!(word_en&BIT(3))) - { + if (!(word_en&BIT(3))) { targetdata[6] = sourdata[6]; targetdata[7] = sourdata[7]; } -- GitLab From 2892d397972496075523c63ad5bec77175654125 Mon Sep 17 00:00:00 2001 From: Andreas Schlick Date: Thu, 7 Aug 2014 19:20:50 +0200 Subject: [PATCH 0559/9167] staging: rtl8723au: Remove unnecessary bit masking. Signed-off-by: Andreas Schlick Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8723au/core/rtw_efuse.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8723au/core/rtw_efuse.c b/drivers/staging/rtl8723au/core/rtw_efuse.c index 0bec1316af56..abc5d3cefecf 100644 --- a/drivers/staging/rtl8723au/core/rtw_efuse.c +++ b/drivers/staging/rtl8723au/core/rtw_efuse.c @@ -156,8 +156,7 @@ ReadEFuseByte23a(struct rtw_adapter *Adapter, u16 _offset, u8 *pbuf) /* Check bit 32 read-ready */ retry = 0; value32 = rtl8723au_read32(Adapter, EFUSE_CTRL); - /* while(!(((value32 >> 24) & 0xff) & 0x80) && (retry<10)) */ - while (!(((value32 >> 24) & 0xff) & 0x80) && (retry<10000)) { + while (!((value32 >> 24) & 0x80) && retry < 10000) { value32 = rtl8723au_read32(Adapter, EFUSE_CTRL); retry++; } -- GitLab From 2160e944a911dae3c4b40cca72d6c83af6f85bb5 Mon Sep 17 00:00:00 2001 From: Sanjeev Sharma Date: Fri, 8 Aug 2014 09:53:07 +0530 Subject: [PATCH 0560/9167] staging:r819xU: coding style: Fixed commenting style This is a patch to the r819xU_phyreg.h file that fixes commenting style warning Signed-off-by: Sanjeev Sharma Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r819xU_phyreg.h | 189 ++++++++++++----------- 1 file changed, 98 insertions(+), 91 deletions(-) diff --git a/drivers/staging/rtl8192u/r819xU_phyreg.h b/drivers/staging/rtl8192u/r819xU_phyreg.h index 64285d6a33f8..b855627e9816 100644 --- a/drivers/staging/rtl8192u/r819xU_phyreg.h +++ b/drivers/staging/rtl8192u/r819xU_phyreg.h @@ -2,10 +2,11 @@ #define _R819XU_PHYREG_H -#define RF_DATA 0x1d4 // FW will write RF data in the register. +#define RF_DATA 0x1d4 /* FW will write RF data in the register.*/ -//Register //duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF -//page 1 +/* Register duplicate register due to connection: RF_Mode, TRxRN, NumOf L-STF + * page 1 + */ #define rPMAC_Reset 0x100 #define rPMAC_TxStart 0x104 #define rPMAC_TxLegacySIG 0x108 @@ -34,15 +35,16 @@ #define rPMAC_CCKCRxRC32OK 0x188 #define rPMAC_TxStatus 0x18c -//page8 -#define rFPGA0_RFMOD 0x800 //RF mode & CCK TxSC +/* page8 */ +#define rFPGA0_RFMOD 0x800 /* RF mode & CCK TxSC */ #define rFPGA0_TxInfo 0x804 #define rFPGA0_PSDFunction 0x808 #define rFPGA0_TxGainStage 0x80c #define rFPGA0_RFTiming1 0x810 #define rFPGA0_RFTiming2 0x814 -//#define rFPGA0_XC_RFTiming 0x818 -//#define rFPGA0_XD_RFTiming 0x81c +/* #define rFPGA0_XC_RFTiming 0x818 + * #define rFPGA0_XD_RFTiming 0x81c + */ #define rFPGA0_XA_HSSIParameter1 0x820 #define rFPGA0_XA_HSSIParameter2 0x824 #define rFPGA0_XB_HSSIParameter1 0x828 @@ -79,51 +81,51 @@ #define rFPGA0_XAB_RFInterfaceRB 0x8e0 #define rFPGA0_XCD_RFInterfaceRB 0x8e4 -//page 9 -#define rFPGA1_RFMOD 0x900 //RF mode & OFDM TxSC +/* page 9 */ +#define rFPGA1_RFMOD 0x900 /* RF mode & OFDM TxSC */ #define rFPGA1_TxBlock 0x904 #define rFPGA1_DebugSelect 0x908 #define rFPGA1_TxInfo 0x90c -//page a +/* page a */ #define rCCK0_System 0xa00 #define rCCK0_AFESetting 0xa04 #define rCCK0_CCA 0xa08 -#define rCCK0_RxAGC1 0xa0c //AGC default value, saturation level -#define rCCK0_RxAGC2 0xa10 //AGC & DAGC +#define rCCK0_RxAGC1 0xa0c /* AGC default value, saturation level */ +#define rCCK0_RxAGC2 0xa10 /* AGC & DAGC */ #define rCCK0_RxHP 0xa14 -#define rCCK0_DSPParameter1 0xa18 //Timing recovery & Channel estimation threshold -#define rCCK0_DSPParameter2 0xa1c //SQ threshold +#define rCCK0_DSPParameter1 0xa18 /* Timing recovery & Channel estimation threshold */ +#define rCCK0_DSPParameter2 0xa1c /* SQ threshold */ #define rCCK0_TxFilter1 0xa20 #define rCCK0_TxFilter2 0xa24 -#define rCCK0_DebugPort 0xa28 //debug port and Tx filter3 -#define rCCK0_FalseAlarmReport 0xa2c //0xa2d +#define rCCK0_DebugPort 0xa28 /* debug port and Tx filter3 */ +#define rCCK0_FalseAlarmReport 0xa2c /* 0xa2d */ #define rCCK0_TRSSIReport 0xa50 -#define rCCK0_RxReport 0xa54 //0xa57 -#define rCCK0_FACounterLower 0xa5c //0xa5b -#define rCCK0_FACounterUpper 0xa58 //0xa5c +#define rCCK0_RxReport 0xa54 /* 0xa57 */ +#define rCCK0_FACounterLower 0xa5c /* 0xa5b */ +#define rCCK0_FACounterUpper 0xa58 /* 0xa5c */ -//page c +/* page c */ #define rOFDM0_LSTF 0xc00 #define rOFDM0_TRxPathEnable 0xc04 #define rOFDM0_TRMuxPar 0xc08 #define rOFDM0_TRSWIsolation 0xc0c -#define rOFDM0_XARxAFE 0xc10 //RxIQ DC offset, Rx digital filter, DC notch filter -#define rOFDM0_XARxIQImbalance 0xc14 //RxIQ imblance matrix +#define rOFDM0_XARxAFE 0xc10 /* RxIQ DC offset, Rx digital filter, DC notch filter */ +#define rOFDM0_XARxIQImbalance 0xc14 /* RxIQ imblance matrix */ #define rOFDM0_XBRxAFE 0xc18 #define rOFDM0_XBRxIQImbalance 0xc1c #define rOFDM0_XCRxAFE 0xc20 #define rOFDM0_XCRxIQImbalance 0xc24 #define rOFDM0_XDRxAFE 0xc28 #define rOFDM0_XDRxIQImbalance 0xc2c -#define rOFDM0_RxDetector1 0xc30 //PD,BW & SBD -#define rOFDM0_RxDetector2 0xc34 //SBD & Fame Sync. -#define rOFDM0_RxDetector3 0xc38 //Frame Sync. -#define rOFDM0_RxDetector4 0xc3c //PD, SBD, Frame Sync & Short-GI -#define rOFDM0_RxDSP 0xc40 //Rx Sync Path -#define rOFDM0_CFOandDAGC 0xc44 //CFO & DAGC -#define rOFDM0_CCADropThreshold 0xc48 //CCA Drop threshold -#define rOFDM0_ECCAThreshold 0xc4c // energy CCA +#define rOFDM0_RxDetector1 0xc30 /* PD,BW & SBD */ +#define rOFDM0_RxDetector2 0xc34 /* SBD & Fame Sync.*/ +#define rOFDM0_RxDetector3 0xc38 /* Frame Sync.*/ +#define rOFDM0_RxDetector4 0xc3c /* PD, SBD, Frame Sync & Short-GI */ +#define rOFDM0_RxDSP 0xc40 /* Rx Sync Path */ +#define rOFDM0_CFOandDAGC 0xc44 /* CFO & DAGC */ +#define rOFDM0_CCADropThreshold 0xc48 /* CCA Drop threshold */ +#define rOFDM0_ECCAThreshold 0xc4c /* energy CCA */ #define rOFDM0_XAAGCCore1 0xc50 #define rOFDM0_XAAGCCore2 0xc54 #define rOFDM0_XBAGCCore1 0xc58 @@ -156,7 +158,7 @@ #define rOFDM0_TxCoeff6 0xcb8 -//page d +/* page d */ #define rOFDM1_LSTF 0xd00 #define rOFDM1_TRxPathEnable 0xd04 #define rOFDM1_CFO 0xd08 @@ -169,9 +171,10 @@ #define rOFDM1_PseudoNoiseStateAB 0xd50 #define rOFDM1_PseudoNoiseStateCD 0xd54 #define rOFDM1_RxPseudoNoiseWgt 0xd58 -#define rOFDM_PHYCounter1 0xda0 //cca, parity fail -#define rOFDM_PHYCounter2 0xda4 //rate illegal, crc8 fail -#define rOFDM_PHYCounter3 0xda8 //MCS not support +#define rOFDM_PHYCounter1 0xda0 /* cca, parity fail */ +#define rOFDM_PHYCounter2 0xda4 /* rate illegal, crc8 fail */ + +#define rOFDM_PHYCounter3 0xda8 /* MCS not support */ #define rOFDM_ShortCFOAB 0xdac #define rOFDM_ShortCFOCD 0xdb0 #define rOFDM_LongCFOAB 0xdb4 @@ -186,7 +189,7 @@ #define rOFDM_RxEVMCSI 0xdd8 #define rOFDM_SIGReport 0xddc -//page e +/* page e */ #define rTxAGC_Rate18_06 0xe00 #define rTxAGC_Rate54_24 0xe04 #define rTxAGC_CCK_Mcs32 0xe08 @@ -196,8 +199,9 @@ #define rTxAGC_Mcs15_Mcs12 0xe1c -//RF -//Zebra1 +/* RF + * Zebra1 + */ #define rZebra1_HSSIEnable 0x0 #define rZebra1_TRxEnable1 0x1 #define rZebra1_TRxEnable2 0x2 @@ -209,18 +213,19 @@ #define rZebra1_RxLPF 0xb #define rZebra1_RxHPFCorner 0xc -//Zebra4 +/* Zebra4 */ #define rGlobalCtrl 0 #define rRTL8256_TxLPF 19 #define rRTL8256_RxLPF 11 -//RTL8258 +/* RTL8258 */ #define rRTL8258_TxLPF 0x11 #define rRTL8258_RxLPF 0x13 #define rRTL8258_RSSILPF 0xa -//Bit Mask -//page-1 +/* Bit Mask + * page-1 + */ #define bBBResetB 0x100 #define bGlobalResetB 0x200 #define bOFDMTxStart 0x4 @@ -266,7 +271,7 @@ #define bCCKTxStatus 0x1 #define bOFDMTxStatus 0x2 -//page-8 +/* page-8 */ #define bRFMOD 0x1 #define bJapanMode 0x2 #define bCCKTxSC 0x30 @@ -283,14 +288,14 @@ #define bRFStart 0x0000f000 #define bBBStart 0x000000f0 #define bBBCCKStart 0x0000000f -#define bPAEnd 0xf //Reg0x814 +#define bPAEnd 0xf /* Reg0x814 */ #define bTREnd 0x0f000000 #define bRFEnd 0x000f0000 -#define bCCAMask 0x000000f0 //T2R +#define bCCAMask 0x000000f0 /* T2R */ #define bR2RCCAMask 0x00000f00 #define bHSSI_R2TDelay 0xf8000000 #define bHSSI_T2RDelay 0xf80000 -#define bContTxHSSI 0x400 //chane gain at continue Tx +#define bContTxHSSI 0x400 /* chane gain at continue Tx */ #define bIGFromCCK 0x200 #define bAGCAddress 0x3f #define bRxHPTx 0x7000 @@ -301,7 +306,7 @@ #define b3WireDataLength 0x800 #define b3WireAddressLength 0x400 #define b3WireRFPowerDown 0x1 -//#define bHWSISelect 0x8 +/* #define bHWSISelect 0x8 */ #define b5GPAPEPolarity 0x40000000 #define b2GPAPEPolarity 0x80000000 #define bRFSW_TxDefaultAnt 0x3 @@ -312,7 +317,7 @@ #define bRFSI_3WireClock 0x2 #define bRFSI_3WireLoad 0x4 #define bRFSI_3WireRW 0x8 -#define bRFSI_3Wire 0xf //3-wire total control +#define bRFSI_3Wire 0xf /* 3-wire total control */ #define bRFSI_RFENV 0x10 #define bRFSI_TRSW 0x20 #define bRFSI_TRSWB 0x40 @@ -337,12 +342,11 @@ #define bLSIG_Length 0x1fffe #define bLSIG_Parity 0x20 #define bCCKRxPhase 0x4 -#define bLSSIReadAddress 0x3f000000 //LSSI "Read" Address -#define bLSSIReadEdge 0x80000000 //LSSI "Read" edge signal +#define bLSSIReadAddress 0x3f000000 /* LSSI "Read" Address */ +#define bLSSIReadEdge 0x80000000 /* LSSI "Read" edge signal */ #define bLSSIReadBackData 0xfff #define bLSSIReadOKFlag 0x1000 -#define bCCKSampleRate 0x8 //0: 44MHz, 1:88MHz - +#define bCCKSampleRate 0x8 /* 0: 44MHz, 1:88MHz */ #define bRegulator0Standby 0x1 #define bRegulatorPLLStandby 0x2 #define bRegulator1Standby 0x4 @@ -395,12 +399,12 @@ #define bPSDSineToneScale 0x7f000000 #define bPSDReport 0xffff -//page-9 +/* page-9 */ #define bOFDMTxSC 0x30000000 #define bCCKTxOn 0x1 #define bOFDMTxOn 0x2 -#define bDebugPage 0xfff //reset debug page and also HWord, LWord -#define bDebugItem 0xff //reset debug page and LWord +#define bDebugPage 0xfff /* reset debug page and also HWord, LWord */ +#define bDebugItem 0xff /* reset debug page and LWord */ #define bAntL 0x10 #define bAntNonHT 0x100 #define bAntHT1 0x1000 @@ -408,7 +412,7 @@ #define bAntHT1S1 0x100000 #define bAntNonHTS1 0x1000000 -//page-a +/* page-a */ #define bCCKBBMode 0x3 #define bCCKTxPowerSaving 0x80 #define bCCKRxPowerSaving 0x40 @@ -429,7 +433,7 @@ #define bCCKBistMode 0x80000000 #define bCCKCCAMask 0x40000000 #define bCCKTxDACPhase 0x4 -#define bCCKRxADCPhase 0x20000000 //r_rx_clk +#define bCCKRxADCPhase 0x20000000 /* r_rx_clk */ #define bCCKr_cp_mode0 0x0100 #define bCCKTxDCOffset 0xf0 #define bCCKRxDCOffset 0xf @@ -443,12 +447,12 @@ #define bCCKRxIG 0x7f00 #define bCCKLNAPolarity 0x800000 #define bCCKRx1stGain 0x7f0000 -#define bCCKRFExtend 0x20000000 //CCK Rx initial gain polarity +#define bCCKRFExtend 0x20000000 /* CCK Rx initial gain polarity */ #define bCCKRxAGCSatLevel 0x1f000000 #define bCCKRxAGCSatCount 0xe0 -#define bCCKRxRFSettle 0x1f //AGCsamp_dly +#define bCCKRxRFSettle 0x1f /* AGCsamp_dly */ #define bCCKFixedRxAGC 0x8000 -//#define bCCKRxAGCFormat 0x4000 //remove to HSSI register 0x824 +/* #define bCCKRxAGCFormat 0x4000 */ /* remove to HSSI register 0x824 */ #define bCCKAntennaPolarity 0x2000 #define bCCKTxFilterType 0x0c00 #define bCCKRxAGCReportType 0x0300 @@ -489,7 +493,7 @@ #define bCCKDefaultRxPath 0xc000000 #define bCCKOptionRxPath 0x3000000 -//page c +/* page c */ #define bNumOfSTF 0x3 #define bShift_L 0xc0 #define bGI_TH 0xc @@ -591,8 +595,8 @@ #define bRxHP_BBP1 0x7000 #define bRxHP_BBP2 0x70000 #define bRxHP_BBP3 0x700000 -#define bRSSI_H 0x7f0000 //the threshold for high power -#define bRSSI_Gen 0x7f000000 //the threshold for ant diversity +#define bRSSI_H 0x7f0000 /* the threshold for high power */ +#define bRSSI_Gen 0x7f000000 /* the threshold for ant diversity */ #define bRxSettle_TRSW 0x7 #define bRxSettle_LNA 0x38 #define bRxSettle_RSSI 0x1c0 @@ -626,7 +630,7 @@ #define bRxPD_Delay_TH1 0x38 #define bRxPD_Delay_TH2 0x1c0 #define bRxPD_DC_COUNT_MAX 0x600 -//#define bRxMF_Hold 0x3800 +/* #define bRxMF_Hold 0x3800 */ #define bRxPD_Delay_TH 0x8000 #define bRxProcess_Delay 0xf0000 #define bRxSearchrange_GI2_Early 0x700000 @@ -652,7 +656,7 @@ #define bExtLNAGain 0x7c00 -//page d +/* page d */ #define bSTBCEn 0x4 #define bAntennaMapping 0x10 #define bNss 0x20 @@ -662,12 +666,13 @@ #define bOFDMContinueTx 0x10000000 #define bOFDMSingleCarrier 0x20000000 #define bOFDMSingleTone 0x40000000 -//#define bRxPath1 0x01 -//#define bRxPath2 0x02 -//#define bRxPath3 0x04 -//#define bRxPath4 0x08 -//#define bTxPath1 0x10 -//#define bTxPath2 0x20 +/* #define bRxPath1 0x01 + * #define bRxPath2 0x02 + * #define bRxPath3 0x04 + * #define bRxPath4 0x08 + * #define bTxPath1 0x10 + * #define bTxPath2 0x20 + */ #define bHTDetect 0x100 #define bCFOEn 0x10000 #define bCFOValue 0xfff00000 @@ -680,8 +685,8 @@ #define bCounter_MCSNoSupport 0xffff #define bCounter_FastSync 0xffff #define bShortCFO 0xfff -#define bShortCFOTLength 12 //total -#define bShortCFOFLength 11 //fraction +#define bShortCFOTLength 12 /* total */ +#define bShortCFOFLength 11 /* fraction */ #define bLongCFO 0x7ff #define bLongCFOTLength 11 #define bLongCFOFLength 11 @@ -758,7 +763,7 @@ #define bUChCfg 0x7000000 #define bUpdEqz 0x8000000 -//page e +/* page e */ #define bTxAGCRate18_06 0x7f7f7f7f #define bTxAGCRate54_24 0x7f7f7f7f #define bTxAGCRateMCS32 0x7f @@ -769,7 +774,7 @@ #define bTxAGCRateMCS15_MCS12 0x7f7f7f7f -//Rx Pseduo noise +/* Rx Pseduo noise */ #define bRxPesudoNoiseOn 0x20000000 #define bRxPesudoNoise_A 0xff #define bRxPesudoNoise_B 0xff00 @@ -780,8 +785,9 @@ #define bPesudoNoiseState_C 0xffff #define bPesudoNoiseState_D 0xffff0000 -//RF -//Zebra1 +/* RF + * Zebra1 + */ #define bZebra1_HSSIEnable 0x8 #define bZebra1_TRxControl 0xc00 #define bZebra1_TRxGainSetting 0x07f @@ -792,18 +798,18 @@ #define bZebra1_TxLPFBW 0x400 #define bZebra1_RxLPFBW 0x600 -//Zebra4 +/* Zebra4 */ #define bRTL8256RegModeCtrl1 0x100 #define bRTL8256RegModeCtrl0 0x40 #define bRTL8256_TxLPFBW 0x18 #define bRTL8256_RxLPFBW 0x600 -//RTL8258 +/* RTL8258 */ #define bRTL8258_TxLPFBW 0xc #define bRTL8258_RxLPFBW 0xc00 #define bRTL8258_RSSILPFBW 0xc0 -//byte endable for sb_write +/* byte endable for sb_write */ #define bByte0 0x1 #define bByte1 0x2 #define bByte2 0x4 @@ -812,7 +818,7 @@ #define bWord1 0xc #define bDWord 0xf -//for PutRegsetting & GetRegSetting BitMask +/* for PutRegsetting & GetRegSetting BitMask */ #define bMaskByte0 0xff #define bMaskByte1 0xff00 #define bMaskByte2 0xff0000 @@ -821,7 +827,7 @@ #define bMaskLWord 0x0000ffff #define bMaskDWord 0xffffffff -//for PutRFRegsetting & GetRFRegSetting BitMask +/* for PutRFRegsetting & GetRFRegSetting BitMask */ #define bMask12Bits 0xfff #define bEnable 0x1 @@ -830,14 +836,14 @@ #define LeftAntenna 0x0 #define RightAntenna 0x1 -#define tCheckTxStatus 500 //500ms -#define tUpdateRxCounter 100 //100ms +#define tCheckTxStatus 500 /* 500ms */ +#define tUpdateRxCounter 100 /* 100ms */ #define rateCCK 0 #define rateOFDM 1 #define rateHT 2 -//define Register-End +/* define Register-End */ #define bPMAC_End 0x1ff #define bFPGAPHY0_End 0x8ff #define bFPGAPHY1_End 0x9ff @@ -845,12 +851,13 @@ #define bOFDMPHY0_End 0xcff #define bOFDMPHY1_End 0xdff -//define max debug item in each debug page -//#define bMaxItem_FPGA_PHY0 0x9 -//#define bMaxItem_FPGA_PHY1 0x3 -//#define bMaxItem_PHY_11B 0x16 -//#define bMaxItem_OFDM_PHY0 0x29 -//#define bMaxItem_OFDM_PHY1 0x0 +/* define max debug item in each debug page + * #define bMaxItem_FPGA_PHY0 0x9 + * #define bMaxItem_FPGA_PHY1 0x3 + * #define bMaxItem_PHY_11B 0x16 + * #define bMaxItem_OFDM_PHY0 0x29 + * #define bMaxItem_OFDM_PHY1 0x0 + */ #define bPMACControl 0x0 #define bWMACControl 0x1 @@ -868,4 +875,4 @@ #define rRTL8256TxBBBW 19 #define bRTL8256TxBBBW 0x18 -#endif //__INC_HAL8190PCIPHYREG_H +#endif /* __INC_HAL8190PCIPHYREG_H */ -- GitLab From effda6973dba27d80a669855603bdc0971f89449 Mon Sep 17 00:00:00 2001 From: Martin Berglund Date: Thu, 7 Aug 2014 23:08:34 +0100 Subject: [PATCH 0561/9167] staging: vt6655: wpactl.c: Fix sparse warnings Add missing __user macro casting in the function wpa_set_keys. This is okay since the function handles the possibility of param->u.wpa_key.key and param->u.wpa_key.seq pointing to kernelspace using a flag, fcpfkernel. Signed-off-by: Martin Berglund Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wpactl.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 5f454ca2a3bc..d75dd797bd9e 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -224,7 +224,9 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, } else { spin_unlock_irq(&pDevice->lock); if (param->u.wpa_key.key && - copy_from_user(&abyKey[0], param->u.wpa_key.key, param->u.wpa_key.key_len)) { + 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; } @@ -262,7 +264,9 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, } else { spin_unlock_irq(&pDevice->lock); if (param->u.wpa_key.seq && - copy_from_user(&abySeq[0], param->u.wpa_key.seq, param->u.wpa_key.seq_len)) { + 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; } -- GitLab From 11a72e5e11429c1598a53bc314765e0ff15da2c7 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sat, 9 Aug 2014 20:15:56 +0100 Subject: [PATCH 0562/9167] staging: vt6655: rxtx: Replace typedef struct tagSMICHDRHead With struct vnt_mic_hdr replacing pointer assigments in s_vFillTxKey. The size of new struture is the same as old with packing Create the struture rxtx.h where it is only used. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/desc.h | 11 ----- drivers/staging/vt6655/rxtx.c | 88 +++++++++++++++++------------------ drivers/staging/vt6655/rxtx.h | 17 +++++++ 3 files changed, 60 insertions(+), 56 deletions(-) diff --git a/drivers/staging/vt6655/desc.h b/drivers/staging/vt6655/desc.h index 05efa4e1b682..d3c9b0c4329f 100644 --- a/drivers/staging/vt6655/desc.h +++ b/drivers/staging/vt6655/desc.h @@ -550,17 +550,6 @@ typedef struct tagSTxDataHead_a_FB { STxDataHead_a_FB, *PSTxDataHead_a_FB; typedef const STxDataHead_a_FB *PCSTxDataHead_a_FB; -// -// MICHDR data header -// -typedef struct tagSMICHDRHead { - u32 adwHDR0[4]; - u32 adwHDR1[4]; - u32 adwHDR2[4]; -} __attribute__ ((__packed__)) -SMICHDRHead, *PSMICHDRHead; -typedef const SMICHDRHead *PCSMICHDRHead; - typedef struct tagSBEACONCtl { u32 BufReady:1; u32 TSF:15; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 0d45aa076fed..0866d9f3f51b 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -196,9 +196,9 @@ s_vFillTxKey( 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); - unsigned short wValue; PS802_11Header pMACHeader = (PS802_11Header)pbyHdrBuf; unsigned long dwRevIVCounter; unsigned char byKeyIndex = 0; @@ -262,40 +262,38 @@ s_vFillTxKey( //Append IV&ExtIV after Mac Header *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - //Fill MICHDR0 - *pMICHDR = 0x59; - *((unsigned char *)(pMICHDR+1)) = 0; // TxPriority - memcpy(pMICHDR+2, &(pMACHeader->abyAddr2[0]), 6); - *((unsigned char *)(pMICHDR+8)) = HIBYTE(HIWORD(pTransmitKey->dwTSC47_16)); - *((unsigned char *)(pMICHDR+9)) = LOBYTE(HIWORD(pTransmitKey->dwTSC47_16)); - *((unsigned char *)(pMICHDR+10)) = HIBYTE(LOWORD(pTransmitKey->dwTSC47_16)); - *((unsigned char *)(pMICHDR+11)) = LOBYTE(LOWORD(pTransmitKey->dwTSC47_16)); - *((unsigned char *)(pMICHDR+12)) = HIBYTE(pTransmitKey->wTSC15_0); - *((unsigned char *)(pMICHDR+13)) = LOBYTE(pTransmitKey->wTSC15_0); - *((unsigned char *)(pMICHDR+14)) = HIBYTE(wPayloadLen); - *((unsigned char *)(pMICHDR+15)) = LOBYTE(wPayloadLen); - - //Fill MICHDR1 - *((unsigned char *)(pMICHDR+16)) = 0; // HLEN[15:8] + /* MICHDR0 */ + mic_hdr->id = 0x59; + mic_hdr->tx_priority = 0; + memcpy(mic_hdr->mic_addr2, pMACHeader->abyAddr2, ETH_ALEN); + + /* 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) - *((unsigned char *)(pMICHDR+17)) = 28; // HLEN[7:0] + mic_hdr->hlen = cpu_to_be16(28); else - *((unsigned char *)(pMICHDR+17)) = 22; // HLEN[7:0] - - wValue = cpu_to_le16(pMACHeader->wFrameCtl & 0xC78F); - memcpy(pMICHDR+18, (unsigned char *)&wValue, 2); // MSKFRACTL - memcpy(pMICHDR+20, &(pMACHeader->abyAddr1[0]), 6); - memcpy(pMICHDR+26, &(pMACHeader->abyAddr2[0]), 6); - - //Fill MICHDR2 - memcpy(pMICHDR+32, &(pMACHeader->abyAddr3[0]), 6); - wValue = pMACHeader->wSeqCtl; - wValue &= 0x000F; - wValue = cpu_to_le16(wValue); - memcpy(pMICHDR+38, (unsigned char *)&wValue, 2); // MSKSEQCTL - if (pDevice->bLongHeader) - memcpy(pMICHDR+40, &(pMACHeader->abyAddr4[0]), 6); + mic_hdr->hlen = cpu_to_be16(22); + memcpy(mic_hdr->addr1, pMACHeader->abyAddr1, ETH_ALEN); + memcpy(mic_hdr->addr2, pMACHeader->abyAddr2, ETH_ALEN); + + /* MICHDR2 */ + memcpy(mic_hdr->addr3, pMACHeader->abyAddr3, ETH_ALEN); + 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); } } @@ -1252,7 +1250,7 @@ s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyT PSTxBufHead psTxBufHd = (PSTxBufHead) pbyTxBufferAddr; unsigned int cbHeaderLength = 0; void *pvRrvTime; - PSMICHDRHead pMICHDR; + struct vnt_mic_hdr *pMICHDR; void *pvRTS; void *pvCTS; void *pvTxDataHd; @@ -1297,7 +1295,7 @@ s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyT if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { cbIVlen = 8;//RSN Header cbICVlen = 8;//MIC - cbMICHDR = sizeof(SMICHDRHead); + cbMICHDR = sizeof(struct vnt_mic_hdr); } if (pDevice->byLocalID > REV_ID_VT3253_A1) { //MAC Header should be padding 0 to DW alignment. @@ -1333,14 +1331,14 @@ s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyT if (byFBOption == AUTO_FB_NONE) { if (bRTS == true) {//RTS_need pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); pvRTS = (PSRTS_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR); pvCTS = NULL; pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g)); cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g) + sizeof(STxDataHead_g); } else { //RTS_needless pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); pvRTS = NULL; pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS)); @@ -1350,14 +1348,14 @@ s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyT // Auto Fall Back if (bRTS == true) {//RTS_need pvRrvTime = (PSRrvTime_gRTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS)); pvRTS = (PSRTS_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR); pvCTS = NULL; pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB)); cbHeaderLength = wTxBufSize + sizeof(SRrvTime_gRTS) + cbMICHDR + sizeof(SRTS_g_FB) + sizeof(STxDataHead_g_FB); } else { //RTS_needless pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); pvRTS = NULL; pvCTS = (PSCTS_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); pvTxDataHd = (PSTxDataHead_g_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS_FB)); @@ -1369,14 +1367,14 @@ s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyT if (byFBOption == AUTO_FB_NONE) { if (bRTS == true) { pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); pvRTS = (PSRTS_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); pvCTS = NULL; pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab)); cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_ab) + sizeof(STxDataHead_ab); } else { //RTS_needless, need MICHDR pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); pvRTS = NULL; pvCTS = NULL; pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); @@ -1386,14 +1384,14 @@ s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyT // Auto Fall Back if (bRTS == true) {//RTS_need pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); pvRTS = (PSRTS_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); pvCTS = NULL; pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB)); cbHeaderLength = wTxBufSize + sizeof(PSRrvTime_ab) + cbMICHDR + sizeof(SRTS_a_FB) + sizeof(STxDataHead_a_FB); } else { //RTS_needless pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); pvRTS = NULL; pvCTS = NULL; pvTxDataHd = (PSTxDataHead_a_FB) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); @@ -2656,7 +2654,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un } else if (pDevice->eEncryptionStatus == Ndis802_11Encryption3Enabled) { cbIVlen = 8;//RSN Header cbICVlen = 8;//MIC - cbMICHDR = sizeof(SMICHDRHead); + cbMICHDR = sizeof(struct vnt_mic_hdr); pTxBufHead->wFragCtl |= FRAGCTL_AES; pDevice->bAES = true; } @@ -2676,7 +2674,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) {//802.11g packet pvRrvTime = (PSRrvTime_gCTS) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); + pMICHDR = (struct vnt_mic_hdr *)(pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS)); pvRTS = NULL; pvCTS = (PSCTS) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR); pvTxDataHd = (PSTxDataHead_g) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_gCTS) + cbMICHDR + sizeof(SCTS)); @@ -2685,7 +2683,7 @@ vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, un } else {//802.11a/b packet pvRrvTime = (PSRrvTime_ab) (pbyTxBufferAddr + wTxBufSize); - pMICHDR = (PSMICHDRHead) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); + pMICHDR = (struct vnt_mic_hdr *) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab)); pvRTS = NULL; pvCTS = NULL; pvTxDataHd = (PSTxDataHead_ab) (pbyTxBufferAddr + wTxBufSize + sizeof(SRrvTime_ab) + cbMICHDR); diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index 601bedb211d6..a9a8edec1c4b 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -39,6 +39,23 @@ /*--------------------- Export Functions --------------------------*/ +/* MIC HDR data header */ +struct vnt_mic_hdr { + u8 id; + u8 tx_priority; + u8 mic_addr2[ETH_ALEN]; + u8 ccmp_pn[6]; + __be16 payload_len; + __be16 hlen; + __le16 frame_control; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctrl; + u8 addr4[ETH_ALEN]; + u16 packing; /* packing to 48 bytes */ +} __packed; + void vGenerateMACHeader( PSDevice pDevice, -- GitLab From f2af99ee5bca2eccc2d61bfee0ad82c84af18f8f Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 12:21:56 +0100 Subject: [PATCH 0563/9167] staging: vt6655: Remove TxInSleep macro TxInSleep is always enabled remove the macro and any else code. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 2 -- drivers/staging/vt6655/device_main.c | 6 ++---- drivers/staging/vt6655/power.c | 6 +----- drivers/staging/vt6655/rxtx.c | 2 -- drivers/staging/vt6655/ttype.h | 4 ---- drivers/staging/vt6655/wcmd.c | 5 +---- drivers/staging/vt6655/wcmd.h | 3 +-- drivers/staging/vt6655/wmgr.c | 2 -- 8 files changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 9bf0ea9af66e..b857881e52e5 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -643,12 +643,10 @@ typedef struct __device_info { // command timer struct timer_list sTimerCommand; -#ifdef TxInSleep struct timer_list sTimerTxData; unsigned long nTxDataTimeCout; bool fTxDataInSleep; bool IsTxDataTrigger; -#endif #ifdef WPA_SM_Transtatus bool fWPA_Authened; //is WPA/WPA-PSK or WPA2/WPA2-PSK authen?? diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 0b583a37f5b3..3896eb325961 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -1720,9 +1720,8 @@ static int device_close(struct net_device *dev) bScheduleCommand((void *)pDevice, WLAN_CMD_DISASSOCIATE, NULL); mdelay(30); } -#ifdef TxInSleep + del_timer(&pDevice->sTimerTxData); -#endif del_timer(&pDevice->sTimerCommand); del_timer(&pMgmt->sTimerSecondCallback); if (pDevice->bDiversityRegCtlON) { @@ -2232,9 +2231,8 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) pLastTD->pTDInfo->skb = skb; pLastTD->pTDInfo->byFlags = 0; pLastTD->pTDInfo->byFlags |= TD_FLAGS_NETIF_SKB; -#ifdef TxInSleep pDevice->nTxDataTimeCout = 0; //2008-8-21 chester for send null packet -#endif + if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 1) netif_stop_queue(dev); diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index 2a21cbd1c6ac..f08c26fbb10f 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -274,13 +274,9 @@ PSbSendNullPacket( if (!pDevice->bLinkPass) return false; -#ifdef TxInSleep if (!pDevice->bEnablePSMode && !pDevice->fTxDataInSleep) return false; -#else - if (!pDevice->bEnablePSMode) - return false; -#endif + if (pDevice->bEnablePSMode) { for (uIdx = 0; uIdx < TYPE_MAXTD; uIdx++) { if (pDevice->iTDUsed[uIdx] != 0) diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 0866d9f3f51b..2270e2ac0878 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -2326,9 +2326,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; -#ifdef TxInSleep pDevice->nTxDataTimeCout = 0; //2008-8-21 chester for send null packet -#endif // Poll Transmit the adapter MACvTransmit0(pDevice->PortOffset); diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h index b1d8ae732774..3f3a768ed95c 100644 --- a/drivers/staging/vt6655/ttype.h +++ b/drivers/staging/vt6655/ttype.h @@ -31,10 +31,6 @@ /******* Common definitions and typedefs ***********************************/ -#ifndef TxInSleep -#define TxInSleep -#endif - #ifndef WPA_SM_Transtatus #define WPA_SM_Transtatus #endif diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index f12eef064c45..16ed097b1467 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -647,7 +647,6 @@ vCommandTimer( if (netif_queue_stopped(pDevice->dev)) netif_wake_queue(pDevice->dev); -#ifdef TxInSleep if (pDevice->IsTxDataTrigger) { //TxDataTimer is not triggered at the first time del_timer(&pDevice->sTimerTxData); init_timer(&pDevice->sTimerTxData); @@ -660,7 +659,7 @@ vCommandTimer( pDevice->IsTxDataTrigger = true; add_timer(&pDevice->sTimerTxData); -#endif + } else if (pMgmt->eCurrState < WMAC_STATE_ASSOCPENDING) { printk("WLAN_ASSOCIATE_WAIT:Association Fail???\n"); } else if (pDevice->byLinkWaitCount <= 4) { //mike add:wait another 2 sec if associated_frame delay! @@ -984,7 +983,6 @@ vResetCommandTimer( pDevice->bCmdClear = false; } -#ifdef TxInSleep void BSSvSecondTxData( void *hDeviceContext @@ -1019,4 +1017,3 @@ BSSvSecondTxData( add_timer(&pDevice->sTimerTxData); return; } -#endif diff --git a/drivers/staging/vt6655/wcmd.h b/drivers/staging/vt6655/wcmd.h index 126b61c48791..6ef04de69f37 100644 --- a/drivers/staging/vt6655/wcmd.h +++ b/drivers/staging/vt6655/wcmd.h @@ -114,11 +114,10 @@ vCommandTimerWait( void *hDeviceContext, unsigned int MSecond ); -#ifdef TxInSleep + void BSSvSecondTxData( void *hDeviceContext ); -#endif #endif //__WCMD_H__ diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index e88e11606db0..3b9819e4aa4d 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -388,7 +388,6 @@ vMgrTimerInit( pDevice->sTimerCommand.function = (TimerFunction)vCommandTimer; pDevice->sTimerCommand.expires = RUN_AT(HZ); -#ifdef TxInSleep init_timer(&pDevice->sTimerTxData); pDevice->sTimerTxData.data = (unsigned long) pDevice; pDevice->sTimerTxData.function = (TimerFunction)BSSvSecondTxData; @@ -396,7 +395,6 @@ vMgrTimerInit( pDevice->fTxDataInSleep = false; pDevice->IsTxDataTrigger = false; pDevice->nTxDataTimeCout = 0; -#endif pDevice->cbFreeCmdQueue = CMD_Q_SIZE; pDevice->uCmdDequeueIdx = 0; -- GitLab From c98323a7da3cf3625c37743974d007a1fe6539a5 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 12:21:57 +0100 Subject: [PATCH 0564/9167] staging: vt6655: BSSvSecondTxData remove #if 1 else directive There is a code alignment error after this directive realign code Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/wcmd.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 16ed097b1467..b7e68a08a8a0 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -1001,19 +1001,17 @@ BSSvSecondTxData( } spin_lock_irq(&pDevice->lock); -#if 1 - if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || //open && sharekey linking - pDevice->fWPA_Authened) { //wpa linking -#else - if (pDevice->bLinkPass == true) { -#endif - pDevice->fTxDataInSleep = true; - PSbSendNullPacket(pDevice); //send null packet - pDevice->fTxDataInSleep = false; - } - spin_unlock_irq(&pDevice->lock); - pDevice->sTimerTxData.expires = RUN_AT(10*HZ); //10s callback - add_timer(&pDevice->sTimerTxData); - return; + /* open && sharekey linking */ + if ((pDevice->bLinkPass && (pMgmt->eAuthenMode < WMAC_AUTH_WPA)) || + pDevice->fWPA_Authened) { /* wpa linking */ + pDevice->fTxDataInSleep = true; + PSbSendNullPacket(pDevice); /* send null packet */ + pDevice->fTxDataInSleep = false; } + + spin_unlock_irq(&pDevice->lock); + + pDevice->sTimerTxData.expires = RUN_AT(10*HZ); /* 10s callback */ + add_timer(&pDevice->sTimerTxData); +} -- GitLab From 0fc2a76eef05ee1aa82b3d9bf34eea2b50f5e1ba Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 12:21:58 +0100 Subject: [PATCH 0565/9167] staging: vt6655: Replace and remove typedef QWORD/ DQWORD Replace the variables with u64/__le64. The endian variant is needed in some places endian correction is needed. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211mgr.c | 8 +-- drivers/staging/vt6655/80211mgr.h | 6 +- drivers/staging/vt6655/bssdb.c | 10 ++- drivers/staging/vt6655/bssdb.h | 8 +-- drivers/staging/vt6655/card.c | 116 ++++++++++++------------------ drivers/staging/vt6655/card.h | 10 +-- drivers/staging/vt6655/device.h | 2 +- drivers/staging/vt6655/dpc.c | 9 ++- drivers/staging/vt6655/hostap.c | 10 +-- drivers/staging/vt6655/key.c | 22 +++--- drivers/staging/vt6655/key.h | 8 +-- drivers/staging/vt6655/ttype.h | 23 ------ drivers/staging/vt6655/wmgr.c | 40 ++++------- drivers/staging/vt6655/wmgr.h | 2 +- drivers/staging/vt6655/wpactl.c | 12 ++-- 15 files changed, 114 insertions(+), 172 deletions(-) diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c index 96b0d61623e4..2c1fd82e8e85 100644 --- a/drivers/staging/vt6655/80211mgr.c +++ b/drivers/staging/vt6655/80211mgr.c @@ -91,7 +91,7 @@ vMgrEncodeBeacon( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pqwTimestamp = (PQWORD) + pFrame->pqwTimestamp = (__le64 *) (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_BEACON_OFF_TS); pFrame->pwBeaconInterval = (unsigned short *) @@ -125,7 +125,7 @@ vMgrDecodeBeacon( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pqwTimestamp = (PQWORD) + pFrame->pqwTimestamp = (__le64 *) (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_BEACON_OFF_TS); pFrame->pwBeaconInterval = (unsigned short *) @@ -695,7 +695,7 @@ vMgrEncodeProbeResponse( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pqwTimestamp = (PQWORD) + pFrame->pqwTimestamp = (__le64 *) (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_TS); pFrame->pwBeaconInterval = (unsigned short *) @@ -730,7 +730,7 @@ vMgrDecodeProbeResponse( pFrame->pHdr = (PUWLAN_80211HDR)pFrame->pBuf; /* Fixed Fields */ - pFrame->pqwTimestamp = (PQWORD) + pFrame->pqwTimestamp = (__le64 *) (WLAN_HDR_A3_DATA_PTR(&(pFrame->pHdr->sA3)) + WLAN_PROBERESP_OFF_TS); pFrame->pwBeaconInterval = (unsigned short *) diff --git a/drivers/staging/vt6655/80211mgr.h b/drivers/staging/vt6655/80211mgr.h index 8b126bbd9fa5..94fb93d54bfd 100644 --- a/drivers/staging/vt6655/80211mgr.h +++ b/drivers/staging/vt6655/80211mgr.h @@ -31,6 +31,8 @@ #ifndef __80211MGR_H__ #define __80211MGR_H__ +#include + #include "ttype.h" #include "80211hdr.h" @@ -464,7 +466,7 @@ typedef struct tagWLAN_FR_BEACON { unsigned int len; unsigned char *pBuf; PUWLAN_80211HDR pHdr; - PQWORD pqwTimestamp; + __le64 *pqwTimestamp; unsigned short *pwBeaconInterval; unsigned short *pwCapInfo; PWLAN_IE_SSID pSSID; @@ -577,7 +579,7 @@ typedef struct tagWLAN_FR_PROBERESP { unsigned int len; unsigned char *pBuf; PUWLAN_80211HDR pHdr; - PQWORD pqwTimestamp; + __le64 *pqwTimestamp; unsigned short *pwBeaconInterval; unsigned short *pwCapInfo; PWLAN_IE_SSID pSSID; diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index 9569f43a3ed7..0d6b27ebae5c 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -316,7 +316,7 @@ bool BSSbInsertToBSSList( void *hDeviceContext, unsigned char *abyBSSIDAddr, - QWORD qwTimestamp, + __le64 qwTimestamp, unsigned short wBeaconInterval, unsigned short wCapInfo, unsigned char byCurrChannel, @@ -356,8 +356,7 @@ BSSbInsertToBSSList( /* save the BSS info */ pBSSList->bActive = true; memcpy(pBSSList->abyBSSID, abyBSSIDAddr, WLAN_BSSID_LEN); - HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp)); - LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp)); + pBSSList->qwBSSTimestamp = le64_to_cpu(qwTimestamp); pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); pBSSList->wCapInfo = cpu_to_le16(wCapInfo); pBSSList->uClearCount = 0; @@ -521,7 +520,7 @@ BSSbInsertToBSSList( bool BSSbUpdateToBSSList( void *hDeviceContext, - QWORD qwTimestamp, + __le64 qwTimestamp, unsigned short wBeaconInterval, unsigned short wCapInfo, unsigned char byCurrChannel, @@ -551,8 +550,7 @@ BSSbUpdateToBSSList( if (pBSSList == NULL) return false; - HIDWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(HIDWORD(qwTimestamp)); - LODWORD(pBSSList->qwBSSTimestamp) = cpu_to_le32(LODWORD(qwTimestamp)); + pBSSList->qwBSSTimestamp = le64_to_cpu(qwTimestamp); pBSSList->wBeaconInterval = cpu_to_le16(wBeaconInterval); pBSSList->wCapInfo = cpu_to_le16(wCapInfo); pBSSList->uClearCount = 0; diff --git a/drivers/staging/vt6655/bssdb.h b/drivers/staging/vt6655/bssdb.h index bf299e3b8acf..5d4dd28b6223 100644 --- a/drivers/staging/vt6655/bssdb.h +++ b/drivers/staging/vt6655/bssdb.h @@ -131,8 +131,8 @@ typedef struct tagKnownBSS { unsigned int uClearCount; unsigned int uIELength; - QWORD qwBSSTimestamp; - QWORD qwLocalTSF; + u64 qwBSSTimestamp; + u64 qwLocalTSF; CARD_PHY_TYPE eNetworkTypeInUse; @@ -233,7 +233,7 @@ bool BSSbInsertToBSSList( void *hDeviceContext, unsigned char *abyBSSIDAddr, - QWORD qwTimestamp, + __le64 qwTimestamp, unsigned short wBeaconInterval, unsigned short wCapInfo, unsigned char byCurrChannel, @@ -253,7 +253,7 @@ BSSbInsertToBSSList( bool BSSbUpdateToBSSList( void *hDeviceContext, - QWORD qwTimestamp, + __le64 qwTimestamp, unsigned short wBeaconInterval, unsigned short wCapInfo, unsigned char byCurrChannel, diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 4ae8d9362edf..5295463cb2bd 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -573,21 +573,17 @@ bool CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned * Return Value: none * */ -bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF) +bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, u64 qwBSSTimestamp, u64 qwLocalTSF) { PSDevice pDevice = (PSDevice) pDeviceHandler; - QWORD qwTSFOffset; + u64 qwTSFOffset = 0; - HIDWORD(qwTSFOffset) = 0; - LODWORD(qwTSFOffset) = 0; - - if ((HIDWORD(qwBSSTimestamp) != HIDWORD(qwLocalTSF)) || - (LODWORD(qwBSSTimestamp) != LODWORD(qwLocalTSF))) { + if (qwBSSTimestamp != qwLocalTSF) { qwTSFOffset = CARDqGetTSFOffset(byRxRate, qwBSSTimestamp, qwLocalTSF); // adjust TSF // HW's TSF add TSF Offset reg - VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST, LODWORD(qwTSFOffset)); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_TSFOFST + 4, HIDWORD(qwTSFOffset)); + 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); } return true; @@ -614,33 +610,32 @@ bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval) unsigned int uLowNextTBTT = 0; unsigned int uHighRemain = 0; unsigned int uLowRemain = 0; - QWORD qwNextTBTT; + u64 qwNextTBTT = 0; - HIDWORD(qwNextTBTT) = 0; - LODWORD(qwNextTBTT) = 0; CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter uBeaconInterval = wBeaconInterval * 1024; // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval - uLowNextTBTT = (LODWORD(qwNextTBTT) >> 10) << 10; + uLowNextTBTT = ((qwNextTBTT & 0xffffffffULL) >> 10) << 10; uLowRemain = (uLowNextTBTT) % uBeaconInterval; // high dword (mod) bcn - uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwNextTBTT)) + uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * (u32)(qwNextTBTT >> 32)) % uBeaconInterval; uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval; uLowRemain = uBeaconInterval - uLowRemain; // check if carry when add one beacon interval if ((~uLowNextTBTT) < uLowRemain) - HIDWORD(qwNextTBTT)++; + qwNextTBTT = ((qwNextTBTT >> 32) + 1) << 32; - LODWORD(qwNextTBTT) = uLowNextTBTT + uLowRemain; + qwNextTBTT = (qwNextTBTT & 0xffffffff00000000ULL) | + (u64)(uLowNextTBTT + uLowRemain); // set HW beacon interval VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, wBeaconInterval); pDevice->wBeaconInterval = wBeaconInterval; // Set NextTBTT - VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT)); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT)); + 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); return true; @@ -1077,8 +1072,8 @@ CARDbStartMeasure( { PSDevice pDevice = (PSDevice) pDeviceHandler; PWLAN_IE_MEASURE_REQ pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs; - QWORD qwCurrTSF; - QWORD qwStartTSF; + u64 qwCurrTSF; + u64 qwStartTSF; bool bExpired = true; unsigned short wDuration = 0; @@ -1109,32 +1104,22 @@ CARDbStartMeasure( pDevice->uNumOfMeasureEIDs--; if (pDevice->byLocalID > REV_ID_VT3253_B1) { - HIDWORD(qwStartTSF) = HIDWORD(*((PQWORD)(pDevice->pCurrMeasureEID->sReq.abyStartTime))); - LODWORD(qwStartTSF) = LODWORD(*((PQWORD)(pDevice->pCurrMeasureEID->sReq.abyStartTime))); + qwStartTSF = *((u64 *)(pDevice->pCurrMeasureEID->sReq.abyStartTime)); wDuration = *((unsigned short *)(pDevice->pCurrMeasureEID->sReq.abyDuration)); wDuration += 1; // 1 TU for channel switching - if ((LODWORD(qwStartTSF) == 0) && (HIDWORD(qwStartTSF) == 0)) { + if (qwStartTSF == 0) { // start immediately by setting start TSF == current TSF + 2 TU - LODWORD(qwStartTSF) = LODWORD(qwCurrTSF) + 2048; - HIDWORD(qwStartTSF) = HIDWORD(qwCurrTSF); - if (LODWORD(qwCurrTSF) > LODWORD(qwStartTSF)) - HIDWORD(qwStartTSF)++; + qwStartTSF = qwCurrTSF + 2048; bExpired = false; break; } else { // start at setting start TSF - 1TU(for channel switching) - if (LODWORD(qwStartTSF) < 1024) - HIDWORD(qwStartTSF)--; - - LODWORD(qwStartTSF) -= 1024; + qwStartTSF -= 1024; } - if ((HIDWORD(qwCurrTSF) < HIDWORD(qwStartTSF)) || - ((HIDWORD(qwCurrTSF) == HIDWORD(qwStartTSF)) && - (LODWORD(qwCurrTSF) < LODWORD(qwStartTSF))) -) { + if (qwCurrTSF < qwStartTSF) { bExpired = false; break; } @@ -1161,8 +1146,8 @@ CARDbStartMeasure( if (!bExpired) { MACvSelectPage1(pDevice->PortOffset); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART, LODWORD(qwStartTSF)); - VNSvOutPortD(pDevice->PortOffset + MAC_REG_MSRSTART + 4, HIDWORD(qwStartTSF)); + 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); @@ -1948,25 +1933,17 @@ bool CARDbSoftwareReset(void *pDeviceHandler) * Return Value: TSF Offset value * */ -QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2) +u64 CARDqGetTSFOffset(unsigned char byRxRate, u64 qwTSF1, u64 qwTSF2) { - QWORD qwTSFOffset; + u64 qwTSFOffset = 0; unsigned short wRxBcnTSFOffst = 0; - HIDWORD(qwTSFOffset) = 0; - LODWORD(qwTSFOffset) = 0; wRxBcnTSFOffst = cwRXBCNTSFOff[byRxRate%MAX_RATE]; - (qwTSF2).u.dwLowDword += (unsigned long)(wRxBcnTSFOffst); - if ((qwTSF2).u.dwLowDword < (unsigned long)(wRxBcnTSFOffst)) - (qwTSF2).u.dwHighDword++; - - LODWORD(qwTSFOffset) = LODWORD(qwTSF1) - LODWORD(qwTSF2); - if (LODWORD(qwTSF1) < LODWORD(qwTSF2)) { - // if borrow needed - HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2) - 1; - } else { - HIDWORD(qwTSFOffset) = HIDWORD(qwTSF1) - HIDWORD(qwTSF2); - } + + qwTSF2 += (u64)wRxBcnTSFOffst; + + qwTSFOffset = qwTSF1 - qwTSF2; + return qwTSFOffset; } @@ -1983,7 +1960,7 @@ QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2) * Return Value: true if success; otherwise false * */ -bool CARDbGetCurrentTSF(void __iomem *dwIoBase, PQWORD pqwCurrTSF) +bool CARDbGetCurrentTSF(void __iomem *dwIoBase, u64 *pqwCurrTSF) { unsigned short ww; unsigned char byData; @@ -1996,8 +1973,8 @@ bool CARDbGetCurrentTSF(void __iomem *dwIoBase, PQWORD pqwCurrTSF) } if (ww == W_MAX_TIMEOUT) return false; - VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, &LODWORD(*pqwCurrTSF)); - VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, &HIDWORD(*pqwCurrTSF)); + VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR, (u32 *)pqwCurrTSF); + VNSvInPortD(dwIoBase + MAC_REG_TSFCNTR + 4, (u32 *)pqwCurrTSF + 1); return true; } @@ -2016,7 +1993,7 @@ bool CARDbGetCurrentTSF(void __iomem *dwIoBase, PQWORD pqwCurrTSF) * Return Value: TSF value of next Beacon * */ -QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval) +u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) { unsigned int uLowNextTBTT; unsigned int uHighRemain, uLowRemain; @@ -2024,20 +2001,21 @@ QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval) uBeaconInterval = wBeaconInterval * 1024; // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval - uLowNextTBTT = (LODWORD(qwTSF) >> 10) << 10; + uLowNextTBTT = ((qwTSF & 0xffffffffULL) >> 10) << 10; // low dword (mod) bcn uLowRemain = (uLowNextTBTT) % uBeaconInterval; // high dword (mod) bcn - uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * HIDWORD(qwTSF)) + uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * (u32)(qwTSF >> 32)) % uBeaconInterval; uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval; uLowRemain = uBeaconInterval - uLowRemain; // check if carry when add one beacon interval if ((~uLowNextTBTT) < uLowRemain) - HIDWORD(qwTSF)++; + qwTSF = ((qwTSF >> 32) + 1) << 32; - LODWORD(qwTSF) = uLowNextTBTT + uLowRemain; + qwTSF = (qwTSF & 0xffffffff00000000ULL) | + (u64)(uLowNextTBTT + uLowRemain); return qwTSF; } @@ -2058,15 +2036,14 @@ QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval) */ void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterval) { - QWORD qwNextTBTT; + u64 qwNextTBTT = 0; - HIDWORD(qwNextTBTT) = 0; - LODWORD(qwNextTBTT) = 0; CARDbGetCurrentTSF(dwIoBase, &qwNextTBTT); //Get Local TSF counter + qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); // Set NextTBTT - VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwNextTBTT)); - VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwNextTBTT)); + VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwNextTBTT); + VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwNextTBTT >> 32)); MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); } @@ -2085,13 +2062,12 @@ void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterva * Return Value: none * */ -void CARDvUpdateNextTBTT(void __iomem *dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval) +void CARDvUpdateNextTBTT(void __iomem *dwIoBase, u64 qwTSF, unsigned short wBeaconInterval) { qwTSF = CARDqGetNextTBTT(qwTSF, wBeaconInterval); // Set NextTBTT - VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, LODWORD(qwTSF)); - VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, HIDWORD(qwTSF)); + VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwTSF); + VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32)); MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:Update Next TBTT[%8xh:%8xh]\n", - (unsigned int) HIDWORD(qwTSF), (unsigned int) LODWORD(qwTSF)); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:Update Next TBTT[%8llx]\n", qwTSF); } diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 2f1a05ef44a1..6e3698bca86a 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -85,10 +85,10 @@ bool CARDbIsOFDMinBasicRate(void *pDeviceHandler); void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode); bool CARDbSoftwareReset(void *pDeviceHandler); void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterval); -void CARDvUpdateNextTBTT(void __iomem *dwIoBase, QWORD qwTSF, unsigned short wBeaconInterval); -bool CARDbGetCurrentTSF(void __iomem *dwIoBase, PQWORD pqwCurrTSF); -QWORD CARDqGetNextTBTT(QWORD qwTSF, unsigned short wBeaconInterval); -QWORD CARDqGetTSFOffset(unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2); +void CARDvUpdateNextTBTT(void __iomem *dwIoBase, u64 qwTSF, unsigned short wBeaconInterval); +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(void *pDeviceHandler, unsigned long ulTxPower); unsigned char CARDbyGetPktType(void *pDeviceHandler); void CARDvSafeResetTx(void *pDeviceHandler); @@ -99,7 +99,7 @@ bool CARDbRadioPowerOn(void *pDeviceHandler); bool CARDbIsShortPreamble(void *pDeviceHandler); bool CARDbIsShorSlotTime(void *pDeviceHandler); bool CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs); -bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, QWORD qwBSSTimestamp, QWORD qwLocalTSF); +bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, u64 qwBSSTimestamp, u64 qwLocalTSF); bool CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType); bool CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType); bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval); diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index b857881e52e5..96d14da2b036 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -566,7 +566,7 @@ typedef struct __device_info { SKeyManagement sKey; unsigned long dwIVCounter; - QWORD qwPacketNumber; //For CCMP and TKIP as TSC(6 bytes) + u64 qwPacketNumber; /* For CCMP and TKIP as TSC(6 bytes) */ unsigned int uCurrentWEPMode; RC4Ext SBox; diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 0bcf6c7472fe..449741989912 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -283,7 +283,7 @@ device_receive_frame( unsigned char *pbyRsr; unsigned char *pbyNewRsr; unsigned char *pbyRSSI; - PQWORD pqwTSFTime; + __le64 *pqwTSFTime; unsigned short *pwFrameSize; unsigned char *pbyFrame; bool bDeFragRx = false; @@ -334,7 +334,7 @@ device_receive_frame( pbyRSSI = (unsigned char *)(skb->data + FrameSize - 2); pbyNewRsr = (unsigned char *)(skb->data + FrameSize - 3); pbySQ = (unsigned char *)(skb->data + FrameSize - 4); - pqwTSFTime = (PQWORD)(skb->data + FrameSize - 12); + pqwTSFTime = (__le64 *)(skb->data + FrameSize - 12); pbyFrame = (unsigned char *)(skb->data + 4); // get packet size @@ -515,8 +515,7 @@ device_receive_frame( pRxPacket->cbMPDULen = FrameSize; pRxPacket->uRSSI = *pbyRSSI; pRxPacket->bySQ = *pbySQ; - HIDWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(HIDWORD(*pqwTSFTime)); - LODWORD(pRxPacket->qwLocalTSF) = cpu_to_le32(LODWORD(*pqwTSFTime)); + pRxPacket->qwLocalTSF = le64_to_cpu(*pqwTSFTime); if (bIsWEP) { // strip IV pbyData1 = WLAN_HDR_A3_DATA_PTR(skb->data+4); @@ -796,7 +795,7 @@ device_receive_frame( RSC = dwRxTSC47_16; RSC <<= 16; RSC += wRxTSC15_0; - memcpy(&(pKey->KeyRSC), &RSC, sizeof(QWORD)); + pKey->KeyRSC = RSC; if ((pDevice->sMgmtObj.eCurrMode == WMAC_MODE_ESS_STA) && (pDevice->sMgmtObj.eCurrState == WMAC_STATE_ASSOC)) { diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index f105c2ac091b..29e8eb39c350 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -417,7 +417,7 @@ static int hostap_set_encryption(PSDevice pDevice, unsigned long dwKeyIndex = 0; unsigned char abyKey[MAX_KEY_LEN]; unsigned char abySeq[MAX_KEY_LEN]; - unsigned long long KeyRSC; + u64 KeyRSC; unsigned char byKeyDecMode = KEY_CTL_WEP; int iNodeIndex = -1; int ii; @@ -509,7 +509,7 @@ static int hostap_set_encryption(PSDevice pDevice, ¶m->sta_addr[0], dwKeyIndex & ~(USE_KEYRSC), param->u.crypt.key_len, - (PQWORD) &(KeyRSC), + (u64 *) &KeyRSC, (unsigned char *)abyKey, KEY_CTL_WEP, pDevice->PortOffset, @@ -534,7 +534,7 @@ static int hostap_set_encryption(PSDevice pDevice, if (param->u.crypt.seq) { memcpy(&abySeq, param->u.crypt.seq, 8); for (ii = 0; ii < 8; ii++) - KeyRSC |= (unsigned long)abySeq[ii] << (ii * 8); + KeyRSC |= (u64)abySeq[ii] << (ii * 8); dwKeyIndex |= 1 << 29; pMgmt->sNodeDBTable[iNodeIndex].KeyRSC = KeyRSC; @@ -563,7 +563,7 @@ static int hostap_set_encryption(PSDevice pDevice, KeybSetDefaultKey(&(pDevice->sKey), dwKeyIndex, param->u.crypt.key_len, - (PQWORD) &(KeyRSC), + (u64 *) &KeyRSC, abyKey, byKeyDecMode, pDevice->PortOffset, @@ -576,7 +576,7 @@ static int hostap_set_encryption(PSDevice pDevice, ¶m->sta_addr[0], dwKeyIndex, param->u.crypt.key_len, - (PQWORD) &(KeyRSC), + (u64 *) &KeyRSC, (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 9339e2a4073a..19037908097d 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -184,7 +184,7 @@ bool KeybSetKey( unsigned char *pbyBSSID, unsigned long dwKeyIndex, unsigned long uKeyLength, - PQWORD pKeyRSC, + u64 *pKeyRSC, unsigned char *pbyKey, unsigned char byKeyDecMode, void __iomem *dwIoBase, @@ -245,9 +245,9 @@ bool KeybSetKey( if ((dwKeyIndex & USE_KEYRSC) == 0) { // RSC set by NIC - memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); + pKey->KeyRSC = 0; } else { - memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); + pKey->KeyRSC = *pKeyRSC; } pKey->dwTSC47_16 = 0; pKey->wTSC15_0 = 0; @@ -308,9 +308,9 @@ bool KeybSetKey( if ((dwKeyIndex & USE_KEYRSC) == 0) { // RSC set by NIC - memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); + pKey->KeyRSC = 0; } else { - memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); + pKey->KeyRSC = *pKeyRSC; } pKey->dwTSC47_16 = 0; pKey->wTSC15_0 = 0; @@ -606,7 +606,7 @@ bool KeybSetDefaultKey( PSKeyManagement pTable, unsigned long dwKeyIndex, unsigned long uKeyLength, - PQWORD pKeyRSC, + u64 *pKeyRSC, unsigned char *pbyKey, unsigned char byKeyDecMode, void __iomem *dwIoBase, @@ -669,9 +669,9 @@ bool KeybSetDefaultKey( if ((dwKeyIndex & USE_KEYRSC) == 0) { // RSC set by NIC - memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); + pKey->KeyRSC = 0; } else { - memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); + pKey->KeyRSC = *pKeyRSC; } pKey->dwTSC47_16 = 0; pKey->wTSC15_0 = 0; @@ -712,7 +712,7 @@ bool KeybSetAllGroupKey( PSKeyManagement pTable, unsigned long dwKeyIndex, unsigned long uKeyLength, - PQWORD pKeyRSC, + u64 *pKeyRSC, unsigned char *pbyKey, unsigned char byKeyDecMode, void __iomem *dwIoBase, @@ -764,9 +764,9 @@ bool KeybSetAllGroupKey( if ((dwKeyIndex & USE_KEYRSC) == 0) { // RSC set by NIC - memset(&(pKey->KeyRSC), 0, sizeof(QWORD)); + pKey->KeyRSC = 0; } else { - memcpy(&(pKey->KeyRSC), pKeyRSC, sizeof(QWORD)); + pKey->KeyRSC = *pKeyRSC; } pKey->dwTSC47_16 = 0; pKey->wTSC15_0 = 0; diff --git a/drivers/staging/vt6655/key.h b/drivers/staging/vt6655/key.h index 3eb881b69a55..44efe18315af 100644 --- a/drivers/staging/vt6655/key.h +++ b/drivers/staging/vt6655/key.h @@ -57,7 +57,7 @@ typedef struct tagSKeyItem { bool bKeyValid; unsigned long uKeyLength; unsigned char abyKey[MAX_KEY_LEN]; - QWORD KeyRSC; + u64 KeyRSC; unsigned long dwTSC47_16; unsigned short wTSC15_0; unsigned char byCipherSuite; @@ -108,7 +108,7 @@ bool KeybSetKey( unsigned char *pbyBSSID, unsigned long dwKeyIndex, unsigned long uKeyLength, - PQWORD pKeyRSC, + u64 *pKeyRSC, unsigned char *pbyKey, unsigned char byKeyDecMode, void __iomem *dwIoBase, @@ -119,7 +119,7 @@ bool KeybSetDefaultKey( PSKeyManagement pTable, unsigned long dwKeyIndex, unsigned long uKeyLength, - PQWORD pKeyRSC, + u64 *pKeyRSC, unsigned char *pbyKey, unsigned char byKeyDecMode, void __iomem *dwIoBase, @@ -166,7 +166,7 @@ bool KeybSetAllGroupKey( PSKeyManagement pTable, unsigned long dwKeyIndex, unsigned long uKeyLength, - PQWORD pKeyRSC, + u64 *pKeyRSC, unsigned char *pbyKey, unsigned char byKeyDecMode, void __iomem *dwIoBase, diff --git a/drivers/staging/vt6655/ttype.h b/drivers/staging/vt6655/ttype.h index 3f3a768ed95c..747ef62ec9be 100644 --- a/drivers/staging/vt6655/ttype.h +++ b/drivers/staging/vt6655/ttype.h @@ -39,27 +39,4 @@ #define Calcu_LinkQual #endif -/****** Simple typedefs ***************************************************/ - -/* These lines assume that your compiler's longs are 32 bits and - * shorts are 16 bits. It is already assumed that chars are 8 bits, - * but it doesn't matter if they're signed or unsigned. - */ - -// QWORD is for those situation that we want -// an 8-byte-aligned 8 byte long structure -// which is NOT really a floating point number. -typedef union tagUQuadWord { - struct { - unsigned int dwLowDword; - unsigned int dwHighDword; - } u; - double DoNotUseThisField; -} UQuadWord; -typedef UQuadWord QWORD; // 64-bit - -/****** Common pointer types ***********************************************/ - -typedef QWORD *PQWORD; - #endif // __TTYPE_H__ diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index 3b9819e4aa4d..79ba37baeb13 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -1721,7 +1721,7 @@ s_vMgrRxBeacon( { PKnownBSS pBSSList; WLAN_FR_BEACON sFrame; - QWORD qwTSFOffset; + u64 qwTSFOffset; bool bIsBSSIDEqual = false; bool bIsSSIDEqual = false; bool bTSFLargeDiff = false; @@ -1733,8 +1733,8 @@ s_vMgrRxBeacon( unsigned char byTIMBitOn = 0; unsigned short wAIDNumber = 0; unsigned int uNodeIndex; - QWORD qwTimestamp, qwLocalTSF; - QWORD qwCurrTSF; + u64 qwTimestamp, qwLocalTSF; + u64 qwCurrTSF; unsigned short wStartIndex = 0; unsigned short wAIDIndex = 0; unsigned char byCurrChannel = pRxPacket->byRxChannel; @@ -1972,32 +1972,22 @@ s_vMgrRxBeacon( } } - HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp)); - LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp)); - HIDWORD(qwLocalTSF) = HIDWORD(pRxPacket->qwLocalTSF); - LODWORD(qwLocalTSF) = LODWORD(pRxPacket->qwLocalTSF); + qwTimestamp = le64_to_cpu(*sFrame.pqwTimestamp); + qwLocalTSF = pRxPacket->qwLocalTSF; // check if beacon TSF larger or small than our local TSF - if (HIDWORD(qwTimestamp) == HIDWORD(qwLocalTSF)) { - if (LODWORD(qwTimestamp) >= LODWORD(qwLocalTSF)) - bTSFOffsetPostive = true; - else - bTSFOffsetPostive = false; - } else if (HIDWORD(qwTimestamp) > HIDWORD(qwLocalTSF)) { + if (qwTimestamp >= qwLocalTSF) bTSFOffsetPostive = true; - } else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) { + else bTSFOffsetPostive = false; - } if (bTSFOffsetPostive) qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF)); else qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwLocalTSF), (qwTimestamp)); - if (HIDWORD(qwTSFOffset) != 0 || - (LODWORD(qwTSFOffset) > TRIVIAL_SYNC_DIFFERENCE)) { + if (qwTSFOffset > TRIVIAL_SYNC_DIFFERENCE) bTSFLargeDiff = true; - } // if infra mode if (bIsAPBeacon) { @@ -2194,7 +2184,7 @@ vMgrCreateOwnIBSS( unsigned short wMaxSuppRate; unsigned char byTopCCKBasicRate; unsigned char byTopOFDMBasicRate; - QWORD qwCurrTSF; + 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}; @@ -2316,12 +2306,12 @@ vMgrCreateOwnIBSS( if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { // BSSID selected must be randomized as spec 11.1.3 - pMgmt->abyCurrBSSID[5] = (unsigned char) (LODWORD(qwCurrTSF) & 0x000000ff); - pMgmt->abyCurrBSSID[4] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0000ff00) >> 8); - pMgmt->abyCurrBSSID[3] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00ff0000) >> 16); - pMgmt->abyCurrBSSID[2] = (unsigned char)((LODWORD(qwCurrTSF) & 0x00000ff0) >> 4); - pMgmt->abyCurrBSSID[1] = (unsigned char)((LODWORD(qwCurrTSF) & 0x000ff000) >> 12); - pMgmt->abyCurrBSSID[0] = (unsigned char)((LODWORD(qwCurrTSF) & 0x0ff00000) >> 20); + 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]; diff --git a/drivers/staging/vt6655/wmgr.h b/drivers/staging/vt6655/wmgr.h index a71daed7fa0b..ce939b30ac2a 100644 --- a/drivers/staging/vt6655/wmgr.h +++ b/drivers/staging/vt6655/wmgr.h @@ -175,7 +175,7 @@ typedef struct tagSTxMgmtPacket { // Rx Management Packet descriptor typedef struct tagSRxMgmtPacket { PUWLAN_80211HDR p80211Header; - QWORD qwLocalTSF; + u64 qwLocalTSF; unsigned int cbMPDULen; unsigned int cbPayloadLen; unsigned int uRSSI; diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index d75dd797bd9e..746769c177f3 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -196,7 +196,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, unsigned long dwKeyIndex = 0; unsigned char abyKey[MAX_KEY_LEN]; unsigned char abySeq[MAX_KEY_LEN]; - QWORD KeyRSC; + u64 KeyRSC; unsigned char byKeyDecMode = KEY_CTL_WEP; int ret = 0; int uu, ii; @@ -276,9 +276,9 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, if (param->u.wpa_key.seq_len > 0) { for (ii = 0; ii < param->u.wpa_key.seq_len; ii++) { if (ii < 4) - LODWORD(KeyRSC) |= (abySeq[ii] << (ii * 8)); + KeyRSC |= (u64)(abySeq[ii] << (ii * 8)); else - HIDWORD(KeyRSC) |= (abySeq[ii] << ((ii-4) * 8)); + KeyRSC |= (u64)(abySeq[ii] << ((ii-4) * 8)); } dwKeyIndex |= 1 << 29; } @@ -341,7 +341,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, if (KeybSetAllGroupKey(&(pDevice->sKey), dwKeyIndex, param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), + (u64 *) &KeyRSC, (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, @@ -349,7 +349,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, KeybSetDefaultKey(&(pDevice->sKey), dwKeyIndex, param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), + (u64 *) &KeyRSC, (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, @@ -377,7 +377,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, ¶m->addr[0], dwKeyIndex, param->u.wpa_key.key_len, - (PQWORD) &(KeyRSC), + (u64 *) &KeyRSC, (unsigned char *)abyKey, byKeyDecMode, pDevice->PortOffset, -- GitLab From 989ae8601b28b053d4882ad70ce62420f19f9e91 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 12:21:59 +0100 Subject: [PATCH 0566/9167] staging: vt6655: CARDqGetNextTBTT calculate qwTSF using do_div Use do_div to compute equation as shown replacing existing code. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 5295463cb2bd..a5da3d26c36f 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -1995,27 +1995,18 @@ bool CARDbGetCurrentTSF(void __iomem *dwIoBase, u64 *pqwCurrTSF) */ u64 CARDqGetNextTBTT(u64 qwTSF, unsigned short wBeaconInterval) { - unsigned int uLowNextTBTT; - unsigned int uHighRemain, uLowRemain; - unsigned int uBeaconInterval; + u32 beacon_int; - uBeaconInterval = wBeaconInterval * 1024; - // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval - uLowNextTBTT = ((qwTSF & 0xffffffffULL) >> 10) << 10; - // low dword (mod) bcn - uLowRemain = (uLowNextTBTT) % uBeaconInterval; - // high dword (mod) bcn - uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * (u32)(qwTSF >> 32)) - % uBeaconInterval; - uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval; - uLowRemain = uBeaconInterval - uLowRemain; + beacon_int = wBeaconInterval * 1024; - // check if carry when add one beacon interval - if ((~uLowNextTBTT) < uLowRemain) - qwTSF = ((qwTSF >> 32) + 1) << 32; - - qwTSF = (qwTSF & 0xffffffff00000000ULL) | - (u64)(uLowNextTBTT + uLowRemain); + /* Next TBTT = + * ((local_current_TSF / beacon_interval) + 1) * beacon_interval + */ + if (beacon_int) { + do_div(qwTSF, beacon_int); + qwTSF += 1; + qwTSF *= beacon_int; + } return qwTSF; } -- GitLab From 4a5f718409f92f3bc12ee8020a4874d004f612ba Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 12:22:00 +0100 Subject: [PATCH 0567/9167] staging: vt6655: CARDbSetBeaconPeriod call CARDbGetCurrentTSF to get TBTT There is already a function to get next TBTT. Replace code with CARDqGetNextTBTT. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index a5da3d26c36f..931fca8bb471 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -606,29 +606,11 @@ bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, u64 qwBSSTimes bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval) { PSDevice pDevice = (PSDevice) pDeviceHandler; - unsigned int uBeaconInterval = 0; - unsigned int uLowNextTBTT = 0; - unsigned int uHighRemain = 0; - unsigned int uLowRemain = 0; u64 qwNextTBTT = 0; CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter - uBeaconInterval = wBeaconInterval * 1024; - // Next TBTT = ((local_current_TSF / beacon_interval) + 1) * beacon_interval - uLowNextTBTT = ((qwNextTBTT & 0xffffffffULL) >> 10) << 10; - uLowRemain = (uLowNextTBTT) % uBeaconInterval; - // high dword (mod) bcn - uHighRemain = (((0xffffffff % uBeaconInterval) + 1) * (u32)(qwNextTBTT >> 32)) - % uBeaconInterval; - uLowRemain = (uHighRemain + uLowRemain) % uBeaconInterval; - uLowRemain = uBeaconInterval - uLowRemain; - - // check if carry when add one beacon interval - if ((~uLowNextTBTT) < uLowRemain) - qwNextTBTT = ((qwNextTBTT >> 32) + 1) << 32; - - qwNextTBTT = (qwNextTBTT & 0xffffffff00000000ULL) | - (u64)(uLowNextTBTT + uLowRemain); + + qwNextTBTT = CARDqGetNextTBTT(qwNextTBTT, wBeaconInterval); // set HW beacon interval VNSvOutPortW(pDevice->PortOffset + MAC_REG_BI, wBeaconInterval); -- GitLab From 3e66a2aadd5f89f0012ac4f66dd3456c5921a39e Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 12:22:01 +0100 Subject: [PATCH 0568/9167] staging: vt6655: upc.h: Remove unused macros PCBv* are not used Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/upc.h | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h index e262f1b00e66..00e5a00a72e0 100644 --- a/drivers/staging/vt6655/upc.h +++ b/drivers/staging/vt6655/upc.h @@ -68,33 +68,6 @@ do { \ writel((unsigned long)dwData, dwIOAddress); \ } while (0) -// -// ALWAYS IO-Mapped IO when in 16-bit/32-bit environment -// -#define PCBvInPortB(dwIOAddress, pbyData) \ -do { \ - *(pbyData) = inb(dwIOAddress); \ -} while (0) - -#define PCBvInPortW(dwIOAddress, pwData) \ -do { \ - *(pwData) = inw(dwIOAddress); \ -} while (0) - -#define PCBvInPortD(dwIOAddress, pdwData) \ -do { \ - *(pdwData) = inl(dwIOAddress); \ -} while (0) - -#define PCBvOutPortB(dwIOAddress, byData) \ - outb(byData, dwIOAddress) - -#define PCBvOutPortW(dwIOAddress, wData) \ - outw(wData, dwIOAddress) - -#define PCBvOutPortD(dwIOAddress, dwData) \ - outl(dwData, dwIOAddress) - #define PCAvDelayByIO(uDelayUnit) \ do { \ unsigned char byData; \ -- GitLab From 965d017f49f7094348d95d8034f1ef94ddce601c Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 12:22:02 +0100 Subject: [PATCH 0569/9167] staging: vt6655: upc.h replace read and write memory functions Update to the newer memory functions readb -> ioread8 readw -> ioread16 readl -> ioread32 writeb -> iowrite8 writew -> iowrite16 writel -> iowrite32 Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/upc.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/vt6655/upc.h b/drivers/staging/vt6655/upc.h index 00e5a00a72e0..c5c889cade25 100644 --- a/drivers/staging/vt6655/upc.h +++ b/drivers/staging/vt6655/upc.h @@ -40,32 +40,32 @@ #define VNSvInPortB(dwIOAddress, pbyData) \ do { \ - *(pbyData) = readb(dwIOAddress); \ + *(pbyData) = ioread8(dwIOAddress); \ } while (0) #define VNSvInPortW(dwIOAddress, pwData) \ do { \ - *(pwData) = readw(dwIOAddress); \ + *(pwData) = ioread16(dwIOAddress); \ } while (0) #define VNSvInPortD(dwIOAddress, pdwData) \ do { \ - *(pdwData) = readl(dwIOAddress); \ + *(pdwData) = ioread32(dwIOAddress); \ } while (0) #define VNSvOutPortB(dwIOAddress, byData) \ do { \ - writeb((unsigned char)byData, dwIOAddress); \ + iowrite8((u8)byData, dwIOAddress); \ } while (0) #define VNSvOutPortW(dwIOAddress, wData) \ do { \ - writew((unsigned short)wData, dwIOAddress); \ + iowrite16((u16)wData, dwIOAddress); \ } while (0) #define VNSvOutPortD(dwIOAddress, dwData) \ do { \ - writel((unsigned long)dwData, dwIOAddress); \ + iowrite32((u32)dwData, dwIOAddress); \ } while (0) #define PCAvDelayByIO(uDelayUnit) \ -- GitLab From 3f8597f4e4b39b0505b3891f64d4c3be78d86717 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:46:55 +0100 Subject: [PATCH 0570/9167] staging: vt6655: device.h use change __device_info to vnt_private Coverting all functions to struct vnt_private in device.h and device_main.c Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 19 ++-- drivers/staging/vt6655/device_main.c | 158 ++++++++++++++------------- 2 files changed, 93 insertions(+), 84 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 96d14da2b036..878b6d272555 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -337,9 +337,10 @@ typedef struct __device_opt { u32 flags; } OPTIONS, *POPTIONS; -typedef struct __device_info { - struct __device_info *next; - struct __device_info *prev; +/* TODO Convert all functions to struct vnt_private and remove typedef */ +typedef struct vnt_private { + struct vnt_private *next; + struct vnt_private *prev; struct pci_dev *pcid; @@ -744,7 +745,8 @@ typedef struct __device_info { bool bCommit; } DEVICE_INFO, *PSDevice; -static inline bool device_get_ip(PSDevice pInfo) { +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; @@ -770,7 +772,10 @@ static inline PDEVICE_TD_INFO alloc_td_info(void) /*--------------------- Export Functions --------------------------*/ -bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex); -bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF); -int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter); +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 3896eb325961..4f7509fc17c4 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -249,7 +249,7 @@ DEVICE_PARAM(bDiversityANTEnable, "ANT diversity mode"); // static int device_nics = 0; -static PSDevice pDevice_Infos = NULL; +static struct vnt_private *pDevice_Infos = NULL; static struct net_device *root_device_dev = NULL; static CHIP_INFO chip_info_table[] = { @@ -266,12 +266,13 @@ static const struct pci_device_id vt6655_pci_id_table[] = { /*--------------------- Static Functions --------------------------*/ static int vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent); -static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice, PCHIP_INFO); -static void device_free_info(PSDevice pDevice); -static bool device_get_pci_info(PSDevice, struct pci_dev *pcid); -static void device_print_info(PSDevice pDevice); +static void vt6655_init_info(struct pci_dev *pcid, + struct vnt_private **ppDevice, PCHIP_INFO); +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 struct net_device_stats *device_get_stats(struct net_device *dev); -static void device_init_diversity_timer(PSDevice 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); @@ -290,28 +291,28 @@ static struct notifier_block device_notifier = { }; #endif -static void device_init_rd0_ring(PSDevice pDevice); -static void device_init_rd1_ring(PSDevice pDevice); -static void device_init_defrag_cb(PSDevice pDevice); -static void device_init_td0_ring(PSDevice pDevice); -static void device_init_td1_ring(PSDevice pDevice); +static void device_init_rd0_ring(struct vnt_private *pDevice); +static void device_init_rd1_ring(struct vnt_private *pDevice); +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(PSDevice pDevice); +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(PSDevice pDevice, unsigned int uIdx); -static int device_tx_srv(PSDevice pDevice, unsigned int uIdx); -static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pDesc); -static void device_init_registers(PSDevice pDevice); -static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc); -static void device_free_td0_ring(PSDevice pDevice); -static void device_free_td1_ring(PSDevice pDevice); -static void device_free_rd0_ring(PSDevice pDevice); -static void device_free_rd1_ring(PSDevice pDevice); -static void device_free_rings(PSDevice pDevice); -static void device_free_frag_buf(PSDevice pDevice); +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); +static void device_init_registers(struct vnt_private *pDevice); +static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc); +static void device_free_td0_ring(struct vnt_private *pDevice); +static void device_free_td1_ring(struct vnt_private *pDevice); +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); @@ -331,14 +332,15 @@ static char *get_chip_name(int chip_id) static void vt6655_remove(struct pci_dev *pcid) { - PSDevice pDevice = pci_get_drvdata(pcid); + struct vnt_private *pDevice = pci_get_drvdata(pcid); if (pDevice == NULL) return; device_free_info(pDevice); } -static void device_get_options(PSDevice pDevice, int index, char *devname) +static void device_get_options(struct vnt_private *pDevice, + int index, char *devname) { POPTIONS pOpts = &(pDevice->sOpts); @@ -363,7 +365,8 @@ static void device_get_options(PSDevice pDevice, int index, char *devname) } static void -device_set_options(PSDevice pDevice) { +device_set_options(struct vnt_private *pDevice) +{ unsigned char abyBroadcastAddr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; unsigned char abySNAP_RFC1042[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}; unsigned char abySNAP_Bridgetunnel[ETH_ALEN] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0xF8}; @@ -411,7 +414,8 @@ device_set_options(PSDevice pDevice) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->bDiversityRegCtlON= %d\n", (int)pDevice->bDiversityRegCtlON); } -static void s_vCompleteCurrentMeasure(PSDevice pDevice, unsigned char byResult) +static void s_vCompleteCurrentMeasure(struct vnt_private *pDevice, + unsigned char byResult) { unsigned int ii; unsigned long dwDuration = 0; @@ -453,7 +457,7 @@ static void s_vCompleteCurrentMeasure(PSDevice pDevice, unsigned char byResult) // Initialisation of MAC & BBP registers // -static void device_init_registers(PSDevice pDevice) +static void device_init_registers(struct vnt_private *pDevice) { unsigned int ii; unsigned char byValue; @@ -763,7 +767,7 @@ static void device_init_registers(PSDevice pDevice) netif_stop_queue(pDevice->dev); } -static void device_init_diversity_timer(PSDevice pDevice) +static void device_init_diversity_timer(struct vnt_private *pDevice) { init_timer(&pDevice->TimerSQ3Tmax1); pDevice->TimerSQ3Tmax1.data = (unsigned long) pDevice; @@ -781,7 +785,7 @@ static void device_init_diversity_timer(PSDevice pDevice) pDevice->TimerSQ3Tmax3.expires = RUN_AT(HZ); } -static bool device_release_WPADEV(PSDevice pDevice) +static bool device_release_WPADEV(struct vnt_private *pDevice) { viawget_wpa_header *wpahdr; int ii = 0; @@ -827,7 +831,7 @@ 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; - PSDevice pDevice; + struct vnt_private *pDevice; int rc; if (device_nics++ >= MAX_UINTS) { @@ -837,7 +841,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) dev = alloc_etherdev(sizeof(DEVICE_INFO)); - pDevice = (PSDevice) netdev_priv(dev); + pDevice = netdev_priv(dev); if (dev == NULL) { pr_err(DEVICE_NAME ": allocate net device failed\n"); @@ -977,7 +981,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) return 0; } -static void device_print_info(PSDevice pDevice) +static void device_print_info(struct vnt_private *pDevice) { struct net_device *dev = pDevice->dev; @@ -989,9 +993,11 @@ static void device_print_info(PSDevice pDevice) DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d\n", pDevice->dev->irq); } -static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice, - PCHIP_INFO pChip_info) { - PSDevice p; +static void vt6655_init_info(struct pci_dev *pcid, + struct vnt_private **ppDevice, + PCHIP_INFO pChip_info) +{ + struct vnt_private *p; memset(*ppDevice, 0, sizeof(DEVICE_INFO)); @@ -1013,7 +1019,8 @@ static void vt6655_init_info(struct pci_dev *pcid, PSDevice *ppDevice, spin_lock_init(&((*ppDevice)->lock)); } -static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid) +static bool device_get_pci_info(struct vnt_private *pDevice, + struct pci_dev *pcid) { u16 pci_cmd; u8 b; @@ -1061,9 +1068,9 @@ static bool device_get_pci_info(PSDevice pDevice, struct pci_dev *pcid) return true; } -static void device_free_info(PSDevice pDevice) +static void device_free_info(struct vnt_private *pDevice) { - PSDevice ptr; + struct vnt_private *ptr; struct net_device *dev = pDevice->dev; ASSERT(pDevice); @@ -1106,7 +1113,7 @@ static void device_free_info(PSDevice pDevice) free_netdev(dev); } -static bool device_init_rings(PSDevice pDevice) +static bool device_init_rings(struct vnt_private *pDevice) { void *vir_pool; @@ -1182,7 +1189,7 @@ static bool device_init_rings(PSDevice pDevice) return true; } -static void device_free_rings(PSDevice pDevice) +static void device_free_rings(struct vnt_private *pDevice) { pci_free_consistent(pDevice->pcid, pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + @@ -1203,7 +1210,7 @@ static void device_free_rings(PSDevice pDevice) ); } -static void device_init_rd0_ring(PSDevice pDevice) +static void device_init_rd0_ring(struct vnt_private *pDevice) { int i; dma_addr_t curr = pDevice->rd0_pool_dma; @@ -1228,7 +1235,7 @@ static void device_init_rd0_ring(PSDevice pDevice) pDevice->pCurrRD[0] = &(pDevice->aRD0Ring[0]); } -static void device_init_rd1_ring(PSDevice pDevice) +static void device_init_rd1_ring(struct vnt_private *pDevice) { int i; dma_addr_t curr = pDevice->rd1_pool_dma; @@ -1253,7 +1260,7 @@ static void device_init_rd1_ring(PSDevice pDevice) pDevice->pCurrRD[1] = &(pDevice->aRD1Ring[0]); } -static void device_init_defrag_cb(PSDevice pDevice) +static void device_init_defrag_cb(struct vnt_private *pDevice) { int i; PSDeFragControlBlock pDeF; @@ -1270,7 +1277,7 @@ static void device_init_defrag_cb(PSDevice pDevice) pDevice->cbFreeDFCB = pDevice->cbDFCB; } -static void device_free_rd0_ring(PSDevice pDevice) +static void device_free_rd0_ring(struct vnt_private *pDevice) { int i; @@ -1287,7 +1294,7 @@ static void device_free_rd0_ring(PSDevice pDevice) } } -static void device_free_rd1_ring(PSDevice pDevice) +static void device_free_rd1_ring(struct vnt_private *pDevice) { int i; @@ -1304,7 +1311,7 @@ static void device_free_rd1_ring(PSDevice pDevice) } } -static void device_free_frag_buf(PSDevice pDevice) +static void device_free_frag_buf(struct vnt_private *pDevice) { PSDeFragControlBlock pDeF; int i; @@ -1318,7 +1325,7 @@ static void device_free_frag_buf(PSDevice pDevice) } } -static void device_init_td0_ring(PSDevice pDevice) +static void device_init_td0_ring(struct vnt_private *pDevice) { int i; dma_addr_t curr; @@ -1343,7 +1350,7 @@ static void device_init_td0_ring(PSDevice pDevice) pDevice->apTailTD[0] = pDevice->apCurrTD[0] = &(pDevice->apTD0Rings[0]); } -static void device_init_td1_ring(PSDevice pDevice) +static void device_init_td1_ring(struct vnt_private *pDevice) { int i; dma_addr_t curr; @@ -1369,7 +1376,7 @@ static void device_init_td1_ring(PSDevice pDevice) pDevice->apTailTD[1] = pDevice->apCurrTD[1] = &(pDevice->apTD1Rings[0]); } -static void device_free_td0_ring(PSDevice pDevice) +static void device_free_td0_ring(struct vnt_private *pDevice) { int i; @@ -1388,7 +1395,7 @@ static void device_free_td0_ring(PSDevice pDevice) } } -static void device_free_td1_ring(PSDevice pDevice) +static void device_free_td1_ring(struct vnt_private *pDevice) { int i; @@ -1409,7 +1416,7 @@ static void device_free_td1_ring(PSDevice pDevice) /*-----------------------------------------------------------------*/ -static int device_rx_srv(PSDevice pDevice, unsigned int uIdx) +static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx) { PSRxDesc pRD; int works = 0; @@ -1435,7 +1442,7 @@ static int device_rx_srv(PSDevice pDevice, unsigned int uIdx) return works; } -static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) +static bool device_alloc_rx_buf(struct vnt_private *pDevice, PSRxDesc pRD) { PDEVICE_RD_INFO pRDInfo = pRD->pRDInfo; @@ -1456,7 +1463,8 @@ static bool device_alloc_rx_buf(PSDevice pDevice, PSRxDesc pRD) return true; } -bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) +bool device_alloc_frag_buf(struct vnt_private *pDevice, + PSDeFragControlBlock pDeF) { pDeF->skb = dev_alloc_skb((int)pDevice->rx_buf_sz); if (pDeF->skb == NULL) @@ -1467,7 +1475,7 @@ bool device_alloc_frag_buf(PSDevice pDevice, PSDeFragControlBlock pDeF) return true; } -static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) +static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) { PSTxDesc pTD; bool bFull = false; @@ -1591,7 +1599,7 @@ static int device_tx_srv(PSDevice pDevice, unsigned int uIdx) return works; } -static void device_error(PSDevice pDevice, unsigned short status) +static void device_error(struct vnt_private *pDevice, unsigned short status) { if (status & ISR_FETALERR) { DBG_PRT(MSG_LEVEL_ERR, KERN_ERR @@ -1606,7 +1614,7 @@ static void device_error(PSDevice pDevice, unsigned short status) } } -static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc) +static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc) { PDEVICE_TD_INFO pTDInfo = pDesc->pTDInfo; struct sk_buff *skb = pTDInfo->skb; @@ -1627,7 +1635,7 @@ static void device_free_tx_buf(PSDevice pDevice, PSTxDesc pDesc) static int device_open(struct net_device *dev) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); int i; #ifdef WPA_SM_Transtatus extern SWPAResult wpa_Result; @@ -1711,7 +1719,7 @@ static int device_open(struct net_device *dev) static int device_close(struct net_device *dev) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = pDevice->pMgmt; //PLICE_DEBUG-> //PLICE_DEBUG<- @@ -1757,7 +1765,7 @@ static int device_close(struct net_device *dev) static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) { - PSDevice pDevice = netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); unsigned char *pbMPDU; unsigned int cbMPDULen = 0; @@ -1787,7 +1795,8 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) return 0; } -bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeIndex) +bool device_dma0_xmit(struct vnt_private *pDevice, + struct sk_buff *skb, unsigned int uNodeIndex) { PSMgmtObject pMgmt = pDevice->pMgmt; PSTxDesc pHeadTD, pLastTD; @@ -1927,10 +1936,8 @@ bool device_dma0_xmit(PSDevice pDevice, struct sk_buff *skb, unsigned int uNodeI } //TYPE_AC0DMA data tx -static int device_xmit(struct sk_buff *skb, struct net_device *dev) -{ - PSDevice pDevice = netdev_priv(dev); - +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; @@ -2282,8 +2289,7 @@ 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; - PSDevice pDevice = (PSDevice)netdev_priv(dev); - + struct vnt_private *pDevice = netdev_priv(dev); int max_count = 0; unsigned long dwMIBCounter = 0; PSMgmtObject pMgmt = pDevice->pMgmt; @@ -2575,7 +2581,8 @@ static int Config_FileGetParameter(unsigned char *string, return true; } -int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter) +int Config_FileOperation(struct vnt_private *pDevice, + bool fwrite, unsigned char *Parameter) { unsigned char *buffer = kmalloc(1024, GFP_KERNEL); unsigned char tmpbuffer[20]; @@ -2622,10 +2629,8 @@ int Config_FileOperation(PSDevice pDevice, bool fwrite, unsigned char *Parameter return result; } -static void device_set_multi(struct net_device *dev) -{ - PSDevice pDevice = (PSDevice)netdev_priv(dev); - +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; @@ -2670,15 +2675,14 @@ static void device_set_multi(struct net_device *dev) static struct net_device_stats *device_get_stats(struct net_device *dev) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); return &pDevice->stats; } static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); - + struct vnt_private *pDevice = netdev_priv(dev); struct iwreq *wrq = (struct iwreq *)rq; int rc = 0; PSMgmtObject pMgmt = pDevice->pMgmt; @@ -3175,7 +3179,7 @@ viawget_suspend(struct pci_dev *pcid, pm_message_t state) { int power_status; // to silence the compiler - PSDevice pDevice = pci_get_drvdata(pcid); + struct vnt_private *pDevice = pci_get_drvdata(pcid); PSMgmtObject pMgmt = pDevice->pMgmt; netif_stop_queue(pDevice->dev); @@ -3201,7 +3205,7 @@ viawget_suspend(struct pci_dev *pcid, pm_message_t state) static int viawget_resume(struct pci_dev *pcid) { - PSDevice pDevice = pci_get_drvdata(pcid); + struct vnt_private *pDevice = pci_get_drvdata(pcid); PSMgmtObject pMgmt = pDevice->pMgmt; int power_status; // to silence the compiler -- GitLab From 582d6c220b16ba5e13743bd5cb14e8e0974d45f3 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:46:56 +0100 Subject: [PATCH 0571/9167] staging: vt6655: baseband replace PSDevice Coverting all functions to struct vnt_private. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/baseband.c | 30 +++++++++++++++--------------- drivers/staging/vt6655/baseband.h | 17 +++++++++-------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index f212b88c8cec..3d76ed5ad5f1 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -1711,18 +1711,18 @@ static const unsigned short awcFrameTime[MAX_RATE] = static unsigned long -s_ulGetRatio(PSDevice pDevice); +s_ulGetRatio(struct vnt_private *pDevice); static void s_vChangeAntenna( - PSDevice pDevice + struct vnt_private *pDevice ); static void s_vChangeAntenna( - PSDevice pDevice + struct vnt_private *pDevice ) { if (pDevice->dwRxAntennaSel == 0) { @@ -1827,7 +1827,7 @@ BBuGetFrameTime( */ void BBvCalculateParameter( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned int cbFrameLength, unsigned short wRate, unsigned char byPacketType, @@ -2115,7 +2115,7 @@ bool BBbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned ch * */ -bool BBbVT3253Init(PSDevice pDevice) +bool BBbVT3253Init(struct vnt_private *pDevice) { bool bResult = true; int ii; @@ -2310,7 +2310,7 @@ void BBvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyBBRegs) * */ -void BBvLoopbackOn(PSDevice pDevice) +void BBvLoopbackOn(struct vnt_private *pDevice) { unsigned char byData; void __iomem *dwIoBase = pDevice->PortOffset; @@ -2363,7 +2363,7 @@ void BBvLoopbackOn(PSDevice pDevice) * Return Value: none * */ -void BBvLoopbackOff(PSDevice pDevice) +void BBvLoopbackOff(struct vnt_private *pDevice) { unsigned char byData; void __iomem *dwIoBase = pDevice->PortOffset; @@ -2398,7 +2398,7 @@ void BBvLoopbackOff(PSDevice pDevice) * */ void -BBvSetShortSlotTime(PSDevice pDevice) +BBvSetShortSlotTime(struct vnt_private *pDevice) { unsigned char byBBRxConf = 0; unsigned char byBBVGA = 0; @@ -2418,7 +2418,7 @@ BBvSetShortSlotTime(PSDevice pDevice) BBbWriteEmbedded(pDevice->PortOffset, 0x0A, byBBRxConf); /* CR10 */ } -void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData) +void BBvSetVGAGainOffset(struct vnt_private *pDevice, unsigned char byData) { unsigned char byBBRxConf = 0; @@ -2594,7 +2594,7 @@ BBvExitDeepSleep(void __iomem *dwIoBase, unsigned char byLocalID) static unsigned long -s_ulGetRatio(PSDevice pDevice) +s_ulGetRatio(struct vnt_private *pDevice) { unsigned long ulRatio = 0; unsigned long ulMaxPacket; @@ -2689,7 +2689,7 @@ s_ulGetRatio(PSDevice pDevice) } void -BBvClearAntDivSQ3Value(PSDevice pDevice) +BBvClearAntDivSQ3Value(struct vnt_private *pDevice) { unsigned int ii; @@ -2713,8 +2713,8 @@ BBvClearAntDivSQ3Value(PSDevice pDevice) * */ -void -BBvAntennaDiversity(PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ3) +void BBvAntennaDiversity(struct vnt_private *pDevice, + unsigned char byRxRate, unsigned char bySQ3) { if ((byRxRate >= MAX_RATE) || (pDevice->wAntDiversityMaxRate >= MAX_RATE)) return; @@ -2798,7 +2798,7 @@ TimerSQ3CallBack( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TimerSQ3CallBack..."); spin_lock_irq(&pDevice->lock); @@ -2840,7 +2840,7 @@ TimerState1CallBack( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TimerState1CallBack..."); diff --git a/drivers/staging/vt6655/baseband.h b/drivers/staging/vt6655/baseband.h index fcf1f9373672..6b4388504f5c 100644 --- a/drivers/staging/vt6655/baseband.h +++ b/drivers/staging/vt6655/baseband.h @@ -78,7 +78,7 @@ BBuGetFrameTime( void BBvCalculateParameter( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned int cbFrameLength, unsigned short wRate, unsigned char byPacketType, @@ -91,15 +91,15 @@ bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned ch bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byData); void BBvReadAllRegs(void __iomem *dwIoBase, unsigned char *pbyBBRegs); -void BBvLoopbackOn(PSDevice pDevice); -void BBvLoopbackOff(PSDevice pDevice); -void BBvSetShortSlotTime(PSDevice pDevice); +void BBvLoopbackOn(struct vnt_private *pDevice); +void BBvLoopbackOff(struct vnt_private *pDevice); +void BBvSetShortSlotTime(struct vnt_private *pDevice); bool BBbIsRegBitsOn(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits); bool BBbIsRegBitsOff(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned char byTestBits); -void BBvSetVGAGainOffset(PSDevice pDevice, unsigned char byData); +void BBvSetVGAGainOffset(struct vnt_private *pDevice, unsigned char byData); // VT3253 Baseband -bool BBbVT3253Init(PSDevice pDevice); +bool BBbVT3253Init(struct vnt_private *pDevice); void BBvSoftwareReset(void __iomem *dwIoBase); void BBvPowerSaveModeON(void __iomem *dwIoBase); void BBvPowerSaveModeOFF(void __iomem *dwIoBase); @@ -120,8 +120,9 @@ TimerState1CallBack( void *hDeviceContext ); -void BBvAntennaDiversity(PSDevice pDevice, unsigned char byRxRate, unsigned char bySQ3); +void BBvAntennaDiversity(struct vnt_private *pDevice, + unsigned char byRxRate, unsigned char bySQ3); void -BBvClearAntDivSQ3Value(PSDevice pDevice); +BBvClearAntDivSQ3Value(struct vnt_private *pDevice); #endif // __BASEBAND_H__ -- GitLab From d052270b4372d015fbc19a0e0071b8f3640bff2b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:46:57 +0100 Subject: [PATCH 0572/9167] staging: vt6655: card change PSDevice to struct vnt_private Repacing void *pDeviceHandler Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/card.c | 111 +++++++++++++--------------------- drivers/staging/vt6655/card.h | 83 +++++++++++++------------ 2 files changed, 84 insertions(+), 110 deletions(-) diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 931fca8bb471..633585fd4a96 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -224,7 +224,8 @@ s_vCalculateOFDMRParameter( */ static void -s_vSetRSPINF(PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, void *pvExtSupportRateIEs) +s_vSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, + void *pvSupportRateIEs, void *pvExtSupportRateIEs) { unsigned char byServ = 0, bySignal = 0; // For CCK unsigned short wLen = 0; @@ -348,9 +349,8 @@ s_vSetRSPINF(PSDevice pDevice, CARD_PHY_TYPE ePHYType, void *pvSupportRateIEs, v * Return Value: true if short preamble; otherwise false * */ -bool CARDbIsShortPreamble(void *pDeviceHandler) +bool CARDbIsShortPreamble(struct vnt_private *pDevice) { - PSDevice pDevice = (PSDevice) pDeviceHandler; if (pDevice->byPreambleType == 0) return false; @@ -370,9 +370,8 @@ bool CARDbIsShortPreamble(void *pDeviceHandler) * Return Value: true if short slot time; otherwise false * */ -bool CARDbIsShorSlotTime(void *pDeviceHandler) +bool CARDbIsShorSlotTime(struct vnt_private *pDevice) { - PSDevice pDevice = (PSDevice) pDeviceHandler; return pDevice->bShortSlotTime; } @@ -389,9 +388,10 @@ bool CARDbIsShorSlotTime(void *pDeviceHandler) * Return Value: None. * */ -bool CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs) +bool CARDbSetPhyParameter(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType, + unsigned short wCapInfo, unsigned char byERPField, + void *pvSupportRateIEs, void *pvExtSupportRateIEs) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned char byCWMaxMin = 0; unsigned char bySlot = 0; unsigned char bySIFS = 0; @@ -573,9 +573,9 @@ bool CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned * Return Value: none * */ -bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, u64 qwBSSTimestamp, u64 qwLocalTSF) +bool CARDbUpdateTSF(struct vnt_private *pDevice, unsigned char byRxRate, + u64 qwBSSTimestamp, u64 qwLocalTSF) { - PSDevice pDevice = (PSDevice) pDeviceHandler; u64 qwTSFOffset = 0; if (qwBSSTimestamp != qwLocalTSF) { @@ -603,9 +603,9 @@ bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, u64 qwBSSTimes * Return Value: true if succeed; otherwise false * */ -bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval) +bool CARDbSetBeaconPeriod(struct vnt_private *pDevice, + unsigned short wBeaconInterval) { - PSDevice pDevice = (PSDevice) pDeviceHandler; u64 qwNextTBTT = 0; CARDbGetCurrentTSF(pDevice->PortOffset, &qwNextTBTT); //Get Local TSF counter @@ -636,9 +636,8 @@ bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval) * Return Value: true if all data packet complete; otherwise false. * */ -bool CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType) +bool CARDbStopTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) { - PSDevice pDevice = (PSDevice) pDeviceHandler; if (ePktType == PKT_TYPE_802_11_ALL) { pDevice->bStopBeacon = true; @@ -690,9 +689,8 @@ bool CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType) * Return Value: true if success; false if failed. * */ -bool CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType) +bool CARDbStartTxPacket(struct vnt_private *pDevice, CARD_PKT_TYPE ePktType) { - PSDevice pDevice = (PSDevice) pDeviceHandler; if (ePktType == PKT_TYPE_802_11_ALL) { pDevice->bStopBeacon = false; @@ -729,9 +727,9 @@ bool CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType) * Return Value: true if success; false if failed. * */ -bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE eOPMode) +bool CARDbSetBSSID(struct vnt_private *pDevice, + unsigned char *pbyBSSID, CARD_OP_MODE eOPMode) { - PSDevice pDevice = (PSDevice) pDeviceHandler; MACvWriteBSSIDAddress(pDevice->PortOffset, pbyBSSID); memcpy(pDevice->abyBSSID, pbyBSSID, WLAN_BSSID_LEN); @@ -795,11 +793,10 @@ bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE e * */ bool CARDbSetTxDataRate( - void *pDeviceHandler, + struct vnt_private *pDevice, unsigned short wDataRate ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; pDevice->wCurrentRate = wDataRate; return true; @@ -821,10 +818,9 @@ bool CARDbSetTxDataRate( -*/ bool CARDbPowerDown( - void *pDeviceHandler + struct vnt_private *pDevice ) { - PSDevice pDevice = (PSDevice)pDeviceHandler; unsigned int uIdx; // check if already in Doze mode @@ -858,9 +854,8 @@ CARDbPowerDown( * Return Value: true if success; otherwise false * */ -bool CARDbRadioPowerOff(void *pDeviceHandler) +bool CARDbRadioPowerOff(struct vnt_private *pDevice) { - PSDevice pDevice = (PSDevice)pDeviceHandler; bool bResult = true; if (pDevice->bRadioOff == true) @@ -904,9 +899,8 @@ bool CARDbRadioPowerOff(void *pDeviceHandler) * Return Value: true if success; otherwise false * */ -bool CARDbRadioPowerOn(void *pDeviceHandler) +bool CARDbRadioPowerOn(struct vnt_private *pDevice) { - PSDevice pDevice = (PSDevice) pDeviceHandler; bool bResult = true; pr_debug("chester power on\n"); @@ -947,9 +941,8 @@ bool CARDbRadioPowerOn(void *pDeviceHandler) return bResult; } -bool CARDbRemoveKey(void *pDeviceHandler, unsigned char *pbyBSSID) +bool CARDbRemoveKey(struct vnt_private *pDevice, unsigned char *pbyBSSID) { - PSDevice pDevice = (PSDevice) pDeviceHandler; KeybRemoveAllKey(&(pDevice->sKey), pbyBSSID, pDevice->PortOffset); return true; @@ -973,13 +966,12 @@ bool CARDbRemoveKey(void *pDeviceHandler, unsigned char *pbyBSSID) -*/ bool CARDbAdd_PMKID_Candidate( - void *pDeviceHandler, + struct vnt_private *pDevice, unsigned char *pbyBSSID, bool bRSNCapExist, unsigned short wRSNCap ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; struct pmkid_candidate *pCandidateList; unsigned int ii = 0; @@ -1023,10 +1015,9 @@ CARDbAdd_PMKID_Candidate( void * CARDpGetCurrentAddress( - void *pDeviceHandler + struct vnt_private *pDevice ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; return pDevice->abyCurrentNetAddr; } @@ -1047,12 +1038,11 @@ CARDpGetCurrentAddress( -*/ bool CARDbStartMeasure( - void *pDeviceHandler, + struct vnt_private *pDevice, void *pvMeasureEIDs, unsigned int uNumOfMeasureEIDs ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; PWLAN_IE_MEASURE_REQ pEID = (PWLAN_IE_MEASURE_REQ) pvMeasureEIDs; u64 qwCurrTSF; u64 qwStartTSF; @@ -1163,13 +1153,12 @@ CARDbStartMeasure( -*/ bool CARDbChannelSwitch( - void *pDeviceHandler, + struct vnt_private *pDevice, unsigned char byMode, unsigned char byNewChannel, unsigned char byCount ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; bool bResult = true; if (byCount == 0) { @@ -1205,7 +1194,7 @@ CARDbChannelSwitch( -*/ bool CARDbSetQuiet( - void *pDeviceHandler, + struct vnt_private *pDevice, bool bResetQuiet, unsigned char byQuietCount, unsigned char byQuietPeriod, @@ -1213,7 +1202,6 @@ CARDbSetQuiet( unsigned short wQuietOffset ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned int ii = 0; if (bResetQuiet) { @@ -1258,10 +1246,9 @@ CARDbSetQuiet( -*/ bool CARDbStartQuiet( - void *pDeviceHandler + struct vnt_private *pDevice ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned int ii = 0; unsigned long dwStartTime = 0xFFFFFFFF; unsigned int uCurrentQuietIndex = 0; @@ -1358,12 +1345,11 @@ CARDbStartQuiet( -*/ void CARDvSetPowerConstraint( - void *pDeviceHandler, + struct vnt_private *pDevice, unsigned char byChannel, char byPower ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; if (byChannel > CB_MAX_CHANNEL_24G) { if (pDevice->bCountryInfo5G == true) @@ -1392,12 +1378,11 @@ CARDvSetPowerConstraint( -*/ void CARDvGetPowerCapability( - void *pDeviceHandler, + struct vnt_private *pDevice, unsigned char *pbyMinPower, unsigned char *pbyMaxPower ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned char byDec = 0; *pbyMaxPower = pDevice->abyOFDMDefaultPwr[pDevice->byCurrentCh]; @@ -1427,10 +1412,9 @@ CARDvGetPowerCapability( */ char CARDbyGetTransmitPower( - void *pDeviceHandler + struct vnt_private *pDevice ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; return pDevice->byCurPwrdBm; } @@ -1438,10 +1422,9 @@ CARDbyGetTransmitPower( //xxx void CARDvSafeResetTx( - void *pDeviceHandler + struct vnt_private *pDevice ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned int uu; PSTxDesc pCurrTD; @@ -1491,10 +1474,9 @@ CARDvSafeResetTx( -*/ void CARDvSafeResetRx( - void *pDeviceHandler + struct vnt_private *pDevice ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned int uu; PSRxDesc pDesc; @@ -1545,9 +1527,9 @@ CARDvSafeResetRx( * Return Value: response Control frame rate * */ -static unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned short wRateIdx) +static unsigned short CARDwGetCCKControlRate(struct vnt_private *pDevice, + unsigned short wRateIdx) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned int ui = (unsigned int) wRateIdx; while (ui > RATE_1M) { @@ -1572,9 +1554,9 @@ static unsigned short CARDwGetCCKControlRate(void *pDeviceHandler, unsigned shor * Return Value: response Control frame rate * */ -static unsigned short CARDwGetOFDMControlRate(void *pDeviceHandler, unsigned short wRateIdx) +static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, + unsigned short wRateIdx) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned int ui = (unsigned int) wRateIdx; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BASIC RATE: %X\n", pDevice->wBasicRate); @@ -1608,9 +1590,8 @@ static unsigned short CARDwGetOFDMControlRate(void *pDeviceHandler, unsigned sho * Return Value: None. * */ -void CARDvSetRSPINF(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) +void CARDvSetRSPINF(struct vnt_private *pDevice, CARD_PHY_TYPE ePHYType) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned char byServ = 0x00, bySignal = 0x00; //For CCK unsigned short wLen = 0x0000; unsigned char byTxRate, byRsvTime; //For OFDM @@ -1733,10 +1714,9 @@ void CARDvSetRSPINF(void *pDeviceHandler, CARD_PHY_TYPE ePHYType) * Return Value: None. * */ -void vUpdateIFS(void *pDeviceHandler) +void vUpdateIFS(struct vnt_private *pDevice) { - //Set SIFS, DIFS, EIFS, SlotTime, CwMin - PSDevice pDevice = (PSDevice) pDeviceHandler; + /* Set SIFS, DIFS, EIFS, SlotTime, CwMin */ unsigned char byMaxMin = 0; @@ -1785,9 +1765,8 @@ void vUpdateIFS(void *pDeviceHandler) VNSvOutPortB(pDevice->PortOffset + MAC_REG_CWMAXMIN0, (unsigned char)byMaxMin); } -void CARDvUpdateBasicTopRate(void *pDeviceHandler) +void CARDvUpdateBasicTopRate(struct vnt_private *pDevice) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned char byTopOFDM = RATE_24M, byTopCCK = RATE_1M; unsigned char ii; @@ -1811,9 +1790,8 @@ void CARDvUpdateBasicTopRate(void *pDeviceHandler) pDevice->byTopCCKBasicRate = byTopCCK; } -bool CARDbAddBasicRate(void *pDeviceHandler, unsigned short wRateIdx) +bool CARDbAddBasicRate(struct vnt_private *pDevice, unsigned short wRateIdx) { - PSDevice pDevice = (PSDevice) pDeviceHandler; unsigned short wRate = (unsigned short)(1<wBasicRate |= wRate; @@ -1824,9 +1802,8 @@ bool CARDbAddBasicRate(void *pDeviceHandler, unsigned short wRateIdx) return true; } -bool CARDbIsOFDMinBasicRate(void *pDeviceHandler) +bool CARDbIsOFDMinBasicRate(struct vnt_private *pDevice) { - PSDevice pDevice = (PSDevice)pDeviceHandler; int ii; for (ii = RATE_54M; ii >= RATE_6M; ii--) { @@ -1836,9 +1813,8 @@ bool CARDbIsOFDMinBasicRate(void *pDeviceHandler) return false; } -unsigned char CARDbyGetPktType(void *pDeviceHandler) +unsigned char CARDbyGetPktType(struct vnt_private *pDevice) { - PSDevice pDevice = (PSDevice) pDeviceHandler; if (pDevice->byBBType == BB_TYPE_11A || pDevice->byBBType == BB_TYPE_11B) return (unsigned char)pDevice->byBBType; @@ -1889,9 +1865,8 @@ void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode) * Return Value: none * */ -bool CARDbSoftwareReset(void *pDeviceHandler) +bool CARDbSoftwareReset(struct vnt_private *pDevice) { - PSDevice pDevice = (PSDevice) pDeviceHandler; // reset MAC if (!MACbSafeSoftwareReset(pDevice->PortOffset)) diff --git a/drivers/staging/vt6655/card.h b/drivers/staging/vt6655/card.h index 6e3698bca86a..f7fd83404f34 100644 --- a/drivers/staging/vt6655/card.h +++ b/drivers/staging/vt6655/card.h @@ -77,49 +77,48 @@ typedef enum _CARD_OP_MODE { OP_MODE_UNKNOWN } CARD_OP_MODE, *PCARD_OP_MODE; -void CARDvSetRSPINF(void *pDeviceHandler, CARD_PHY_TYPE ePHYType); -void vUpdateIFS(void *pDeviceHandler); -void CARDvUpdateBasicTopRate(void *pDeviceHandler); -bool CARDbAddBasicRate(void *pDeviceHandler, unsigned short wRateIdx); -bool CARDbIsOFDMinBasicRate(void *pDeviceHandler); +struct vnt_private; + +void CARDvSetRSPINF(struct vnt_private *, CARD_PHY_TYPE ePHYType); +void vUpdateIFS(struct vnt_private *); +void CARDvUpdateBasicTopRate(struct vnt_private *); +bool CARDbAddBasicRate(struct vnt_private *, unsigned short wRateIdx); +bool CARDbIsOFDMinBasicRate(struct vnt_private *); void CARDvSetLoopbackMode(void __iomem *dwIoBase, unsigned short wLoopbackMode); -bool CARDbSoftwareReset(void *pDeviceHandler); +bool CARDbSoftwareReset(struct vnt_private *); void CARDvSetFirstNextTBTT(void __iomem *dwIoBase, unsigned short wBeaconInterval); void CARDvUpdateNextTBTT(void __iomem *dwIoBase, u64 qwTSF, unsigned short wBeaconInterval); 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(void *pDeviceHandler, unsigned long ulTxPower); -unsigned char CARDbyGetPktType(void *pDeviceHandler); -void CARDvSafeResetTx(void *pDeviceHandler); -void CARDvSafeResetRx(void *pDeviceHandler); - -bool CARDbRadioPowerOff(void *pDeviceHandler); -bool CARDbRadioPowerOn(void *pDeviceHandler); -bool CARDbIsShortPreamble(void *pDeviceHandler); -bool CARDbIsShorSlotTime(void *pDeviceHandler); -bool CARDbSetPhyParameter(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, unsigned short wCapInfo, unsigned char byERPField, void *pvSupportRateIEs, void *pvExtSupportRateIEs); -bool CARDbUpdateTSF(void *pDeviceHandler, unsigned char byRxRate, u64 qwBSSTimestamp, u64 qwLocalTSF); -bool CARDbStopTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType); -bool CARDbStartTxPacket(void *pDeviceHandler, CARD_PKT_TYPE ePktType); -bool CARDbSetBeaconPeriod(void *pDeviceHandler, unsigned short wBeaconInterval); -bool CARDbSetBSSID(void *pDeviceHandler, unsigned char *pbyBSSID, CARD_OP_MODE eOPMode); - -bool -CARDbPowerDown( - void *pDeviceHandler -); - -bool CARDbSetTxDataRate( - void *pDeviceHandler, - unsigned short wDataRate -); - -bool CARDbRemoveKey(void *pDeviceHandler, unsigned char *pbyBSSID); +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, CARD_OP_MODE eOPMode); + +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( - void *pDeviceHandler, + struct vnt_private *, unsigned char *pbyBSSID, bool bRSNCapExist, unsigned short wRSNCap @@ -127,19 +126,19 @@ CARDbAdd_PMKID_Candidate( void * CARDpGetCurrentAddress( - void *pDeviceHandler + struct vnt_private * ); bool CARDbStartMeasure( - void *pDeviceHandler, + struct vnt_private *, void *pvMeasureEIDs, unsigned int uNumOfMeasureEIDs ); bool CARDbChannelSwitch( - void *pDeviceHandler, + struct vnt_private *, unsigned char byMode, unsigned char byNewChannel, unsigned char byCount @@ -147,7 +146,7 @@ CARDbChannelSwitch( bool CARDbSetQuiet( - void *pDeviceHandler, + struct vnt_private *, bool bResetQuiet, unsigned char byQuietCount, unsigned char byQuietPeriod, @@ -157,26 +156,26 @@ CARDbSetQuiet( bool CARDbStartQuiet( - void *pDeviceHandler + struct vnt_private * ); void CARDvSetPowerConstraint( - void *pDeviceHandler, + struct vnt_private *, unsigned char byChannel, char byPower ); void CARDvGetPowerCapability( - void *pDeviceHandler, + struct vnt_private *, unsigned char *pbyMinPower, unsigned char *pbyMaxPower ); char CARDbyGetTransmitPower( - void *pDeviceHandler + struct vnt_private * ); #endif // __CARD_H__ -- GitLab From 0ffc58742d835b83fa9f055233c11dcdf6724e77 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:46:58 +0100 Subject: [PATCH 0573/9167] staging: vt6655: channel/wcmd/wctl/wmgr use struct vnt_private * Replacing PSDevice. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/channel.c | 10 +-- drivers/staging/vt6655/wcmd.c | 28 ++++---- drivers/staging/vt6655/wctl.c | 8 ++- drivers/staging/vt6655/wctl.h | 6 +- drivers/staging/vt6655/wmgr.c | 120 +++++++++++++++---------------- 5 files changed, 87 insertions(+), 85 deletions(-) diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index d5b89b7aaf23..753d523800c3 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -416,7 +416,7 @@ bool channel_get_list(unsigned int uCountryCodeIdx, unsigned char *pbyChannelTab void init_channel_table(void *pDeviceHandler) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + struct vnt_private *pDevice = pDeviceHandler; bool bMultiBand = false; unsigned int ii; @@ -521,7 +521,7 @@ unsigned char get_channel_number(void *pDeviceHandler, unsigned char byChannelIn */ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + struct vnt_private *pDevice = pDeviceHandler; bool bResult = true; if (pDevice->byCurrentCh == uConnectionChannel) @@ -583,7 +583,7 @@ bool set_channel(void *pDeviceHandler, unsigned int uConnectionChannel) void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + struct vnt_private *pDevice = pDeviceHandler; unsigned int ii = 0; unsigned int uu = 0; unsigned int step = 0; @@ -632,7 +632,7 @@ void set_country_info(void *pDeviceHandler, CARD_PHY_TYPE ePHYType, void *pIE) unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + struct vnt_private *pDevice = pDeviceHandler; unsigned int ii; unsigned char byCount; PWLAN_IE_SUPP_CH pIE = (PWLAN_IE_SUPP_CH) pbyIEs; @@ -703,7 +703,7 @@ unsigned char set_support_channels(void *pDeviceHandler, unsigned char *pbyIEs) void set_country_IE(void *pDeviceHandler, void *pIE) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + struct vnt_private *pDevice = pDeviceHandler; unsigned int ii; PWLAN_IE_COUNTRY pIECountry = (PWLAN_IE_COUNTRY) pIE; diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index b7e68a08a8a0..0045f7f7995d 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -65,13 +65,13 @@ static int msglevel = MSG_LEVEL_INFO; static void s_vProbeChannel( - PSDevice pDevice + struct vnt_private *pDevice ); static PSTxMgmtPacket s_MgrMakeProbeRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned char *pScanBSSID, PWLAN_IE_SSID pSSID, @@ -82,7 +82,7 @@ s_MgrMakeProbeRequest( static bool s_bCommandComplete( - PSDevice pDevice + struct vnt_private *pDevice ); /*--------------------- Export Variables --------------------------*/ @@ -104,7 +104,7 @@ s_bCommandComplete( */ static void -vAdHocBeaconStop(PSDevice pDevice) +vAdHocBeaconStop(struct vnt_private *pDevice) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); bool bStop; @@ -151,7 +151,7 @@ vAdHocBeaconStop(PSDevice pDevice) */ static void -vAdHocBeaconRestart(PSDevice pDevice) +vAdHocBeaconRestart(struct vnt_private *pDevice) { PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -181,7 +181,7 @@ vAdHocBeaconRestart(PSDevice pDevice) static void s_vProbeChannel( - PSDevice pDevice + struct vnt_private *pDevice ) { //1M, 2M, 5M, 11M, 18M, 24M, 36M, 54M @@ -236,7 +236,7 @@ s_vProbeChannel( static PSTxMgmtPacket s_MgrMakeProbeRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned char *pScanBSSID, PWLAN_IE_SSID pSSID, @@ -287,7 +287,7 @@ vCommandTimerWait( unsigned int MSecond ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; init_timer(&pDevice->sTimerCommand); pDevice->sTimerCommand.data = (unsigned long) pDevice; @@ -302,7 +302,7 @@ vCommandTimer( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; PWLAN_IE_SSID pItemSSID; PWLAN_IE_SSID pItemSSIDCurr; @@ -801,7 +801,7 @@ vCommandTimer( static bool s_bCommandComplete( - PSDevice pDevice + struct vnt_private *pDevice ) { PWLAN_IE_SSID pSSID; @@ -875,7 +875,7 @@ bool bScheduleCommand( unsigned char *pbyItem0 ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; if (pDevice->cbFreeCmdQueue == 0) return false; @@ -944,7 +944,7 @@ bool bClearBSSID_SCAN( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; unsigned int uCmdDequeueIdx = pDevice->uCmdDequeueIdx; unsigned int ii; @@ -966,7 +966,7 @@ vResetCommandTimer( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; //delete timer del_timer(&pDevice->sTimerCommand); @@ -988,7 +988,7 @@ BSSvSecondTxData( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); pDevice->nTxDataTimeCout++; diff --git a/drivers/staging/vt6655/wctl.c b/drivers/staging/vt6655/wctl.c index fddea9fc9cfe..5a54d98d985a 100644 --- a/drivers/staging/vt6655/wctl.c +++ b/drivers/staging/vt6655/wctl.c @@ -105,7 +105,8 @@ bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader) * Return Value: index number in Defragment Database * */ -unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader) +unsigned int WCTLuSearchDFCB(struct vnt_private *pDevice, + PS802_11Header pMACHeader) { unsigned int ii; @@ -133,7 +134,7 @@ unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader) * Return Value: index number in Defragment Database * */ -unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader) +unsigned int WCTLuInsertDFCB(struct vnt_private *pDevice, PS802_11Header pMACHeader) { unsigned int ii; @@ -169,7 +170,8 @@ unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader) * Return Value: true if it is valid fragment packet and we have resource to defragment; otherwise false * */ -bool WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV) +bool WCTLbHandleFragment(struct vnt_private *pDevice, PS802_11Header pMACHeader, + unsigned int cbFrameLength, bool bWEP, bool bExtIV) { unsigned int uHeaderSize; diff --git a/drivers/staging/vt6655/wctl.h b/drivers/staging/vt6655/wctl.h index 1ffb2734cfae..f0995d86f71f 100644 --- a/drivers/staging/vt6655/wctl.h +++ b/drivers/staging/vt6655/wctl.h @@ -97,9 +97,9 @@ do { \ /*--------------------- Export Functions --------------------------*/ bool WCTLbIsDuplicate(PSCache pCache, PS802_11Header pMACHeader); -bool WCTLbHandleFragment(PSDevice pDevice, PS802_11Header pMACHeader, +bool WCTLbHandleFragment(struct vnt_private *, PS802_11Header pMACHeader, unsigned int cbFrameLength, bool bWEP, bool bExtIV); -unsigned int WCTLuSearchDFCB(PSDevice pDevice, PS802_11Header pMACHeader); -unsigned int WCTLuInsertDFCB(PSDevice pDevice, PS802_11Header pMACHeader); +unsigned int WCTLuSearchDFCB(struct vnt_private *, PS802_11Header pMACHeader); +unsigned int WCTLuInsertDFCB(struct vnt_private *, PS802_11Header pMACHeader); #endif // __WCTL_H__ diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index 79ba37baeb13..d696f5bf76d1 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -92,7 +92,7 @@ static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ //2008-8-4 by chester static bool ChannelExceedZoneType( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byCurrChannel ); @@ -100,7 +100,7 @@ static bool ChannelExceedZoneType( static PSTxMgmtPacket s_MgrMakeAssocRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned char *pDAddr, unsigned short wCurrCapInfo, @@ -113,7 +113,7 @@ s_MgrMakeAssocRequest( static void s_vMgrRxAssocRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, unsigned int uNodeIndex @@ -122,7 +122,7 @@ s_vMgrRxAssocRequest( static PSTxMgmtPacket s_MgrMakeReAssocRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned char *pDAddr, unsigned short wCurrCapInfo, @@ -135,7 +135,7 @@ s_MgrMakeReAssocRequest( static void s_vMgrRxAssocResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, bool bReAssocType @@ -144,7 +144,7 @@ s_vMgrRxAssocResponse( static void s_vMgrRxDisassociation( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ); @@ -153,7 +153,7 @@ s_vMgrRxDisassociation( static void s_vMgrRxAuthenSequence_1( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PWLAN_FR_AUTHEN pFrame ); @@ -161,7 +161,7 @@ s_vMgrRxAuthenSequence_1( static void s_vMgrRxAuthenSequence_2( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PWLAN_FR_AUTHEN pFrame ); @@ -169,7 +169,7 @@ s_vMgrRxAuthenSequence_2( static void s_vMgrRxAuthenSequence_3( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PWLAN_FR_AUTHEN pFrame ); @@ -177,7 +177,7 @@ s_vMgrRxAuthenSequence_3( static void s_vMgrRxAuthenSequence_4( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PWLAN_FR_AUTHEN pFrame ); @@ -185,7 +185,7 @@ s_vMgrRxAuthenSequence_4( static void s_vMgrRxAuthentication( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ); @@ -193,7 +193,7 @@ s_vMgrRxAuthentication( static void s_vMgrRxDeauthentication( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ); @@ -203,7 +203,7 @@ s_vMgrRxDeauthentication( static void s_vMgrRxProbeRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ); @@ -211,7 +211,7 @@ s_vMgrRxProbeRequest( static void s_vMgrRxProbeResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ); @@ -220,7 +220,7 @@ s_vMgrRxProbeResponse( static void s_vMgrRxBeacon( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, bool bInScan @@ -236,7 +236,7 @@ s_vMgrFormatTIM( static PSTxMgmtPacket s_MgrMakeBeacon( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned short wCurrCapInfo, unsigned short wCurrBeaconPeriod, @@ -252,7 +252,7 @@ s_MgrMakeBeacon( static PSTxMgmtPacket s_MgrMakeAssocResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned short wCurrCapInfo, unsigned short wAssocStatus, @@ -266,7 +266,7 @@ s_MgrMakeAssocResponse( static PSTxMgmtPacket s_MgrMakeReAssocResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned short wCurrCapInfo, unsigned short wAssocStatus, @@ -280,7 +280,7 @@ s_MgrMakeReAssocResponse( static PSTxMgmtPacket s_MgrMakeProbeResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned short wCurrCapInfo, unsigned short wCurrBeaconPeriod, @@ -305,7 +305,7 @@ s_vMgrLogStatus( static void s_vMgrSynchBSS( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned int uBSSMode, PKnownBSS pCurr, PCMD_STATUS pStatus @@ -320,7 +320,7 @@ s_bCipherMatch( ); static void Encyption_Rebuild( - PSDevice pDevice, + struct vnt_private *pDevice, PKnownBSS pCurr ); @@ -343,7 +343,7 @@ vMgrObjectInit( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; int ii; @@ -375,7 +375,7 @@ vMgrTimerInit( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; init_timer(&pMgmt->sTimerSecondCallback); @@ -416,7 +416,7 @@ vMgrObjectReset( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; pMgmt->eCurrMode = WMAC_MODE_STANDBY; @@ -443,7 +443,7 @@ vMgrAssocBeginSta( PCMD_STATUS pStatus ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSTxMgmtPacket pTxPacket; pMgmt->wCurrCapInfo = 0; @@ -509,7 +509,7 @@ vMgrReAssocBeginSta( PCMD_STATUS pStatus ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSTxMgmtPacket pTxPacket; pMgmt->wCurrCapInfo = 0; @@ -576,7 +576,7 @@ vMgrDisassocBeginSta( PCMD_STATUS pStatus ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSTxMgmtPacket pTxPacket = NULL; WLAN_FR_DISASSOC sFrame; @@ -628,7 +628,7 @@ vMgrDisassocBeginSta( static void s_vMgrRxAssocRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, unsigned int uNodeIndex @@ -778,7 +778,7 @@ s_vMgrRxAssocRequest( static void s_vMgrRxReAssocRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, unsigned int uNodeIndex @@ -920,7 +920,7 @@ s_vMgrRxReAssocRequest( static void s_vMgrRxAssocResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, bool bReAssocType @@ -1073,7 +1073,7 @@ vMgrAuthenBeginSta( PCMD_STATUS pStatus ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; WLAN_FR_AUTHEN sFrame; PSTxMgmtPacket pTxPacket = NULL; @@ -1129,7 +1129,7 @@ vMgrDeAuthenBeginSta( PCMD_STATUS pStatus ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; WLAN_FR_DEAUTHEN sFrame; PSTxMgmtPacket pTxPacket = NULL; @@ -1173,7 +1173,7 @@ vMgrDeAuthenBeginSta( static void s_vMgrRxAuthentication( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ) @@ -1227,7 +1227,7 @@ s_vMgrRxAuthentication( static void s_vMgrRxAuthenSequence_1( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PWLAN_FR_AUTHEN pFrame ) @@ -1239,7 +1239,7 @@ s_vMgrRxAuthenSequence_1( // Insert a Node entry if (!BSSDBbIsSTAInNodeDB(pMgmt, pFrame->pHdr->sA3.abyAddr2, &uNodeIndex)) { - BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); + BSSvCreateOneNode(pDevice, &uNodeIndex); memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, pFrame->pHdr->sA3.abyAddr2, WLAN_ADDR_LEN); } @@ -1326,7 +1326,7 @@ s_vMgrRxAuthenSequence_1( static void s_vMgrRxAuthenSequence_2( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PWLAN_FR_AUTHEN pFrame ) @@ -1411,7 +1411,7 @@ s_vMgrRxAuthenSequence_2( static void s_vMgrRxAuthenSequence_3( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PWLAN_FR_AUTHEN pFrame ) @@ -1493,7 +1493,7 @@ s_vMgrRxAuthenSequence_3( static void s_vMgrRxAuthenSequence_4( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PWLAN_FR_AUTHEN pFrame ) @@ -1523,7 +1523,7 @@ s_vMgrRxAuthenSequence_4( static void s_vMgrRxDisassociation( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ) @@ -1593,7 +1593,7 @@ s_vMgrRxDisassociation( static void s_vMgrRxDeauthentication( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ) @@ -1676,7 +1676,7 @@ s_vMgrRxDeauthentication( -*/ static bool ChannelExceedZoneType( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byCurrChannel ) { @@ -1713,7 +1713,7 @@ ChannelExceedZoneType( static void s_vMgrRxBeacon( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket, bool bInScan @@ -2026,7 +2026,7 @@ s_vMgrRxBeacon( // send out ps-poll packet if (pMgmt->bInTIM) - PSvSendPSPOLL((PSDevice)pDevice); + PSvSendPSPOLL(pDevice); } else { pMgmt->bInTIMWake = false; @@ -2077,7 +2077,7 @@ s_vMgrRxBeacon( pMgmt->sNodeDBTable[uNodeIndex].uInActiveCount = 0; } else { // Todo, initial Node content - BSSvCreateOneNode((PSDevice)pDevice, &uNodeIndex); + BSSvCreateOneNode(pDevice, &uNodeIndex); pMgmt->abyCurrSuppRates[1] = RATEuSetIE((PWLAN_IE_SUPP_RATES)sFrame.pSuppRates, (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, @@ -2178,7 +2178,7 @@ vMgrCreateOwnIBSS( PCMD_STATUS pStatus ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned short wMaxBasicRate; unsigned short wMaxSuppRate; @@ -2414,7 +2414,7 @@ vMgrJoinBSSBegin( PCMD_STATUS pStatus ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; PKnownBSS pCurr = NULL; unsigned int ii, uu; @@ -2629,7 +2629,7 @@ vMgrJoinBSSBegin( static void s_vMgrSynchBSS( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned int uBSSMode, PKnownBSS pCurr, PCMD_STATUS pStatus @@ -2767,7 +2767,7 @@ s_vMgrSynchBSS( //mike add: fix NetworkManager 0.7.0 hidden ssid mode in WPA encryption // ,need reset eAuthenMode and eEncryptionStatus static void Encyption_Rebuild( - PSDevice pDevice, + struct vnt_private *pDevice, PKnownBSS pCurr ) { @@ -2882,7 +2882,7 @@ s_vMgrFormatTIM( static PSTxMgmtPacket s_MgrMakeBeacon( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned short wCurrCapInfo, unsigned short wCurrBeaconPeriod, @@ -3101,7 +3101,7 @@ s_MgrMakeBeacon( static PSTxMgmtPacket s_MgrMakeProbeResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned short wCurrCapInfo, unsigned short wCurrBeaconPeriod, @@ -3283,7 +3283,7 @@ s_MgrMakeProbeResponse( static PSTxMgmtPacket s_MgrMakeAssocRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned char *pDAddr, unsigned short wCurrCapInfo, @@ -3543,7 +3543,7 @@ s_MgrMakeAssocRequest( static PSTxMgmtPacket s_MgrMakeReAssocRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned char *pDAddr, unsigned short wCurrCapInfo, @@ -3788,7 +3788,7 @@ s_MgrMakeReAssocRequest( static PSTxMgmtPacket s_MgrMakeAssocResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned short wCurrCapInfo, unsigned short wAssocStatus, @@ -3859,7 +3859,7 @@ s_MgrMakeAssocResponse( static PSTxMgmtPacket s_MgrMakeReAssocResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, unsigned short wCurrCapInfo, unsigned short wAssocStatus, @@ -3931,7 +3931,7 @@ s_MgrMakeReAssocResponse( static void s_vMgrRxProbeResponse( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ) @@ -4050,7 +4050,7 @@ s_vMgrRxProbeResponse( static void s_vMgrRxProbeRequest( - PSDevice pDevice, + struct vnt_private *pDevice, PSMgmtObject pMgmt, PSRxMgmtPacket pRxPacket ) @@ -4129,7 +4129,7 @@ vMgrRxManagePacket( PSRxMgmtPacket pRxPacket ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; bool bInScan = false; unsigned int uNodeIndex = 0; NODE_STATE eNodeState = 0; @@ -4267,7 +4267,7 @@ bMgrPrepareBeaconToSend( PSMgmtObject pMgmt ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSTxMgmtPacket pTxPacket; if (pDevice->bEncryptionEnable || pDevice->bEnable8021x) @@ -4386,7 +4386,7 @@ bAdd_PMKID_Candidate( PSRSNCapObject psRSNCapObj ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; struct pmkid_candidate *pCandidateList; unsigned int ii = 0; @@ -4443,7 +4443,7 @@ vFlush_PMKID_Candidate( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; if (pDevice == NULL) return; -- GitLab From cf76dc4b85447e17678d61505eb1b92743c4b67b Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:46:59 +0100 Subject: [PATCH 0574/9167] staging: vt6655: bssdb/datarate/dpc/power/rxtx use struct vnt_private Replacing PSDevice. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/bssdb.c | 32 +++++++------- drivers/staging/vt6655/datarate.c | 4 +- drivers/staging/vt6655/dpc.c | 23 +++++----- drivers/staging/vt6655/dpc.h | 2 +- drivers/staging/vt6655/power.c | 12 +++--- drivers/staging/vt6655/rxtx.c | 70 +++++++++++++++++-------------- drivers/staging/vt6655/rxtx.h | 22 ++++++---- 7 files changed, 88 insertions(+), 77 deletions(-) diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index 0d6b27ebae5c..bb59b989def0 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -117,7 +117,7 @@ BSSpSearchBSSList( CARD_PHY_TYPE ePhyType ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned char *pbyBSSID = NULL; PWLAN_IE_SSID pSSID = NULL; @@ -240,7 +240,7 @@ BSSvClearBSSList( bool bKeepCurrBSSID ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int ii; @@ -280,7 +280,7 @@ BSSpAddrIsInBSSList( PWLAN_IE_SSID pSSID ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; PKnownBSS pBSSList = NULL; unsigned int ii; @@ -333,7 +333,7 @@ BSSbInsertToBSSList( void *pRxPacketContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; PKnownBSS pBSSList = NULL; @@ -540,7 +540,7 @@ BSSbUpdateToBSSList( ) { int ii; - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; PSRxMgmtPacket pRxPacket = (PSRxMgmtPacket)pRxPacketContext; long ldBm; @@ -715,7 +715,7 @@ BSSDBbIsSTAInNodeDB(void *pMgmtObject, unsigned char *abyDstAddr, void BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int ii; unsigned int BigestCount = 0; @@ -777,7 +777,7 @@ BSSvRemoveOneNode( unsigned int uNodeIndex ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + 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; @@ -810,7 +810,7 @@ BSSvUpdateAPNode( PWLAN_IE_SUPP_RATES pExtSuppRates ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uRateLen = WLAN_RATES_MAXLEN; @@ -861,7 +861,7 @@ BSSvAddMulticastNode( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; if (!pDevice->bEnableHostWEP) @@ -904,7 +904,7 @@ BSSvSecondCallBack( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int ii; PWLAN_IE_SSID pItemSSID, pCurrSSID; @@ -1207,7 +1207,7 @@ BSSvUpdateNodeTxCounter( unsigned int uFIFOHeaderSize ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uNodeIndex = 0; unsigned char byTxRetry = (byTsr0 & TSR0_NCR); @@ -1360,7 +1360,7 @@ BSSvClearNodeDBTable( ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; struct sk_buff *skb; unsigned int ii; @@ -1385,7 +1385,7 @@ void s_vCheckSensitivity( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PKnownBSS pBSSList = NULL; PSMgmtObject pMgmt = pDevice->pMgmt; int ii; @@ -1435,7 +1435,7 @@ BSSvClearAnyBSSJoinRecord( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int ii; @@ -1448,7 +1448,7 @@ void s_uCalculateLinkQual( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; unsigned long TxOkRatio, TxCnt; unsigned long RxOkRatio, RxCnt; unsigned long RssiRatio; @@ -1488,7 +1488,7 @@ void s_vCheckPreEDThreshold( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PKnownBSS pBSSList = NULL; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index 565028c4ab03..d489fe4a4ecb 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -195,7 +195,7 @@ RATEvParseMaxRate( unsigned char *pbyTopOFDMRate ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + struct vnt_private *pDevice = pDeviceHandler; unsigned int ii; unsigned char byHighSuppRate = 0; unsigned char byRate = 0; @@ -295,7 +295,7 @@ RATEvTxRateFallBack( PKnownNodeDB psNodeDBTable ) { - PSDevice pDevice = (PSDevice) pDeviceHandler; + 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}; diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index 449741989912..d26ca96d2da4 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -79,18 +79,18 @@ s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, PSEthernetHeader psEthHeader); static void -s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr, +s_vProcessRxMACHeader(struct vnt_private *pDevice, unsigned char *pbyRxBufferAddr, unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, unsigned int *pcbHeadSize); static bool s_bAPModeRxCtl( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyFrame, int iSANodeIndex ); static bool s_bAPModeRxData( - PSDevice pDevice, + struct vnt_private *pDevice, struct sk_buff *skb, unsigned int FrameSize, unsigned int cbHeaderOffset, @@ -99,7 +99,7 @@ static bool s_bAPModeRxData( ); static bool s_bHandleRxEncryption( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyFrame, unsigned int FrameSize, unsigned char *pbyRsr, @@ -112,7 +112,7 @@ static bool s_bHandleRxEncryption( static bool s_bHostWepRxEncryption( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyFrame, unsigned int FrameSize, unsigned char *pbyRsr, @@ -145,7 +145,8 @@ static bool s_bHostWepRxEncryption( * -*/ static void -s_vProcessRxMACHeader(PSDevice pDevice, unsigned char *pbyRxBufferAddr, +s_vProcessRxMACHeader(struct vnt_private *pDevice, + unsigned char *pbyRxBufferAddr, unsigned int cbPacketSize, bool bIsWEP, bool bExtIV, unsigned int *pcbHeadSize) { @@ -270,7 +271,7 @@ s_vGetDASA(unsigned char *pbyRxBufferAddr, unsigned int *pcbHeaderSize, bool device_receive_frame( - PSDevice pDevice, + struct vnt_private *pDevice, PSRxDesc pCurrRD ) { @@ -871,7 +872,7 @@ device_receive_frame( } static bool s_bAPModeRxCtl( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyFrame, int iSANodeIndex ) @@ -969,7 +970,7 @@ static bool s_bAPModeRxCtl( } static bool s_bHandleRxEncryption( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyFrame, unsigned int FrameSize, unsigned char *pbyRsr, @@ -1106,7 +1107,7 @@ static bool s_bHandleRxEncryption( } static bool s_bHostWepRxEncryption( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyFrame, unsigned int FrameSize, unsigned char *pbyRsr, @@ -1226,7 +1227,7 @@ static bool s_bHostWepRxEncryption( } static bool s_bAPModeRxData( - PSDevice pDevice, + struct vnt_private *pDevice, struct sk_buff *skb, unsigned int FrameSize, unsigned int cbHeaderOffset, diff --git a/drivers/staging/vt6655/dpc.h b/drivers/staging/vt6655/dpc.h index 4914890115e4..a068b846b1be 100644 --- a/drivers/staging/vt6655/dpc.h +++ b/drivers/staging/vt6655/dpc.h @@ -35,7 +35,7 @@ bool device_receive_frame( - PSDevice pDevice, + struct vnt_private *, PSRxDesc pCurrRD ); diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index f08c26fbb10f..de23f2d98e3d 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -74,7 +74,7 @@ PSvEnablePowerSaving( unsigned short wListenInterval ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned short wAID = pMgmt->wCurrAID | BIT14 | BIT15; @@ -131,7 +131,7 @@ PSvDisablePowerSaving( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; // disable power saving hw function MACbPSWakeup(pDevice->PortOffset); @@ -167,7 +167,7 @@ PSbConsiderPowerDown( bool bCheckCountToWakeUp ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uIdx; @@ -229,7 +229,7 @@ PSvSendPSPOLL( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; PSTxMgmtPacket pTxPacket = NULL; @@ -266,7 +266,7 @@ PSbSendNullPacket( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSTxMgmtPacket pTxPacket = NULL; PSMgmtObject pMgmt = pDevice->pMgmt; unsigned int uIdx; @@ -336,7 +336,7 @@ PSbIsNextTBTTWakeUp( void *hDeviceContext ) { - PSDevice pDevice = (PSDevice)hDeviceContext; + struct vnt_private *pDevice = hDeviceContext; PSMgmtObject pMgmt = pDevice->pMgmt; bool bWakeUp = false; diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index 2270e2ac0878..b6253581eec4 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -112,7 +112,7 @@ static const unsigned short wFB_Opt1[2][5] = { static void s_vFillTxKey( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyBuf, unsigned char *pbyIVHead, PSKeyItem pTransmitKey, @@ -124,7 +124,7 @@ s_vFillTxKey( static void s_vFillRTSHead( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byPktType, void *pvRTS, unsigned int cbFrameLength, @@ -138,7 +138,7 @@ s_vFillRTSHead( static void s_vGenerateTxParameter( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byPktType, void *pTxBufHead, void *pvRrvTime, @@ -152,7 +152,7 @@ s_vGenerateTxParameter( ); static void s_vFillFragParameter( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyBuffer, unsigned int uTxType, void *pvtdCurr, @@ -161,15 +161,17 @@ static void s_vFillFragParameter( ); static unsigned int -s_cbFillTxBufHead(PSDevice 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); +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); static unsigned int s_uFillDataHead( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byPktType, void *pTxDataHead, unsigned int cbFrameLength, @@ -187,7 +189,7 @@ s_uFillDataHead( static void s_vFillTxKey( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyBuf, unsigned char *pbyIVHead, PSKeyItem pTransmitKey, @@ -300,7 +302,7 @@ s_vFillTxKey( static void s_vSWencryption( - PSDevice pDevice, + struct vnt_private *pDevice, PSKeyItem pTransmitKey, unsigned char *pbyPayloadHead, unsigned short wPayloadSize @@ -346,7 +348,7 @@ s_vSWencryption( static unsigned int s_uGetTxRsvTime( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byPktType, unsigned int cbFrameLength, unsigned short wRate, @@ -371,7 +373,7 @@ s_uGetTxRsvTime( static unsigned int s_uGetRTSCTSRsvTime( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byRTSRsvType, unsigned char byPktType, unsigned int cbFrameLength, @@ -409,7 +411,7 @@ s_uGetRTSCTSRsvTime( static unsigned int s_uGetDataDuration( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byDurType, unsigned int cbFrameLength, unsigned char byPktType, @@ -568,7 +570,7 @@ s_uGetDataDuration( static unsigned int s_uGetRTSCTSDuration( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byDurType, unsigned int cbFrameLength, unsigned char byPktType, @@ -661,7 +663,7 @@ s_uGetRTSCTSDuration( static unsigned int s_uFillDataHead( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byPktType, void *pTxDataHead, unsigned int cbFrameLength, @@ -790,7 +792,7 @@ s_uFillDataHead( static void s_vFillRTSHead( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byPktType, void *pvRTS, unsigned int cbFrameLength, @@ -965,7 +967,7 @@ s_vFillRTSHead( static void s_vFillCTSHead( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned int uDMAIdx, unsigned char byPktType, void *pvCTS, @@ -1063,7 +1065,7 @@ s_vFillCTSHead( static void s_vGenerateTxParameter( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byPktType, void *pTxBufHead, void *pvRrvTime, @@ -1169,7 +1171,7 @@ s_vGenerateTxParameter( static void s_vFillFragParameter( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyBuffer, unsigned int uTxType, void *pvtdCurr, @@ -1205,10 +1207,12 @@ s_vFillFragParameter( } static unsigned int -s_cbFillTxBufHead(PSDevice 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) +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 int cbMACHdLen; unsigned int cbFrameSize; @@ -1859,8 +1863,9 @@ s_cbFillTxBufHead(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyT } void -vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktType, unsigned char *pbyTxBufferAddr, - bool bNeedEncrypt, unsigned int cbPayloadSize, unsigned int uDMAIdx, +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) @@ -1986,7 +1991,7 @@ vGenerateFIFOHeader(PSDevice pDevice, unsigned char byPktType, unsigned char *pb void vGenerateMACHeader( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char *pbyBufferAddr, unsigned short wDuration, PSEthernetHeader psEthHeader, @@ -2049,7 +2054,7 @@ vGenerateMACHeader( pMACHeader->wFrameCtl |= FC_MOREFRAG; } -CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) +CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) { PSTxDesc pFrstTD; unsigned char byPktType; @@ -2334,7 +2339,7 @@ CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) return CMD_STATUS_PENDING; } -CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) +CMD_STATUS csBeacon_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) { unsigned char byPktType; unsigned char *pbyBuffer = (unsigned char *)pDevice->tx_beacon_bufs; @@ -2408,7 +2413,7 @@ CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket) unsigned int cbGetFragCount( - PSDevice pDevice, + struct vnt_private *pDevice, PSKeyItem pTransmitKey, unsigned int cbFrameBodySize, PSEthernetHeader psEthHeader @@ -2485,8 +2490,9 @@ cbGetFragCount( return uMACfragNum; } -void -vDMA0_tx_80211(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, unsigned int cbMPDULen) { +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; diff --git a/drivers/staging/vt6655/rxtx.h b/drivers/staging/vt6655/rxtx.h index a9a8edec1c4b..26baf3b44b96 100644 --- a/drivers/staging/vt6655/rxtx.h +++ b/drivers/staging/vt6655/rxtx.h @@ -58,7 +58,7 @@ struct vnt_mic_hdr { void vGenerateMACHeader( - PSDevice pDevice, + struct vnt_private *, unsigned char *pbyBufferAddr, unsigned short wDuration, PSEthernetHeader psEthHeader, @@ -70,20 +70,24 @@ vGenerateMACHeader( unsigned int cbGetFragCount( - PSDevice pDevice, + struct vnt_private *, PSKeyItem pTransmitKey, unsigned int cbFrameBodySize, PSEthernetHeader psEthHeader ); void -vGenerateFIFOHeader(PSDevice pDevice, 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); +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(PSDevice pDevice, struct sk_buff *skb, unsigned char *pbMPDU, unsigned int cbMPDULen); -CMD_STATUS csMgmt_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); -CMD_STATUS csBeacon_xmit(PSDevice pDevice, PSTxMgmtPacket pPacket); +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); #endif // __RXTX_H__ -- GitLab From 8f335dd136f9ccfb04e35ada2f80bdb958faf6be Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:47:00 +0100 Subject: [PATCH 0575/9167] staging: vt6655: hostap/ioctl/iwctl use struct vnt_private Replacing PSDevice. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/hostap.c | 29 ++++++++-------- drivers/staging/vt6655/hostap.h | 4 +-- drivers/staging/vt6655/ioctl.c | 2 +- drivers/staging/vt6655/ioctl.h | 2 +- drivers/staging/vt6655/iwctl.c | 60 ++++++++++++++++----------------- 5 files changed, 49 insertions(+), 48 deletions(-) diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index 29e8eb39c350..c10a1b56ebb8 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -68,9 +68,9 @@ static int msglevel = MSG_LEVEL_INFO; * */ -static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) +static int hostap_enable_hostapd(struct vnt_private *pDevice, int rtnl_locked) { - PSDevice apdev_priv; + struct vnt_private *apdev_priv; struct net_device *dev = pDevice->dev; int ret; const struct net_device_ops apdev_netdev_ops = { @@ -130,7 +130,7 @@ static int hostap_enable_hostapd(PSDevice pDevice, int rtnl_locked) * */ -static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked) +static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name); @@ -172,7 +172,8 @@ static int hostap_disable_hostapd(PSDevice pDevice, int rtnl_locked) * */ -int vt6655_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) +int vt6655_hostap_set_hostapd(struct vnt_private *pDevice, + int val, int rtnl_locked) { if (val < 0 || val > 1) return -EINVAL; @@ -201,7 +202,7 @@ int vt6655_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked) * Return Value: * */ -static int hostap_remove_sta(PSDevice pDevice, +static int hostap_remove_sta(struct vnt_private *pDevice, struct viawget_hostapd_param *param) { unsigned int uNodeIndex; @@ -227,14 +228,14 @@ static int hostap_remove_sta(PSDevice pDevice, * Return Value: * */ -static int hostap_add_sta(PSDevice pDevice, +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((PSDevice)pDevice, &uNodeIndex); + BSSvCreateOneNode(pDevice, &uNodeIndex); memcpy(pMgmt->sNodeDBTable[uNodeIndex].abyMACAddr, param->sta_addr, WLAN_ADDR_LEN); pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; @@ -285,7 +286,7 @@ static int hostap_add_sta(PSDevice pDevice, * */ -static int hostap_get_info_sta(PSDevice pDevice, +static int hostap_get_info_sta(struct vnt_private *pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; @@ -314,7 +315,7 @@ static int hostap_get_info_sta(PSDevice pDevice, * Return Value: * */ -static int hostap_set_flags_sta(PSDevice pDevice, +static int hostap_set_flags_sta(struct vnt_private *pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; @@ -345,7 +346,7 @@ static int hostap_set_flags_sta(PSDevice pDevice, * Return Value: * */ -static int hostap_set_generic_element(PSDevice pDevice, +static int hostap_set_generic_element(struct vnt_private *pDevice, struct viawget_hostapd_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; @@ -389,7 +390,7 @@ static int hostap_set_generic_element(PSDevice pDevice, * */ -static void hostap_flush_sta(PSDevice pDevice) +static void hostap_flush_sta(struct vnt_private *pDevice) { // reserved node index =0 for multicast node. BSSvClearNodeDBTable(pDevice, 1); @@ -409,7 +410,7 @@ static void hostap_flush_sta(PSDevice pDevice) * Return Value: * */ -static int hostap_set_encryption(PSDevice pDevice, +static int hostap_set_encryption(struct vnt_private *pDevice, struct viawget_hostapd_param *param, int param_len) { @@ -635,7 +636,7 @@ static int hostap_set_encryption(PSDevice pDevice, * Return Value: * */ -static int hostap_get_encryption(PSDevice pDevice, +static int hostap_get_encryption(struct vnt_private *pDevice, struct viawget_hostapd_param *param, int param_len) { @@ -675,7 +676,7 @@ static int hostap_get_encryption(PSDevice pDevice, * Return Value: * */ -int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p) +int vt6655_hostap_ioctl(struct vnt_private *pDevice, struct iw_point *p) { struct viawget_hostapd_param *param; int ret = 0; diff --git a/drivers/staging/vt6655/hostap.h b/drivers/staging/vt6655/hostap.h index 6e801a428183..17df4e403fcf 100644 --- a/drivers/staging/vt6655/hostap.h +++ b/drivers/staging/vt6655/hostap.h @@ -52,7 +52,7 @@ #define ARPHRD_IEEE80211 801 #endif -int vt6655_hostap_set_hostapd(PSDevice pDevice, int val, int rtnl_locked); -int vt6655_hostap_ioctl(PSDevice pDevice, struct iw_point *p); +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/ioctl.c b/drivers/staging/vt6655/ioctl.c index 65e59336f03b..306a7db937f7 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -44,7 +44,7 @@ static int msglevel = MSG_LEVEL_INFO; SWPAResult wpa_Result; #endif -int private_ioctl(PSDevice pDevice, struct ifreq *rq) +int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) { PSCmdRequest pReq = (PSCmdRequest)rq; PSMgmtObject pMgmt = pDevice->pMgmt; diff --git a/drivers/staging/vt6655/ioctl.h b/drivers/staging/vt6655/ioctl.h index 187fc915fd12..2dc5a5743e8d 100644 --- a/drivers/staging/vt6655/ioctl.h +++ b/drivers/staging/vt6655/ioctl.h @@ -31,6 +31,6 @@ #include "device.h" -int private_ioctl(PSDevice pDevice, struct ifreq *rq); +int private_ioctl(struct vnt_private *, struct ifreq *rq); #endif // __IOCTL_H__ diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 7ce23b57e78d..0c73064a147d 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -76,7 +76,7 @@ static int msglevel = MSG_LEVEL_INFO; struct iw_statistics *iwctl_get_wireless_stats(struct net_device *dev) { - PSDevice pDevice = netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); long ldBm; pDevice->wstats.status = pDevice->eOPMode; @@ -134,7 +134,7 @@ static int iwctl_siwscan(struct net_device *dev, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + 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]; @@ -198,7 +198,7 @@ static int iwctl_giwscan(struct net_device *dev, char *extra) { int ii, jj, kk; - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PKnownBSS pBSS; PWLAN_IE_SSID pItemSSID; @@ -350,7 +350,7 @@ int iwctl_siwfreq(struct net_device *dev, struct iw_freq *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ\n"); @@ -398,7 +398,7 @@ int iwctl_giwfreq(struct net_device *dev, struct iw_freq *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ\n"); @@ -429,7 +429,7 @@ int iwctl_siwmode(struct net_device *dev, __u32 *wmode, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; @@ -495,7 +495,7 @@ int iwctl_giwmode(struct net_device *dev, __u32 *wmode, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE\n"); @@ -635,7 +635,7 @@ int iwctl_siwap(struct net_device *dev, struct sockaddr *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + 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}; @@ -694,7 +694,7 @@ int iwctl_giwap(struct net_device *dev, struct sockaddr *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP\n"); @@ -728,7 +728,7 @@ int iwctl_giwaplist(struct net_device *dev, struct iw_quality *q = NULL; PKnownBSS pBSS = NULL; - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n"); @@ -794,7 +794,7 @@ int iwctl_siwessid(struct net_device *dev, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; //2008-0409-05, by Einsn Liu @@ -903,7 +903,7 @@ int iwctl_giwessid(struct net_device *dev, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; @@ -933,7 +933,7 @@ int iwctl_siwrate(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); int rc = 0; u8 brate = 0; int i; @@ -1014,7 +1014,7 @@ int iwctl_giwrate(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); //2007-0118-05, by EinsnLiu //Mark the unnecessary sentences. // PSMgmtObject pMgmt = &(pDevice->sMgmtObj); @@ -1059,7 +1059,7 @@ int iwctl_siwrts(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS\n"); @@ -1088,7 +1088,7 @@ int iwctl_giwrts(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS\n"); wrq->value = pDevice->wRTSThreshold; @@ -1107,7 +1107,7 @@ int iwctl_siwfrag(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); int rc = 0; int fthr = wrq->value; @@ -1134,7 +1134,7 @@ int iwctl_giwfrag(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG\n"); wrq->value = pDevice->wFragmentationThreshold; @@ -1152,7 +1152,7 @@ int iwctl_siwretry(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); int rc = 0; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY\n"); @@ -1187,7 +1187,7 @@ int iwctl_giwretry(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY\n"); wrq->disabled = 0; // Can't be disabled @@ -1217,7 +1217,7 @@ int iwctl_siwencode(struct net_device *dev, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + 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; @@ -1348,7 +1348,7 @@ int iwctl_giwencode(struct net_device *dev, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); char abyKey[WLAN_WEP232_KEYLEN]; @@ -1410,7 +1410,7 @@ int iwctl_siwpower(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; @@ -1460,7 +1460,7 @@ int iwctl_giwpower(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int mode = pDevice->ePSMode; @@ -1490,7 +1490,7 @@ int iwctl_giwsens(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); long ldBm; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n"); @@ -1514,7 +1514,7 @@ int iwctl_siwauth(struct net_device *dev, struct iw_param *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(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 @@ -1623,7 +1623,7 @@ int iwctl_siwgenie(struct net_device *dev, struct iw_point *wrq, char __user *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; char length; @@ -1663,7 +1663,7 @@ int iwctl_giwgenie(struct net_device *dev, struct iw_point *wrq, char __user *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int ret = 0; int space = wrq->length; @@ -1688,7 +1688,7 @@ int iwctl_siwencodeext(struct net_device *dev, struct iw_point *wrq, char *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(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 @@ -1810,7 +1810,7 @@ int iwctl_siwmlme(struct net_device *dev, struct iw_point *wrq, char __user *extra) { - PSDevice pDevice = (PSDevice)netdev_priv(dev); + struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); struct iw_mlme mime; -- GitLab From 6af4336e64dde7d0dd910c10de5dced9ef7ecf64 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:47:01 +0100 Subject: [PATCH 0576/9167] staging: vt6655: rf/wpactl/wroute use struct vnt_private Replacing PSDevice. Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/rf.c | 8 ++++---- drivers/staging/vt6655/rf.h | 8 ++++---- drivers/staging/vt6655/wpactl.c | 28 ++++++++++++++-------------- drivers/staging/vt6655/wpactl.h | 6 +++--- drivers/staging/vt6655/wroute.c | 2 +- drivers/staging/vt6655/wroute.h | 3 ++- 6 files changed, 28 insertions(+), 27 deletions(-) diff --git a/drivers/staging/vt6655/rf.c b/drivers/staging/vt6655/rf.c index 42b257f916d3..e505af91bfd0 100644 --- a/drivers/staging/vt6655/rf.c +++ b/drivers/staging/vt6655/rf.c @@ -746,7 +746,7 @@ static bool RFbAL2230SelectChannel(void __iomem *dwIoBase, unsigned char byChann * */ bool RFbInit( - PSDevice pDevice + struct vnt_private *pDevice ) { bool bResult = true; @@ -897,7 +897,7 @@ bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigne * */ bool RFbSetPower( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned int uRATE, unsigned int uCH ) @@ -978,7 +978,7 @@ bool RFbSetPower( */ bool RFbRawSetPower( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byPwr, unsigned int uRATE ) @@ -1042,7 +1042,7 @@ bool RFbRawSetPower( -*/ void RFvRSSITodBm( - PSDevice pDevice, + struct vnt_private *pDevice, unsigned char byCurrRSSI, long *pldBm ) diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index ba55561c45d2..be4ef88b7666 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -77,19 +77,19 @@ bool IFRFbWriteEmbedded(void __iomem *dwIoBase, unsigned long dwData); bool RFbSelectChannel(void __iomem *dwIoBase, unsigned char byRFType, unsigned char byChannel); bool RFbInit( - PSDevice pDevice + struct vnt_private * ); bool RFvWriteWakeProgSyn(void __iomem *dwIoBase, unsigned char byRFType, unsigned int uChannel); -bool RFbSetPower(PSDevice pDevice, unsigned int uRATE, unsigned int uCH); +bool RFbSetPower(struct vnt_private *, unsigned int uRATE, unsigned int uCH); bool RFbRawSetPower( - PSDevice pDevice, + struct vnt_private *, unsigned char byPwr, unsigned int uRATE ); void RFvRSSITodBm( - PSDevice pDevice, + struct vnt_private *, unsigned char byCurrRSSI, long *pldBm ); diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 746769c177f3..5a1bfe9f31fa 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -83,13 +83,13 @@ static void wpadev_setup(struct net_device *dev) * */ -static int wpa_init_wpadev(PSDevice pDevice) +static int wpa_init_wpadev(struct vnt_private *pDevice) { - PSDevice wpadev_priv; + struct vnt_private *wpadev_priv; struct net_device *dev = pDevice->dev; int ret = 0; - pDevice->wpadev = alloc_netdev(sizeof(PSDevice), "vntwpa", + pDevice->wpadev = alloc_netdev(sizeof(*wpadev_priv), "vntwpa", NET_NAME_UNKNOWN, wpadev_setup); if (pDevice->wpadev == NULL) return -ENOMEM; @@ -134,7 +134,7 @@ static int wpa_init_wpadev(PSDevice pDevice) * */ -static int wpa_release_wpadev(PSDevice pDevice) +static int wpa_release_wpadev(struct vnt_private *pDevice) { if (pDevice->skb) { dev_kfree_skb(pDevice->skb); @@ -166,7 +166,7 @@ static int wpa_release_wpadev(PSDevice pDevice) * */ -int wpa_set_wpadev(PSDevice pDevice, int val) +int wpa_set_wpadev(struct vnt_private *pDevice, int val) { if (val) return wpa_init_wpadev(pDevice); @@ -188,7 +188,7 @@ int wpa_set_wpadev(PSDevice pDevice, int val) * */ -int wpa_set_keys(PSDevice pDevice, void *ctx, +int wpa_set_keys(struct vnt_private *pDevice, void *ctx, bool fcpfkernel) __must_hold(&pDevice->lock) { struct viawget_wpa_param *param = ctx; @@ -412,7 +412,7 @@ int wpa_set_keys(PSDevice pDevice, void *ctx, * */ -static int wpa_set_wpa(PSDevice pDevice, +static int wpa_set_wpa(struct vnt_private *pDevice, struct viawget_wpa_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; @@ -437,7 +437,7 @@ static int wpa_set_wpa(PSDevice pDevice, * */ -static int wpa_set_disassociate(PSDevice pDevice, +static int wpa_set_disassociate(struct vnt_private *pDevice, struct viawget_wpa_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; @@ -466,7 +466,7 @@ static int wpa_set_disassociate(PSDevice pDevice, * */ -static int wpa_set_scan(PSDevice pDevice, +static int wpa_set_scan(struct vnt_private *pDevice, struct viawget_wpa_param *param) { spin_lock_irq(&pDevice->lock); @@ -491,7 +491,7 @@ static int wpa_set_scan(PSDevice pDevice, * */ -static int wpa_get_bssid(PSDevice pDevice, +static int wpa_get_bssid(struct vnt_private *pDevice, struct viawget_wpa_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; @@ -515,7 +515,7 @@ static int wpa_get_bssid(PSDevice pDevice, * */ -static int wpa_get_ssid(PSDevice pDevice, +static int wpa_get_ssid(struct vnt_private *pDevice, struct viawget_wpa_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; @@ -543,7 +543,7 @@ static int wpa_get_ssid(PSDevice pDevice, * */ -static int wpa_get_scan(PSDevice pDevice, +static int wpa_get_scan(struct vnt_private *pDevice, struct viawget_wpa_param *param) { struct viawget_scan_result *scan_buf; @@ -660,7 +660,7 @@ static int wpa_get_scan(PSDevice pDevice, * */ -static int wpa_set_associate(PSDevice pDevice, +static int wpa_set_associate(struct vnt_private *pDevice, struct viawget_wpa_param *param) { PSMgmtObject pMgmt = pDevice->pMgmt; @@ -804,7 +804,7 @@ static int wpa_set_associate(PSDevice pDevice, * */ -int wpa_ioctl(PSDevice pDevice, struct iw_point *p) +int wpa_ioctl(struct vnt_private *pDevice, struct iw_point *p) { struct viawget_wpa_param *param; int ret = 0; diff --git a/drivers/staging/vt6655/wpactl.h b/drivers/staging/vt6655/wpactl.h index f7638baf340d..c1b4a7292061 100644 --- a/drivers/staging/vt6655/wpactl.h +++ b/drivers/staging/vt6655/wpactl.h @@ -57,8 +57,8 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_CCKM, KEY_MGMT_PSK, KEY_MGMT_NONE, /*--------------------- Export Functions --------------------------*/ -int wpa_set_wpadev(PSDevice pDevice, int val); -int wpa_ioctl(PSDevice pDevice, struct iw_point *p); -int wpa_set_keys(PSDevice pDevice, void *ctx, bool fcpfkernel); +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__ diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c index 4da3fef139dc..44ce6e274957 100644 --- a/drivers/staging/vt6655/wroute.c +++ b/drivers/staging/vt6655/wroute.c @@ -62,7 +62,7 @@ static int msglevel = MSG_LEVEL_INFO; * Return Value: true if packet duplicate; otherwise false * */ -bool ROUTEbRelay(PSDevice pDevice, unsigned char *pbySkbData, +bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex) { PSMgmtObject pMgmt = pDevice->pMgmt; diff --git a/drivers/staging/vt6655/wroute.h b/drivers/staging/vt6655/wroute.h index 3abc1d36f89d..e59eec955cac 100644 --- a/drivers/staging/vt6655/wroute.h +++ b/drivers/staging/vt6655/wroute.h @@ -39,6 +39,7 @@ /*--------------------- Export Functions --------------------------*/ -bool ROUTEbRelay(PSDevice pDevice, unsigned char *pbySkbData, unsigned int uDataLen, unsigned int uNodeIndex); +bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, + unsigned int uDataLen, unsigned int uNodeIndex); #endif /* __WROUTE_H__ */ -- GitLab From 1bd6375760ef13baeee404276b95034c691f2ed8 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:47:02 +0100 Subject: [PATCH 0577/9167] staging: vt6655: device_main Replace DEVICE_INFO with size of pointer Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 4f7509fc17c4..beab35d8a4cb 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -839,7 +839,7 @@ vt6655_probe(struct pci_dev *pcid, const struct pci_device_id *ent) return -ENODEV; } - dev = alloc_etherdev(sizeof(DEVICE_INFO)); + dev = alloc_etherdev(sizeof(*pDevice)); pDevice = netdev_priv(dev); @@ -999,7 +999,7 @@ static void vt6655_init_info(struct pci_dev *pcid, { struct vnt_private *p; - memset(*ppDevice, 0, sizeof(DEVICE_INFO)); + memset(*ppDevice, 0, sizeof(**ppDevice)); if (pDevice_Infos == NULL) { pDevice_Infos = *ppDevice; -- GitLab From 80f598ae8a8dbe7d56e9d08d205405dd9f6aecdd Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Sun, 10 Aug 2014 15:47:03 +0100 Subject: [PATCH 0578/9167] staging: vt6655: remove typedef from struct vnt_private Signed-off-by: Malcolm Priestley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/device.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index 878b6d272555..e1a322fa9c02 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -337,8 +337,7 @@ typedef struct __device_opt { u32 flags; } OPTIONS, *POPTIONS; -/* TODO Convert all functions to struct vnt_private and remove typedef */ -typedef struct vnt_private { +struct vnt_private { struct vnt_private *next; struct vnt_private *prev; @@ -743,7 +742,7 @@ typedef struct vnt_private { struct iw_statistics wstats; // wireless stats bool bCommit; -} DEVICE_INFO, *PSDevice; +}; static inline bool device_get_ip(struct vnt_private *pInfo) { -- GitLab From 86140346adbb426b7b4e8ec397c9ef6db572c3e0 Mon Sep 17 00:00:00 2001 From: "Ragnar B. Johannsson" Date: Sun, 10 Aug 2014 22:23:48 +0000 Subject: [PATCH 0579/9167] staging: vt6656: remove unnecessary braces Removes unnecessary braces to comply with coding style. Signed-off-by: Ragnar B. Johannsson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/usbpipe.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vt6656/usbpipe.c b/drivers/staging/vt6656/usbpipe.c index cba653292996..88bf518f23eb 100644 --- a/drivers/staging/vt6656/usbpipe.c +++ b/drivers/staging/vt6656/usbpipe.c @@ -131,11 +131,10 @@ static void vnt_start_interrupt_urb_complete(struct urb *urb) } status = usb_submit_urb(priv->interrupt_urb, GFP_ATOMIC); - if (status) { + if (status) dev_dbg(&priv->usb->dev, "Submit int URB failed %d\n", status); - } else { + else priv->int_buf.in_use = true; - } } int vnt_start_interrupt_urb(struct vnt_private *priv) -- GitLab From de657d59f2ccc433e7380b23fb565438c2bb7ffb Mon Sep 17 00:00:00 2001 From: "Ragnar B. Johannsson" Date: Sun, 10 Aug 2014 22:23:49 +0000 Subject: [PATCH 0580/9167] staging: vt6656: fix incorrect indentation Use tabs, not spaces. Signed-off-by: Ragnar B. Johannsson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rxtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 2d1ef88808ff..08ce18ddfd8a 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -573,7 +573,7 @@ static u16 vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, memcpy(buf->data.ra, priv->current_net_addr, ETH_ALEN); return vnt_rxtx_datahead_g(tx_context, &buf->data_head); - } + } return 0; } -- GitLab From 76be25ba313086c81392fe5dcddf73b806be2100 Mon Sep 17 00:00:00 2001 From: "Ragnar B. Johannsson" Date: Sun, 10 Aug 2014 22:23:50 +0000 Subject: [PATCH 0581/9167] staging: vt6656: add blank line after declaration Adds a blank line after declaration to comply with coding style. Signed-off-by: Ragnar B. Johannsson Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rxtx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index 08ce18ddfd8a..852ebe86a1c1 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -1036,6 +1036,7 @@ static int vnt_beacon_xmit(struct vnt_private *priv, 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->seq_counter << 4); } -- GitLab From 139cc6aed5b235ca2b32b23962667d1173ce6005 Mon Sep 17 00:00:00 2001 From: Junien Fridrick Date: Sun, 10 Aug 2014 23:05:38 +0000 Subject: [PATCH 0582/9167] staging: lustre: fix coding style issue: missing space after 'if' Coding style issue reported by checkpatch.pl Signed-off-by: Junien Fridrick Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/remote_perm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/remote_perm.c b/drivers/staging/lustre/lustre/llite/remote_perm.c index f61fefc9baf0..3a9c8e8f3f47 100644 --- a/drivers/staging/lustre/lustre/llite/remote_perm.c +++ b/drivers/staging/lustre/lustre/llite/remote_perm.c @@ -100,7 +100,7 @@ void free_rmtperm_hash(struct hlist_head *hash) struct ll_remote_perm *lrp; struct hlist_node *next; - if(!hash) + if (!hash) return; for (i = 0; i < REMOTE_PERM_HASHSIZE; i++) -- GitLab From ffdac6ce36580cacb72ab7775cc52e947c62721c Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:27 +0530 Subject: [PATCH 0583/9167] staging: lustre: remove space between function name and and open parenthesis Fixes following checkpatch warning: WARNING: space prohibited between function name and open parenthesis '(' Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_internal.h | 2 +- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 4 ++-- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 2 +- drivers/staging/lustre/lustre/mdc/mdc_request.c | 14 +++++++------- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index e8235559e27f..f4da8f3523d2 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -40,7 +40,7 @@ #include "../include/lustre_mdc.h" #include "../include/lustre_mds.h" -#if defined (CONFIG_PROC_FS) +#if defined CONFIG_PROC_FS void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars); #else static inline void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index f54dd90c7e50..60217ba440aa 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -42,7 +42,7 @@ static void __mdc_pack_body(struct mdt_body *b, __u32 suppgid) { - LASSERT (b != NULL); + LASSERT(b != NULL); b->suppgid = suppgid; b->uid = from_kuid(&init_user_ns, current_uid()); @@ -409,7 +409,7 @@ void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data) CLASSERT(sizeof(struct mdt_rec_reint) == sizeof(struct mdt_rec_link)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); - LASSERT (rec != NULL); + LASSERT(rec != NULL); rec->lk_opcode = REINT_LINK; rec->lk_fsuid = op_data->op_fsuid;//current->fsuid; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index 71219b90e22b..88b43823c632 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -633,7 +633,7 @@ static int mdc_finish_enqueue(struct obd_export *exp, body = req_capsule_server_get(pill, &RMF_MDT_BODY); if (body == NULL) { - CERROR ("Can't swab mdt_body\n"); + CERROR("Can't swab mdt_body\n"); return -EPROTO; } diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 4a1cc4eb73d5..0b517e550477 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -1702,7 +1702,7 @@ static int mdc_quotactl(struct obd_device *unused, struct obd_export *exp, if (oqc) { *oqctl = *oqc; } else if (!rc) { - CERROR ("Can't unpack obd_quotactl\n"); + CERROR("Can't unpack obd_quotactl\n"); rc = -EPROTO; } } else if (!rc) { @@ -2426,14 +2426,14 @@ static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg) struct lprocfs_static_vars lvars = { NULL }; int rc; - OBD_ALLOC(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock)); + OBD_ALLOC(cli->cl_rpc_lock, sizeof(*cli->cl_rpc_lock)); if (!cli->cl_rpc_lock) return -ENOMEM; mdc_init_rpc_lock(cli->cl_rpc_lock); ptlrpcd_addref(); - OBD_ALLOC(cli->cl_close_lock, sizeof (*cli->cl_close_lock)); + OBD_ALLOC(cli->cl_close_lock, sizeof(*cli->cl_close_lock)); if (!cli->cl_close_lock) GOTO(err_rpc_lock, rc = -ENOMEM); mdc_init_rpc_lock(cli->cl_close_lock); @@ -2459,9 +2459,9 @@ static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg) return rc; err_close_lock: - OBD_FREE(cli->cl_close_lock, sizeof (*cli->cl_close_lock)); + OBD_FREE(cli->cl_close_lock, sizeof(*cli->cl_close_lock)); err_rpc_lock: - OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock)); + OBD_FREE(cli->cl_rpc_lock, sizeof(*cli->cl_rpc_lock)); ptlrpcd_decref(); return rc; } @@ -2523,8 +2523,8 @@ static int mdc_cleanup(struct obd_device *obd) { struct client_obd *cli = &obd->u.cli; - OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock)); - OBD_FREE(cli->cl_close_lock, sizeof (*cli->cl_close_lock)); + OBD_FREE(cli->cl_rpc_lock, sizeof(*cli->cl_rpc_lock)); + OBD_FREE(cli->cl_close_lock, sizeof(*cli->cl_close_lock)); ptlrpcd_decref(); -- GitLab From 444014d6f529434a856564f2d9436a33416b2f43 Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:28 +0530 Subject: [PATCH 0584/9167] staging: lustre: remove spaces from start of line Fixes the following checkpatch warning: WARNING: please, no spaces at the start of a line Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index d1d891b91663..f883d9c28f20 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -209,6 +209,6 @@ static struct lprocfs_vars lprocfs_mdc_module_vars[] = { void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars) { - lvars->module_vars = lprocfs_mdc_module_vars; - lvars->obd_vars = lprocfs_mdc_obd_vars; + lvars->module_vars = lprocfs_mdc_module_vars; + lvars->obd_vars = lprocfs_mdc_obd_vars; } -- GitLab From 982ec91f50a0e417cb353a2e5dff5af16541377a Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:29 +0530 Subject: [PATCH 0585/9167] staging: lustre: move open brace to next line after functions Fixes the following checkpatch error: ERROR: open brace '{' following function declarations go on the next line Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 3 ++- drivers/staging/lustre/lustre/mdc/mdc_request.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index 60217ba440aa..daaa7422c03f 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -256,7 +256,8 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, set_mrc_cr_flags(rec, cr_flags); } -static inline __u64 attr_pack(unsigned int ia_valid) { +static inline __u64 attr_pack(unsigned int ia_valid) +{ __u64 sa_valid = 0; if (ia_valid & ATTR_MODE) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 0b517e550477..0bcf624620ce 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2384,7 +2384,8 @@ int mdc_fid_alloc(struct obd_export *exp, struct lu_fid *fid, return seq_client_alloc_fid(NULL, seq, fid); } -struct obd_uuid *mdc_get_uuid(struct obd_export *exp) { +struct obd_uuid *mdc_get_uuid(struct obd_export *exp) +{ struct client_obd *cli = &exp->exp_obd->u.cli; return &cli->cl_target_uuid; } -- GitLab From e5e663ae7a6dc2c402211d38a65b12a189220723 Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:30 +0530 Subject: [PATCH 0586/9167] staging: lustre: fix lines over 80 chars Fixes the following checkpatch warning: WARNING: line over 80 characters Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/lproc_mdc.c | 6 ++++-- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 9 ++++++--- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 7 ++++--- drivers/staging/lustre/lustre/mdc/mdc_request.c | 6 ++++-- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c index f883d9c28f20..16341c818358 100644 --- a/drivers/staging/lustre/lustre/mdc/lproc_mdc.c +++ b/drivers/staging/lustre/lustre/mdc/lproc_mdc.c @@ -56,7 +56,8 @@ static ssize_t mdc_max_rpcs_in_flight_seq_write(struct file *file, size_t count, loff_t *off) { - struct obd_device *dev = ((struct seq_file *)file->private_data)->private; + struct obd_device *dev = + ((struct seq_file *)file->private_data)->private; struct client_obd *cli = &dev->u.cli; int val, rc; @@ -84,7 +85,8 @@ static int mdc_kuc_open(struct inode *inode, struct file *file) static ssize_t mdc_kuc_write(struct file *file, const char *buffer, size_t count, loff_t *off) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct obd_device *obd = + ((struct seq_file *)file->private_data)->private; struct kuc_hdr *lh; struct hsm_action_list *hal; struct hsm_action_item *hai; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index daaa7422c03f..16e2e0b611d1 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -52,7 +52,8 @@ static void __mdc_pack_body(struct mdt_body *b, __u32 suppgid) b->capability = cfs_curproc_cap_pack(); } -void mdc_pack_capa(struct ptlrpc_request *req, const struct req_msg_field *field, +void mdc_pack_capa(struct ptlrpc_request *req, + const struct req_msg_field *field, struct obd_capa *oc) { struct req_capsule *pill = &req->rq_pill; @@ -317,7 +318,8 @@ static void mdc_setattr_pack_rec(struct mdt_rec_setattr *rec, rec->sa_atime = LTIME_S(op_data->op_attr.ia_atime); rec->sa_mtime = LTIME_S(op_data->op_attr.ia_mtime); rec->sa_ctime = LTIME_S(op_data->op_attr.ia_ctime); - rec->sa_attr_flags = ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags; + rec->sa_attr_flags = + ((struct ll_iattr *)&op_data->op_attr)->ia_attr_flags; if ((op_data->op_attr.ia_valid & ATTR_GID) && in_group_p(op_data->op_attr.ia_gid)) rec->sa_suppgid = @@ -552,7 +554,8 @@ int mdc_enter_request(struct client_obd *cli) list_add_tail(&mcw.mcw_entry, &cli->cl_cache_waiters); init_waitqueue_head(&mcw.mcw_waitq); client_obd_list_unlock(&cli->cl_loi_list_lock); - rc = l_wait_event(mcw.mcw_waitq, mdc_req_avail(cli, &mcw), &lwi); + rc = l_wait_event(mcw.mcw_waitq, mdc_req_avail(cli, &mcw), + &lwi); if (rc) { client_obd_list_lock(&cli->cl_loi_list_lock); if (list_empty(&mcw.mcw_entry)) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index 88b43823c632..5de9e8862393 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -450,8 +450,8 @@ static struct ptlrpc_request *mdc_intent_unlink_pack(struct obd_export *exp, } static struct ptlrpc_request *mdc_intent_getattr_pack(struct obd_export *exp, - struct lookup_intent *it, - struct md_op_data *op_data) + struct lookup_intent *it, + struct md_op_data *op_data) { struct ptlrpc_request *req; struct obd_device *obddev = class_exp2obd(exp); @@ -1039,7 +1039,8 @@ static int mdc_finish_intent_lock(struct obd_export *exp, memcpy(&old_lock, lockh, sizeof(*lockh)); if (ldlm_lock_match(NULL, LDLM_FL_BLOCK_GRANTED, NULL, - LDLM_IBITS, &policy, LCK_NL, &old_lock, 0)) { + LDLM_IBITS, &policy, LCK_NL, + &old_lock, 0)) { ldlm_lock_decref_and_cancel(lockh, it->d.lustre.it_lock_mode); memcpy(lockh, &old_lock, sizeof(old_lock)); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 0bcf624620ce..5126262aa73d 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -897,7 +897,8 @@ int mdc_close(struct obd_export *exp, struct md_op_data *op_data, mod->mod_open_req->rq_replay = 0; spin_unlock(&mod->mod_open_req->rq_lock); } else { - CDEBUG(D_HA, "couldn't find open req; expecting close error\n"); + CDEBUG(D_HA, + "couldn't find open req; expecting close error\n"); } mdc_close_pack(req, op_data); @@ -1084,7 +1085,8 @@ int mdc_readpage(struct obd_export *exp, struct md_op_data *op_data, CERROR("too many resend retries, returning error\n"); return -EIO; } - lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(resends), NULL, NULL, NULL); + lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(resends), + NULL, NULL, NULL); l_wait_event(waitq, 0, &lwi); goto restart_bulk; -- GitLab From 301af9068dd1b72ee80d0321b67eb5d76e08b3c0 Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:31 +0530 Subject: [PATCH 0587/9167] staging: lustre: Add missing spaces around operators and braces. Fixes the following checkpatch errors: ERROR: space required after that ',' (ctx:VxV) ERROR: space required after that close brace '}' Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 25 ++++++++++--------- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 5 ++-- drivers/staging/lustre/lustre/mdc/mdc_reint.c | 2 +- .../staging/lustre/lustre/mdc/mdc_request.c | 7 +++--- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index 16e2e0b611d1..35ce2fdf696c 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -345,7 +345,8 @@ void mdc_setattr_pack(struct ptlrpc_request *req, struct md_op_data *op_data, struct mdt_ioepoch *epoch; struct lov_user_md *lum = NULL; - CLASSERT(sizeof(struct mdt_rec_reint) ==sizeof(struct mdt_rec_setattr)); + CLASSERT(sizeof(struct mdt_rec_reint) == + sizeof(struct mdt_rec_setattr)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); mdc_setattr_pack_rec(rec, op_data); @@ -385,18 +386,18 @@ void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data) rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); LASSERT(rec != NULL); - rec->ul_opcode = op_data->op_cli_flags & CLI_RM_ENTRY ? + rec->ul_opcode = op_data->op_cli_flags & CLI_RM_ENTRY ? REINT_RMENTRY : REINT_UNLINK; - rec->ul_fsuid = op_data->op_fsuid; - rec->ul_fsgid = op_data->op_fsgid; - rec->ul_cap = op_data->op_cap; - rec->ul_mode = op_data->op_mode; - rec->ul_suppgid1= op_data->op_suppgids[0]; - rec->ul_suppgid2= -1; - rec->ul_fid1 = op_data->op_fid1; - rec->ul_fid2 = op_data->op_fid2; - rec->ul_time = op_data->op_mod_time; - rec->ul_bias = op_data->op_bias; + rec->ul_fsuid = op_data->op_fsuid; + rec->ul_fsgid = op_data->op_fsgid; + rec->ul_cap = op_data->op_cap; + rec->ul_mode = op_data->op_mode; + rec->ul_suppgid1 = op_data->op_suppgids[0]; + rec->ul_suppgid2 = -1; + rec->ul_fid1 = op_data->op_fid1; + rec->ul_fid2 = op_data->op_fid2; + rec->ul_time = op_data->op_mod_time; + rec->ul_bias = op_data->op_bias; mdc_pack_capa(req, &RMF_CAPA1, op_data->op_capa1); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index 5de9e8862393..a5a2597616e9 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -621,7 +621,7 @@ static int mdc_finish_enqueue(struct obd_export *exp, * function without doing so, and try to replay a failed create * (bug 3440) */ if (it->it_op & IT_OPEN && req->rq_replay && - (!it_disposition(it, DISP_OPEN_OPEN) ||intent->it_status != 0)) + (!it_disposition(it, DISP_OPEN_OPEN) || intent->it_status != 0)) mdc_clear_replay_flag(req, intent->it_status); DEBUG_REQ(D_RPCTRACE, req, "op: %d disposition: %x, status: %d", @@ -1047,7 +1047,8 @@ static int mdc_finish_intent_lock(struct obd_export *exp, it->d.lustre.it_lock_handle = lockh->cookie; } } - CDEBUG(D_DENTRY,"D_IT dentry %.*s intent: %s status %d disp %x rc %d\n", + CDEBUG(D_DENTRY, + "D_IT dentry %.*s intent: %s status %d disp %x rc %d\n", op_data->op_namelen, op_data->op_name, ldlm_it2str(it->it_op), it->d.lustre.it_status, it->d.lustre.it_disposition, rc); return rc; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_reint.c b/drivers/staging/lustre/lustre/mdc/mdc_reint.c index c5420a42bc33..b8c0f482b76f 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_reint.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_reint.c @@ -71,7 +71,7 @@ int mdc_resource_get_unused(struct obd_export *exp, const struct lu_fid *fid, __u64 bits) { struct ldlm_namespace *ns = exp->exp_obd->obd_namespace; - ldlm_policy_data_t policy = {{0}}; + ldlm_policy_data_t policy = {}; struct ldlm_res_id res_id; struct ldlm_resource *res; int count; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 5126262aa73d..6def92133227 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -326,7 +326,8 @@ static int mdc_is_subdir(struct obd_export *exp, return rc; } -static int mdc_xattr_common(struct obd_export *exp,const struct req_format *fmt, +static int mdc_xattr_common(struct obd_export *exp, + const struct req_format *fmt, const struct lu_fid *fid, struct obd_capa *oc, int opcode, obd_valid valid, const char *xattr_name, const char *input, @@ -544,7 +545,7 @@ int mdc_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req, int lmvsize; struct lov_mds_md *lmv; - if(!S_ISDIR(md->body->mode)) { + if (!S_ISDIR(md->body->mode)) { CDEBUG(D_INFO, "OBD_MD_FLDIREA set, should be a " "directory, but is not\n"); GOTO(out, rc = -EPROTO); @@ -1536,7 +1537,7 @@ static int changelog_kkuc_cb(const struct lu_env *env, struct llog_handle *llh, memcpy(lh + 1, &rec->cr, len - sizeof(*lh)); rc = libcfs_kkuc_msg_put(cs->cs_fp, lh); - CDEBUG(D_CHANGELOG, "kucmsg fp %p len %d rc %d\n", cs->cs_fp, len,rc); + CDEBUG(D_CHANGELOG, "kucmsg fp %p len %d rc %d\n", cs->cs_fp, len, rc); return rc; } -- GitLab From 125ffec0bd80313124b719465c9fd529b39d6230 Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:32 +0530 Subject: [PATCH 0588/9167] staging: lustre: replace c99 style comments with C89 Fixes the following checkpatch error: ERROR: do not use C99 // comments Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index 35ce2fdf696c..8b301f4d7e23 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -416,9 +416,9 @@ void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data) LASSERT(rec != NULL); rec->lk_opcode = REINT_LINK; - rec->lk_fsuid = op_data->op_fsuid;//current->fsuid; - rec->lk_fsgid = op_data->op_fsgid;//current->fsgid; - rec->lk_cap = op_data->op_cap;//current->cap_effective; + rec->lk_fsuid = op_data->op_fsuid; /* current->fsuid; */ + rec->lk_fsgid = op_data->op_fsgid; /* current->fsgid; */ + rec->lk_cap = op_data->op_cap; /* current->cap_effective; */ rec->lk_suppgid1 = op_data->op_suppgids[0]; rec->lk_suppgid2 = op_data->op_suppgids[1]; rec->lk_fid1 = op_data->op_fid1; -- GitLab From 7436d0704fd3fc98287bded7f30ad2b9b3a7e61b Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:33 +0530 Subject: [PATCH 0589/9167] staging: lustre: add blank lines after declarations Fixes the following checkpatch warning: WARNING: Missing a blank line after declarations Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_lib.c | 1 + drivers/staging/lustre/lustre/mdc/mdc_locks.c | 3 +++ drivers/staging/lustre/lustre/mdc/mdc_request.c | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_lib.c b/drivers/staging/lustre/lustre/mdc/mdc_lib.c index 8b301f4d7e23..e8732cc30ce2 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_lib.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_lib.c @@ -490,6 +490,7 @@ void mdc_getattr_pack(struct ptlrpc_request *req, __u64 valid, int flags, if (op_data->op_name) { char *tmp = req_capsule_client_get(&req->rq_pill, &RMF_NAME); + LOGL0(op_data->op_name, op_data->op_namelen, tmp); } diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index a5a2597616e9..4d837d61be65 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -134,6 +134,7 @@ int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data, if (lock->l_resource->lr_lvb_inode && lock->l_resource->lr_lvb_inode != data) { struct inode *old_inode = lock->l_resource->lr_lvb_inode; + LASSERTF(old_inode->i_state & I_FREEING, "Found existing inode %p/%lu/%u state %lu in lock: " "setting data to %p/%lu/%u\n", old_inode, @@ -678,6 +679,7 @@ static int mdc_finish_enqueue(struct obd_export *exp, */ if ((it->it_op & IT_OPEN) && req->rq_replay) { void *lmm; + if (req_capsule_get_size(pill, &RMF_EADATA, RCL_CLIENT) < body->eadatasize) @@ -1029,6 +1031,7 @@ static int mdc_finish_intent_lock(struct obd_export *exp, lock = ldlm_handle2lock(lockh); if (lock) { ldlm_policy_data_t policy = lock->l_policy_data; + LDLM_DEBUG(lock, "matching against this"); LASSERTF(fid_res_name_eq(&mdt_body->fid1, diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 6def92133227..57d903156917 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -203,6 +203,7 @@ static int mdc_getattr_common(struct obd_export *exp, if (body->valid & OBD_MD_FLMDSCAPA) { struct lustre_capa *capa; + capa = req_capsule_server_get(pill, &RMF_CAPA1); if (capa == NULL) return -EPROTO; @@ -283,6 +284,7 @@ int mdc_getattr_name(struct obd_export *exp, struct md_op_data *op_data, if (op_data->op_name) { char *name = req_capsule_client_get(&req->rq_pill, &RMF_NAME); + LASSERT(strnlen(op_data->op_name, op_data->op_namelen) == op_data->op_namelen); memcpy(name, op_data->op_name, op_data->op_namelen); @@ -696,6 +698,7 @@ void mdc_replay_open(struct ptlrpc_request *req) void mdc_commit_open(struct ptlrpc_request *req) { struct md_open_data *mod = req->rq_cb_data; + if (mod == NULL) return; @@ -2390,6 +2393,7 @@ int mdc_fid_alloc(struct obd_export *exp, struct lu_fid *fid, struct obd_uuid *mdc_get_uuid(struct obd_export *exp) { struct client_obd *cli = &exp->exp_obd->u.cli; + return &cli->cl_target_uuid; } @@ -2742,6 +2746,7 @@ int __init mdc_init(void) { int rc; struct lprocfs_static_vars lvars = { NULL }; + lprocfs_mdc_init_vars(&lvars); rc = class_register_type(&mdc_obd_ops, &mdc_md_ops, lvars.module_vars, -- GitLab From ee990b3368d678611fd4d28ae702a3c24ea1d76c Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Wed, 13 Aug 2014 19:31:16 +0530 Subject: [PATCH 0590/9167] ] staging: lustre: fix multi line strings Fixes the following checkpatch warning: WARNING: quoted string split across lines Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 9 +++-- drivers/staging/lustre/lustre/mdc/mdc_reint.c | 3 +- .../staging/lustre/lustre/mdc/mdc_request.c | 36 +++++++++---------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index 4d837d61be65..7f724e3c3f06 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -136,11 +136,10 @@ int mdc_set_lock_data(struct obd_export *exp, __u64 *lockh, void *data, struct inode *old_inode = lock->l_resource->lr_lvb_inode; LASSERTF(old_inode->i_state & I_FREEING, - "Found existing inode %p/%lu/%u state %lu in lock: " - "setting data to %p/%lu/%u\n", old_inode, - old_inode->i_ino, old_inode->i_generation, - old_inode->i_state, - new_inode, new_inode->i_ino, new_inode->i_generation); + "Found existing inode %p/%lu/%u state %lu in lock: setting data to %p/%lu/%u\n", + old_inode, old_inode->i_ino, old_inode->i_generation, + old_inode->i_state, new_inode, new_inode->i_ino, + new_inode->i_generation); } lock->l_resource->lr_lvb_inode = new_inode; if (bits) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_reint.c b/drivers/staging/lustre/lustre/mdc/mdc_reint.c index b8c0f482b76f..46800335ca7d 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_reint.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_reint.c @@ -158,8 +158,7 @@ int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data, *mod = obd_mod_alloc(); if (*mod == NULL) { - DEBUG_REQ(D_ERROR, req, "Can't allocate " - "md_open_data"); + DEBUG_REQ(D_ERROR, req, "Can't allocate md_open_data"); } else { req->rq_replay = 1; req->rq_cb_data = *mod; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 57d903156917..1dfe90e7418f 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -517,14 +517,14 @@ int mdc_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req, struct lov_mds_md *lmm; if (!S_ISREG(md->body->mode)) { - CDEBUG(D_INFO, "OBD_MD_FLEASIZE set, should be a " - "regular file, but is not\n"); + CDEBUG(D_INFO, + "OBD_MD_FLEASIZE set, should be a regular file, but is not\n"); GOTO(out, rc = -EPROTO); } if (md->body->eadatasize == 0) { - CDEBUG(D_INFO, "OBD_MD_FLEASIZE set, " - "but eadatasize 0\n"); + CDEBUG(D_INFO, + "OBD_MD_FLEASIZE set, but eadatasize 0\n"); GOTO(out, rc = -EPROTO); } lmmsize = md->body->eadatasize; @@ -537,8 +537,8 @@ int mdc_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req, GOTO(out, rc); if (rc < sizeof(*md->lsm)) { - CDEBUG(D_INFO, "lsm size too small: " - "rc < sizeof (*md->lsm) (%d < %d)\n", + CDEBUG(D_INFO, + "lsm size too small: rc < sizeof (*md->lsm) (%d < %d)\n", rc, (int)sizeof(*md->lsm)); GOTO(out, rc = -EPROTO); } @@ -548,14 +548,14 @@ int mdc_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req, struct lov_mds_md *lmv; if (!S_ISDIR(md->body->mode)) { - CDEBUG(D_INFO, "OBD_MD_FLDIREA set, should be a " - "directory, but is not\n"); + CDEBUG(D_INFO, + "OBD_MD_FLDIREA set, should be a directory, but is not\n"); GOTO(out, rc = -EPROTO); } if (md->body->eadatasize == 0) { - CDEBUG(D_INFO, "OBD_MD_FLDIREA is set, " - "but eadatasize 0\n"); + CDEBUG(D_INFO, + "OBD_MD_FLDIREA is set, but eadatasize 0\n"); return -EPROTO; } if (md->body->valid & OBD_MD_MEA) { @@ -571,8 +571,8 @@ int mdc_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req, GOTO(out, rc); if (rc < sizeof(*md->mea)) { - CDEBUG(D_INFO, "size too small: " - "rc < sizeof(*md->mea) (%d < %d)\n", + CDEBUG(D_INFO, + "size too small: rc < sizeof(*md->mea) (%d < %d)\n", rc, (int)sizeof(*md->mea)); GOTO(out, rc = -EPROTO); } @@ -778,8 +778,8 @@ int mdc_set_open_replay_data(struct obd_export *exp, rec->cr_old_handle.cookie = body->handle.cookie; open_req->rq_replay_cb = mdc_replay_open; if (!fid_is_sane(&body->fid1)) { - DEBUG_REQ(D_ERROR, open_req, "Saving replay request with " - "insane fid"); + DEBUG_REQ(D_ERROR, open_req, + "Saving replay request with insane fid"); LBUG(); } @@ -928,8 +928,8 @@ int mdc_close(struct obd_export *exp, struct md_op_data *op_data, rc = lustre_msg_get_status(req->rq_repmsg); if (lustre_msg_get_type(req->rq_repmsg) == PTL_RPC_MSG_ERR) { - DEBUG_REQ(D_ERROR, req, "type == PTL_RPC_MSG_ERR, err " - "= %d", rc); + DEBUG_REQ(D_ERROR, req, + "type == PTL_RPC_MSG_ERR, err = %d", rc); if (rc > 0) rc = -rc; } @@ -2055,8 +2055,8 @@ static int mdc_hsm_copytool_send(int len, void *val) return -EPROTO; } - CDEBUG(D_HSM, " Received message mg=%x t=%d m=%d l=%d actions=%d " - "on %s\n", + CDEBUG(D_HSM, + "Received message mg=%x t=%d m=%d l=%d actions=%d on %s\n", lh->kuc_magic, lh->kuc_transport, lh->kuc_msgtype, lh->kuc_msglen, hal->hal_count, hal->hal_fsname); -- GitLab From c35e01ff0859d77d2dea5cca974acf798a940e18 Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:35 +0530 Subject: [PATCH 0591/9167] staging: lustre: Added space between type name and * Fixes the following checkpatch error: ERROR: "(foo*)" should be "(foo *)" Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index 7f724e3c3f06..c03d77c9c5b8 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -218,7 +218,7 @@ int mdc_find_cbdata(struct obd_export *exp, struct ldlm_res_id res_id; int rc = 0; - fid_build_reg_res_name((struct lu_fid*)fid, &res_id); + fid_build_reg_res_name((struct lu_fid *)fid, &res_id); rc = ldlm_resource_iterate(class_exp2obd(exp)->obd_namespace, &res_id, it, data); if (rc == LDLM_ITER_STOP) -- GitLab From 1a4cd3e9d53d786367c30e3a2a0864b69d370b3c Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:36 +0530 Subject: [PATCH 0592/9167] staging: lustre: Fix misplaced opening brace warnings Fixes the following checkpatch error: ERROR: that open brace { should be on the previous line Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 18 +++++++++++------- drivers/staging/lustre/lustre/mdc/mdc_reint.c | 3 +-- .../staging/lustre/lustre/mdc/mdc_request.c | 7 +++++-- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index c03d77c9c5b8..288ce9119ed5 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -785,14 +785,18 @@ int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, __u64 flags, saved_flags = extra_lock_flags; int rc; struct ldlm_res_id res_id; - static const ldlm_policy_data_t lookup_policy = - { .l_inodebits = { MDS_INODELOCK_LOOKUP } }; - static const ldlm_policy_data_t update_policy = - { .l_inodebits = { MDS_INODELOCK_UPDATE } }; - static const ldlm_policy_data_t layout_policy = - { .l_inodebits = { MDS_INODELOCK_LAYOUT } }; + static const ldlm_policy_data_t lookup_policy = { + .l_inodebits = { MDS_INODELOCK_LOOKUP } + }; + static const ldlm_policy_data_t update_policy = { + .l_inodebits = { MDS_INODELOCK_UPDATE } + }; + static const ldlm_policy_data_t layout_policy = { + .l_inodebits = { MDS_INODELOCK_LAYOUT } + }; static const ldlm_policy_data_t getxattr_policy = { - .l_inodebits = { MDS_INODELOCK_XATTR } }; + .l_inodebits = { MDS_INODELOCK_XATTR } + }; ldlm_policy_data_t const *policy = &lookup_policy; int generation, resends = 0; struct ldlm_reply *lockrep; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_reint.c b/drivers/staging/lustre/lustre/mdc/mdc_reint.c index 46800335ca7d..01af30ac1a52 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_reint.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_reint.c @@ -152,8 +152,7 @@ int mdc_setattr(struct obd_export *exp, struct md_op_data *op_data, ptlrpc_request_set_replen(req); if (mod && (op_data->op_flags & MF_EPOCH_OPEN) && - req->rq_import->imp_replayable) - { + req->rq_import->imp_replayable) { LASSERT(*mod == NULL); *mod = obd_mod_alloc(); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 1dfe90e7418f..d6fd21187806 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -1794,8 +1794,11 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, GOTO(out, rc); case OBD_IOC_CHANGELOG_CLEAR: { struct ioc_changelog *icc = karg; - struct changelog_setinfo cs = - {.cs_recno = icc->icc_recno, .cs_id = icc->icc_id}; + struct changelog_setinfo cs = { + .cs_recno = icc->icc_recno, + .cs_id = icc->icc_id + }; + rc = obd_set_info_async(NULL, exp, strlen(KEY_CHANGELOG_CLEAR), KEY_CHANGELOG_CLEAR, sizeof(cs), &cs, NULL); -- GitLab From 78dd07983b405df2f98ae96137c69cb9e208b312 Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:37 +0530 Subject: [PATCH 0593/9167] staging: lustre: move else on the same line as closing brace Fix the following checkpatch error: ERROR: else should follow close brace '}' Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_request.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index d6fd21187806..ffe9e3dd74e6 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -587,8 +587,7 @@ int mdc_get_lustre_md(struct obd_export *exp, struct ptlrpc_request *req, lustre_swab_mdt_remote_perm); if (!md->remote_perm) GOTO(out, rc = -EPROTO); - } - else if (md->body->valid & OBD_MD_FLACL) { + } else if (md->body->valid & OBD_MD_FLACL) { /* for ACL, it's possible that FLACL is set but aclsize is zero. * only when aclsize != 0 there's an actual segment for ACL * in reply buffer. -- GitLab From eb44520b3ad9407704dd111c9acd48911c83beba Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:38 +0530 Subject: [PATCH 0594/9167] staging: lustre: remove parentheses usage with return Fix the following checkpatch error: ERROR: return is not a function, parentheses are not required Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_request.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index ffe9e3dd74e6..57f4952f6391 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -2588,7 +2588,7 @@ static int mdc_process_config(struct obd_device *obd, obd_count len, void *buf) rc = 0; break; } - return(rc); + return rc; } -- GitLab From ab909585b813193bb45f52367c1e7d056e33cfa9 Mon Sep 17 00:00:00 2001 From: Srikrishan Malik Date: Mon, 11 Aug 2014 23:57:39 +0530 Subject: [PATCH 0595/9167] staging: lustre: Cleanup variable declarations in mdc_enqueue() Changes: - move const union vars to the top - move rc to bottom - do not initialize req - set lvb_type to enum member instead of 0 - change __u64 to u64 - fix inconsistant columnization Signed-off-by: Srikrishan Malik Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index 288ce9119ed5..c64a38eaee3e 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -778,13 +778,8 @@ static int mdc_finish_enqueue(struct obd_export *exp, int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, struct lookup_intent *it, struct md_op_data *op_data, struct lustre_handle *lockh, void *lmm, int lmmsize, - struct ptlrpc_request **reqp, __u64 extra_lock_flags) + struct ptlrpc_request **reqp, u64 extra_lock_flags) { - struct obd_device *obddev = class_exp2obd(exp); - struct ptlrpc_request *req = NULL; - __u64 flags, saved_flags = extra_lock_flags; - int rc; - struct ldlm_res_id res_id; static const ldlm_policy_data_t lookup_policy = { .l_inodebits = { MDS_INODELOCK_LOOKUP } }; @@ -798,9 +793,14 @@ int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, .l_inodebits = { MDS_INODELOCK_XATTR } }; ldlm_policy_data_t const *policy = &lookup_policy; - int generation, resends = 0; - struct ldlm_reply *lockrep; - enum lvb_type lvb_type = 0; + struct obd_device *obddev = class_exp2obd(exp); + struct ptlrpc_request *req; + u64 flags, saved_flags = extra_lock_flags; + struct ldlm_res_id res_id; + int generation, resends = 0; + struct ldlm_reply *lockrep; + enum lvb_type lvb_type = LVB_T_NONE; + int rc; LASSERTF(!it || einfo->ei_type == LDLM_IBITS, "lock type %d\n", einfo->ei_type); -- GitLab From 459d3236ad453642db3b99817c10a57d7d77faa4 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Mon, 11 Aug 2014 22:18:29 -0400 Subject: [PATCH 0596/9167] staging/lustre/lnet: Fix potential uninitialized variable warning Greg reports that with one of the patches in his queue there's now an unused variable warning in lnet_parse_ip2nets for ipaddrs variable. Apparently the warning is a false positive as in all cases where lnet_ipaddr_enumerate can return without setting ipaddrs to something a negative return value is returned that is then checked before we actually use ipaddrs. Assign ipaddrs to NULL to quiet this. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lnet/lnet/config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lnet/lnet/config.c b/drivers/staging/lustre/lnet/lnet/config.c index ede664bfb748..af171e25a5ec 100644 --- a/drivers/staging/lustre/lnet/lnet/config.c +++ b/drivers/staging/lustre/lnet/lnet/config.c @@ -1172,7 +1172,7 @@ lnet_ipaddr_enumerate(__u32 **ipaddrsp) int lnet_parse_ip2nets(char **networksp, char *ip2nets) { - __u32 *ipaddrs; + __u32 *ipaddrs = NULL; int nip = lnet_ipaddr_enumerate(&ipaddrs); int rc; -- GitLab From 0ae015be950d498def53a429f50f3ca4f4ed482f Mon Sep 17 00:00:00 2001 From: Hema Prathaban Date: Tue, 12 Aug 2014 17:26:38 +0530 Subject: [PATCH 0597/9167] staging: lustre: lustre: ptlrpc: Fix requires space Fix checkpatch.pl issues spaces required. Signed-off-by: Hema Prathaban Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/client.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index 4146e8b29a6d..dd017f3a77dd 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -267,7 +267,7 @@ static void ptlrpc_at_adj_service(struct ptlrpc_request *req, if (oldse != 0) 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, + req->rq_import->imp_obd->obd_name, req->rq_request_portal, oldse, at_get(&at->iat_service_estimate[idx])); } @@ -2132,7 +2132,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) * interrupts are allowed. Wait until all * complete, or an in-flight req times out. */ - lwi = LWI_TIMEOUT(cfs_time_seconds(timeout? timeout : 1), + lwi = LWI_TIMEOUT(cfs_time_seconds(timeout ? timeout : 1), ptlrpc_expired_set, set); rc = l_wait_event(set->set_waitq, ptlrpc_check_set(NULL, set), &lwi); @@ -2186,7 +2186,7 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) } if (set->set_interpret != NULL) { - int (*interpreter)(struct ptlrpc_request_set *set,void *,int) = + int (*interpreter)(struct ptlrpc_request_set *set, void *, int) = set->set_interpret; rc = interpreter (set, set->set_arg, rc); } else { @@ -2222,7 +2222,7 @@ static void __ptlrpc_free_req(struct ptlrpc_request *request, int locked) } LASSERTF(!request->rq_receiving_reply, "req %p\n", request); - LASSERTF(request->rq_rqbd == NULL, "req %p\n",request);/* client-side */ + LASSERTF(request->rq_rqbd == NULL, "req %p\n", request);/* client-side */ LASSERTF(list_empty(&request->rq_list), "req %p\n", request); LASSERTF(list_empty(&request->rq_set_chain), "req %p\n", request); LASSERTF(list_empty(&request->rq_exp_list), "req %p\n", request); -- GitLab From 0028d585b4f491948c3e732293f5aa781aee1ee9 Mon Sep 17 00:00:00 2001 From: Hema Prathaban Date: Wed, 13 Aug 2014 16:22:41 +0530 Subject: [PATCH 0598/9167] staging: lustre: lustre: ptlrpc: Fix pointer declaration This patch fixes the following checkpatch.pl issue in client.c: ERROR: "foo * bar" should be "foo *bar" Signed-off-by: Hema Prathaban Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/client.c b/drivers/staging/lustre/lustre/ptlrpc/client.c index dd017f3a77dd..8fa9b7127c27 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/client.c +++ b/drivers/staging/lustre/lustre/ptlrpc/client.c @@ -721,7 +721,7 @@ struct ptlrpc_request *__ptlrpc_request_alloc(struct obd_import *imp, */ static struct ptlrpc_request * ptlrpc_request_alloc_internal(struct obd_import *imp, - struct ptlrpc_request_pool * pool, + struct ptlrpc_request_pool *pool, const struct req_format *format) { struct ptlrpc_request *request; @@ -751,7 +751,7 @@ EXPORT_SYMBOL(ptlrpc_request_alloc); * initialize its buffer structure according to capsule template \a format. */ struct ptlrpc_request *ptlrpc_request_alloc_pool(struct obd_import *imp, - struct ptlrpc_request_pool * pool, + struct ptlrpc_request_pool *pool, const struct req_format *format) { return ptlrpc_request_alloc_internal(imp, pool, format); @@ -2692,7 +2692,7 @@ struct ptlrpc_replay_async_args { */ static int ptlrpc_replay_interpret(const struct lu_env *env, struct ptlrpc_request *req, - void * data, int rc) + void *data, int rc) { struct ptlrpc_replay_async_args *aa = data; struct obd_import *imp = req->rq_import; -- GitLab From 3901270b1519a6b416383dfb29eeb79ed104dbbf Mon Sep 17 00:00:00 2001 From: Hema Prathaban Date: Thu, 14 Aug 2014 12:50:04 +0530 Subject: [PATCH 0599/9167] staging: lustre: lustre: ptlrpc: Donot initialise null This patch fixes the following error using checkpatch.pl Error: Do not initialise statics to 0 or NULL Signed-off-by: Hema Prathaban Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/ptlrpc/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/ptlrpc/connection.c b/drivers/staging/lustre/lustre/ptlrpc/connection.c index adff1ab4f5a4..62154c45f420 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/connection.c +++ b/drivers/staging/lustre/lustre/ptlrpc/connection.c @@ -41,7 +41,7 @@ #include "ptlrpc_internal.h" -static struct cfs_hash *conn_hash = NULL; +static struct cfs_hash *conn_hash; static cfs_hash_ops_t conn_hash_ops; struct ptlrpc_connection * -- GitLab From bf8fa21cb70ceaf8d5898c57b80e707dfca79fa9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:31:55 +0200 Subject: [PATCH 0600/9167] Staging: bcm: Bcmchar.c: Fixed indentation of function arguments Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 56 +++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index c1e01f7d64ba..aff21d0d36f3 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -3,7 +3,8 @@ #include "headers.h" static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *Adapter, - PUCHAR pReadData, struct bcm_nvm_readwrite *stNVMReadWrite) + PUCHAR pReadData, + struct bcm_nvm_readwrite *stNVMReadWrite) { INT Status = STATUS_FAILURE; @@ -40,7 +41,8 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *Adapter, } static int handle_flash2x_adapter(struct bcm_mini_adapter *Adapter, - PUCHAR pReadData, struct bcm_nvm_readwrite *stNVMReadWrite) + PUCHAR pReadData, + struct bcm_nvm_readwrite *stNVMReadWrite) { /* * New Requirement:- @@ -179,7 +181,9 @@ static int bcm_char_release(struct inode *inode, struct file *filp) return 0; } -static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, +static ssize_t bcm_char_read(struct file *filp, + char __user *buf, + size_t size, loff_t *f_pos) { struct bcm_tarang_data *pTarang = filp->private_data; @@ -635,7 +639,7 @@ static int bcm_char_ioctl_led_thread_state_change_req(void __user *argp, } static int bcm_char_ioctl_gpio_status_request(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_gpio_info gpio_info = {0}; struct bcm_ioctl_buffer IoBuffer; @@ -677,7 +681,7 @@ static int bcm_char_ioctl_gpio_status_request(void __user *argp, } static int bcm_char_ioctl_gpio_multi_request(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX]; struct bcm_gpio_multi_info *pgpio_multi_info = @@ -784,7 +788,7 @@ static int bcm_char_ioctl_gpio_multi_request(void __user *argp, } static int bcm_char_ioctl_gpio_mode_request(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX]; struct bcm_gpio_multi_mode *pgpio_multi_mode = @@ -877,7 +881,7 @@ static int bcm_char_ioctl_gpio_mode_request(void __user *argp, } static int bcm_char_ioctl_misc_request(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_ioctl_buffer IoBuffer; PVOID pvBuffer = NULL; @@ -959,7 +963,7 @@ static int bcm_char_ioctl_buffer_download_start( } static int bcm_char_ioctl_buffer_download(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_firmware_info *psFwInfo = NULL; struct bcm_ioctl_buffer IoBuffer; @@ -1044,7 +1048,7 @@ static int bcm_char_ioctl_buffer_download(void __user *argp, } static int bcm_char_ioctl_buffer_download_stop(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { INT Status; int timeout = 0; @@ -1151,7 +1155,7 @@ static int bcm_char_ioctl_qos_threshold(ULONG arg, } static int bcm_char_ioctl_switch_transfer_mode(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { UINT uiData = 0; @@ -1190,7 +1194,7 @@ static int bcm_char_ioctl_get_driver_version(void __user *argp) } static int bcm_char_ioctl_get_current_status(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_link_state link_state; struct bcm_ioctl_buffer IoBuffer; @@ -1221,7 +1225,7 @@ static int bcm_char_ioctl_get_current_status(void __user *argp, static int bcm_char_ioctl_set_mac_tracing(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_ioctl_buffer IoBuffer; UINT tracing_flag; @@ -1242,7 +1246,7 @@ static int bcm_char_ioctl_set_mac_tracing(void __user *argp, } static int bcm_char_ioctl_get_dsx_indication(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_ioctl_buffer IoBuffer; ULONG ulSFId = 0; @@ -1268,7 +1272,8 @@ static int bcm_char_ioctl_get_dsx_indication(void __user *argp, } static int bcm_char_ioctl_get_host_mibs(void __user *argp, - struct bcm_mini_adapter *Adapter, struct bcm_tarang_data *pTarang) + struct bcm_mini_adapter *Adapter, + struct bcm_tarang_data *pTarang) { struct bcm_ioctl_buffer IoBuffer; INT Status = STATUS_FAILURE; @@ -1305,7 +1310,7 @@ static int bcm_char_ioctl_get_host_mibs(void __user *argp, } static int bcm_char_ioctl_bulk_wrm(void __user *argp, - struct bcm_mini_adapter *Adapter, UINT cmd) + struct bcm_mini_adapter *Adapter, UINT cmd) { struct bcm_bulk_wrm_buffer *pBulkBuffer; struct bcm_ioctl_buffer IoBuffer; @@ -1376,7 +1381,7 @@ static int bcm_char_ioctl_bulk_wrm(void __user *argp, } static int bcm_char_ioctl_get_nvm_size(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_ioctl_buffer IoBuffer; @@ -1393,7 +1398,7 @@ static int bcm_char_ioctl_get_nvm_size(void __user *argp, } static int bcm_char_ioctl_cal_init(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_ioctl_buffer IoBuffer; UINT uiSectorSize = 0; @@ -1440,7 +1445,7 @@ static int bcm_char_ioctl_cal_init(void __user *argp, } static int bcm_char_ioctl_set_debug(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { #ifdef DEBUG struct bcm_ioctl_buffer IoBuffer; @@ -1483,7 +1488,7 @@ static int bcm_char_ioctl_set_debug(void __user *argp, } static int bcm_char_ioctl_nvm_rw(void __user *argp, - struct bcm_mini_adapter *Adapter, UINT cmd) + struct bcm_mini_adapter *Adapter, UINT cmd) { struct bcm_nvm_readwrite stNVMReadWrite; struct timeval tv0, tv1; @@ -1895,7 +1900,7 @@ BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, } static int bcm_char_ioctl_set_active_section(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { enum bcm_flash2x_section_val eFlash2xSectionVal = 0; INT Status = STATUS_FAILURE; @@ -1950,7 +1955,7 @@ static int bcm_char_ioctl_set_active_section(void __user *argp, } static int bcm_char_ioctl_copy_section(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_flash2x_copy_section sCopySectStrut = {0}; struct bcm_ioctl_buffer IoBuffer; @@ -2051,7 +2056,7 @@ static int bcm_char_ioctl_copy_section(void __user *argp, } static int bcm_char_ioctl_get_flash_cs_info(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_ioctl_buffer IoBuffer; INT Status = STATUS_SUCCESS; @@ -2093,7 +2098,7 @@ static int bcm_char_ioctl_get_flash_cs_info(void __user *argp, } static int bcm_char_ioctl_select_dsd(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_ioctl_buffer IoBuffer; INT Status = STATUS_FAILURE; @@ -2153,7 +2158,7 @@ static int bcm_char_ioctl_select_dsd(void __user *argp, } static int bcm_char_ioctl_nvm_raw_read(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *Adapter) { struct bcm_nvm_readwrite stNVMRead; struct bcm_ioctl_buffer IoBuffer; @@ -2255,7 +2260,8 @@ static int bcm_char_ioctl_nvm_raw_read(void __user *argp, } static int bcm_char_ioctl_cntrlmsg_mask(void __user *argp, - struct bcm_mini_adapter *Adapter, struct bcm_tarang_data *pTarang) + struct bcm_mini_adapter *Adapter, + struct bcm_tarang_data *pTarang) { struct bcm_ioctl_buffer IoBuffer; INT Status = STATUS_FAILURE; -- GitLab From 5a7add1cc72f1ef3662146505add0fa5744fdbec Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:31:56 +0200 Subject: [PATCH 0601/9167] Staging: bcm: Bcmchar.c: Renamed variable "Adapter" -> "ad" Renamed variable "Adapter" -> "ad" in bcm_handle_nvm_read_cmd() handle_flash2x_adapter() bcm_char_open() bcm_char_release() bcm_char_read() bcm_char_ioctl_reg_read_private() bcm_char_ioctl_reg_write_private() bcm_char_ioctl_reg_write_private() bcm_char_ioctl_eeprom_reg_read() bcm_char_ioctl_gpio_set_request() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 174 +++++++++++++++++----------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index aff21d0d36f3..c65fc396502e 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -2,29 +2,29 @@ #include "headers.h" -static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *Adapter, +static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, PUCHAR pReadData, struct bcm_nvm_readwrite *stNVMReadWrite) { INT Status = STATUS_FAILURE; - down(&Adapter->NVMRdmWrmLock); + down(&ad->NVMRdmWrmLock); - if ((Adapter->IdleMode == TRUE) || (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { + if ((ad->IdleMode == TRUE) || (ad->bShutStatus == TRUE) || + (ad->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); - up(&Adapter->NVMRdmWrmLock); + up(&ad->NVMRdmWrmLock); kfree(pReadData); return -EACCES; } - Status = BeceemNVMRead(Adapter, (PUINT)pReadData, + Status = BeceemNVMRead(ad, (PUINT)pReadData, stNVMReadWrite->uiOffset, stNVMReadWrite->uiNumBytes); - up(&Adapter->NVMRdmWrmLock); + up(&ad->NVMRdmWrmLock); if (Status != STATUS_SUCCESS) { kfree(pReadData); @@ -40,7 +40,7 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *Adapter, return STATUS_SUCCESS; } -static int handle_flash2x_adapter(struct bcm_mini_adapter *Adapter, +static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, PUCHAR pReadData, struct bcm_nvm_readwrite *stNVMReadWrite) { @@ -62,17 +62,17 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *Adapter, INT Status; ULONG ulDSDMagicNumInUsrBuff = 0; - Status = BcmFlash2xCorruptSig(Adapter, Adapter->eActiveDSD); + Status = BcmFlash2xCorruptSig(ad, ad->eActiveDSD); if (Status == STATUS_SUCCESS) return STATUS_SUCCESS; if (((stNVMReadWrite->uiOffset + stNVMReadWrite->uiNumBytes) != - Adapter->uiNVMDSDSize) || + ad->uiNVMDSDSize) || (stNVMReadWrite->uiNumBytes < SIGNATURE_SIZE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input.."); - up(&Adapter->NVMRdmWrmLock); + up(&ad->NVMRdmWrmLock); kfree(pReadData); return Status; } @@ -81,9 +81,9 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *Adapter, ntohl(*(PUINT)(pReadData + stNVMReadWrite->uiNumBytes - SIGNATURE_SIZE)); if (ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input.."); - up(&Adapter->NVMRdmWrmLock); + up(&ad->NVMRdmWrmLock); kfree(pReadData); return Status; } @@ -105,27 +105,27 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *Adapter, static int bcm_char_open(struct inode *inode, struct file *filp) { - struct bcm_mini_adapter *Adapter = NULL; + struct bcm_mini_adapter *ad = NULL; struct bcm_tarang_data *pTarang = NULL; - Adapter = GET_BCM_ADAPTER(gblpnetdev); + ad = GET_BCM_ADAPTER(gblpnetdev); pTarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL); if (!pTarang) return -ENOMEM; - pTarang->Adapter = Adapter; + pTarang->Adapter = ad; pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB); - down(&Adapter->RxAppControlQueuelock); - pTarang->next = Adapter->pTarangs; - Adapter->pTarangs = pTarang; - up(&Adapter->RxAppControlQueuelock); + down(&ad->RxAppControlQueuelock); + pTarang->next = ad->pTarangs; + ad->pTarangs = pTarang; + up(&ad->RxAppControlQueuelock); /* Store the Adapter structure */ filp->private_data = pTarang; /* Start Queuing the control response Packets */ - atomic_inc(&Adapter->ApplicationRunning); + atomic_inc(&ad->ApplicationRunning); nonseekable_open(inode, filp); return 0; @@ -134,7 +134,7 @@ static int bcm_char_open(struct inode *inode, struct file *filp) static int bcm_char_release(struct inode *inode, struct file *filp) { struct bcm_tarang_data *pTarang, *tmp, *ptmp; - struct bcm_mini_adapter *Adapter = NULL; + struct bcm_mini_adapter *ad = NULL; struct sk_buff *pkt, *npkt; pTarang = (struct bcm_tarang_data *)filp->private_data; @@ -142,11 +142,11 @@ static int bcm_char_release(struct inode *inode, struct file *filp) if (pTarang == NULL) return 0; - Adapter = pTarang->Adapter; + ad = pTarang->Adapter; - down(&Adapter->RxAppControlQueuelock); + down(&ad->RxAppControlQueuelock); - tmp = Adapter->pTarangs; + tmp = ad->pTarangs; for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) { if (tmp == pTarang) break; @@ -154,11 +154,11 @@ static int bcm_char_release(struct inode *inode, struct file *filp) if (tmp) { if (!ptmp) - Adapter->pTarangs = tmp->next; + ad->pTarangs = tmp->next; else ptmp->next = tmp->next; } else { - up(&Adapter->RxAppControlQueuelock); + up(&ad->RxAppControlQueuelock); return 0; } @@ -169,10 +169,10 @@ static int bcm_char_release(struct inode *inode, struct file *filp) pkt = npkt; } - up(&Adapter->RxAppControlQueuelock); + up(&ad->RxAppControlQueuelock); /* Stop Queuing the control response Packets */ - atomic_dec(&Adapter->ApplicationRunning); + atomic_dec(&ad->ApplicationRunning); kfree(pTarang); @@ -187,33 +187,33 @@ static ssize_t bcm_char_read(struct file *filp, loff_t *f_pos) { struct bcm_tarang_data *pTarang = filp->private_data; - struct bcm_mini_adapter *Adapter = pTarang->Adapter; + struct bcm_mini_adapter *ad = pTarang->Adapter; struct sk_buff *Packet = NULL; ssize_t PktLen = 0; int wait_ret_val = 0; unsigned long ret = 0; wait_ret_val = wait_event_interruptible( - Adapter->process_read_wait_queue, + ad->process_read_wait_queue, (pTarang->RxAppControlHead || - Adapter->device_removed)); + ad->device_removed)); if ((wait_ret_val == -ERESTARTSYS)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + 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 (Adapter->device_removed) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + 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 == Adapter->fw_download_done) + if (false == ad->fw_download_done) return -EACCES; - down(&Adapter->RxAppControlQueuelock); + down(&ad->RxAppControlQueuelock); if (pTarang->RxAppControlHead) { Packet = pTarang->RxAppControlHead; @@ -222,7 +222,7 @@ static ssize_t bcm_char_read(struct file *filp, pTarang->AppCtrlQueueLen--; } - up(&Adapter->RxAppControlQueuelock); + up(&ad->RxAppControlQueuelock); if (Packet) { PktLen = Packet->len; @@ -230,22 +230,22 @@ static ssize_t bcm_char_read(struct file *filp, min_t(size_t, PktLen, size)); if (ret) { dev_kfree_skb(Packet); - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "Returning from copy to user failure\n"); return -EFAULT; } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %zd Bytes From Adapter packet = %p by process %d!\n", PktLen, Packet, current->pid); dev_kfree_skb(Packet); } - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n"); + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n"); return PktLen; } static int bcm_char_ioctl_reg_read_private(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *ad) { struct bcm_rdm_buffer sRdmBuffer = {0}; struct bcm_ioctl_buffer IoBuffer; @@ -279,7 +279,7 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, if (!temp_buff) return -ENOMEM; - bytes = rdmalt(Adapter, (UINT)sRdmBuffer.Register, + bytes = rdmalt(ad, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, Bufflen); if (bytes > 0) { Status = STATUS_SUCCESS; @@ -296,7 +296,7 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, } static int bcm_char_ioctl_reg_write_private(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *ad) { struct bcm_wrm_buffer sWrmBuffer = {0}; struct bcm_ioctl_buffer IoBuffer; @@ -317,25 +317,25 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, return -EFAULT; uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; - if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && + if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && ((uiTempVar == EEPROM_REJECT_REG_1) || (uiTempVar == EEPROM_REJECT_REG_2) || (uiTempVar == EEPROM_REJECT_REG_3) || (uiTempVar == EEPROM_REJECT_REG_4))) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); return -EFAULT; } - Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register, + Status = wrmalt(ad, (UINT)sWrmBuffer.Register, (PUINT)sWrmBuffer.Data, sizeof(ULONG)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); Status = -EFAULT; } @@ -343,7 +343,7 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, } static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *ad) { struct bcm_rdm_buffer sRdmBuffer = {0}; struct bcm_ioctl_buffer IoBuffer; @@ -352,11 +352,11 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, INT Status; int bytes; - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { + if ((ad->IdleMode == TRUE) || + (ad->bShutStatus == TRUE) || + (ad->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); return -EACCES; } @@ -384,7 +384,7 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || ((ULONG)sRdmBuffer.Register & 0x3)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", (int)sRdmBuffer.Register); @@ -393,7 +393,7 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, } uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; - bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, + bytes = rdmaltWithLock(ad, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength); if (bytes > 0) { @@ -411,7 +411,7 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, } static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, - struct bcm_mini_adapter *Adapter, + struct bcm_mini_adapter *ad, UINT cmd) { struct bcm_wrm_buffer sWrmBuffer = {0}; @@ -419,11 +419,11 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, UINT uiTempVar = 0; INT Status; - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { + if ((ad->IdleMode == TRUE) || + (ad->bShutStatus == TRUE) || + (ad->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); return -EACCES; } @@ -443,34 +443,34 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || ((ULONG)sWrmBuffer.Register & 0x3)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)sWrmBuffer.Register); return -EINVAL; } uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; - if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && + if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && ((uiTempVar == EEPROM_REJECT_REG_1) || (uiTempVar == EEPROM_REJECT_REG_2) || (uiTempVar == EEPROM_REJECT_REG_3) || (uiTempVar == EEPROM_REJECT_REG_4)) && (cmd == IOCTL_BCM_REGISTER_WRITE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); return -EFAULT; } - Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, + Status = wrmaltWithLock(ad, (UINT)sWrmBuffer.Register, (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, + BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); Status = -EFAULT; } @@ -478,7 +478,7 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, } static int bcm_char_ioctl_gpio_set_request(void __user *argp, - struct bcm_mini_adapter *Adapter) + struct bcm_mini_adapter *ad) { struct bcm_gpio_info gpio_info = {0}; struct bcm_ioctl_buffer IoBuffer; @@ -489,11 +489,11 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, INT Status; int bytes; - if ((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus == TRUE) || - (Adapter->bPreparingForLowPowerMode == TRUE)) { + if ((ad->IdleMode == TRUE) || + (ad->bShutStatus == TRUE) || + (ad->bPreparingForLowPowerMode == TRUE)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); return -EACCES; @@ -513,8 +513,8 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, uiOperation = gpio_info.uiGpioValue; value = (1< is not correspond to LED !!!", value); @@ -524,16 +524,16 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, /* Set - setting 1 */ if (uiOperation) { /* Set the gpio output register */ - Status = wrmaltWithLock(Adapter, + Status = wrmaltWithLock(ad, BCM_GPIO_OUTPUT_SET_REG, (PUINT)(&value), sizeof(UINT)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to set the %dth GPIO\n", uiBit); @@ -541,16 +541,16 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, } } else { /* Set the gpio output register */ - Status = wrmaltWithLock(Adapter, + Status = wrmaltWithLock(ad, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)(&value), sizeof(UINT)); if (Status == STATUS_SUCCESS) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); } else { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to clear the %dth GPIO\n", uiBit); @@ -558,11 +558,11 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, } } - bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, + bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); if (bytes < 0) { Status = bytes; - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO_MODE_REGISTER read failed"); return Status; } else { @@ -571,15 +571,15 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, /* Set the gpio mode register to output */ *(UINT *)ucResetValue |= (1< Date: Sun, 10 Aug 2014 14:31:57 +0200 Subject: [PATCH 0602/9167] Staging: bcm: Bcmchar.c: Renamed variable "pReadData" -> "read_data" Renamed variable "pReadData" -> "read_data" in bcm_handle_nvm_read_cmd() handle_flash2x_adapter() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index c65fc396502e..5b8e8be3efdf 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -3,7 +3,7 @@ #include "headers.h" static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, - PUCHAR pReadData, + PUCHAR read_data, struct bcm_nvm_readwrite *stNVMReadWrite) { INT Status = STATUS_FAILURE; @@ -17,23 +17,23 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); up(&ad->NVMRdmWrmLock); - kfree(pReadData); + kfree(read_data); return -EACCES; } - Status = BeceemNVMRead(ad, (PUINT)pReadData, + Status = BeceemNVMRead(ad, (PUINT)read_data, stNVMReadWrite->uiOffset, stNVMReadWrite->uiNumBytes); up(&ad->NVMRdmWrmLock); if (Status != STATUS_SUCCESS) { - kfree(pReadData); + kfree(read_data); return Status; } - if (copy_to_user(stNVMReadWrite->pBuffer, pReadData, + if (copy_to_user(stNVMReadWrite->pBuffer, read_data, stNVMReadWrite->uiNumBytes)) { - kfree(pReadData); + kfree(read_data); return -EFAULT; } @@ -41,7 +41,7 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, } static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, - PUCHAR pReadData, + PUCHAR read_data, struct bcm_nvm_readwrite *stNVMReadWrite) { /* @@ -73,18 +73,18 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, 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(pReadData); + kfree(read_data); return Status; } ulDSDMagicNumInUsrBuff = - ntohl(*(PUINT)(pReadData + stNVMReadWrite->uiNumBytes - + ntohl(*(PUINT)(read_data + stNVMReadWrite->uiNumBytes - SIGNATURE_SIZE)); if (ulDSDMagicNumInUsrBuff != 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(pReadData); + kfree(read_data); return Status; } -- GitLab From 9dc535b57a0d1971044c28ca11bb6a95603a54e1 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:31:58 +0200 Subject: [PATCH 0603/9167] Staging: bcm: Bcmchar.c: Renamed variable "stNVMReadWrite" -> "nvm_rw" Renamed variable "stNVMReadWrite" -> "nvm_rw" in bcm_handle_nvm_read_cmd() handle_flash2x_adapter() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 5b8e8be3efdf..f6ab4520235a 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -4,7 +4,7 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, PUCHAR read_data, - struct bcm_nvm_readwrite *stNVMReadWrite) + struct bcm_nvm_readwrite *nvm_rw) { INT Status = STATUS_FAILURE; @@ -22,8 +22,8 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, } Status = BeceemNVMRead(ad, (PUINT)read_data, - stNVMReadWrite->uiOffset, - stNVMReadWrite->uiNumBytes); + nvm_rw->uiOffset, + nvm_rw->uiNumBytes); up(&ad->NVMRdmWrmLock); if (Status != STATUS_SUCCESS) { @@ -31,8 +31,7 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, return Status; } - if (copy_to_user(stNVMReadWrite->pBuffer, read_data, - stNVMReadWrite->uiNumBytes)) { + if (copy_to_user(nvm_rw->pBuffer, read_data, nvm_rw->uiNumBytes)) { kfree(read_data); return -EFAULT; } @@ -42,7 +41,7 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, PUCHAR read_data, - struct bcm_nvm_readwrite *stNVMReadWrite) + struct bcm_nvm_readwrite *nvm_rw) { /* * New Requirement:- @@ -66,9 +65,9 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, if (Status == STATUS_SUCCESS) return STATUS_SUCCESS; - if (((stNVMReadWrite->uiOffset + stNVMReadWrite->uiNumBytes) != + if (((nvm_rw->uiOffset + nvm_rw->uiNumBytes) != ad->uiNVMDSDSize) || - (stNVMReadWrite->uiNumBytes < SIGNATURE_SIZE)) { + (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.."); @@ -78,7 +77,7 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, } ulDSDMagicNumInUsrBuff = - ntohl(*(PUINT)(read_data + stNVMReadWrite->uiNumBytes - + ntohl(*(PUINT)(read_data + nvm_rw->uiNumBytes - SIGNATURE_SIZE)); if (ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) { BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, -- GitLab From bd9a40788d7d25b6fa17ad119c9000c536e6e58d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:31:59 +0200 Subject: [PATCH 0604/9167] Staging: bcm: Bcmchar.c: Renamed variable "Status" -> "status" Renamed variable "Status" -> "status" in bcm_handle_nvm_read_cmd() handle_flash2x_adapter() bcm_char_ioctl_reg_read_private() bcm_char_ioctl_reg_write_private() bcm_char_ioctl_reg_write_private() bcm_char_ioctl_eeprom_reg_read() bcm_char_ioctl_gpio_set_request() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 80 +++++++++++++++++------------------ 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index f6ab4520235a..74e91bea3e45 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -6,7 +6,7 @@ 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; + INT status = STATUS_FAILURE; down(&ad->NVMRdmWrmLock); @@ -21,14 +21,14 @@ static int bcm_handle_nvm_read_cmd(struct bcm_mini_adapter *ad, return -EACCES; } - Status = BeceemNVMRead(ad, (PUINT)read_data, + status = BeceemNVMRead(ad, (PUINT)read_data, nvm_rw->uiOffset, nvm_rw->uiNumBytes); up(&ad->NVMRdmWrmLock); - if (Status != STATUS_SUCCESS) { + if (status != STATUS_SUCCESS) { kfree(read_data); - return Status; + return status; } if (copy_to_user(nvm_rw->pBuffer, read_data, nvm_rw->uiNumBytes)) { @@ -58,11 +58,11 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, * if DSD sig is corrupted, DSD data won't be * considered valid. */ - INT Status; + INT status; ULONG ulDSDMagicNumInUsrBuff = 0; - Status = BcmFlash2xCorruptSig(ad, ad->eActiveDSD); - if (Status == STATUS_SUCCESS) + status = BcmFlash2xCorruptSig(ad, ad->eActiveDSD); + if (status == STATUS_SUCCESS) return STATUS_SUCCESS; if (((nvm_rw->uiOffset + nvm_rw->uiNumBytes) != @@ -73,7 +73,7 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, "DSD Sig is present neither in Flash nor User provided Input.."); up(&ad->NVMRdmWrmLock); kfree(read_data); - return Status; + return status; } ulDSDMagicNumInUsrBuff = @@ -84,7 +84,7 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, "DSD Sig is present neither in Flash nor User provided Input.."); up(&ad->NVMRdmWrmLock); kfree(read_data); - return Status; + return status; } return STATUS_SUCCESS; @@ -249,7 +249,7 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, struct bcm_rdm_buffer sRdmBuffer = {0}; struct bcm_ioctl_buffer IoBuffer; PCHAR temp_buff; - INT Status = STATUS_FAILURE; + INT status = STATUS_FAILURE; UINT Bufflen; u16 temp_value; int bytes; @@ -281,17 +281,17 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, bytes = rdmalt(ad, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, Bufflen); if (bytes > 0) { - Status = STATUS_SUCCESS; + status = STATUS_SUCCESS; if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) { kfree(temp_buff); return -EFAULT; } } else { - Status = bytes; + status = bytes; } kfree(temp_buff); - return Status; + return status; } static int bcm_char_ioctl_reg_write_private(void __user *argp, @@ -300,7 +300,7 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, struct bcm_wrm_buffer sWrmBuffer = {0}; struct bcm_ioctl_buffer IoBuffer; UINT uiTempVar = 0; - INT Status; + INT status; /* Copy Ioctl Buffer structure */ @@ -327,18 +327,18 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, return -EFAULT; } - Status = wrmalt(ad, (UINT)sWrmBuffer.Register, + status = wrmalt(ad, (UINT)sWrmBuffer.Register, (PUINT)sWrmBuffer.Data, sizeof(ULONG)); - if (Status == STATUS_SUCCESS) { + 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; + status = -EFAULT; } - return Status; + return status; } static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, @@ -348,7 +348,7 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, struct bcm_ioctl_buffer IoBuffer; PCHAR temp_buff = NULL; UINT uiTempVar = 0; - INT Status; + INT status; int bytes; if ((ad->IdleMode == TRUE) || @@ -396,17 +396,17 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, (PUINT)temp_buff, IoBuffer.OutputLength); if (bytes > 0) { - Status = STATUS_SUCCESS; + status = STATUS_SUCCESS; if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) { kfree(temp_buff); return -EFAULT; } } else { - Status = bytes; + status = bytes; } kfree(temp_buff); - return Status; + return status; } static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, @@ -416,7 +416,7 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, struct bcm_wrm_buffer sWrmBuffer = {0}; struct bcm_ioctl_buffer IoBuffer; UINT uiTempVar = 0; - INT Status; + INT status; if ((ad->IdleMode == TRUE) || (ad->bShutStatus == TRUE) || @@ -461,19 +461,19 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, return -EFAULT; } - Status = wrmaltWithLock(ad, (UINT)sWrmBuffer.Register, + status = wrmaltWithLock(ad, (UINT)sWrmBuffer.Register, (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); - if (Status == STATUS_SUCCESS) { + 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; + status = -EFAULT; } - return Status; + return status; } static int bcm_char_ioctl_gpio_set_request(void __user *argp, @@ -485,7 +485,7 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, UINT value = 0; UINT uiBit = 0; UINT uiOperation = 0; - INT Status; + INT status; int bytes; if ((ad->IdleMode == TRUE) || @@ -523,11 +523,11 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, /* Set - setting 1 */ if (uiOperation) { /* Set the gpio output register */ - Status = wrmaltWithLock(ad, + status = wrmaltWithLock(ad, BCM_GPIO_OUTPUT_SET_REG, (PUINT)(&value), sizeof(UINT)); - if (Status == STATUS_SUCCESS) { + if (status == STATUS_SUCCESS) { BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); @@ -536,15 +536,15 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, OSAL_DBG, DBG_LVL_ALL, "Failed to set the %dth GPIO\n", uiBit); - return Status; + return status; } } else { /* Set the gpio output register */ - Status = wrmaltWithLock(ad, + status = wrmaltWithLock(ad, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)(&value), sizeof(UINT)); - if (Status == STATUS_SUCCESS) { + if (status == STATUS_SUCCESS) { BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); @@ -553,27 +553,27 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, OSAL_DBG, DBG_LVL_ALL, "Failed to clear the %dth GPIO\n", uiBit); - return Status; + return status; } } bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); if (bytes < 0) { - Status = bytes; + status = bytes; BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO_MODE_REGISTER read failed"); - return Status; + return status; } else { - Status = STATUS_SUCCESS; + status = STATUS_SUCCESS; } /* Set the gpio mode register to output */ *(UINT *)ucResetValue |= (1< Date: Sun, 10 Aug 2014 14:32:00 +0200 Subject: [PATCH 0605/9167] Staging: bcm: Bcmchar.c: Renamed variable "ulDSDMagicNumInUsrBuff" -> "dsd_magic_num_in_usr_buff" Renamed variable "ulDSDMagicNumInUsrBuff" -> "dsd_magic_num_in_usr_buff" in handle_flash2x_adapter(). Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 74e91bea3e45..c4e126f769df 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -59,7 +59,7 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, * considered valid. */ INT status; - ULONG ulDSDMagicNumInUsrBuff = 0; + ULONG dsd_magic_num_in_usr_buff = 0; status = BcmFlash2xCorruptSig(ad, ad->eActiveDSD); if (status == STATUS_SUCCESS) @@ -76,10 +76,10 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, return status; } - ulDSDMagicNumInUsrBuff = + dsd_magic_num_in_usr_buff = ntohl(*(PUINT)(read_data + nvm_rw->uiNumBytes - SIGNATURE_SIZE)); - if (ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) { + 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); -- GitLab From f90a8a25f500700bb1c603b5c9d8a5069e6aa5b9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:01 +0200 Subject: [PATCH 0606/9167] Staging: bcm: Bcmchar.c: Renamed variable "pTarang" -> "tarang" Renamed variable "pTarang" -> "tarang" in bcm_char_open() bcm_char_release() bcm_char_read() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index c4e126f769df..1481074fbd7b 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -105,23 +105,23 @@ static int handle_flash2x_adapter(struct bcm_mini_adapter *ad, static int bcm_char_open(struct inode *inode, struct file *filp) { struct bcm_mini_adapter *ad = NULL; - struct bcm_tarang_data *pTarang = NULL; + struct bcm_tarang_data *tarang = NULL; ad = GET_BCM_ADAPTER(gblpnetdev); - pTarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL); - if (!pTarang) + tarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL); + if (!tarang) return -ENOMEM; - pTarang->Adapter = ad; - pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB); + tarang->Adapter = ad; + tarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB); down(&ad->RxAppControlQueuelock); - pTarang->next = ad->pTarangs; - ad->pTarangs = pTarang; + tarang->next = ad->pTarangs; + ad->pTarangs = tarang; up(&ad->RxAppControlQueuelock); /* Store the Adapter structure */ - filp->private_data = pTarang; + filp->private_data = tarang; /* Start Queuing the control response Packets */ atomic_inc(&ad->ApplicationRunning); @@ -132,22 +132,22 @@ static int bcm_char_open(struct inode *inode, struct file *filp) static int bcm_char_release(struct inode *inode, struct file *filp) { - struct bcm_tarang_data *pTarang, *tmp, *ptmp; + struct bcm_tarang_data *tarang, *tmp, *ptmp; struct bcm_mini_adapter *ad = NULL; struct sk_buff *pkt, *npkt; - pTarang = (struct bcm_tarang_data *)filp->private_data; + tarang = (struct bcm_tarang_data *)filp->private_data; - if (pTarang == NULL) + if (tarang == NULL) return 0; - ad = pTarang->Adapter; + ad = tarang->Adapter; down(&ad->RxAppControlQueuelock); tmp = ad->pTarangs; for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) { - if (tmp == pTarang) + if (tmp == tarang) break; } @@ -161,7 +161,7 @@ static int bcm_char_release(struct inode *inode, struct file *filp) return 0; } - pkt = pTarang->RxAppControlHead; + pkt = tarang->RxAppControlHead; while (pkt) { npkt = pkt->next; kfree_skb(pkt); @@ -173,7 +173,7 @@ static int bcm_char_release(struct inode *inode, struct file *filp) /* Stop Queuing the control response Packets */ atomic_dec(&ad->ApplicationRunning); - kfree(pTarang); + kfree(tarang); /* remove this filp from the asynchronously notified filp's */ filp->private_data = NULL; @@ -185,8 +185,8 @@ static ssize_t bcm_char_read(struct file *filp, size_t size, loff_t *f_pos) { - struct bcm_tarang_data *pTarang = filp->private_data; - struct bcm_mini_adapter *ad = pTarang->Adapter; + struct bcm_tarang_data *tarang = filp->private_data; + struct bcm_mini_adapter *ad = tarang->Adapter; struct sk_buff *Packet = NULL; ssize_t PktLen = 0; int wait_ret_val = 0; @@ -194,7 +194,7 @@ static ssize_t bcm_char_read(struct file *filp, wait_ret_val = wait_event_interruptible( ad->process_read_wait_queue, - (pTarang->RxAppControlHead || + (tarang->RxAppControlHead || ad->device_removed)); if ((wait_ret_val == -ERESTARTSYS)) { @@ -214,11 +214,11 @@ static ssize_t bcm_char_read(struct file *filp, down(&ad->RxAppControlQueuelock); - if (pTarang->RxAppControlHead) { - Packet = pTarang->RxAppControlHead; - DEQUEUEPACKET(pTarang->RxAppControlHead, - pTarang->RxAppControlTail); - pTarang->AppCtrlQueueLen--; + if (tarang->RxAppControlHead) { + Packet = tarang->RxAppControlHead; + DEQUEUEPACKET(tarang->RxAppControlHead, + tarang->RxAppControlTail); + tarang->AppCtrlQueueLen--; } up(&ad->RxAppControlQueuelock); -- GitLab From dab41a0ea8a7704b8a7bf806f123fd8a3d2c0362 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:02 +0200 Subject: [PATCH 0607/9167] Staging: bcm: Bcmchar.c: Renamed variable "PktLen" -> "pkt_len" Renamed variable "PktLen" -> "pkt_len" in bcm_char_read(). Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 1481074fbd7b..36c7b270d81d 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -188,7 +188,7 @@ static ssize_t bcm_char_read(struct file *filp, struct bcm_tarang_data *tarang = filp->private_data; struct bcm_mini_adapter *ad = tarang->Adapter; struct sk_buff *Packet = NULL; - ssize_t PktLen = 0; + ssize_t pkt_len = 0; int wait_ret_val = 0; unsigned long ret = 0; @@ -224,9 +224,9 @@ static ssize_t bcm_char_read(struct file *filp, up(&ad->RxAppControlQueuelock); if (Packet) { - PktLen = Packet->len; + pkt_len = Packet->len; ret = copy_to_user(buf, Packet->data, - min_t(size_t, PktLen, size)); + min_t(size_t, pkt_len, size)); if (ret) { dev_kfree_skb(Packet); BCM_DEBUG_PRINT(ad, DBG_TYPE_PRINTK, 0, 0, @@ -235,12 +235,12 @@ static ssize_t bcm_char_read(struct file *filp, } BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %zd Bytes From Adapter packet = %p by process %d!\n", - PktLen, Packet, current->pid); + pkt_len, Packet, current->pid); dev_kfree_skb(Packet); } BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n"); - return PktLen; + return pkt_len; } static int bcm_char_ioctl_reg_read_private(void __user *argp, -- GitLab From aafec40c30e97cbcbc703ca17ab1ebf7fc06cf3a Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:03 +0200 Subject: [PATCH 0608/9167] Staging: bcm: Bcmchar.c: Renamed variable "Packet" -> "packet" Renamed variable "Packet" -> "packet" in bcm_char_read(). Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 36c7b270d81d..40433da1ceb6 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -187,7 +187,7 @@ static ssize_t bcm_char_read(struct file *filp, { struct bcm_tarang_data *tarang = filp->private_data; struct bcm_mini_adapter *ad = tarang->Adapter; - struct sk_buff *Packet = NULL; + struct sk_buff *packet = NULL; ssize_t pkt_len = 0; int wait_ret_val = 0; unsigned long ret = 0; @@ -215,7 +215,7 @@ static ssize_t bcm_char_read(struct file *filp, down(&ad->RxAppControlQueuelock); if (tarang->RxAppControlHead) { - Packet = tarang->RxAppControlHead; + packet = tarang->RxAppControlHead; DEQUEUEPACKET(tarang->RxAppControlHead, tarang->RxAppControlTail); tarang->AppCtrlQueueLen--; @@ -223,20 +223,20 @@ static ssize_t bcm_char_read(struct file *filp, up(&ad->RxAppControlQueuelock); - if (Packet) { - pkt_len = Packet->len; - ret = copy_to_user(buf, Packet->data, + 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); + 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); + pkt_len, packet, current->pid); + dev_kfree_skb(packet); } BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n"); -- GitLab From 201893bc516a1797d2fac8e931fe551eb78ed8f5 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:04 +0200 Subject: [PATCH 0609/9167] Staging: bcm: Bcmchar.c: Renamed variable "sRdmBuffer" -> "rdm_buff" Renamed variable "sRdmBuffer" -> "rdm_buff" in bcm_char_ioctl_reg_read_private() bcm_char_ioctl_reg_write_private() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 40433da1ceb6..d605e9c234ec 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -246,7 +246,7 @@ static ssize_t bcm_char_read(struct file *filp, static int bcm_char_ioctl_reg_read_private(void __user *argp, struct bcm_mini_adapter *ad) { - struct bcm_rdm_buffer sRdmBuffer = {0}; + struct bcm_rdm_buffer rdm_buff = {0}; struct bcm_ioctl_buffer IoBuffer; PCHAR temp_buff; INT status = STATUS_FAILURE; @@ -258,10 +258,10 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (IoBuffer.InputLength > sizeof(sRdmBuffer)) + if (IoBuffer.InputLength > sizeof(rdm_buff)) return -EINVAL; - if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, + if (copy_from_user(&rdm_buff, IoBuffer.InputBuffer, IoBuffer.InputLength)) return -EFAULT; @@ -278,7 +278,7 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, if (!temp_buff) return -ENOMEM; - bytes = rdmalt(ad, (UINT)sRdmBuffer.Register, + bytes = rdmalt(ad, (UINT)rdm_buff.Register, (PUINT)temp_buff, Bufflen); if (bytes > 0) { status = STATUS_SUCCESS; @@ -344,7 +344,7 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, struct bcm_mini_adapter *ad) { - struct bcm_rdm_buffer sRdmBuffer = {0}; + struct bcm_rdm_buffer rdm_buff = {0}; struct bcm_ioctl_buffer IoBuffer; PCHAR temp_buff = NULL; UINT uiTempVar = 0; @@ -364,10 +364,10 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (IoBuffer.InputLength > sizeof(sRdmBuffer)) + if (IoBuffer.InputLength > sizeof(rdm_buff)) return -EINVAL; - if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, + if (copy_from_user(&rdm_buff, IoBuffer.InputBuffer, IoBuffer.InputLength)) return -EFAULT; @@ -380,19 +380,19 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, if (!temp_buff) return STATUS_FAILURE; - if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)sRdmBuffer.Register & 0x3)) { + 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)sRdmBuffer.Register); + (int)rdm_buff.Register); kfree(temp_buff); return -EINVAL; } - uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; - bytes = rdmaltWithLock(ad, (UINT)sRdmBuffer.Register, + uiTempVar = rdm_buff.Register & EEPROM_REJECT_MASK; + bytes = rdmaltWithLock(ad, (UINT)rdm_buff.Register, (PUINT)temp_buff, IoBuffer.OutputLength); if (bytes > 0) { -- GitLab From 00c6fbcdab7ba34f3597715497b3a8224164c508 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:05 +0200 Subject: [PATCH 0610/9167] Staging: bcm: Bcmchar.c: Renamed variable "IoBuffer" -> "io_buff" Renamed variable "IoBuffer" -> "io_buff" in bcm_char_ioctl_reg_read_private() bcm_char_ioctl_reg_write_private() bcm_char_ioctl_reg_write_private() bcm_char_ioctl_eeprom_reg_read() bcm_char_ioctl_gpio_set_request() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 68 +++++++++++++++++------------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index d605e9c234ec..7eac6be4a141 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -247,7 +247,7 @@ 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 IoBuffer; + struct bcm_ioctl_buffer io_buff; PCHAR temp_buff; INT status = STATUS_FAILURE; UINT Bufflen; @@ -255,22 +255,22 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, int bytes; /* Copy Ioctl Buffer structure */ - if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) + if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (IoBuffer.InputLength > sizeof(rdm_buff)) + if (io_buff.InputLength > sizeof(rdm_buff)) return -EINVAL; - if (copy_from_user(&rdm_buff, IoBuffer.InputBuffer, - IoBuffer.InputLength)) + if (copy_from_user(&rdm_buff, io_buff.InputBuffer, + io_buff.InputLength)) return -EFAULT; - if (IoBuffer.OutputLength > USHRT_MAX || - IoBuffer.OutputLength == 0) { + if (io_buff.OutputLength > USHRT_MAX || + io_buff.OutputLength == 0) { return -EINVAL; } - Bufflen = IoBuffer.OutputLength; + Bufflen = io_buff.OutputLength; temp_value = 4 - (Bufflen % 4); Bufflen += temp_value % 4; @@ -282,7 +282,7 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, (PUINT)temp_buff, Bufflen); if (bytes > 0) { status = STATUS_SUCCESS; - if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) { + if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) { kfree(temp_buff); return -EFAULT; } @@ -298,21 +298,21 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, struct bcm_mini_adapter *ad) { struct bcm_wrm_buffer sWrmBuffer = {0}; - struct bcm_ioctl_buffer IoBuffer; + struct bcm_ioctl_buffer io_buff; UINT uiTempVar = 0; INT status; /* Copy Ioctl Buffer structure */ - if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) + if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (IoBuffer.InputLength > sizeof(sWrmBuffer)) + if (io_buff.InputLength > sizeof(sWrmBuffer)) return -EINVAL; /* Get WrmBuffer structure */ - if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, - IoBuffer.InputLength)) + if (copy_from_user(&sWrmBuffer, io_buff.InputBuffer, + io_buff.InputLength)) return -EFAULT; uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; @@ -345,7 +345,7 @@ 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 IoBuffer; + struct bcm_ioctl_buffer io_buff; PCHAR temp_buff = NULL; UINT uiTempVar = 0; INT status; @@ -361,22 +361,22 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, } /* Copy Ioctl Buffer structure */ - if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) + if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (IoBuffer.InputLength > sizeof(rdm_buff)) + if (io_buff.InputLength > sizeof(rdm_buff)) return -EINVAL; - if (copy_from_user(&rdm_buff, IoBuffer.InputBuffer, - IoBuffer.InputLength)) + if (copy_from_user(&rdm_buff, io_buff.InputBuffer, + io_buff.InputLength)) return -EFAULT; - if (IoBuffer.OutputLength > USHRT_MAX || - IoBuffer.OutputLength == 0) { + if (io_buff.OutputLength > USHRT_MAX || + io_buff.OutputLength == 0) { return -EINVAL; } - temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL); + temp_buff = kmalloc(io_buff.OutputLength, GFP_KERNEL); if (!temp_buff) return STATUS_FAILURE; @@ -393,11 +393,11 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, uiTempVar = rdm_buff.Register & EEPROM_REJECT_MASK; bytes = rdmaltWithLock(ad, (UINT)rdm_buff.Register, - (PUINT)temp_buff, IoBuffer.OutputLength); + (PUINT)temp_buff, io_buff.OutputLength); if (bytes > 0) { status = STATUS_SUCCESS; - if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) { + if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) { kfree(temp_buff); return -EFAULT; } @@ -414,7 +414,7 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, UINT cmd) { struct bcm_wrm_buffer sWrmBuffer = {0}; - struct bcm_ioctl_buffer IoBuffer; + struct bcm_ioctl_buffer io_buff; UINT uiTempVar = 0; INT status; @@ -428,15 +428,15 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, } /* Copy Ioctl Buffer structure */ - if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) + if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (IoBuffer.InputLength > sizeof(sWrmBuffer)) + if (io_buff.InputLength > sizeof(sWrmBuffer)) return -EINVAL; /* Get WrmBuffer structure */ - if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, - IoBuffer.InputLength)) + if (copy_from_user(&sWrmBuffer, io_buff.InputBuffer, + io_buff.InputLength)) return -EFAULT; if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || @@ -480,7 +480,7 @@ 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 IoBuffer; + struct bcm_ioctl_buffer io_buff; UCHAR ucResetValue[4]; UINT value = 0; UINT uiBit = 0; @@ -498,14 +498,14 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, return -EACCES; } - if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) + if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (IoBuffer.InputLength > sizeof(gpio_info)) + if (io_buff.InputLength > sizeof(gpio_info)) return -EINVAL; - if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, - IoBuffer.InputLength)) + if (copy_from_user(&gpio_info, io_buff.InputBuffer, + io_buff.InputLength)) return -EFAULT; uiBit = gpio_info.uiGpioNumber; -- GitLab From 343fae74744506948d86af5144d3d9eadda59943 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:06 +0200 Subject: [PATCH 0611/9167] Staging: bcm: Bcmchar.c: Renamed variable "Bufflen" -> "buff_len" Renamed variable "Bufflen" -> "buff_len" in bcm_char_ioctl_reg_read_private(). Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 7eac6be4a141..f8da3e96ab09 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -250,7 +250,7 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, struct bcm_ioctl_buffer io_buff; PCHAR temp_buff; INT status = STATUS_FAILURE; - UINT Bufflen; + UINT buff_len; u16 temp_value; int bytes; @@ -270,16 +270,16 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, return -EINVAL; } - Bufflen = io_buff.OutputLength; - temp_value = 4 - (Bufflen % 4); - Bufflen += temp_value % 4; + buff_len = io_buff.OutputLength; + temp_value = 4 - (buff_len % 4); + buff_len += temp_value % 4; - temp_buff = kmalloc(Bufflen, GFP_KERNEL); + temp_buff = kmalloc(buff_len, GFP_KERNEL); if (!temp_buff) return -ENOMEM; bytes = rdmalt(ad, (UINT)rdm_buff.Register, - (PUINT)temp_buff, Bufflen); + (PUINT)temp_buff, buff_len); if (bytes > 0) { status = STATUS_SUCCESS; if (copy_to_user(io_buff.OutputBuffer, temp_buff, bytes)) { -- GitLab From 95123f22a17f57bb5c51d662b1ecc3f6cc21afe6 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:07 +0200 Subject: [PATCH 0612/9167] Staging: bcm: Bcmchar.c: Renamed variable "sWrmBuffer" -> "wrm_buff" Renamed variable "sWrmBuffer" -> "wrm_buff" in bcm_char_ioctl_reg_write_private() bcm_char_ioctl_eeprom_reg_read() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index f8da3e96ab09..7f12213cf9f4 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -297,7 +297,7 @@ static int bcm_char_ioctl_reg_read_private(void __user *argp, static int bcm_char_ioctl_reg_write_private(void __user *argp, struct bcm_mini_adapter *ad) { - struct bcm_wrm_buffer sWrmBuffer = {0}; + struct bcm_wrm_buffer wrm_buff = {0}; struct bcm_ioctl_buffer io_buff; UINT uiTempVar = 0; INT status; @@ -307,15 +307,15 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (io_buff.InputLength > sizeof(sWrmBuffer)) + if (io_buff.InputLength > sizeof(wrm_buff)) return -EINVAL; /* Get WrmBuffer structure */ - if (copy_from_user(&sWrmBuffer, io_buff.InputBuffer, + if (copy_from_user(&wrm_buff, io_buff.InputBuffer, io_buff.InputLength)) return -EFAULT; - uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; + uiTempVar = wrm_buff.Register & EEPROM_REJECT_MASK; if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && ((uiTempVar == EEPROM_REJECT_REG_1) || (uiTempVar == EEPROM_REJECT_REG_2) || @@ -327,8 +327,8 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, return -EFAULT; } - status = wrmalt(ad, (UINT)sWrmBuffer.Register, - (PUINT)sWrmBuffer.Data, sizeof(ULONG)); + 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, @@ -413,7 +413,7 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, struct bcm_mini_adapter *ad, UINT cmd) { - struct bcm_wrm_buffer sWrmBuffer = {0}; + struct bcm_wrm_buffer wrm_buff = {0}; struct bcm_ioctl_buffer io_buff; UINT uiTempVar = 0; INT status; @@ -431,24 +431,24 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, if (copy_from_user(&io_buff, argp, sizeof(struct bcm_ioctl_buffer))) return -EFAULT; - if (io_buff.InputLength > sizeof(sWrmBuffer)) + if (io_buff.InputLength > sizeof(wrm_buff)) return -EINVAL; /* Get WrmBuffer structure */ - if (copy_from_user(&sWrmBuffer, io_buff.InputBuffer, + if (copy_from_user(&wrm_buff, io_buff.InputBuffer, io_buff.InputLength)) return -EFAULT; - if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)sWrmBuffer.Register & 0x3)) { + 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)sWrmBuffer.Register); + (int)wrm_buff.Register); return -EINVAL; } - uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; + uiTempVar = wrm_buff.Register & EEPROM_REJECT_MASK; if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && ((uiTempVar == EEPROM_REJECT_REG_1) || (uiTempVar == EEPROM_REJECT_REG_2) || @@ -461,9 +461,9 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, return -EFAULT; } - status = wrmaltWithLock(ad, (UINT)sWrmBuffer.Register, - (PUINT)sWrmBuffer.Data, - sWrmBuffer.Length); + 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, -- GitLab From 41e708109475001431a8182716f90898621e0555 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:08 +0200 Subject: [PATCH 0613/9167] Staging: bcm: Bcmchar.c: Renamed variable "uiTempVar" -> "tmp" Renamed variable "uiTempVar" -> "tmp" in bcm_char_ioctl_reg_write_private() bcm_char_ioctl_eeprom_reg_read() Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 7f12213cf9f4..0622bfc835de 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -299,7 +299,7 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, { struct bcm_wrm_buffer wrm_buff = {0}; struct bcm_ioctl_buffer io_buff; - UINT uiTempVar = 0; + UINT tmp = 0; INT status; /* Copy Ioctl Buffer structure */ @@ -315,12 +315,12 @@ static int bcm_char_ioctl_reg_write_private(void __user *argp, io_buff.InputLength)) return -EFAULT; - uiTempVar = wrm_buff.Register & EEPROM_REJECT_MASK; + tmp = wrm_buff.Register & EEPROM_REJECT_MASK; if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && - ((uiTempVar == EEPROM_REJECT_REG_1) || - (uiTempVar == EEPROM_REJECT_REG_2) || - (uiTempVar == EEPROM_REJECT_REG_3) || - (uiTempVar == EEPROM_REJECT_REG_4))) { + ((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"); @@ -347,7 +347,7 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, struct bcm_rdm_buffer rdm_buff = {0}; struct bcm_ioctl_buffer io_buff; PCHAR temp_buff = NULL; - UINT uiTempVar = 0; + UINT tmp = 0; INT status; int bytes; @@ -391,7 +391,7 @@ static int bcm_char_ioctl_eeprom_reg_read(void __user *argp, return -EINVAL; } - uiTempVar = rdm_buff.Register & EEPROM_REJECT_MASK; + tmp = rdm_buff.Register & EEPROM_REJECT_MASK; bytes = rdmaltWithLock(ad, (UINT)rdm_buff.Register, (PUINT)temp_buff, io_buff.OutputLength); @@ -415,7 +415,7 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, { struct bcm_wrm_buffer wrm_buff = {0}; struct bcm_ioctl_buffer io_buff; - UINT uiTempVar = 0; + UINT tmp = 0; INT status; if ((ad->IdleMode == TRUE) || @@ -448,12 +448,12 @@ static int bcm_char_ioctl_eeprom_reg_write(void __user *argp, return -EINVAL; } - uiTempVar = wrm_buff.Register & EEPROM_REJECT_MASK; + tmp = wrm_buff.Register & EEPROM_REJECT_MASK; if (!((ad->pstargetparams->m_u32Customize) & VSG_MODE) && - ((uiTempVar == EEPROM_REJECT_REG_1) || - (uiTempVar == EEPROM_REJECT_REG_2) || - (uiTempVar == EEPROM_REJECT_REG_3) || - (uiTempVar == EEPROM_REJECT_REG_4)) && + ((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, -- GitLab From 80c329ad0c1a743ca15e997bbcef8bc622c1df58 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 10 Aug 2014 14:32:09 +0200 Subject: [PATCH 0614/9167] Staging: bcm: Bcmchar.c: Renamed variable "ucResetValue" -> "reset_val" Renamed variable "ucResetValue" -> "reset_val" in bcm_char_ioctl_gpio_set_request(). Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 0622bfc835de..c63eb375f418 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -481,7 +481,7 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, { struct bcm_gpio_info gpio_info = {0}; struct bcm_ioctl_buffer io_buff; - UCHAR ucResetValue[4]; + UCHAR reset_val[4]; UINT value = 0; UINT uiBit = 0; UINT uiOperation = 0; @@ -558,7 +558,7 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, } bytes = rdmaltWithLock(ad, (UINT)GPIO_MODE_REGISTER, - (PUINT)ucResetValue, sizeof(UINT)); + (PUINT)reset_val, sizeof(UINT)); if (bytes < 0) { status = bytes; BCM_DEBUG_PRINT(ad, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, @@ -569,9 +569,9 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, } /* Set the gpio mode register to output */ - *(UINT *)ucResetValue |= (1< Date: Sun, 10 Aug 2014 14:32:10 +0200 Subject: [PATCH 0615/9167] Staging: bcm: Bcmchar.c: Renamed variable "uiBit" -> "bit" Renamed variable "uiBit" -> "bit" in bcm_char_ioctl_gpio_set_request(). Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index c63eb375f418..6ae95d0c2b9e 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -483,7 +483,7 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, struct bcm_ioctl_buffer io_buff; UCHAR reset_val[4]; UINT value = 0; - UINT uiBit = 0; + UINT bit = 0; UINT uiOperation = 0; INT status; int bytes; @@ -508,9 +508,9 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, io_buff.InputLength)) return -EFAULT; - uiBit = gpio_info.uiGpioNumber; + bit = gpio_info.uiGpioNumber; uiOperation = gpio_info.uiGpioValue; - value = (1< Date: Sun, 10 Aug 2014 14:32:11 +0200 Subject: [PATCH 0616/9167] Staging: bcm: Bcmchar.c: Renamed variable "uiOperation" -> "operation" Renamed variable "uiOperation" -> "operation" in bcm_char_ioctl_gpio_set_request(). Signed-off-by: Matthias Beyer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Bcmchar.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 6ae95d0c2b9e..8b23ec947fd0 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -484,7 +484,7 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, UCHAR reset_val[4]; UINT value = 0; UINT bit = 0; - UINT uiOperation = 0; + UINT operation = 0; INT status; int bytes; @@ -509,7 +509,7 @@ static int bcm_char_ioctl_gpio_set_request(void __user *argp, return -EFAULT; bit = gpio_info.uiGpioNumber; - uiOperation = gpio_info.uiGpioValue; + operation = gpio_info.uiGpioValue; value = (1< Date: Sun, 10 Aug 2014 20:04:36 -0700 Subject: [PATCH 0617/9167] drivers/staging/rtl8192u/r8192U_wx.c: fix warnings issued by sparse This minor patch motivated by eudyptula challenge fixes the following warnings issued by `sparse' in drivers/staging/rtl8192u/r8192U_wx.c: .../r8192U_wx.c:27:5: warning: symbol 'rtl8180_rates' was not declared. Should it be static? .../r8192U_wx.c:961:22: warning: symbol 'r8192_get_wireless_stats' was not declared. Should it be static? .../r8192U_wx.c:990:24: warning: symbol 'r8192_wx_handlers_def' was not declared. Should it be static? Signed-off-by: Ovidiu Toader Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_wx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index 6808e872296e..a404ed47aa4d 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -22,9 +22,10 @@ #include "r8192U_hw.h" #include "dot11d.h" +#include "r8192U_wx.h" #define RATE_COUNT 12 -u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, +static const u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000}; -- GitLab From f2ea5ff8a7cde20542d47d1398d3fc710d357f6f Mon Sep 17 00:00:00 2001 From: Jeremiah Mahler Date: Tue, 12 Aug 2014 00:03:44 -0700 Subject: [PATCH 0618/9167] staging: rtl8192u/ieee80211: Fix sparse ieee80211_debug_init/_exit not declared warning A sparse warning is generated about 'ieee80211_debug_init' and 'ieee80211_debug_exit' not being declared. drivers/staging/rtl8192u/ieee80211/ieee80211_module.c:275:12: warning: symbol 'ieee80211_debug_init' was not declared. Should it be static? drivers/staging/rtl8192u/ieee80211/ieee80211_module.c:297:13: warning: symbol 'ieee80211_debug_exit' was not declared. Should it be static? These functions are used outside of this file so using static will not work. The prototypes are given in r8192U_core.c but sparse nonetheless still gives a warning. Fix the sparse warning by moving these prototypes from r8192U_core.c to ieee80211.h. Signed-off-by: Jeremiah Mahler Cc: Joel Pelaez Jorge Cc: Andrea Merello Cc: "John W. Linville" Cc: Joe Perches Cc: Himangi Saraogi Cc: Arnd Bergmann Cc: Peter P Waskiewicz Jr Cc: Ana Rey Cc: Chaitanya Hazarey Cc: Rickard Strandqvist Cc: Teodora Baluta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211.h | 4 ++++ drivers/staging/rtl8192u/r8192U_core.c | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 1040bab9702a..c118551066c8 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -2485,6 +2485,10 @@ extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_reques extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b); +/* ieee80211_module.c */ +extern int ieee80211_debug_init(void); +extern void ieee80211_debug_exit(void); + //extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee); extern void ieee80211_wx_sync_scan_wq(struct work_struct *work); diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index bd8a497af06e..eb96bedb1c53 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -4805,8 +4805,6 @@ static void rtl8192_usb_disconnect(struct usb_interface *intf) } /* fun with the built-in ieee80211 stack... */ -extern int ieee80211_debug_init(void); -extern void ieee80211_debug_exit(void); extern int ieee80211_crypto_init(void); extern void ieee80211_crypto_deinit(void); extern int ieee80211_crypto_tkip_init(void); -- GitLab From d6c28c23f89b00a01b34670f0f1ddcdc2e0bca67 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:14 +0530 Subject: [PATCH 0619/9167] staging: rtl8188eu: Cleanup firmware initialization code Using rtl8188ee's (drivers/net/wireless/rtlwifi/rtl8188ee/fw.c) neat and clean firmware initialization code to replace rtl8188eu's messy firmware initialization code. Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/Makefile | 1 + drivers/staging/rtl8188eu/hal/fw.c | 236 ++++++++++++++ .../staging/rtl8188eu/hal/rtl8188e_hal_init.c | 298 ------------------ drivers/staging/rtl8188eu/hal/usb_halinit.c | 6 +- drivers/staging/rtl8188eu/include/drv_types.h | 7 - drivers/staging/rtl8188eu/include/fw.h | 59 ++++ .../staging/rtl8188eu/include/rtl8188e_hal.h | 47 +-- drivers/staging/rtl8188eu/os_dep/os_intfs.c | 7 +- 8 files changed, 309 insertions(+), 352 deletions(-) create mode 100644 drivers/staging/rtl8188eu/hal/fw.c create mode 100644 drivers/staging/rtl8188eu/include/fw.h diff --git a/drivers/staging/rtl8188eu/Makefile b/drivers/staging/rtl8188eu/Makefile index aeebf9311f15..32d64a77c83a 100644 --- a/drivers/staging/rtl8188eu/Makefile +++ b/drivers/staging/rtl8188eu/Makefile @@ -17,6 +17,7 @@ r8188eu-y := \ core/rtw_sta_mgt.o \ core/rtw_wlan_util.o \ core/rtw_xmit.o \ + hal/fw.o \ hal/HalHWImg8188E_MAC.o \ hal/HalHWImg8188E_BB.o \ hal/HalHWImg8188E_RF.o \ diff --git a/drivers/staging/rtl8188eu/hal/fw.c b/drivers/staging/rtl8188eu/hal/fw.c new file mode 100644 index 000000000000..09324ae80e72 --- /dev/null +++ b/drivers/staging/rtl8188eu/hal/fw.c @@ -0,0 +1,236 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2013 Realtek Corporation. + * + * 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. + * + * 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, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * + * Larry Finger + * + *****************************************************************************/ + +#include "fw.h" +#include "drv_types.h" +#include "usb_ops_linux.h" +#include "rtl8188e_spec.h" +#include "rtl8188e_hal.h" + +#include +#include + +static void _rtl88e_enable_fw_download(struct adapter *adapt, bool enable) +{ + u8 tmp; + + if (enable) { + tmp = usb_read8(adapt, REG_MCUFWDL); + usb_write8(adapt, REG_MCUFWDL, tmp | 0x01); + + tmp = usb_read8(adapt, REG_MCUFWDL + 2); + usb_write8(adapt, REG_MCUFWDL + 2, tmp & 0xf7); + } else { + tmp = usb_read8(adapt, REG_MCUFWDL); + usb_write8(adapt, REG_MCUFWDL, tmp & 0xfe); + + usb_write8(adapt, REG_MCUFWDL + 1, 0x00); + } +} + +static void _rtl88e_fw_block_write(struct adapter *adapt, + const u8 *buffer, u32 size) +{ + u32 blk_sz = sizeof(u32); + u8 *buf_ptr = (u8 *)buffer; + u32 *pu4BytePtr = (u32 *)buffer; + u32 i, offset, blk_cnt, remain; + + blk_cnt = size / blk_sz; + remain = size % blk_sz; + + for (i = 0; i < blk_cnt; i++) { + offset = i * blk_sz; + usb_write32(adapt, (FW_8192C_START_ADDRESS + offset), + *(pu4BytePtr + i)); + } + + if (remain) { + offset = blk_cnt * blk_sz; + buf_ptr += offset; + for (i = 0; i < remain; i++) { + usb_write8(adapt, (FW_8192C_START_ADDRESS + + offset + i), *(buf_ptr + i)); + } + } +} + +static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) +{ + u32 fwlen = *pfwlen; + u8 remain = (u8) (fwlen % 4); + + remain = (remain == 0) ? 0 : (4 - remain); + + while (remain > 0) { + pfwbuf[fwlen] = 0; + fwlen++; + remain--; + } + + *pfwlen = fwlen; +} + +static void _rtl88e_fw_page_write(struct adapter *adapt, + u32 page, const u8 *buffer, u32 size) +{ + u8 value8; + u8 u8page = (u8) (page & 0x07); + + value8 = (usb_read8(adapt, REG_MCUFWDL + 2) & 0xF8) | u8page; + + usb_write8(adapt, (REG_MCUFWDL + 2), value8); + _rtl88e_fw_block_write(adapt, buffer, size); +} + +static void _rtl88e_write_fw(struct adapter *adapt, u8 *buffer, u32 size) +{ + u8 *buf_ptr = buffer; + u32 page_no, remain; + u32 page, offset; + + _rtl88e_fill_dummy(buf_ptr, &size); + + page_no = size / FW_8192C_PAGE_SIZE; + remain = size % FW_8192C_PAGE_SIZE; + + for (page = 0; page < page_no; page++) { + offset = page * FW_8192C_PAGE_SIZE; + _rtl88e_fw_page_write(adapt, page, (buf_ptr + offset), + FW_8192C_PAGE_SIZE); + } + + if (remain) { + offset = page_no * FW_8192C_PAGE_SIZE; + page = page_no; + _rtl88e_fw_page_write(adapt, page, (buf_ptr + offset), remain); + } +} + +static void rtl88e_firmware_selfreset(struct adapter *adapt) +{ + u8 u1b_tmp; + + u1b_tmp = usb_read8(adapt, REG_SYS_FUNC_EN+1); + usb_write8(adapt, REG_SYS_FUNC_EN+1, (u1b_tmp & (~BIT(2)))); + usb_write8(adapt, REG_SYS_FUNC_EN+1, (u1b_tmp | BIT(2))); +} + +static int _rtl88e_fw_free_to_go(struct adapter *adapt) +{ + int err = -EIO; + u32 counter = 0; + u32 value32; + + do { + value32 = usb_read32(adapt, REG_MCUFWDL); + if (value32 & FWDL_ChkSum_rpt) + break; + } while (counter++ < POLLING_READY_TIMEOUT_COUNT); + + if (counter >= POLLING_READY_TIMEOUT_COUNT) { + goto exit; + } + + value32 = usb_read32(adapt, REG_MCUFWDL); + value32 |= MCUFWDL_RDY; + value32 &= ~WINTINI_RDY; + usb_write32(adapt, REG_MCUFWDL, value32); + + rtl88e_firmware_selfreset(adapt); + counter = 0; + + do { + value32 = usb_read32(adapt, REG_MCUFWDL); + if (value32 & WINTINI_RDY) { + err = 0; + goto exit; + } + + udelay(FW_8192C_POLLING_DELAY); + + } while (counter++ < POLLING_READY_TIMEOUT_COUNT); + +exit: + return err; +} + +int rtl88e_download_fw(struct adapter *adapt) +{ + struct hal_data_8188e *rtlhal = GET_HAL_DATA(adapt); + struct dvobj_priv *dvobj = adapter_to_dvobj(adapt); + struct device *device = dvobj_to_dev(dvobj); + const struct firmware *fw; + const char fw_name[] = "rtlwifi/rtl8188eufw.bin"; + struct rtl92c_firmware_header *pfwheader = NULL; + u8 *pfwdata; + u32 fwsize; + int err; + + 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", + FW_8188E_SIZE); + return -1; + } + + pfwdata = kzalloc(FW_8188E_SIZE, GFP_KERNEL); + if (!pfwdata) + return -ENOMEM; + + rtlhal->pfirmware = pfwdata; + memcpy(rtlhal->pfirmware, fw->data, fw->size); + rtlhal->fwsize = fw->size; + release_firmware(fw); + + fwsize = rtlhal->fwsize; + pfwheader = (struct rtl92c_firmware_header *)pfwdata; + + if (IS_FW_HEADER_EXIST(pfwheader)) { + pfwdata = pfwdata + 32; + fwsize = fwsize - 32; + } + + if (usb_read8(adapt, REG_MCUFWDL) & RAM_DL_SEL) { + usb_write8(adapt, REG_MCUFWDL, 0); + rtl88e_firmware_selfreset(adapt); + } + _rtl88e_enable_fw_download(adapt, true); + usb_write8(adapt, REG_MCUFWDL, usb_read8(adapt, REG_MCUFWDL) | FWDL_ChkSum_rpt); + _rtl88e_write_fw(adapt, pfwdata, fwsize); + _rtl88e_enable_fw_download(adapt, false); + + err = _rtl88e_fw_free_to_go(adapt); + + return err; +} diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index fbf70f6a0151..ac4bedee0205 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -170,145 +170,8 @@ void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len) DBG_88E("###### %s ######\n", __func__); } -static void _FWDownloadEnable(struct adapter *padapter, bool enable) -{ - u8 tmp; - - if (enable) { - /* MCU firmware download enable. */ - tmp = usb_read8(padapter, REG_MCUFWDL); - usb_write8(padapter, REG_MCUFWDL, tmp | 0x01); - - /* 8051 reset */ - tmp = usb_read8(padapter, REG_MCUFWDL+2); - usb_write8(padapter, REG_MCUFWDL+2, tmp&0xf7); - } else { - /* MCU firmware download disable. */ - tmp = usb_read8(padapter, REG_MCUFWDL); - usb_write8(padapter, REG_MCUFWDL, tmp&0xfe); - - /* Reserved for fw extension. */ - usb_write8(padapter, REG_MCUFWDL+1, 0x00); - } -} - #define MAX_REG_BOLCK_SIZE 196 -static int _BlockWrite(struct adapter *padapter, void *buffer, u32 buffSize) -{ - int ret = _SUCCESS; - u32 blockSize_p1 = 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */ - u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */ - u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */ - u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0; - u32 remainSize_p1 = 0, remainSize_p2 = 0; - u8 *bufferPtr = (u8 *)buffer; - u32 i = 0, offset = 0; - - blockSize_p1 = MAX_REG_BOLCK_SIZE; - - /* 3 Phase #1 */ - blockCount_p1 = buffSize / blockSize_p1; - remainSize_p1 = buffSize % blockSize_p1; - - if (blockCount_p1) { - RT_TRACE(_module_hal_init_c_, _drv_notice_, - ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n", - buffSize, blockSize_p1, blockCount_p1, remainSize_p1)); - } - - for (i = 0; i < blockCount_p1; i++) { - ret = usb_writeN(padapter, (FW_8188E_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1)); - if (ret == _FAIL) - goto exit; - } - - /* 3 Phase #2 */ - if (remainSize_p1) { - offset = blockCount_p1 * blockSize_p1; - - blockCount_p2 = remainSize_p1/blockSize_p2; - remainSize_p2 = remainSize_p1%blockSize_p2; - - if (blockCount_p2) { - RT_TRACE(_module_hal_init_c_, _drv_notice_, - ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n", - (buffSize-offset), blockSize_p2 , blockCount_p2, remainSize_p2)); - } - - for (i = 0; i < blockCount_p2; i++) { - ret = usb_writeN(padapter, (FW_8188E_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2)); - - if (ret == _FAIL) - goto exit; - } - } - - /* 3 Phase #3 */ - if (remainSize_p2) { - offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2); - - blockCount_p3 = remainSize_p2 / blockSize_p3; - - RT_TRACE(_module_hal_init_c_, _drv_notice_, - ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n", - (buffSize-offset), blockSize_p3, blockCount_p3)); - - for (i = 0; i < blockCount_p3; i++) { - ret = usb_write8(padapter, (FW_8188E_START_ADDRESS + offset + i), *(bufferPtr + offset + i)); - - if (ret == _FAIL) - goto exit; - } - } - -exit: - return ret; -} - -static int _PageWrite(struct adapter *padapter, u32 page, void *buffer, u32 size) -{ - u8 value8; - u8 u8Page = (u8)(page & 0x07); - - value8 = (usb_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page; - usb_write8(padapter, REG_MCUFWDL+2, value8); - - return _BlockWrite(padapter, buffer, size); -} - -static int _WriteFW(struct adapter *padapter, void *buffer, u32 size) -{ - /* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */ - /* We can remove _ReadChipVersion from ReadpadapterInfo8192C later. */ - int ret = _SUCCESS; - u32 pageNums, remainSize; - u32 page, offset; - u8 *bufferPtr = (u8 *)buffer; - - pageNums = size / MAX_PAGE_SIZE; - remainSize = size % MAX_PAGE_SIZE; - - for (page = 0; page < pageNums; page++) { - offset = page * MAX_PAGE_SIZE; - ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_PAGE_SIZE); - - if (ret == _FAIL) - goto exit; - } - if (remainSize) { - offset = pageNums * MAX_PAGE_SIZE; - page = pageNums; - ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize); - - if (ret == _FAIL) - goto exit; - } - RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n")); -exit: - return ret; -} - void _8051Reset88E(struct adapter *padapter) { u8 u1bTmp; @@ -319,167 +182,6 @@ void _8051Reset88E(struct adapter *padapter) DBG_88E("=====> _8051Reset88E(): 8051 reset success .\n"); } -static s32 _FWFreeToGo(struct adapter *padapter) -{ - u32 counter = 0; - u32 value32; - - /* polling CheckSum report */ - do { - value32 = usb_read32(padapter, REG_MCUFWDL); - if (value32 & FWDL_ChkSum_rpt) - break; - } while (counter++ < POLLING_READY_TIMEOUT_COUNT); - - if (counter >= POLLING_READY_TIMEOUT_COUNT) { - DBG_88E("%s: chksum report fail! REG_MCUFWDL:0x%08x\n", __func__, value32); - return _FAIL; - } - DBG_88E("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __func__, value32); - - value32 = usb_read32(padapter, REG_MCUFWDL); - value32 |= MCUFWDL_RDY; - value32 &= ~WINTINI_RDY; - usb_write32(padapter, REG_MCUFWDL, value32); - - _8051Reset88E(padapter); - - /* polling for FW ready */ - counter = 0; - do { - value32 = usb_read32(padapter, REG_MCUFWDL); - if (value32 & WINTINI_RDY) { - DBG_88E("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __func__, value32); - return _SUCCESS; - } - udelay(5); - } while (counter++ < POLLING_READY_TIMEOUT_COUNT); - - DBG_88E("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", __func__, value32); - return _FAIL; -} - -#define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0) - -static int load_firmware(struct rt_firmware *pFirmware, struct device *device) -{ - int rtstatus = _SUCCESS; - const struct firmware *fw; - const char fw_name[] = "rtlwifi/rtl8188eufw.bin"; - - if (request_firmware(&fw, fw_name, device)) { - rtstatus = _FAIL; - goto exit; - } - if (!fw) { - pr_err("Firmware %s not available\n", fw_name); - rtstatus = _FAIL; - goto exit; - } - if (fw->size > FW_8188E_SIZE) { - rtstatus = _FAIL; - RT_TRACE(_module_hal_init_c_, _drv_err_, - ("Firmware size exceed 0x%X. Check it.\n", - FW_8188E_SIZE)); - goto exit; - } - - pFirmware->szFwBuffer = kzalloc(FW_8188E_SIZE, GFP_KERNEL); - if (!pFirmware->szFwBuffer) { - rtstatus = _FAIL; - goto exit; - } - memcpy(pFirmware->szFwBuffer, fw->data, fw->size); - pFirmware->ulFwLength = fw->size; - release_firmware(fw); - - DBG_88E_LEVEL(_drv_info_, - "+%s: !bUsedWoWLANFw, FmrmwareLen:%d+\n", __func__, - pFirmware->ulFwLength); -exit: - return rtstatus; -} - -s32 rtl8188e_FirmwareDownload(struct adapter *padapter) -{ - s32 rtStatus = _SUCCESS; - u8 writeFW_retry = 0; - u32 fwdl_start_time; - struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); - struct device *device = dvobj_to_dev(dvobj); - struct rt_firmware_hdr *pFwHdr = NULL; - u8 *pFirmwareBuf; - u32 FirmwareLen; - static int log_version; - - RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __func__)); - if (!dvobj->firmware.szFwBuffer) - rtStatus = load_firmware(&dvobj->firmware, device); - if (rtStatus == _FAIL) { - dvobj->firmware.szFwBuffer = NULL; - goto Exit; - } - pFirmwareBuf = dvobj->firmware.szFwBuffer; - FirmwareLen = dvobj->firmware.ulFwLength; - - /* To Check Fw header. Added by tynli. 2009.12.04. */ - pFwHdr = (struct rt_firmware_hdr *)dvobj->firmware.szFwBuffer; - - pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version); - pHalData->FirmwareSubVersion = pFwHdr->Subversion; - pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature); - - if (!log_version++) - pr_info("%sFirmware Version %d, SubVersion %d, Signature 0x%x\n", - DRIVER_PREFIX, pHalData->FirmwareVersion, - pHalData->FirmwareSubVersion, pHalData->FirmwareSignature); - - if (IS_FW_HEADER_EXIST(pFwHdr)) { - /* Shift 32 bytes for FW header */ - pFirmwareBuf = pFirmwareBuf + 32; - FirmwareLen = FirmwareLen - 32; - } - - /* Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself, */ - /* or it will cause download Fw fail. 2010.02.01. by tynli. */ - if (usb_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) { /* 8051 RAM code */ - usb_write8(padapter, REG_MCUFWDL, 0x00); - _8051Reset88E(padapter); - } - - _FWDownloadEnable(padapter, true); - fwdl_start_time = jiffies; - while (1) { - /* reset the FWDL chksum */ - usb_write8(padapter, REG_MCUFWDL, usb_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt); - - rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen); - - if (rtStatus == _SUCCESS || - (rtw_get_passing_time_ms(fwdl_start_time) > 500 && writeFW_retry++ >= 3)) - break; - - DBG_88E("%s writeFW_retry:%u, time after fwdl_start_time:%ums\n", - __func__, writeFW_retry, rtw_get_passing_time_ms(fwdl_start_time) - ); - } - _FWDownloadEnable(padapter, false); - if (_SUCCESS != rtStatus) { - DBG_88E("DL Firmware failed!\n"); - goto Exit; - } - - rtStatus = _FWFreeToGo(padapter); - if (_SUCCESS != rtStatus) { - DBG_88E("DL Firmware failed!\n"); - goto Exit; - } - RT_TRACE(_module_hal_init_c_, _drv_info_, ("Firmware is ready to run!\n")); -Exit: - return rtStatus; -} - void rtl8188e_InitializeFirmwareVars(struct adapter *padapter) { struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index e18393317bdc..42541c56ad00 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -22,7 +22,7 @@ #include #include #include - +#include #include #include #include @@ -744,9 +744,9 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter) Adapter->bFWReady = false; haldata->fw_ractrl = false; } else { - status = rtl8188e_FirmwareDownload(Adapter); + status = rtl88e_download_fw(Adapter); - if (status != _SUCCESS) { + if (status) { DBG_88E("%s: Download Firmware failed!!\n", __func__); Adapter->bFWReady = false; haldata->fw_ractrl = false; diff --git a/drivers/staging/rtl8188eu/include/drv_types.h b/drivers/staging/rtl8188eu/include/drv_types.h index 8f42d48243f0..c81317906adc 100644 --- a/drivers/staging/rtl8188eu/include/drv_types.h +++ b/drivers/staging/rtl8188eu/include/drv_types.h @@ -141,15 +141,8 @@ struct registry_priv { #define MAX_CONTINUAL_URB_ERR 4 -struct rt_firmware { - u8 *szFwBuffer; - u32 ulFwLength; -}; - struct dvobj_priv { struct adapter *if1; - struct rt_firmware firmware; - /* For 92D, DMDP have 2 interface. */ u8 InterfaceNumber; u8 NumInterfaces; diff --git a/drivers/staging/rtl8188eu/include/fw.h b/drivers/staging/rtl8188eu/include/fw.h new file mode 100644 index 000000000000..c7c7e7e5ffac --- /dev/null +++ b/drivers/staging/rtl8188eu/include/fw.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * Copyright(c) 2009-2013 Realtek Corporation. + * + * 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. + * + * 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, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae + * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, + * Hsinchu 300, Taiwan. + * Larry Finger + * + *****************************************************************************/ +#include "drv_types.h" +#include + +#ifndef __RTL92C__FW__H__ +#define __RTL92C__FW__H__ + +#define FW_8192C_START_ADDRESS 0x1000 +#define FW_8192C_PAGE_SIZE 4096 +#define FW_8192C_POLLING_DELAY 5 + +struct rtl92c_firmware_header { + u16 signature; + u8 category; + u8 function; + u16 version; + u8 subversion; + u8 rsvd1; + u8 month; + u8 date; + u8 hour; + u8 minute; + u16 ramcodesize; + u16 rsvd2; + u32 svnindex; + u32 rsvd3; + u32 rsvd4; + u32 rsvd5; +}; + +int rtl88e_download_fw(struct adapter *adapt); + +#endif diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h index fb206538392e..8b73c036ac0c 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h @@ -70,45 +70,10 @@ #define MAX_PAGE_SIZE 4096 /* @ page : 4k bytes */ #define IS_FW_HEADER_EXIST(_pFwHdr) \ - ((le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x92C0 || \ - (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88C0 || \ - (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x2300 || \ - (le16_to_cpu(_pFwHdr->Signature)&0xFFF0) == 0x88E0) - -/* This structure must be careful with byte-ordering */ - -struct rt_firmware_hdr { - /* 8-byte alinment required */ - /* LONG WORD 0 ---- */ - __le16 Signature; /* 92C0: test chip; 92C, - * 88C0: test chip; 88C1: MP A-cut; - * 92C1: MP A-cut */ - u8 Category; /* AP/NIC and USB/PCI */ - u8 Function; /* Reserved for different FW function - * indcation, for further use when - * driver needs to download different - * FW for different conditions */ - __le16 Version; /* FW Version */ - u8 Subversion; /* FW Subversion, default 0x00 */ - u16 Rsvd1; - - /* LONG WORD 1 ---- */ - u8 Month; /* Release time Month field */ - u8 Date; /* Release time Date field */ - u8 Hour; /* Release time Hour field */ - u8 Minute; /* Release time Minute field */ - __le16 RamCodeSize; /* The size of RAM code */ - u8 Foundry; - u8 Rsvd2; - - /* LONG WORD 2 ---- */ - __le32 SvnIdx; /* The SVN entry index */ - u32 Rsvd3; - - /* LONG WORD 3 ---- */ - u32 Rsvd4; - u32 Rsvd5; -}; + ((le16_to_cpu(_pFwHdr->signature)&0xFFF0) == 0x92C0 || \ + (le16_to_cpu(_pFwHdr->signature)&0xFFF0) == 0x88C0 || \ + (le16_to_cpu(_pFwHdr->signature)&0xFFF0) == 0x2300 || \ + (le16_to_cpu(_pFwHdr->signature)&0xFFF0) == 0x88E0) #define DRIVER_EARLY_INT_TIME 0x05 #define BCN_DMA_ATIME_INT_TIME 0x02 @@ -242,7 +207,8 @@ struct hal_data_8188e { struct HAL_VERSION VersionID; enum rt_regulator_mode RegulatorMode; /* switching regulator or LDO */ u16 CustomerID; - + u8 *pfirmware; + u32 fwsize; u16 FirmwareVersion; u16 FirmwareVersionRev; u16 FirmwareSubVersion; @@ -419,7 +385,6 @@ struct hal_data_8188e { (GET_HAL_DATA(_Adapter)->MultiFunc & RT_MULTI_FUNC_GPS) /* rtl8188e_hal_init.c */ -s32 rtl8188e_FirmwareDownload(struct adapter *padapter); void _8051Reset88E(struct adapter *padapter); void rtl8188e_InitializeFirmwareVars(struct adapter *padapter); diff --git a/drivers/staging/rtl8188eu/os_dep/os_intfs.c b/drivers/staging/rtl8188eu/os_dep/os_intfs.c index c7a44ab33d64..08a80f759b8d 100644 --- a/drivers/staging/rtl8188eu/os_dep/os_intfs.c +++ b/drivers/staging/rtl8188eu/os_dep/os_intfs.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -1121,7 +1122,7 @@ int pm_netdev_open(struct net_device *pnetdev, u8 bnormal) int netdev_close(struct net_device *pnetdev) { struct adapter *padapter = (struct adapter *)rtw_netdev_priv(pnetdev); - struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); + struct hal_data_8188e *rtlhal = GET_HAL_DATA(padapter); RT_TRACE(_module_os_intfs_c_, _drv_info_, ("+88eu_drv - drv_close\n")); @@ -1154,8 +1155,8 @@ int netdev_close(struct net_device *pnetdev) rtw_led_control(padapter, LED_CTL_POWER_OFF); } - kfree(dvobj->firmware.szFwBuffer); - dvobj->firmware.szFwBuffer = NULL; + kfree(rtlhal->pfirmware); + rtlhal->pfirmware = NULL; RT_TRACE(_module_os_intfs_c_, _drv_info_, ("-88eu_drv - drv_close\n")); DBG_88E("-88eu_drv - drv_close, bup =%d\n", padapter->bup); -- GitLab From ff8f35d8c30b37bea061979cd0ec37b24a4148b7 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:15 +0530 Subject: [PATCH 0620/9167] staging: rtl8188eu: Cleanup and simplify MAC configuration code Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/hal/HalHWImg8188E_MAC.c | 120 ++---------------- drivers/staging/rtl8188eu/hal/odm_HWConfig.c | 7 - .../staging/rtl8188eu/hal/rtl8188e_phycfg.c | 37 ------ drivers/staging/rtl8188eu/hal/usb_halinit.c | 15 +-- .../rtl8188eu/include/Hal8188EPhyCfg.h | 1 - .../rtl8188eu/include/HalHWImg8188E_MAC.h | 30 ----- .../staging/rtl8188eu/include/odm_HWConfig.h | 2 - .../staging/rtl8188eu/include/odm_precomp.h | 1 - drivers/staging/rtl8188eu/include/phy.h | 1 + 9 files changed, 15 insertions(+), 199 deletions(-) delete mode 100644 drivers/staging/rtl8188eu/include/HalHWImg8188E_MAC.h create mode 100644 drivers/staging/rtl8188eu/include/phy.h diff --git a/drivers/staging/rtl8188eu/hal/HalHWImg8188E_MAC.c b/drivers/staging/rtl8188eu/hal/HalHWImg8188E_MAC.c index b49b5ab48b18..ccca6a496b2b 100644 --- a/drivers/staging/rtl8188eu/hal/HalHWImg8188E_MAC.c +++ b/drivers/staging/rtl8188eu/hal/HalHWImg8188E_MAC.c @@ -21,36 +21,7 @@ #include "odm_precomp.h" #include -static bool Checkcondition(const u32 condition, const u32 hex) -{ - u32 _board = (hex & 0x000000FF); - u32 _interface = (hex & 0x0000FF00) >> 8; - u32 _platform = (hex & 0x00FF0000) >> 16; - u32 cond = condition; - - if (condition == 0xCDCDCDCD) - return true; - - cond = condition & 0x000000FF; - if ((_board == cond) && cond != 0x00) - return false; - - cond = condition & 0x0000FF00; - cond = cond >> 8; - if ((_interface & cond) == 0 && cond != 0x07) - return false; - - cond = condition & 0x00FF0000; - cond = cond >> 16; - if ((_platform & cond) == 0 && cond != 0x0F) - return false; - return true; -} - - -/****************************************************************************** -* MAC_REG.TXT -******************************************************************************/ +/* MAC_REG.TXT */ static u32 array_MAC_REG_8188E[] = { 0x026, 0x00000041, @@ -145,87 +116,18 @@ static u32 array_MAC_REG_8188E[] = { 0x70B, 0x00000087, }; -enum HAL_STATUS ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *dm_odm) +bool rtl88e_phy_mac_config(struct adapter *adapt) { - #define READ_NEXT_PAIR(v1, v2, i) do { i += 2; v1 = array[i]; v2 = array[i+1]; } while (0) - - u32 hex = 0; - u32 i; - u8 platform = dm_odm->SupportPlatform; - u8 interface_val = dm_odm->SupportInterface; - u8 board = dm_odm->BoardType; - u32 array_len = sizeof(array_MAC_REG_8188E)/sizeof(u32); - u32 *array = array_MAC_REG_8188E; - bool biol = false; + u32 i; + u32 arraylength; + u32 *ptrarray; - struct adapter *adapt = dm_odm->Adapter; - struct xmit_frame *pxmit_frame = NULL; - u8 bndy_cnt = 1; - enum HAL_STATUS rst = HAL_STATUS_SUCCESS; - hex += board; - hex += interface_val << 8; - hex += platform << 16; - hex += 0xFF000000; + arraylength = sizeof(array_MAC_REG_8188E)/sizeof(u32); + ptrarray = array_MAC_REG_8188E; - biol = rtw_IOL_applied(adapt); + for (i = 0; i < arraylength; i = i + 2) + usb_write8(adapt, ptrarray[i], (u8) ptrarray[i + 1]); - if (biol) { - pxmit_frame = rtw_IOL_accquire_xmit_frame(adapt); - if (pxmit_frame == NULL) { - pr_info("rtw_IOL_accquire_xmit_frame failed\n"); - return HAL_STATUS_FAILURE; - } - } - - for (i = 0; i < array_len; i += 2) { - u32 v1 = array[i]; - u32 v2 = array[i+1]; - - /* This (offset, data) pair meets the condition. */ - if (v1 < 0xCDCDCDCD) { - if (biol) { - if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) - bndy_cnt++; - rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF); - } else { - odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2); - } - continue; - } else { /* This line is the start line of branch. */ - if (!Checkcondition(array[i], hex)) { - /* Discard the following (offset, data) pairs. */ - READ_NEXT_PAIR(v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && i < array_len - 2) { - READ_NEXT_PAIR(v1, v2, i); - } - i -= 2; /* prevent from for-loop += 2 */ - } else { /* Configure matched pairs and skip to end of if-else. */ - READ_NEXT_PAIR(v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && i < array_len - 2) { - if (biol) { - if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) - bndy_cnt++; - rtw_IOL_append_WB_cmd(pxmit_frame, (u16)v1, (u8)v2, 0xFF); - } else { - odm_ConfigMAC_8188E(dm_odm, v1, (u8)v2); - } - - READ_NEXT_PAIR(v1, v2, i); - } - while (v2 != 0xDEAD && i < array_len - 2) - READ_NEXT_PAIR(v1, v2, i); - } - } - } - if (biol) { - if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { - pr_info("~~~ MAC IOL_exec_cmds Failed !!!\n"); - rst = HAL_STATUS_FAILURE; - } - } - return rst; + usb_write8(adapt, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); + return true; } diff --git a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c index f2e1d02b8ae3..5cd005781f50 100644 --- a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c @@ -460,10 +460,3 @@ enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *dm_odm, } return HAL_STATUS_SUCCESS; } - -enum HAL_STATUS ODM_ConfigMACWithHeaderFile(struct odm_dm_struct *dm_odm) -{ - u8 result = HAL_STATUS_SUCCESS; - result = READ_AND_CONFIG(8188E, _MAC_REG_); - return result; -} diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c index 9f016a5401d8..922d400315c4 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c @@ -354,43 +354,6 @@ rtl8188e_PHY_SetRFReg( phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data); } -/* */ -/* 3. Initial MAC/BB/RF config by reading MAC/BB/RF txt. */ -/* */ - -/*----------------------------------------------------------------------------- - * Function: PHY_MACConfig8192C - * - * Overview: Condig MAC by header file or parameter file. - * - * Input: NONE - * - * Output: NONE - * - * Return: NONE - * - * Revised History: - * When Who Remark - * 08/12/2008 MHC Create Version 0. - * - *---------------------------------------------------------------------------*/ -s32 PHY_MACConfig8188E(struct adapter *Adapter) -{ - struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); - int rtStatus = _SUCCESS; - - /* */ - /* Config MAC */ - /* */ - if (HAL_STATUS_FAILURE == ODM_ConfigMACWithHeaderFile(&pHalData->odmpriv)) - rtStatus = _FAIL; - - /* 2010.07.13 AMPDU aggregation number B */ - usb_write16(Adapter, REG_MAX_AGGR_NUM, MAX_AGGR_NUM); - - return rtStatus; -} - /** * Function: phy_InitBBRFRegisterDefinition * diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index 42541c56ad00..46d92b12b048 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -27,8 +27,8 @@ #include #include #include +#include -#define HAL_MAC_ENABLE 1 #define HAL_BB_ENABLE 1 #define HAL_RF_ENABLE 1 @@ -759,18 +759,9 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter) } rtl8188e_InitializeFirmwareVars(Adapter); - HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_MAC); -#if (HAL_MAC_ENABLE == 1) - status = PHY_MACConfig8188E(Adapter); - if (status == _FAIL) { - DBG_88E(" ### Failed to init MAC ......\n "); - goto exit; - } -#endif + rtl88e_phy_mac_config(Adapter); - /* */ - /* d. Initialize BB related configurations. */ - /* */ +/* d. Initialize BB related configurations. */ HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BB); #if (HAL_BB_ENABLE == 1) status = PHY_BBConfig8188E(Adapter); diff --git a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h index 260ea6bf9e83..ed156d3bb561 100644 --- a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h +++ b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h @@ -208,7 +208,6 @@ void rtl8188e_PHY_SetRFReg(struct adapter *adapter, enum rf_radio_path rfpath, /* Initialization related function */ /* MAC/BB/RF HAL config */ -int PHY_MACConfig8188E(struct adapter *adapter); int PHY_BBConfig8188E(struct adapter *adapter); int PHY_RFConfig8188E(struct adapter *adapter); diff --git a/drivers/staging/rtl8188eu/include/HalHWImg8188E_MAC.h b/drivers/staging/rtl8188eu/include/HalHWImg8188E_MAC.h deleted file mode 100644 index acf78b94fddb..000000000000 --- a/drivers/staging/rtl8188eu/include/HalHWImg8188E_MAC.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** -* -* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. -* -* 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. -* -* 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, USA -* -* -******************************************************************************/ - -#ifndef __INC_MAC_8188E_HW_IMG_H -#define __INC_MAC_8188E_HW_IMG_H - -/****************************************************************************** -* MAC_REG.TXT -******************************************************************************/ - -enum HAL_STATUS ODM_ReadAndConfig_MAC_REG_8188E(struct odm_dm_struct *pDM_Odm); - -#endif /* end of HWIMG_SUPPORT */ diff --git a/drivers/staging/rtl8188eu/include/odm_HWConfig.h b/drivers/staging/rtl8188eu/include/odm_HWConfig.h index 49e7e163ba70..a687d174112d 100644 --- a/drivers/staging/rtl8188eu/include/odm_HWConfig.h +++ b/drivers/staging/rtl8188eu/include/odm_HWConfig.h @@ -127,6 +127,4 @@ enum HAL_STATUS ODM_ConfigRFWithHeaderFile(struct odm_dm_struct *pDM_Odm, enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *pDM_Odm, enum odm_bb_config_type ConfigType); -enum HAL_STATUS ODM_ConfigMACWithHeaderFile(struct odm_dm_struct *pDM_Odm); - #endif diff --git a/drivers/staging/rtl8188eu/include/odm_precomp.h b/drivers/staging/rtl8188eu/include/odm_precomp.h index 0ab8254ce901..7b98be535040 100644 --- a/drivers/staging/rtl8188eu/include/odm_precomp.h +++ b/drivers/staging/rtl8188eu/include/odm_precomp.h @@ -46,7 +46,6 @@ #include "odm_reg.h" -#include "HalHWImg8188E_MAC.h" #include "HalHWImg8188E_RF.h" #include "HalHWImg8188E_BB.h" diff --git a/drivers/staging/rtl8188eu/include/phy.h b/drivers/staging/rtl8188eu/include/phy.h new file mode 100644 index 000000000000..cab4c8e60e1a --- /dev/null +++ b/drivers/staging/rtl8188eu/include/phy.h @@ -0,0 +1 @@ +bool rtl88e_phy_mac_config(struct adapter *adapt); -- GitLab From 586b60877244595246e6aedc3766500d1227d1f2 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:16 +0530 Subject: [PATCH 0621/9167] staging: rtl8188eu: Cleanup and simplify RF configuration code Cleanup and consolidate RF configuration related code in HalHWImg8188E_RF.c file. Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/hal/HalHWImg8188E_RF.c | 269 +++++++++++------- drivers/staging/rtl8188eu/hal/odm_HWConfig.c | 14 - .../staging/rtl8188eu/hal/rtl8188e_phycfg.c | 9 - .../staging/rtl8188eu/hal/rtl8188e_rf6052.c | 96 ------- drivers/staging/rtl8188eu/hal/usb_halinit.c | 10 +- .../rtl8188eu/include/HalHWImg8188E_RF.h | 30 -- .../staging/rtl8188eu/include/odm_HWConfig.h | 4 - .../staging/rtl8188eu/include/odm_precomp.h | 1 - drivers/staging/rtl8188eu/include/phy.h | 1 + .../staging/rtl8188eu/include/rtl8188e_rf.h | 1 - 10 files changed, 161 insertions(+), 274 deletions(-) delete mode 100644 drivers/staging/rtl8188eu/include/HalHWImg8188E_RF.h diff --git a/drivers/staging/rtl8188eu/hal/HalHWImg8188E_RF.c b/drivers/staging/rtl8188eu/hal/HalHWImg8188E_RF.c index 17c6411ce8ac..2648840f9e20 100644 --- a/drivers/staging/rtl8188eu/hal/HalHWImg8188E_RF.c +++ b/drivers/staging/rtl8188eu/hal/HalHWImg8188E_RF.c @@ -20,38 +20,36 @@ #include "odm_precomp.h" -#include +#include -static bool CheckCondition(const u32 Condition, const u32 Hex) +static bool check_condition(struct adapter *adapt, const u32 condition) { - u32 _board = (Hex & 0x000000FF); - u32 _interface = (Hex & 0x0000FF00) >> 8; - u32 _platform = (Hex & 0x00FF0000) >> 16; - u32 cond = Condition; + struct odm_dm_struct *odm = &GET_HAL_DATA(adapt)->odmpriv; + u32 _board = odm->BoardType; + u32 _platform = odm->SupportPlatform; + u32 _interface = odm->SupportInterface; + u32 cond = condition; - if (Condition == 0xCDCDCDCD) + if (condition == 0xCDCDCDCD) return true; - cond = Condition & 0x000000FF; + cond = condition & 0x000000FF; if ((_board == cond) && cond != 0x00) return false; - cond = Condition & 0x0000FF00; + cond = condition & 0x0000FF00; cond = cond >> 8; if ((_interface & cond) == 0 && cond != 0x07) return false; - cond = Condition & 0x00FF0000; + cond = condition & 0x00FF0000; cond = cond >> 16; if ((_platform & cond) == 0 && cond != 0x0F) return false; return true; } - -/****************************************************************************** -* RadioA_1T.TXT -******************************************************************************/ +/* RadioA_1T.TXT */ static u32 Array_RadioA_1T_8188E[] = { 0x000, 0x00030000, @@ -155,115 +153,166 @@ static u32 Array_RadioA_1T_8188E[] = { 0x000, 0x00033E60, }; -enum HAL_STATUS ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *pDM_Odm) +#define READ_NEXT_PAIR(v1, v2, i) \ +do { \ + i += 2; v1 = array[i]; \ + v2 = array[i+1]; \ +} while (0) + +#define RFREG_OFFSET_MASK 0xfffff +#define B3WIREADDREAALENGTH 0x400 +#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) { - #define READ_NEXT_PAIR(v1, v2, i) do \ - { i += 2; v1 = Array[i]; \ - v2 = Array[i+1]; } while (0) - - u32 hex = 0; - u32 i = 0; - u8 platform = pDM_Odm->SupportPlatform; - u8 interfaceValue = pDM_Odm->SupportInterface; - u8 board = pDM_Odm->BoardType; - u32 ArrayLen = sizeof(Array_RadioA_1T_8188E)/sizeof(u32); - u32 *Array = Array_RadioA_1T_8188E; - bool biol = false; - struct adapter *Adapter = pDM_Odm->Adapter; - struct xmit_frame *pxmit_frame = NULL; - u8 bndy_cnt = 1; - enum HAL_STATUS rst = HAL_STATUS_SUCCESS; - - hex += board; - hex += interfaceValue << 8; - hex += platform << 16; - hex += 0xFF000000; - biol = rtw_IOL_applied(Adapter); - - if (biol) { - pxmit_frame = rtw_IOL_accquire_xmit_frame(Adapter); - if (pxmit_frame == NULL) { - pr_info("rtw_IOL_accquire_xmit_frame failed\n"); - return HAL_STATUS_FAILURE; - } + if (addr == 0xfe) { + mdelay(50); + } else if (addr == 0xfd) { + mdelay(5); + } else if (addr == 0xfc) { + mdelay(1); + } else if (addr == 0xfb) { + udelay(50); + } else if (addr == 0xfa) { + udelay(5); + } else if (addr == 0xf9) { + udelay(1); + } else { + rtl8188e_PHY_SetRFReg(adapt, rfpath, addr, mask, data); + udelay(1); } +} - for (i = 0; i < ArrayLen; i += 2) { - u32 v1 = Array[i]; - u32 v2 = Array[i+1]; +static void rtl8188e_config_rf_reg(struct adapter *adapt, + u32 addr, u32 data) +{ + u32 content = 0x1000; /*RF Content: radio_a_txt*/ + u32 maskforphyset = (u32)(content & 0xE000); + + rtl_rfreg_delay(adapt, RF90_PATH_A, addr| maskforphyset, + RFREG_OFFSET_MASK, + data); +} + +static bool rtl88e_phy_config_rf_with_headerfile(struct adapter *adapt) +{ + u32 i; + u32 array_len = sizeof(Array_RadioA_1T_8188E)/sizeof(u32); + u32 *array = Array_RadioA_1T_8188E; + + for (i = 0; i < array_len; i += 2) { + u32 v1 = array[i]; + u32 v2 = array[i+1]; - /* This (offset, data) pair meets the condition. */ if (v1 < 0xCDCDCDCD) { - if (biol) { - if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) - bndy_cnt++; - - if (v1 == 0xffe) - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); - else if (v1 == 0xfd) - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); - else if (v1 == 0xfc) - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); - else if (v1 == 0xfb) - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); - else if (v1 == 0xfa) - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); - else if (v1 == 0xf9) - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); - else - rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask); - } else { - odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2); - } - continue; - } else { /* This line is the start line of branch. */ - if (!CheckCondition(Array[i], hex)) { - /* Discard the following (offset, data) pairs. */ + rtl8188e_config_rf_reg(adapt, v1, v2); + continue; + } else { + if (!check_condition(adapt, array[i])) { READ_NEXT_PAIR(v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && i < ArrayLen - 2) - READ_NEXT_PAIR(v1, v2, i); - i -= 2; /* prevent from for-loop += 2 */ - } else { /* Configure matched pairs and skip to end of if-else. */ - READ_NEXT_PAIR(v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && i < ArrayLen - 2) { - if (biol) { - if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) - bndy_cnt++; - - if (v1 == 0xffe) - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); - else if (v1 == 0xfd) - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); - else if (v1 == 0xfc) - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); - else if (v1 == 0xfb) - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); - else if (v1 == 0xfa) - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); - else if (v1 == 0xf9) - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); - else - rtw_IOL_append_WRF_cmd(pxmit_frame, RF_PATH_A, (u16)v1, v2, bRFRegOffsetMask); - } else { - odm_ConfigRF_RadioA_8188E(pDM_Odm, v1, v2); - } + while (v2 != 0xDEAD && v2 != 0xCDEF && + v2 != 0xCDCD && i < array_len - 2) READ_NEXT_PAIR(v1, v2, i); + i -= 2; + } else { + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && v2 != 0xCDEF && + v2 != 0xCDCD && i < array_len - 2) { + rtl8188e_config_rf_reg(adapt, v1, v2); + READ_NEXT_PAIR(v1, v2, i); } - while (v2 != 0xDEAD && i < ArrayLen - 2) + while (v2 != 0xDEAD && i < array_len - 2) READ_NEXT_PAIR(v1, v2, i); } } } - if (biol) { - if (!rtw_IOL_exec_cmds_sync(pDM_Odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { - rst = HAL_STATUS_FAILURE; - pr_info("~~~ IOL Config %s Failed !!!\n", __func__); + return true; +} + +static bool rf6052_conf_para(struct adapter *adapt) +{ + struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); + u32 u4val = 0; + u8 rfpath; + bool rtstatus = true; + struct bb_reg_def *pphyreg; + + for (rfpath = 0; rfpath < hal_data->NumTotalRFPath; rfpath++) { + pphyreg = &hal_data->PHYRegDef[rfpath]; + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4val = PHY_QueryBBReg(adapt, pphyreg->rfintfs, + BRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4val = PHY_QueryBBReg(adapt, pphyreg->rfintfs, + BRFSI_RFENV << 16); + break; + } + + PHY_SetBBReg(adapt, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); + udelay(1); + + PHY_SetBBReg(adapt, pphyreg->rfintfo, BRFSI_RFENV, 0x1); + udelay(1); + + PHY_SetBBReg(adapt, pphyreg->rfHSSIPara2, + B3WIREADDREAALENGTH, 0x0); + udelay(1); + + PHY_SetBBReg(adapt, pphyreg->rfHSSIPara2, B3WIREDATALENGTH, 0x0); + udelay(1); + + switch (rfpath) { + case RF90_PATH_A: + rtstatus = rtl88e_phy_config_rf_with_headerfile(adapt); + break; + case RF90_PATH_B: + rtstatus = rtl88e_phy_config_rf_with_headerfile(adapt); + break; + case RF90_PATH_C: + break; + case RF90_PATH_D: + break; + } + + switch (rfpath) { + case RF90_PATH_A: + case RF90_PATH_C: + PHY_SetBBReg(adapt, pphyreg->rfintfs, BRFSI_RFENV, u4val); + break; + case RF90_PATH_B: + case RF90_PATH_D: + PHY_SetBBReg(adapt, pphyreg->rfintfs, BRFSI_RFENV << 16, + u4val); + break; } + + if (rtstatus != true) + return false; } - return rst; + + return rtstatus; +} + +static bool rtl88e_phy_rf6052_config(struct adapter *adapt) +{ + struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); + + if (hal_data->rf_type == RF_1T1R) + hal_data->NumTotalRFPath = 1; + else + hal_data->NumTotalRFPath = 2; + + return rf6052_conf_para(adapt); +} + +bool rtl88e_phy_rf_config(struct adapter *adapt) +{ + return rtl88e_phy_rf6052_config(adapt); } diff --git a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c index 5cd005781f50..4d28ce51fae1 100644 --- a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c @@ -432,20 +432,6 @@ void ODM_PhyStatusQuery(struct odm_dm_struct *dm_odm, ODM_PhyStatusQuery_92CSeries(dm_odm, pPhyInfo, pPhyStatus, pPktinfo); } -enum HAL_STATUS ODM_ConfigRFWithHeaderFile(struct odm_dm_struct *dm_odm, - enum rf_radio_path content, - enum rf_radio_path rfpath) -{ - ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, ("===>ODM_ConfigRFWithHeaderFile\n")); - if (rfpath == RF_PATH_A) - READ_AND_CONFIG(8188E, _RadioA_1T_); - ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, (" ===> ODM_ConfigRFWithHeaderFile() Radio_A:Rtl8188ERadioA_1TArray\n")); - ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, (" ===> ODM_ConfigRFWithHeaderFile() Radio_B:Rtl8188ERadioB_1TArray\n")); - - ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("ODM_ConfigRFWithHeaderFile: Radio No %x\n", rfpath)); - return HAL_STATUS_SUCCESS; -} - enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *dm_odm, enum odm_bb_config_type config_tp) { diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c index 922d400315c4..c1a19978debc 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c @@ -585,15 +585,6 @@ PHY_BBConfig8188E( return rtStatus; } -int PHY_RFConfig8188E(struct adapter *Adapter) -{ - int rtStatus = _SUCCESS; - - /* RF config */ - rtStatus = PHY_RF6052_Config8188E(Adapter); - return rtStatus; -} - static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel, u8 *ofdmPowerLevel, u8 *BW20PowerLevel, u8 *BW40PowerLevel) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c b/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c index 8ce9d0e4eeff..655d8e0d5cb7 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_rf6052.c @@ -429,99 +429,3 @@ rtl8188e_PHY_RF6052SetOFDMTxPower( writeOFDMPowerReg88E(Adapter, index, &writeVal[0]); } } - -static int phy_RF6052_Config_ParaFile(struct adapter *Adapter) -{ - struct bb_reg_def *pPhyReg; - struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); - u32 u4RegValue = 0; - u8 eRFPath; - int rtStatus = _SUCCESS; - - /* 3----------------------------------------------------------------- */ - /* 3 <2> Initialize RF */ - /* 3----------------------------------------------------------------- */ - for (eRFPath = 0; eRFPath < pHalData->NumTotalRFPath; eRFPath++) { - pPhyReg = &pHalData->PHYRegDef[eRFPath]; - - /*----Store original RFENV control type----*/ - switch (eRFPath) { - case RF_PATH_A: - case RF_PATH_C: - u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV); - break; - case RF_PATH_B: - case RF_PATH_D: - u4RegValue = PHY_QueryBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16); - break; - } - /*----Set RF_ENV enable----*/ - PHY_SetBBReg(Adapter, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); - udelay(1);/* PlatformStallExecution(1); */ - - /*----Set RF_ENV output high----*/ - PHY_SetBBReg(Adapter, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); - udelay(1);/* PlatformStallExecution(1); */ - - /* Set bit number of Address and Data for RF register */ - PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); /* Set 1 to 4 bits for 8255 */ - udelay(1);/* PlatformStallExecution(1); */ - - PHY_SetBBReg(Adapter, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); /* Set 0 to 12 bits for 8255 */ - udelay(1);/* PlatformStallExecution(1); */ - - /*----Initialize RF fom connfiguration file----*/ - switch (eRFPath) { - case RF_PATH_A: - if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, (enum rf_radio_path)eRFPath, (enum rf_radio_path)eRFPath)) - rtStatus = _FAIL; - break; - case RF_PATH_B: - if (HAL_STATUS_FAILURE == ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, (enum rf_radio_path)eRFPath, (enum rf_radio_path)eRFPath)) - rtStatus = _FAIL; - break; - case RF_PATH_C: - break; - case RF_PATH_D: - break; - } - /*----Restore RFENV control type----*/; - switch (eRFPath) { - case RF_PATH_A: - case RF_PATH_C: - PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); - break; - case RF_PATH_B: - case RF_PATH_D: - PHY_SetBBReg(Adapter, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); - break; - } - if (rtStatus != _SUCCESS) - goto phy_RF6052_Config_ParaFile_Fail; - } - return rtStatus; - -phy_RF6052_Config_ParaFile_Fail: - return rtStatus; -} - -int PHY_RF6052_Config8188E(struct adapter *Adapter) -{ - struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); - int rtStatus = _SUCCESS; - - /* */ - /* Initialize general global value */ - /* */ - /* TODO: Extend RF_PATH_C and RF_PATH_D in the future */ - if (pHalData->rf_type == RF_1T1R) - pHalData->NumTotalRFPath = 1; - else - pHalData->NumTotalRFPath = 2; - - /* */ - /* Config BB and RF */ - /* */ - rtStatus = phy_RF6052_Config_ParaFile(Adapter); - return rtStatus; -} diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index 46d92b12b048..efb3f7f7f6a4 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -30,7 +30,6 @@ #include #define HAL_BB_ENABLE 1 -#define HAL_RF_ENABLE 1 static void _ConfigNormalChipOutEP_8188E(struct adapter *adapt, u8 NumOutPipe) { @@ -771,14 +770,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter) } #endif - HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_RF); -#if (HAL_RF_ENABLE == 1) - status = PHY_RFConfig8188E(Adapter); - if (status == _FAIL) { - DBG_88E(" ### Failed to init RF ......\n "); - goto exit; - } -#endif + rtl88e_phy_rf_config(Adapter); HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_EFUSE_PATCH); status = rtl8188e_iol_efuse_patch(Adapter); diff --git a/drivers/staging/rtl8188eu/include/HalHWImg8188E_RF.h b/drivers/staging/rtl8188eu/include/HalHWImg8188E_RF.h deleted file mode 100644 index 8ecb40d26c70..000000000000 --- a/drivers/staging/rtl8188eu/include/HalHWImg8188E_RF.h +++ /dev/null @@ -1,30 +0,0 @@ -/****************************************************************************** -* -* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. -* -* 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. -* -* 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, USA -* -* -******************************************************************************/ - -#ifndef __INC_RF_8188E_HW_IMG_H -#define __INC_RF_8188E_HW_IMG_H - -/****************************************************************************** - * RadioA_1T.TXT - ******************************************************************************/ - -enum HAL_STATUS ODM_ReadAndConfig_RadioA_1T_8188E(struct odm_dm_struct *odm); - -#endif /* end of HWIMG_SUPPORT */ diff --git a/drivers/staging/rtl8188eu/include/odm_HWConfig.h b/drivers/staging/rtl8188eu/include/odm_HWConfig.h index a687d174112d..1de4e6399435 100644 --- a/drivers/staging/rtl8188eu/include/odm_HWConfig.h +++ b/drivers/staging/rtl8188eu/include/odm_HWConfig.h @@ -120,10 +120,6 @@ void ODM_MacStatusQuery(struct odm_dm_struct *pDM_Odm, bool bPacketToSelf, bool bPacketBeacon); -enum HAL_STATUS ODM_ConfigRFWithHeaderFile(struct odm_dm_struct *pDM_Odm, - enum rf_radio_path Content, - enum rf_radio_path eRFPath); - enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *pDM_Odm, enum odm_bb_config_type ConfigType); diff --git a/drivers/staging/rtl8188eu/include/odm_precomp.h b/drivers/staging/rtl8188eu/include/odm_precomp.h index 7b98be535040..2b3e51bb0212 100644 --- a/drivers/staging/rtl8188eu/include/odm_precomp.h +++ b/drivers/staging/rtl8188eu/include/odm_precomp.h @@ -46,7 +46,6 @@ #include "odm_reg.h" -#include "HalHWImg8188E_RF.h" #include "HalHWImg8188E_BB.h" #include "odm_RegConfig8188E.h" diff --git a/drivers/staging/rtl8188eu/include/phy.h b/drivers/staging/rtl8188eu/include/phy.h index cab4c8e60e1a..254d4182602d 100644 --- a/drivers/staging/rtl8188eu/include/phy.h +++ b/drivers/staging/rtl8188eu/include/phy.h @@ -1 +1,2 @@ bool rtl88e_phy_mac_config(struct adapter *adapt); +bool rtl88e_phy_rf_config(struct adapter *adapt); diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_rf.h b/drivers/staging/rtl8188eu/include/rtl8188e_rf.h index 10fc356e0209..20b5ba0ffb8a 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_rf.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_rf.h @@ -25,7 +25,6 @@ #define RF6052_MAX_PATH 2 -int PHY_RF6052_Config8188E(struct adapter *Adapter); void rtl8188e_RF_ChangeTxPath(struct adapter *Adapter, u16 DataRate); void rtl8188e_PHY_RF6052SetBandwidth(struct adapter *Adapter, enum ht_channel_width Bandwidth); -- GitLab From 40a4325cd9b18bff0bf5c321eb8fd741ac8ec17a Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:17 +0530 Subject: [PATCH 0622/9167] staging: rtl8188eu: Remove unused functions odm_ConfigRF_Radio[A, B]_8188E() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- .../rtl8188eu/hal/odm_RegConfig8188E.c | 19 ------------------- .../rtl8188eu/include/odm_RegConfig8188E.h | 6 ------ 2 files changed, 25 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c index 4d4978bee51d..41caff98a403 100644 --- a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c +++ b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c @@ -45,25 +45,6 @@ void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, } } -void odm_ConfigRF_RadioA_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data) -{ - u32 content = 0x1000; /* RF_Content: radioa_txt */ - u32 maskforPhySet = (u32)(content&0xE000); - - odm_ConfigRFReg_8188E(pDM_Odm, Addr, Data, RF_PATH_A, Addr|maskforPhySet); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigRFWithHeaderFile: [RadioA] %08X %08X\n", Addr, Data)); -} - -void odm_ConfigRF_RadioB_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data) -{ - u32 content = 0x1001; /* RF_Content: radiob_txt */ - u32 maskforPhySet = (u32)(content&0xE000); - - odm_ConfigRFReg_8188E(pDM_Odm, Addr, Data, RF_PATH_B, Addr|maskforPhySet); - - ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigRFWithHeaderFile: [RadioB] %08X %08X\n", Addr, Data)); -} - void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data) { struct adapter *adapt = pDM_Odm->Adapter; diff --git a/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h b/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h index f2bf7a0d9867..c33c45babbf4 100644 --- a/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h +++ b/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h @@ -23,12 +23,6 @@ void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data, enum rf_radio_path RF_PATH, u32 RegAddr); -void odm_ConfigRF_RadioA_8188E(struct odm_dm_struct *pDM_Odm, - u32 Addr, u32 Data); - -void odm_ConfigRF_RadioB_8188E(struct odm_dm_struct *pDM_Odm, - u32 Addr, u32 Data); - void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data); void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, -- GitLab From 02282888d714000db114512268b270d82e1088fb Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:18 +0530 Subject: [PATCH 0623/9167] staging: rtl8188eu: Remove unused function odm_ConfigRFReg_8188E() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- .../rtl8188eu/hal/odm_RegConfig8188E.c | 25 ------------------- .../rtl8188eu/include/odm_RegConfig8188E.h | 3 --- 2 files changed, 28 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c index 41caff98a403..9c6ad5b8b862 100644 --- a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c +++ b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c @@ -20,31 +20,6 @@ #include "odm_precomp.h" -void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, - u32 Data, enum rf_radio_path RF_PATH, - u32 RegAddr) -{ - struct adapter *adapter = pDM_Odm->Adapter; - - if (Addr == 0xffe) { - msleep(50); - } else if (Addr == 0xfd) { - mdelay(5); - } else if (Addr == 0xfc) { - mdelay(1); - } else if (Addr == 0xfb) { - udelay(50); - } else if (Addr == 0xfa) { - udelay(5); - } else if (Addr == 0xf9) { - udelay(1); - } else { - PHY_SetRFReg(adapter, RF_PATH, RegAddr, bRFRegOffsetMask, Data); - /* Add 1us delay between BB/RF register setting. */ - udelay(1); - } -} - void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data) { struct adapter *adapt = pDM_Odm->Adapter; diff --git a/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h b/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h index c33c45babbf4..b0d94e1ab76e 100644 --- a/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h +++ b/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h @@ -20,9 +20,6 @@ #ifndef __INC_ODM_REGCONFIG_H_8188E #define __INC_ODM_REGCONFIG_H_8188E -void odm_ConfigRFReg_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Data, - enum rf_radio_path RF_PATH, u32 RegAddr); - void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data); void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, -- GitLab From f386a9ce637df1cbffbedfaecbd730ef84c7ef04 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:19 +0530 Subject: [PATCH 0624/9167] staging: rtl8188eu: Remove unused function odm_ConfigMAC_8188E() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c | 8 -------- drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h | 2 -- 2 files changed, 10 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c index 9c6ad5b8b862..634d1115b0fe 100644 --- a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c +++ b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c @@ -20,14 +20,6 @@ #include "odm_precomp.h" -void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data) -{ - struct adapter *adapt = pDM_Odm->Adapter; - - usb_write8(adapt, Addr, Data); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, ("===> ODM_ConfigMACWithHeaderFile: [MAC_REG] %08X %08X\n", Addr, Data)); -} - void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) { struct adapter *adapter = pDM_Odm->Adapter; diff --git a/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h b/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h index b0d94e1ab76e..dd49a86f069b 100644 --- a/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h +++ b/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h @@ -20,8 +20,6 @@ #ifndef __INC_ODM_REGCONFIG_H_8188E #define __INC_ODM_REGCONFIG_H_8188E -void odm_ConfigMAC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u8 Data); - void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data); -- GitLab From 9c7d45c24e9dabf4160ae1af7f45e87079e45931 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:20 +0530 Subject: [PATCH 0625/9167] staging: rtl8188eu: Cleanup and simplify Baseband configuration code Cleanup and consolidate Baseband configuration related code in HalHWImg8188E_BB.c file. Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/hal/HalHWImg8188E_BB.c | 474 +++++++++--------- drivers/staging/rtl8188eu/hal/odm_HWConfig.c | 15 - .../staging/rtl8188eu/hal/rtl8188e_phycfg.c | 187 ------- drivers/staging/rtl8188eu/hal/usb_halinit.c | 10 +- .../rtl8188eu/include/HalHWImg8188E_BB.h | 44 -- .../staging/rtl8188eu/include/odm_precomp.h | 2 - drivers/staging/rtl8188eu/include/phy.h | 1 + 7 files changed, 236 insertions(+), 497 deletions(-) delete mode 100644 drivers/staging/rtl8188eu/include/HalHWImg8188E_BB.h diff --git a/drivers/staging/rtl8188eu/hal/HalHWImg8188E_BB.c b/drivers/staging/rtl8188eu/hal/HalHWImg8188E_BB.c index 787e8f1f97f9..00f9cd737193 100644 --- a/drivers/staging/rtl8188eu/hal/HalHWImg8188E_BB.c +++ b/drivers/staging/rtl8188eu/hal/HalHWImg8188E_BB.c @@ -20,7 +20,7 @@ #include "odm_precomp.h" -#include +#include #define read_next_pair(array, v1, v2, i) \ do { \ @@ -29,36 +29,8 @@ v2 = array[i+1]; \ } while (0) -static bool CheckCondition(const u32 condition, const u32 hex) -{ - u32 _board = (hex & 0x000000FF); - u32 _interface = (hex & 0x0000FF00) >> 8; - u32 _platform = (hex & 0x00FF0000) >> 16; - u32 cond = condition; - - if (condition == 0xCDCDCDCD) - return true; - - cond = condition & 0x000000FF; - if ((_board == cond) && cond != 0x00) - return false; - - cond = condition & 0x0000FF00; - cond = cond >> 8; - if ((_interface & cond) == 0 && cond != 0x07) - return false; - - cond = condition & 0x00FF0000; - cond = cond >> 16; - if ((_platform & cond) == 0 && cond != 0x0F) - return false; - return true; -} - -/****************************************************************************** -* AGC_TAB_1T.TXT -******************************************************************************/ +/* AGC_TAB_1T.TXT */ static u32 array_agc_tab_1t_8188e[] = { 0xC78, 0xFB000001, @@ -191,91 +163,25 @@ static u32 array_agc_tab_1t_8188e[] = { 0xC78, 0x407F0001, }; -enum HAL_STATUS ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *dm_odm) +static bool set_baseband_agc_config(struct adapter *adapt) { - u32 hex = 0; - u32 i = 0; - u8 platform = dm_odm->SupportPlatform; - u8 interfaceValue = dm_odm->SupportInterface; - u8 board = dm_odm->BoardType; - u32 arraylen = sizeof(array_agc_tab_1t_8188e)/sizeof(u32); - u32 *array = array_agc_tab_1t_8188e; - bool biol = false; - struct adapter *adapter = dm_odm->Adapter; - struct xmit_frame *pxmit_frame = NULL; - u8 bndy_cnt = 1; - enum HAL_STATUS rst = HAL_STATUS_SUCCESS; - - hex += board; - hex += interfaceValue << 8; - hex += platform << 16; - hex += 0xFF000000; - biol = rtw_IOL_applied(adapter); - - if (biol) { - pxmit_frame = rtw_IOL_accquire_xmit_frame(adapter); - if (pxmit_frame == NULL) { - pr_info("rtw_IOL_accquire_xmit_frame failed\n"); - return HAL_STATUS_FAILURE; - } - } + u32 i; + u32 arraylen = sizeof(array_agc_tab_1t_8188e)/sizeof(u32); + u32 *array = array_agc_tab_1t_8188e; for (i = 0; i < arraylen; i += 2) { u32 v1 = array[i]; u32 v2 = array[i+1]; - /* This (offset, data) pair meets the condition. */ - if (v1 < 0xCDCDCDCD) { - if (biol) { - if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) - bndy_cnt++; - rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); - } else { - odm_ConfigBB_AGC_8188E(dm_odm, v1, bMaskDWord, v2); - } - continue; - } else { - /* This line is the start line of branch. */ - if (!CheckCondition(array[i], hex)) { - /* Discard the following (offset, data) pairs. */ - read_next_pair(array, v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && i < arraylen - 2) - read_next_pair(array, v1, v2, i); - i -= 2; /* prevent from for-loop += 2 */ - } else { /* Configure matched pairs and skip to end of if-else. */ - read_next_pair(array, v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && i < arraylen - 2) { - if (biol) { - if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) - bndy_cnt++; - rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); - } else { - odm_ConfigBB_AGC_8188E(dm_odm, v1, bMaskDWord, v2); - } - read_next_pair(array, v1, v2, i); - } - - while (v2 != 0xDEAD && i < arraylen - 2) - read_next_pair(array, v1, v2, i); - } - } - } - if (biol) { - if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { - printk("~~~ %s IOL_exec_cmds Failed !!!\n", __func__); - rst = HAL_STATUS_FAILURE; + if (v1 < 0xCDCDCDCD){ + PHY_SetBBReg(adapt, v1, bMaskDWord, v2); + udelay(1); } } - return rst; + return true; } -/****************************************************************************** -* PHY_REG_1T.TXT -******************************************************************************/ +/* PHY_REG_1T.TXT */ static u32 array_phy_reg_1t_8188e[] = { 0x800, 0x80040000, @@ -471,122 +377,44 @@ static u32 array_phy_reg_1t_8188e[] = { 0xF00, 0x00000300, }; -enum HAL_STATUS ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *dm_odm) +static void rtl_bb_delay(struct adapter *adapt, u32 addr, u32 data) { - u32 hex = 0; - u32 i = 0; - u8 platform = dm_odm->SupportPlatform; - u8 interfaceValue = dm_odm->SupportInterface; - u8 board = dm_odm->BoardType; - u32 arraylen = sizeof(array_phy_reg_1t_8188e)/sizeof(u32); - u32 *array = array_phy_reg_1t_8188e; - bool biol = false; - struct adapter *adapter = dm_odm->Adapter; - struct xmit_frame *pxmit_frame = NULL; - u8 bndy_cnt = 1; - enum HAL_STATUS rst = HAL_STATUS_SUCCESS; - hex += board; - hex += interfaceValue << 8; - hex += platform << 16; - hex += 0xFF000000; - biol = rtw_IOL_applied(adapter); - - if (biol) { - pxmit_frame = rtw_IOL_accquire_xmit_frame(adapter); - if (pxmit_frame == NULL) { - pr_info("rtw_IOL_accquire_xmit_frame failed\n"); - return HAL_STATUS_FAILURE; - } + if (addr == 0xfe) { + msleep(50); + } else if (addr == 0xfd) { + mdelay(5); + } else if (addr == 0xfc) { + mdelay(1); + } else if (addr == 0xfb) { + udelay(50); + } else if (addr == 0xfa) { + udelay(5); + } else if (addr == 0xf9) { + udelay(1); + } else { + PHY_SetBBReg(adapt, addr, bMaskDWord, data); + /* Add 1us delay between BB/RF register setting. */ + udelay(1); } +} + +static bool set_baseband_phy_config(struct adapter *adapt) +{ + u32 i; + u32 arraylen = sizeof(array_phy_reg_1t_8188e)/sizeof(u32); + u32 *array = array_phy_reg_1t_8188e; for (i = 0; i < arraylen; i += 2) { u32 v1 = array[i]; u32 v2 = array[i+1]; - /* This (offset, data) pair meets the condition. */ - if (v1 < 0xCDCDCDCD) { - if (biol) { - if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) - bndy_cnt++; - if (v1 == 0xfe) { - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); - } else if (v1 == 0xfd) { - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); - } else if (v1 == 0xfc) { - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); - } else if (v1 == 0xfb) { - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); - } else if (v1 == 0xfa) { - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); - } else if (v1 == 0xf9) { - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); - } else { - if (v1 == 0xa24) - dm_odm->RFCalibrateInfo.RegA24 = v2; - rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); - } - } else { - odm_ConfigBB_PHY_8188E(dm_odm, v1, bMaskDWord, v2); - } - continue; - } else { /* This line is the start line of branch. */ - if (!CheckCondition(array[i], hex)) { - /* Discard the following (offset, data) pairs. */ - read_next_pair(array, v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && i < arraylen - 2) - read_next_pair(array, v1, v2, i); - i -= 2; /* prevent from for-loop += 2 */ - } else { /* Configure matched pairs and skip to end of if-else. */ - read_next_pair(array, v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && i < arraylen - 2) { - if (biol) { - if (rtw_IOL_cmd_boundary_handle(pxmit_frame)) - bndy_cnt++; - if (v1 == 0xfe) { - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 50); - } else if (v1 == 0xfd) { - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 5); - } else if (v1 == 0xfc) { - rtw_IOL_append_DELAY_MS_cmd(pxmit_frame, 1); - } else if (v1 == 0xfb) { - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 50); - } else if (v1 == 0xfa) { - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 5); - } else if (v1 == 0xf9) { - rtw_IOL_append_DELAY_US_cmd(pxmit_frame, 1); - } else{ - if (v1 == 0xa24) - dm_odm->RFCalibrateInfo.RegA24 = v2; - - rtw_IOL_append_WD_cmd(pxmit_frame, (u16)v1, v2, bMaskDWord); - } - } else { - odm_ConfigBB_PHY_8188E(dm_odm, v1, bMaskDWord, v2); - } - read_next_pair(array, v1, v2, i); - } - - while (v2 != 0xDEAD && i < arraylen - 2) - read_next_pair(array, v1, v2, i); - } - } + if (v1 < 0xCDCDCDCD) + rtl_bb_delay(adapt, v1, v2); } - if (biol) { - if (!rtw_IOL_exec_cmds_sync(dm_odm->Adapter, pxmit_frame, 1000, bndy_cnt)) { - rst = HAL_STATUS_FAILURE; - pr_info("~~~ IOL Config %s Failed !!!\n", __func__); - } - } - return rst; + return true; } -/****************************************************************************** -* PHY_REG_PG.TXT -******************************************************************************/ +/* PHY_REG_PG.TXT */ static u32 array_phy_reg_pg_8188e[] = { 0xE00, 0xFFFFFFFF, 0x06070809, @@ -680,42 +508,208 @@ static u32 array_phy_reg_pg_8188e[] = { }; -void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm) +static void store_pwrindex_offset(struct adapter *Adapter, u32 regaddr, u32 bitmask, u32 data) { - u32 hex; - u32 i = 0; - u8 platform = dm_odm->SupportPlatform; - u8 interfaceValue = dm_odm->SupportInterface; - u8 board = dm_odm->BoardType; - u32 arraylen = sizeof(array_phy_reg_pg_8188e) / sizeof(u32); - u32 *array = array_phy_reg_pg_8188e; + struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); + + if (regaddr == rTxAGC_A_Rate18_06) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][0] = data; + if (regaddr == rTxAGC_A_Rate54_24) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][1] = data; + if (regaddr == rTxAGC_A_CCK1_Mcs32) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][6] = data; + if (regaddr == rTxAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][7] = data; + if (regaddr == rTxAGC_A_Mcs03_Mcs00) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][2] = data; + if (regaddr == rTxAGC_A_Mcs07_Mcs04) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][3] = data; + if (regaddr == rTxAGC_A_Mcs11_Mcs08) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][4] = data; + if (regaddr == rTxAGC_A_Mcs15_Mcs12) { + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][5] = data; + if (hal_data->rf_type == RF_1T1R) + hal_data->pwrGroupCnt++; + } + if (regaddr == rTxAGC_B_Rate18_06) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][8] = data; + if (regaddr == rTxAGC_B_Rate54_24) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][9] = data; + if (regaddr == rTxAGC_B_CCK1_55_Mcs32) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][14] = data; + if (regaddr == rTxAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][15] = data; + if (regaddr == rTxAGC_B_Mcs03_Mcs00) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][10] = data; + if (regaddr == rTxAGC_B_Mcs07_Mcs04) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][11] = data; + if (regaddr == rTxAGC_B_Mcs11_Mcs08) + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][12] = data; + if (regaddr == rTxAGC_B_Mcs15_Mcs12) { + hal_data->MCSTxPowerLevelOriginalOffset[hal_data->pwrGroupCnt][13] = data; + if (hal_data->rf_type != RF_1T1R) + hal_data->pwrGroupCnt++; + } +} - hex = board + (interfaceValue << 8); - hex += (platform << 16) + 0xFF000000; +static void rtl_addr_delay(struct adapter *adapt, u32 addr, u32 bit_mask ,u32 data) +{ + if (addr == 0xfe) { + msleep(50); + } else if (addr == 0xfd) { + mdelay(5); + } else if (addr == 0xfc) { + mdelay(1); + } else if (addr == 0xfb) { + udelay(50); + } else if (addr == 0xfa) { + udelay(5); + } else if (addr == 0xf9) { + udelay(1); + } else{ + store_pwrindex_offset(adapt, addr, bit_mask, data); + } +} + +static bool config_bb_with_pgheader(struct adapter *adapt) +{ + u32 i = 0; + u32 arraylen = sizeof(array_phy_reg_pg_8188e) / sizeof(u32); + u32 *array = array_phy_reg_pg_8188e; for (i = 0; i < arraylen; i += 3) { u32 v1 = array[i]; u32 v2 = array[i+1]; u32 v3 = array[i+2]; - /* this line is a line of pure_body */ - if (v1 < 0xCDCDCDCD) { - odm_ConfigBB_PHY_REG_PG_8188E(dm_odm, v1, v2, v3); - continue; - } else { /* this line is the start of branch */ - if (!CheckCondition(array[i], hex)) { - /* don't need the hw_body */ - i += 2; /* skip the pair of expression */ - v1 = array[i]; - v2 = array[i+1]; - v3 = array[i+2]; - while (v2 != 0xDEAD) { - i += 3; - v1 = array[i]; - v2 = array[i+1]; - v3 = array[i+1]; - } - } - } + if (v1 < 0xCDCDCDCD) + rtl_addr_delay(adapt, v1, v2, v3); + } + return true; +} + +static void rtl88e_phy_init_bb_rf_register_definition(struct adapter *Adapter) +{ + struct hal_data_8188e *hal_data = GET_HAL_DATA(Adapter); + + hal_data->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; + hal_data->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; + hal_data->PHYRegDef[RF_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW; + hal_data->PHYRegDef[RF_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW; + + hal_data->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; + hal_data->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB; + hal_data->PHYRegDef[RF_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB; + hal_data->PHYRegDef[RF_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB; + + hal_data->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; + hal_data->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; + + hal_data->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; + hal_data->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; + + hal_data->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; + hal_data->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; + + hal_data->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; + hal_data->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; + hal_data->PHYRegDef[RF_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; + hal_data->PHYRegDef[RF_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; + + hal_data->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; + hal_data->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; + hal_data->PHYRegDef[RF_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; + hal_data->PHYRegDef[RF_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; + + hal_data->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; + hal_data->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; + + hal_data->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; + hal_data->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; + + hal_data->PHYRegDef[RF_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; + hal_data->PHYRegDef[RF_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; + hal_data->PHYRegDef[RF_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; + hal_data->PHYRegDef[RF_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; + + hal_data->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; + hal_data->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; + hal_data->PHYRegDef[RF_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; + hal_data->PHYRegDef[RF_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; + + hal_data->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; + hal_data->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; + hal_data->PHYRegDef[RF_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; + hal_data->PHYRegDef[RF_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; + + hal_data->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; + hal_data->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; + hal_data->PHYRegDef[RF_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; + hal_data->PHYRegDef[RF_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; + + hal_data->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE; + hal_data->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; + hal_data->PHYRegDef[RF_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; + hal_data->PHYRegDef[RF_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; + + hal_data->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; + hal_data->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; + hal_data->PHYRegDef[RF_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; + hal_data->PHYRegDef[RF_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; + + hal_data->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE; + hal_data->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; + hal_data->PHYRegDef[RF_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; + hal_data->PHYRegDef[RF_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; + + hal_data->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; + hal_data->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; + hal_data->PHYRegDef[RF_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; + hal_data->PHYRegDef[RF_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; + + hal_data->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback; + hal_data->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback; +} + +static bool config_parafile(struct adapter *adapt) +{ + struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(adapt); + struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); + + set_baseband_phy_config(adapt); + + /* If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */ + if (!pEEPROM->bautoload_fail_flag) { + hal_data->pwrGroupCnt = 0; + config_bb_with_pgheader(adapt); } + set_baseband_agc_config(adapt); + return true; +} + +bool rtl88e_phy_bb_config(struct adapter *adapt) +{ + int rtstatus = true; + struct hal_data_8188e *hal_data = GET_HAL_DATA(adapt); + u32 regval; + u8 crystal_cap; + + rtl88e_phy_init_bb_rf_register_definition(adapt); + + /* Enable BB and RF */ + regval = usb_read16(adapt, REG_SYS_FUNC_EN); + usb_write16(adapt, REG_SYS_FUNC_EN, (u16)(regval|BIT13|BIT0|BIT1)); + + usb_write8(adapt, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB); + + usb_write8(adapt, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB); + + /* Config BB and AGC */ + rtstatus = config_parafile(adapt); + + /* write 0x24[16:11] = 0x24[22:17] = crystal_cap */ + crystal_cap = hal_data->CrystalCap & 0x3F; + PHY_SetBBReg(adapt, REG_AFE_XTAL_CTRL, 0x7ff800, (crystal_cap | (crystal_cap << 6))); + + return rtstatus; } diff --git a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c index 4d28ce51fae1..dbc1368d81fa 100644 --- a/drivers/staging/rtl8188eu/hal/odm_HWConfig.c +++ b/drivers/staging/rtl8188eu/hal/odm_HWConfig.c @@ -431,18 +431,3 @@ void ODM_PhyStatusQuery(struct odm_dm_struct *dm_odm, { ODM_PhyStatusQuery_92CSeries(dm_odm, pPhyInfo, pPhyStatus, pPktinfo); } - -enum HAL_STATUS ODM_ConfigBBWithHeaderFile(struct odm_dm_struct *dm_odm, - enum odm_bb_config_type config_tp) -{ - if (config_tp == CONFIG_BB_PHY_REG) { - READ_AND_CONFIG(8188E, _PHY_REG_1T_); - } else if (config_tp == CONFIG_BB_AGC_TAB) { - READ_AND_CONFIG(8188E, _AGC_TAB_1T_); - } else if (config_tp == CONFIG_BB_PHY_REG_PG) { - READ_AND_CONFIG(8188E, _PHY_REG_PG_); - ODM_RT_TRACE(dm_odm, ODM_COMP_INIT, ODM_DBG_LOUD, - (" ===> phy_ConfigBBWithHeaderFile() agc:Rtl8188EPHY_REG_PGArray\n")); - } - return HAL_STATUS_SUCCESS; -} diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c index c1a19978debc..96361b8bc368 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c @@ -354,122 +354,6 @@ rtl8188e_PHY_SetRFReg( phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data); } -/** -* Function: phy_InitBBRFRegisterDefinition -* -* OverView: Initialize Register definition offset for Radio Path A/B/C/D -* -* Input: -* struct adapter *Adapter, -* -* Output: None -* Return: None -* Note: The initialization value is constant and it should never be changes -*/ -static void -phy_InitBBRFRegisterDefinition( - struct adapter *Adapter -) -{ - struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); - - /* RF Interface Sowrtware Control */ - pHalData->PHYRegDef[RF_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 LSBs if read 32-bit from 0x870 */ - pHalData->PHYRegDef[RF_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; /* 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) */ - pHalData->PHYRegDef[RF_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;/* 16 LSBs if read 32-bit from 0x874 */ - pHalData->PHYRegDef[RF_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;/* 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) */ - - /* RF Interface Readback Value */ - pHalData->PHYRegDef[RF_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; /* 16 LSBs if read 32-bit from 0x8E0 */ - pHalData->PHYRegDef[RF_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;/* 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) */ - pHalData->PHYRegDef[RF_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;/* 16 LSBs if read 32-bit from 0x8E4 */ - pHalData->PHYRegDef[RF_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;/* 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) */ - - /* RF Interface Output (and Enable) */ - pHalData->PHYRegDef[RF_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x860 */ - pHalData->PHYRegDef[RF_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; /* 16 LSBs if read 32-bit from 0x864 */ - - /* RF Interface (Output and) Enable */ - pHalData->PHYRegDef[RF_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) */ - pHalData->PHYRegDef[RF_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; /* 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) */ - - /* Addr of LSSI. Wirte RF register by driver */ - pHalData->PHYRegDef[RF_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; /* LSSI Parameter */ - pHalData->PHYRegDef[RF_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; - - /* RF parameter */ - pHalData->PHYRegDef[RF_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; /* BB Band Select */ - pHalData->PHYRegDef[RF_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; - pHalData->PHYRegDef[RF_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; - pHalData->PHYRegDef[RF_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; - - /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ - pHalData->PHYRegDef[RF_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ - pHalData->PHYRegDef[RF_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ - pHalData->PHYRegDef[RF_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ - pHalData->PHYRegDef[RF_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; /* Tx gain stage */ - - /* Tranceiver A~D HSSI Parameter-1 */ - pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; /* wire control parameter1 */ - pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; /* wire control parameter1 */ - - /* Tranceiver A~D HSSI Parameter-2 */ - pHalData->PHYRegDef[RF_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; /* wire control parameter2 */ - pHalData->PHYRegDef[RF_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; /* wire control parameter2 */ - - /* RF switch Control */ - pHalData->PHYRegDef[RF_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; /* TR/Ant switch control */ - pHalData->PHYRegDef[RF_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; - pHalData->PHYRegDef[RF_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; - pHalData->PHYRegDef[RF_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; - - /* AGC control 1 */ - pHalData->PHYRegDef[RF_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; - pHalData->PHYRegDef[RF_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; - pHalData->PHYRegDef[RF_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; - pHalData->PHYRegDef[RF_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; - - /* AGC control 2 */ - pHalData->PHYRegDef[RF_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; - pHalData->PHYRegDef[RF_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; - pHalData->PHYRegDef[RF_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; - pHalData->PHYRegDef[RF_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; - - /* RX AFE control 1 */ - pHalData->PHYRegDef[RF_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; - pHalData->PHYRegDef[RF_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; - pHalData->PHYRegDef[RF_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; - pHalData->PHYRegDef[RF_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; - - /* RX AFE control 1 */ - pHalData->PHYRegDef[RF_PATH_A].rfRxAFE = rOFDM0_XARxAFE; - pHalData->PHYRegDef[RF_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; - pHalData->PHYRegDef[RF_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; - pHalData->PHYRegDef[RF_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; - - /* Tx AFE control 1 */ - pHalData->PHYRegDef[RF_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; - pHalData->PHYRegDef[RF_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; - pHalData->PHYRegDef[RF_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; - pHalData->PHYRegDef[RF_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; - - /* Tx AFE control 2 */ - pHalData->PHYRegDef[RF_PATH_A].rfTxAFE = rOFDM0_XATxAFE; - pHalData->PHYRegDef[RF_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; - pHalData->PHYRegDef[RF_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; - pHalData->PHYRegDef[RF_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; - - /* Tranceiver LSSI Readback SI mode */ - pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; - pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; - pHalData->PHYRegDef[RF_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; - pHalData->PHYRegDef[RF_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; - - /* Tranceiver LSSI Readback PI mode */ - pHalData->PHYRegDef[RF_PATH_A].rfLSSIReadBackPi = TransceiverA_HSPI_Readback; - pHalData->PHYRegDef[RF_PATH_B].rfLSSIReadBackPi = TransceiverB_HSPI_Readback; -} - void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data) { struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); @@ -514,77 +398,6 @@ void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMa } } -static int phy_BB8188E_Config_ParaFile(struct adapter *Adapter) -{ - struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter); - struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); - int rtStatus = _SUCCESS; - - /* */ - /* 1. Read PHY_REG.TXT BB INIT!! */ - /* We will separate as 88C / 92C according to chip version */ - /* */ - if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG)) - rtStatus = _FAIL; - if (rtStatus != _SUCCESS) - goto phy_BB8190_Config_ParaFile_Fail; - - /* 2. If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */ - if (!pEEPROM->bautoload_fail_flag) { - pHalData->pwrGroupCnt = 0; - - if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG_PG)) - rtStatus = _FAIL; - } - - if (rtStatus != _SUCCESS) - goto phy_BB8190_Config_ParaFile_Fail; - - /* 3. BB AGC table Initialization */ - if (HAL_STATUS_FAILURE == ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_AGC_TAB)) - rtStatus = _FAIL; - - if (rtStatus != _SUCCESS) - goto phy_BB8190_Config_ParaFile_Fail; - -phy_BB8190_Config_ParaFile_Fail: - - return rtStatus; -} - -int -PHY_BBConfig8188E( - struct adapter *Adapter - ) -{ - int rtStatus = _SUCCESS; - struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); - u32 RegVal; - u8 CrystalCap; - - phy_InitBBRFRegisterDefinition(Adapter); - - - /* Enable BB and RF */ - RegVal = usb_read16(Adapter, REG_SYS_FUNC_EN); - usb_write16(Adapter, REG_SYS_FUNC_EN, (u16)(RegVal|BIT13|BIT0|BIT1)); - - /* 20090923 Joseph: Advised by Steven and Jenyu. Power sequence before init RF. */ - - usb_write8(Adapter, REG_RF_CTRL, RF_EN|RF_RSTB|RF_SDMRSTB); - - usb_write8(Adapter, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | FEN_BB_GLB_RSTn | FEN_BBRSTB); - - /* Config BB and AGC */ - rtStatus = phy_BB8188E_Config_ParaFile(Adapter); - - /* write 0x24[16:11] = 0x24[22:17] = CrystalCap */ - CrystalCap = pHalData->CrystalCap & 0x3F; - PHY_SetBBReg(Adapter, REG_AFE_XTAL_CTRL, 0x7ff800, (CrystalCap | (CrystalCap << 6))); - - return rtStatus; -} - static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel, u8 *ofdmPowerLevel, u8 *BW20PowerLevel, u8 *BW40PowerLevel) diff --git a/drivers/staging/rtl8188eu/hal/usb_halinit.c b/drivers/staging/rtl8188eu/hal/usb_halinit.c index efb3f7f7f6a4..c5559dfa4e92 100644 --- a/drivers/staging/rtl8188eu/hal/usb_halinit.c +++ b/drivers/staging/rtl8188eu/hal/usb_halinit.c @@ -760,15 +760,7 @@ static u32 rtl8188eu_hal_init(struct adapter *Adapter) rtl88e_phy_mac_config(Adapter); -/* d. Initialize BB related configurations. */ - HAL_INIT_PROFILE_TAG(HAL_INIT_STAGES_BB); -#if (HAL_BB_ENABLE == 1) - status = PHY_BBConfig8188E(Adapter); - if (status == _FAIL) { - DBG_88E(" ### Failed to init BB ......\n "); - goto exit; - } -#endif + rtl88e_phy_bb_config(Adapter); rtl88e_phy_rf_config(Adapter); diff --git a/drivers/staging/rtl8188eu/include/HalHWImg8188E_BB.h b/drivers/staging/rtl8188eu/include/HalHWImg8188E_BB.h deleted file mode 100644 index e57452104bfb..000000000000 --- a/drivers/staging/rtl8188eu/include/HalHWImg8188E_BB.h +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** -* -* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. -* -* 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. -* -* 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, USA -* -* -******************************************************************************/ - -#ifndef __INC_BB_8188E_HW_IMG_H -#define __INC_BB_8188E_HW_IMG_H - -/* static bool CheckCondition(const u32 Condition, const u32 Hex); */ - -/****************************************************************************** -* AGC_TAB_1T.TXT -******************************************************************************/ - -enum HAL_STATUS ODM_ReadAndConfig_AGC_TAB_1T_8188E(struct odm_dm_struct *odm); - -/****************************************************************************** -* PHY_REG_1T.TXT -******************************************************************************/ - -enum HAL_STATUS ODM_ReadAndConfig_PHY_REG_1T_8188E(struct odm_dm_struct *odm); - -/****************************************************************************** -* PHY_REG_PG.TXT -******************************************************************************/ - -void ODM_ReadAndConfig_PHY_REG_PG_8188E(struct odm_dm_struct *dm_odm); - -#endif diff --git a/drivers/staging/rtl8188eu/include/odm_precomp.h b/drivers/staging/rtl8188eu/include/odm_precomp.h index 2b3e51bb0212..683c5bdcfced 100644 --- a/drivers/staging/rtl8188eu/include/odm_precomp.h +++ b/drivers/staging/rtl8188eu/include/odm_precomp.h @@ -46,8 +46,6 @@ #include "odm_reg.h" -#include "HalHWImg8188E_BB.h" - #include "odm_RegConfig8188E.h" #include "odm_RTL8188E.h" diff --git a/drivers/staging/rtl8188eu/include/phy.h b/drivers/staging/rtl8188eu/include/phy.h index 254d4182602d..676a66c44264 100644 --- a/drivers/staging/rtl8188eu/include/phy.h +++ b/drivers/staging/rtl8188eu/include/phy.h @@ -1,2 +1,3 @@ bool rtl88e_phy_mac_config(struct adapter *adapt); bool rtl88e_phy_rf_config(struct adapter *adapt); +bool rtl88e_phy_bb_config(struct adapter *adapt); -- GitLab From e9ff221347dfc565c1a2f6bbce21baedf7766fb2 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:21 +0530 Subject: [PATCH 0626/9167] staging: rtl8188eu: Remove odm_RegConfig8188E.[h, c] files driver doesn't require these files anymore. Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/Makefile | 1 - .../rtl8188eu/hal/odm_RegConfig8188E.c | 86 ------------------- .../rtl8188eu/include/odm_RegConfig8188E.h | 32 ------- .../staging/rtl8188eu/include/odm_precomp.h | 1 - 4 files changed, 120 deletions(-) delete mode 100644 drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c delete mode 100644 drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h diff --git a/drivers/staging/rtl8188eu/Makefile b/drivers/staging/rtl8188eu/Makefile index 32d64a77c83a..1b8c89ba7ac2 100644 --- a/drivers/staging/rtl8188eu/Makefile +++ b/drivers/staging/rtl8188eu/Makefile @@ -30,7 +30,6 @@ r8188eu-y := \ hal/odm.o \ hal/odm_debug.o \ hal/odm_HWConfig.o \ - hal/odm_RegConfig8188E.o\ hal/odm_RTL8188E.o \ hal/rtl8188e_cmd.o \ hal/rtl8188e_dm.o \ diff --git a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c b/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c deleted file mode 100644 index 634d1115b0fe..000000000000 --- a/drivers/staging/rtl8188eu/hal/odm_RegConfig8188E.c +++ /dev/null @@ -1,86 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. - * - * 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. - * - * 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, USA - * - * - ******************************************************************************/ - -#include "odm_precomp.h" - -void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) -{ - struct adapter *adapter = pDM_Odm->Adapter; - - PHY_SetBBReg(adapter, Addr, Bitmask, Data); - /* Add 1us delay between BB/RF register setting. */ - udelay(1); - - ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, - ("===> ODM_ConfigBBWithHeaderFile: [AGC_TAB] %08X %08X\n", - Addr, Data)); -} - -void odm_ConfigBB_PHY_REG_PG_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, - u32 Bitmask, u32 Data) -{ - if (Addr == 0xfe) { - msleep(50); - } else if (Addr == 0xfd) { - mdelay(5); - } else if (Addr == 0xfc) { - mdelay(1); - } else if (Addr == 0xfb) { - udelay(50); - } else if (Addr == 0xfa) { - udelay(5); - } else if (Addr == 0xf9) { - udelay(1); - } else{ - ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_LOUD, - ("===> @@@@@@@ ODM_ConfigBBWithHeaderFile: [PHY_REG] %08X %08X %08X\n", - Addr, Bitmask, Data)); - storePwrIndexDiffRateOffset(pDM_Odm->Adapter, Addr, Bitmask, Data); - } -} - -void odm_ConfigBB_PHY_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, u32 Bitmask, u32 Data) -{ - struct adapter *adapter = pDM_Odm->Adapter; - - if (Addr == 0xfe) { - msleep(50); - } else if (Addr == 0xfd) { - mdelay(5); - } else if (Addr == 0xfc) { - mdelay(1); - } else if (Addr == 0xfb) { - udelay(50); - } else if (Addr == 0xfa) { - udelay(5); - } else if (Addr == 0xf9) { - udelay(1); - } else { - if (Addr == 0xa24) - pDM_Odm->RFCalibrateInfo.RegA24 = Data; - PHY_SetBBReg(adapter, Addr, Bitmask, Data); - - /* Add 1us delay between BB/RF register setting. */ - udelay(1); - ODM_RT_TRACE(pDM_Odm, ODM_COMP_INIT, ODM_DBG_TRACE, - ("===> ODM_ConfigBBWithHeaderFile: [PHY_REG] %08X %08X\n", - Addr, Data)); - } -} diff --git a/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h b/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h deleted file mode 100644 index dd49a86f069b..000000000000 --- a/drivers/staging/rtl8188eu/include/odm_RegConfig8188E.h +++ /dev/null @@ -1,32 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. - * - * 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. - * - * 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, USA - * - * - ******************************************************************************/ -#ifndef __INC_ODM_REGCONFIG_H_8188E -#define __INC_ODM_REGCONFIG_H_8188E - -void odm_ConfigBB_AGC_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, - u32 Bitmask, u32 Data); - -void odm_ConfigBB_PHY_REG_PG_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, - u32 Bitmask, u32 Data); - -void odm_ConfigBB_PHY_8188E(struct odm_dm_struct *pDM_Odm, u32 Addr, - u32 Bitmask, u32 Data); - -#endif diff --git a/drivers/staging/rtl8188eu/include/odm_precomp.h b/drivers/staging/rtl8188eu/include/odm_precomp.h index 683c5bdcfced..436d6ff14ca3 100644 --- a/drivers/staging/rtl8188eu/include/odm_precomp.h +++ b/drivers/staging/rtl8188eu/include/odm_precomp.h @@ -46,7 +46,6 @@ #include "odm_reg.h" -#include "odm_RegConfig8188E.h" #include "odm_RTL8188E.h" void odm_CmnInfoHook_Debug(struct odm_dm_struct *pDM_Odm); -- GitLab From 939af24f713865d4cbcfb4ee1a0794e701530306 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:22 +0530 Subject: [PATCH 0627/9167] staging: rtl8188eu: Remove unused function storePwrIndexDiffRateOffset() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/hal/rtl8188e_phycfg.c | 44 ------------------- .../rtl8188eu/include/Hal8188EPhyCfg.h | 2 - 2 files changed, 46 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c index 96361b8bc368..0f90cf4171eb 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_phycfg.c @@ -354,50 +354,6 @@ rtl8188e_PHY_SetRFReg( phy_RFSerialWrite(Adapter, eRFPath, RegAddr, Data); } -void storePwrIndexDiffRateOffset(struct adapter *Adapter, u32 RegAddr, u32 BitMask, u32 Data) -{ - struct hal_data_8188e *pHalData = GET_HAL_DATA(Adapter); - - if (RegAddr == rTxAGC_A_Rate18_06) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][0] = Data; - if (RegAddr == rTxAGC_A_Rate54_24) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][1] = Data; - if (RegAddr == rTxAGC_A_CCK1_Mcs32) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][6] = Data; - if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0xffffff00) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][7] = Data; - if (RegAddr == rTxAGC_A_Mcs03_Mcs00) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][2] = Data; - if (RegAddr == rTxAGC_A_Mcs07_Mcs04) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][3] = Data; - if (RegAddr == rTxAGC_A_Mcs11_Mcs08) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][4] = Data; - if (RegAddr == rTxAGC_A_Mcs15_Mcs12) { - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][5] = Data; - if (pHalData->rf_type == RF_1T1R) - pHalData->pwrGroupCnt++; - } - if (RegAddr == rTxAGC_B_Rate18_06) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][8] = Data; - if (RegAddr == rTxAGC_B_Rate54_24) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][9] = Data; - if (RegAddr == rTxAGC_B_CCK1_55_Mcs32) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][14] = Data; - if (RegAddr == rTxAGC_B_CCK11_A_CCK2_11 && BitMask == 0x000000ff) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][15] = Data; - if (RegAddr == rTxAGC_B_Mcs03_Mcs00) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][10] = Data; - if (RegAddr == rTxAGC_B_Mcs07_Mcs04) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][11] = Data; - if (RegAddr == rTxAGC_B_Mcs11_Mcs08) - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][12] = Data; - if (RegAddr == rTxAGC_B_Mcs15_Mcs12) { - pHalData->MCSTxPowerLevelOriginalOffset[pHalData->pwrGroupCnt][13] = Data; - if (pHalData->rf_type != RF_1T1R) - pHalData->pwrGroupCnt++; - } -} - static void getTxPowerIndex88E(struct adapter *Adapter, u8 channel, u8 *cckPowerLevel, u8 *ofdmPowerLevel, u8 *BW20PowerLevel, u8 *BW40PowerLevel) diff --git a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h index ed156d3bb561..49e18252a0af 100644 --- a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h +++ b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h @@ -244,8 +244,6 @@ void PHY_EnableHostClkReq(struct adapter *adapter); bool SetAntennaConfig92C(struct adapter *adapter, u8 defaultant); -void storePwrIndexDiffRateOffset(struct adapter *adapter, u32 regaddr, - u32 mask, u32 data); /*--------------------------Exported Function prototype---------------------*/ #define PHY_QueryBBReg(adapt, regaddr, mask) \ -- GitLab From dcdb40ccabc396047e1ab0f7c965d358e764fcf8 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:23 +0530 Subject: [PATCH 0628/9167] staging: rtl8188eu: Hal8188EPhyCfg.h: Remove unused function declaration Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h index 49e18252a0af..161ad7688da6 100644 --- a/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h +++ b/drivers/staging/rtl8188eu/include/Hal8188EPhyCfg.h @@ -206,17 +206,6 @@ u32 rtl8188e_PHY_QueryRFReg(struct adapter *adapter, enum rf_radio_path rfpath, void rtl8188e_PHY_SetRFReg(struct adapter *adapter, enum rf_radio_path rfpath, u32 regaddr, u32 mask, u32 data); -/* Initialization related function */ -/* MAC/BB/RF HAL config */ -int PHY_BBConfig8188E(struct adapter *adapter); -int PHY_RFConfig8188E(struct adapter *adapter); - -/* RF config */ -int rtl8188e_PHY_ConfigRFWithParaFile(struct adapter *adapter, u8 *filename, - enum rf_radio_path rfpath); -int rtl8188e_PHY_ConfigRFWithHeaderFile(struct adapter *adapter, - enum rf_radio_path rfpath); - /* Read initi reg value for tx power setting. */ void rtl8192c_PHY_GetHWRegOriginalValue(struct adapter *adapter); -- GitLab From f549788fa07738d71c0e54fe0986d7baa56a6d8a Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:24 +0530 Subject: [PATCH 0629/9167] staging: rtl8188eu: Remove unused function rtw_IOL_accquire_xmit_frame() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_iol.c | 36 --------------------- drivers/staging/rtl8188eu/include/rtw_iol.h | 1 - 2 files changed, 37 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_iol.c b/drivers/staging/rtl8188eu/core/rtw_iol.c index 7796287be8f4..5401f7a08a96 100644 --- a/drivers/staging/rtl8188eu/core/rtw_iol.c +++ b/drivers/staging/rtl8188eu/core/rtw_iol.c @@ -20,42 +20,6 @@ #include -struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter) -{ - struct xmit_frame *xmit_frame; - struct xmit_buf *xmitbuf; - struct pkt_attrib *pattrib; - struct xmit_priv *pxmitpriv = &(adapter->xmitpriv); - - xmit_frame = rtw_alloc_xmitframe(pxmitpriv); - if (xmit_frame == NULL) { - DBG_88E("%s rtw_alloc_xmitframe return null\n", __func__); - goto exit; - } - - xmitbuf = rtw_alloc_xmitbuf(pxmitpriv); - if (xmitbuf == NULL) { - DBG_88E("%s rtw_alloc_xmitbuf return null\n", __func__); - rtw_free_xmitframe(pxmitpriv, xmit_frame); - xmit_frame = NULL; - goto exit; - } - - xmit_frame->frame_tag = MGNT_FRAMETAG; - xmit_frame->pxmitbuf = xmitbuf; - xmit_frame->buf_addr = xmitbuf->pbuf; - xmitbuf->priv_data = xmit_frame; - - pattrib = &xmit_frame->attrib; - update_mgntframe_attrib(adapter, pattrib); - pattrib->qsel = 0x10;/* Beacon */ - pattrib->subtype = WIFI_BEACON; - pattrib->pktlen = 0; - pattrib->last_txcmdsz = 0; -exit: - return xmit_frame; -} - int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len) { struct pkt_attrib *pattrib = &xmit_frame->attrib; diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index 80bfd063dd8d..bac4d7f41868 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -46,7 +46,6 @@ enum ioreg_cmd { IOREG_CMD_END = 0xFF, }; -struct xmit_frame *rtw_IOL_accquire_xmit_frame(struct adapter *adapter); int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len); int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary); -- GitLab From a758a007ea6713213ea5458e551258ceab62fea1 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:25 +0530 Subject: [PATCH 0630/9167] staging: rtl8188eu: Remove unused function rtw_IOL_cmd_boundary_handle() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_iol.c | 13 ------------- drivers/staging/rtl8188eu/include/rtw_iol.h | 1 - 2 files changed, 14 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_iol.c b/drivers/staging/rtl8188eu/core/rtw_iol.c index 5401f7a08a96..cd2960cc637a 100644 --- a/drivers/staging/rtl8188eu/core/rtw_iol.c +++ b/drivers/staging/rtl8188eu/core/rtw_iol.c @@ -128,19 +128,6 @@ int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); } -u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame) -{ - u8 is_cmd_bndy = false; - if (((pxmit_frame->attrib.pktlen+32)%256) + 8 >= 256) { - rtw_IOL_append_END_cmd(pxmit_frame); - pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen+32)/256)+1)*256); - - pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen; - is_cmd_bndy = true; - } - return is_cmd_bndy; -} - void rtw_IOL_cmd_buf_dump(struct adapter *Adapter, int buf_len, u8 *pbuf) { int i; diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index bac4d7f41868..f8b05e32a4b4 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -75,7 +75,6 @@ int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, #define rtw_IOL_append_WRF_cmd(xmit_frame, rf_path, addr, value, mask) \ _rtw_IOL_append_WRF_cmd((xmit_frame), (rf_path), (addr), (value), (mask)) -u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame); void rtw_IOL_cmd_buf_dump(struct adapter *Adapter, int buf_len, u8 *pbuf); #endif /* __RTW_IOL_H_ */ -- GitLab From 91ed283ab563727932d6cf92b74dd15226635870 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:26 +0530 Subject: [PATCH 0631/9167] staging: rtl8188eu: Remove unused function rtw_IOL_append_WD_cmd() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_iol.c | 14 -------------- drivers/staging/rtl8188eu/include/rtw_iol.h | 4 ---- 2 files changed, 18 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_iol.c b/drivers/staging/rtl8188eu/core/rtw_iol.c index cd2960cc637a..ebc228d5ef22 100644 --- a/drivers/staging/rtl8188eu/core/rtw_iol.c +++ b/drivers/staging/rtl8188eu/core/rtw_iol.c @@ -77,20 +77,6 @@ int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); } -int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask) -{ - struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0}; - - cmd.address = cpu_to_le16(addr); - cmd.data = cpu_to_le32(value); - - if (mask != 0xFFFFFFFF) { - cmd.length = 12; - cmd.mask = cpu_to_le32(mask); - } - return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); -} - int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask) { struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0}; diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index f8b05e32a4b4..f53bceb2bd6c 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -62,16 +62,12 @@ void read_efuse_from_txpktbuf(struct adapter *adapter, int bcnhead, int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask); -int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, - u32 value, u32 mask); int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask); #define rtw_IOL_append_WB_cmd(xmit_frame, addr, value, mask) \ _rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value) , (mask)) #define rtw_IOL_append_WW_cmd(xmit_frame, addr, value, mask) \ _rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value), (mask)) -#define rtw_IOL_append_WD_cmd(xmit_frame, addr, value, mask) \ - _rtw_IOL_append_WD_cmd((xmit_frame), (addr), (value), (mask)) #define rtw_IOL_append_WRF_cmd(xmit_frame, rf_path, addr, value, mask) \ _rtw_IOL_append_WRF_cmd((xmit_frame), (rf_path), (addr), (value), (mask)) -- GitLab From 94616fbc5cf096a30158036bb87de48de6f3d7f6 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:27 +0530 Subject: [PATCH 0632/9167] staging: rtl8188eu: Remove unused function rtw_IOL_exec_cmds_sync() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_iol.c | 5 ----- drivers/staging/rtl8188eu/include/rtw_iol.h | 3 --- 2 files changed, 8 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_iol.c b/drivers/staging/rtl8188eu/core/rtw_iol.c index ebc228d5ef22..4527aaac4ef7 100644 --- a/drivers/staging/rtl8188eu/core/rtw_iol.c +++ b/drivers/staging/rtl8188eu/core/rtw_iol.c @@ -53,11 +53,6 @@ bool rtw_IOL_applied(struct adapter *adapter) return false; } -int rtw_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) -{ - return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt); -} - int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary) { return _SUCCESS; diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index f53bceb2bd6c..fc5b916f806f 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -49,9 +49,6 @@ enum ioreg_cmd { int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len); int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary); -int rtw_IOL_exec_cmds_sync(struct adapter *adapter, - struct xmit_frame *xmit_frame, u32 max_wating_ms, - u32 bndy_cnt); bool rtw_IOL_applied(struct adapter *adapter); int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us); int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms); -- GitLab From 678826f5034af1a73439a71125bd5f254c9405d1 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:28 +0530 Subject: [PATCH 0633/9167] staging: rtl8188eu: Remove unused functions rtw_IOL_append_DELAY_[US, MS]_cmd() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_iol.c | 16 ---------------- drivers/staging/rtl8188eu/include/rtw_iol.h | 2 -- 2 files changed, 18 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_iol.c b/drivers/staging/rtl8188eu/core/rtw_iol.c index 4527aaac4ef7..5004b8f554ec 100644 --- a/drivers/staging/rtl8188eu/core/rtw_iol.c +++ b/drivers/staging/rtl8188eu/core/rtw_iol.c @@ -86,22 +86,6 @@ int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); } -int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us) -{ - struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0}; - cmd.address = cpu_to_le16(us); - - return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); -} - -int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms) -{ - struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0}; - - cmd.address = cpu_to_le16(ms); - return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); -} - int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) { struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0}; diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index fc5b916f806f..8c298ab51ad5 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -50,8 +50,6 @@ int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len); int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary); bool rtw_IOL_applied(struct adapter *adapter); -int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us); -int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms); int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame); void read_efuse_from_txpktbuf(struct adapter *adapter, int bcnhead, -- GitLab From 63bd7e26d26b09e967067f9e5f8e781983f72f9e Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:29 +0530 Subject: [PATCH 0634/9167] staging: rtl8188eu: Remove unused function rtw_IOL_cmd_tx_pkt_buf_dump() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/hal/rtl8188e_hal_init.c | 32 ------------------- .../staging/rtl8188eu/include/rtl8188e_hal.h | 1 - 2 files changed, 33 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index ac4bedee0205..ea2ce8ba7bd1 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -138,38 +138,6 @@ static int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_fram return ret; } -void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int data_len) -{ - u32 fifo_data, reg_140; - u32 addr, rstatus, loop = 0; - u16 data_cnts = (data_len/8)+1; - u8 *pbuf = vzalloc(data_len+10); - DBG_88E("###### %s ######\n", __func__); - - usb_write8(Adapter, REG_PKT_BUFF_ACCESS_CTRL, TXPKT_BUF_SELECT); - if (pbuf) { - for (addr = 0; addr < data_cnts; addr++) { - usb_write32(Adapter, 0x140, addr); - msleep(1); - loop = 0; - do { - rstatus = (reg_140 = usb_read32(Adapter, REG_PKTBUF_DBG_CTRL)&BIT24); - if (rstatus) { - fifo_data = usb_read32(Adapter, REG_PKTBUF_DBG_DATA_L); - memcpy(pbuf+(addr*8), &fifo_data, 4); - - fifo_data = usb_read32(Adapter, REG_PKTBUF_DBG_DATA_H); - memcpy(pbuf+(addr*8+4), &fifo_data, 4); - } - msleep(1); - } while (!rstatus && (loop++ < 10)); - } - rtw_IOL_cmd_buf_dump(Adapter, data_len, pbuf); - vfree(pbuf); - } - DBG_88E("###### %s ######\n", __func__); -} - #define MAX_REG_BOLCK_SIZE 196 void _8051Reset88E(struct adapter *padapter) diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h index 8b73c036ac0c..814ba1ab4b52 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_hal.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_hal.h @@ -423,7 +423,6 @@ void SetBcnCtrlReg(struct adapter *padapter, u8 SetBits, u8 ClearBits); void rtl8188e_start_thread(struct adapter *padapter); void rtl8188e_stop_thread(struct adapter *padapter); -void rtw_IOL_cmd_tx_pkt_buf_dump(struct adapter *Adapter, int len); s32 iol_execute(struct adapter *padapter, u8 control); void iol_mode_enable(struct adapter *padapter, u8 enable); s32 rtl8188e_iol_efuse_patch(struct adapter *padapter); -- GitLab From b5c391a4b0a46dff8d6e02e30ecd7ce16f446635 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:30 +0530 Subject: [PATCH 0635/9167] staging: rtl8188eu: Remove unused function rtw_IOL_cmd_buf_dump() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_iol.c | 17 ----------------- drivers/staging/rtl8188eu/include/rtw_iol.h | 2 -- 2 files changed, 19 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_iol.c b/drivers/staging/rtl8188eu/core/rtw_iol.c index 5004b8f554ec..7281bb6996f8 100644 --- a/drivers/staging/rtl8188eu/core/rtw_iol.c +++ b/drivers/staging/rtl8188eu/core/rtw_iol.c @@ -92,20 +92,3 @@ int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); } - -void rtw_IOL_cmd_buf_dump(struct adapter *Adapter, int buf_len, u8 *pbuf) -{ - int i; - int j = 1; - - pr_info("###### %s ######\n", __func__); - for (i = 0; i < buf_len; i++) { - printk("%02x-", *(pbuf+i)); - - if (j%32 == 0) - printk("\n"); - j++; - } - printk("\n"); - pr_info("=============ioreg_cmd len=%d===============\n", buf_len); -} diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index 8c298ab51ad5..193f2eb36625 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -66,6 +66,4 @@ int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, #define rtw_IOL_append_WRF_cmd(xmit_frame, rf_path, addr, value, mask) \ _rtw_IOL_append_WRF_cmd((xmit_frame), (rf_path), (addr), (value), (mask)) -void rtw_IOL_cmd_buf_dump(struct adapter *Adapter, int buf_len, u8 *pbuf); - #endif /* __RTW_IOL_H_ */ -- GitLab From 4ffa54e6b191761eb0b71144f135e5b1935e752c Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:31 +0530 Subject: [PATCH 0636/9167] staging: rtl8188eu: Remove rtl8188e_IOL_exec_cmds_sync() and its wrapper function rtl8188e_IOL_exec_cmds_sync() is a unused function. Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/hal_intf.c | 10 ------ .../staging/rtl8188eu/hal/rtl8188e_hal_init.c | 32 ------------------- drivers/staging/rtl8188eu/include/hal_intf.h | 7 ---- 3 files changed, 49 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/hal_intf.c b/drivers/staging/rtl8188eu/hal/hal_intf.c index 2faa690f7e26..bc89e9978ed3 100644 --- a/drivers/staging/rtl8188eu/hal/hal_intf.c +++ b/drivers/staging/rtl8188eu/hal/hal_intf.c @@ -354,16 +354,6 @@ u8 rtw_hal_sreset_get_wifi_status(struct adapter *adapt) return status; } -int rtw_hal_iol_cmd(struct adapter *adapter, struct xmit_frame *xmit_frame, - u32 max_wating_ms, u32 bndy_cnt) -{ - if (adapter->HalFunc.IOL_exec_cmds_sync) - return adapter->HalFunc.IOL_exec_cmds_sync(adapter, xmit_frame, - max_wating_ms, - bndy_cnt); - return _FAIL; -} - void rtw_hal_notch_filter(struct adapter *adapter, bool enable) { if (adapter->HalFunc.hal_notch_filter) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index ea2ce8ba7bd1..16525b073bc3 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -108,36 +108,6 @@ static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy) return rst; } -static int rtl8188e_IOL_exec_cmds_sync(struct adapter *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt) -{ - struct pkt_attrib *pattrib = &xmit_frame->attrib; - u8 i; - int ret = _FAIL; - - if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS) - goto exit; - if (rtw_usb_bulk_size_boundary(adapter, TXDESC_SIZE+pattrib->last_txcmdsz)) { - if (rtw_IOL_append_END_cmd(xmit_frame) != _SUCCESS) - goto exit; - } - - dump_mgntframe_and_wait(adapter, xmit_frame, max_wating_ms); - - iol_mode_enable(adapter, 1); - for (i = 0; i < bndy_cnt; i++) { - u8 page_no = 0; - page_no = i*2; - ret = iol_ioconfig(adapter, page_no); - if (ret != _SUCCESS) - break; - } - iol_mode_enable(adapter, 0); -exit: - /* restore BCN_HEAD */ - usb_write8(adapter, REG_TDECTRL+1, 0); - return ret; -} - #define MAX_REG_BOLCK_SIZE 196 void _8051Reset88E(struct adapter *padapter) @@ -279,8 +249,6 @@ void rtl8188e_set_hal_ops(struct hal_ops *pHalFunc) pHalFunc->SetHalODMVarHandler = &rtl8188e_SetHalODMVar; - pHalFunc->IOL_exec_cmds_sync = &rtl8188e_IOL_exec_cmds_sync; - pHalFunc->hal_notch_filter = &hal_notch_filter_8188e; } diff --git a/drivers/staging/rtl8188eu/include/hal_intf.h b/drivers/staging/rtl8188eu/include/hal_intf.h index 56d5c50bb734..1c5303eefcea 100644 --- a/drivers/staging/rtl8188eu/include/hal_intf.h +++ b/drivers/staging/rtl8188eu/include/hal_intf.h @@ -228,10 +228,6 @@ struct hal_ops { void (*sreset_init_value)(struct adapter *padapter); u8 (*sreset_get_wifi_status)(struct adapter *padapter); - int (*IOL_exec_cmds_sync)(struct adapter *padapter, - struct xmit_frame *frame, u32 max_wait, - u32 bndy_cnt); - void (*hal_notch_filter)(struct adapter *adapter, bool enable); void (*hal_reset_security_engine)(struct adapter *adapter); }; @@ -331,9 +327,6 @@ void rtw_hal_antdiv_rssi_compared(struct adapter *padapter, void rtw_hal_sreset_init(struct adapter *padapter); u8 rtw_hal_sreset_get_wifi_status(struct adapter *padapter); -int rtw_hal_iol_cmd(struct adapter *adapter, struct xmit_frame *xmit_frame, - u32 max_wating_ms, u32 bndy_cnt); - void rtw_hal_notch_filter(struct adapter *adapter, bool enable); void rtw_hal_reset_security_engine(struct adapter *adapter); -- GitLab From 51e3d8ededd1317ab95dc9648ae45b0370464416 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:32 +0530 Subject: [PATCH 0637/9167] staging: rtl8188eu: Remove unused function iol_ioconfig() Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c index 16525b073bc3..50b13323c71d 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188e_hal_init.c @@ -99,15 +99,6 @@ s32 rtl8188e_iol_efuse_patch(struct adapter *padapter) return result; } -static s32 iol_ioconfig(struct adapter *padapter, u8 iocfg_bndy) -{ - s32 rst = _SUCCESS; - - usb_write8(padapter, REG_TDECTRL+1, iocfg_bndy); - rst = iol_execute(padapter, CMD_IOCONFIG); - return rst; -} - #define MAX_REG_BOLCK_SIZE 196 void _8051Reset88E(struct adapter *padapter) -- GitLab From 1eb87e22062be9544431bcab2fd813aa1c795734 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:33 +0530 Subject: [PATCH 0638/9167] staging: rtl8188eu: rtw_iol.c: Remove unused functions Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_iol.c | 63 --------------------- drivers/staging/rtl8188eu/include/rtw_iol.h | 18 ------ 2 files changed, 81 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_iol.c b/drivers/staging/rtl8188eu/core/rtw_iol.c index 7281bb6996f8..cdcf0eacc0e0 100644 --- a/drivers/staging/rtl8188eu/core/rtw_iol.c +++ b/drivers/staging/rtl8188eu/core/rtw_iol.c @@ -20,29 +20,6 @@ #include -int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len) -{ - struct pkt_attrib *pattrib = &xmit_frame->attrib; - u16 buf_offset; - u32 ori_len; - - buf_offset = TXDESC_OFFSET; - ori_len = buf_offset+pattrib->pktlen; - - /* check if the io_buf can accommodate new cmds */ - if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) { - DBG_88E("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", - __func__ , ori_len + cmd_len + 8, MAX_XMITBUF_SZ); - return _FAIL; - } - - memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len); - pattrib->pktlen += cmd_len; - pattrib->last_txcmdsz += cmd_len; - - return _SUCCESS; -} - bool rtw_IOL_applied(struct adapter *adapter) { if (1 == adapter->registrypriv.fw_iol) @@ -52,43 +29,3 @@ bool rtw_IOL_applied(struct adapter *adapter) return true; return false; } - -int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary) -{ - return _SUCCESS; -} - -int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask) -{ - struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0}; - - cmd.address = cpu_to_le16(addr); - cmd.data = cpu_to_le32(value); - - if (mask != 0xFF) { - cmd.length = 12; - cmd.mask = cpu_to_le32(mask); - } - return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); -} - -int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask) -{ - struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0}; - - cmd.address = cpu_to_le16((rf_path<<8) | ((addr) & 0xFF)); - cmd.data = cpu_to_le32(value); - - if (mask != 0x000FFFFF) { - cmd.length = 12; - cmd.mask = cpu_to_le32(mask); - } - return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length); -} - -int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame) -{ - struct ioreg_cfg cmd = {4, IOREG_CMD_END, cpu_to_le16(0xFFFF), cpu_to_le32(0xFF), 0x0}; - - return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4); -} diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index 193f2eb36625..8ebdddbb77a5 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -46,24 +46,6 @@ enum ioreg_cmd { IOREG_CMD_END = 0xFF, }; -int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, - u32 cmd_len); -int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary); bool rtw_IOL_applied(struct adapter *adapter); -int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame); - -void read_efuse_from_txpktbuf(struct adapter *adapter, int bcnhead, - u8 *content, u16 *size); - -int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, - u8 value, u8 mask); -int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, - u16 addr, u32 value, u32 mask); -#define rtw_IOL_append_WB_cmd(xmit_frame, addr, value, mask) \ - _rtw_IOL_append_WB_cmd((xmit_frame), (addr), (value) , (mask)) -#define rtw_IOL_append_WW_cmd(xmit_frame, addr, value, mask) \ - _rtw_IOL_append_WW_cmd((xmit_frame), (addr), (value), (mask)) -#define rtw_IOL_append_WRF_cmd(xmit_frame, rf_path, addr, value, mask) \ - _rtw_IOL_append_WRF_cmd((xmit_frame), (rf_path), (addr), (value), (mask)) #endif /* __RTW_IOL_H_ */ -- GitLab From 43ffc5be9e76d6b86c6b1e60c64eddb57bea4c15 Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:34 +0530 Subject: [PATCH 0639/9167] staging: rtl8188eu: rtw_iol.h: Remove unused struct, enum and macro Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/include/rtw_iol.h | 23 --------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/staging/rtl8188eu/include/rtw_iol.h b/drivers/staging/rtl8188eu/include/rtw_iol.h index 8ebdddbb77a5..68aae7f0b02f 100644 --- a/drivers/staging/rtl8188eu/include/rtw_iol.h +++ b/drivers/staging/rtl8188eu/include/rtw_iol.h @@ -23,29 +23,6 @@ #include #include -#define IOREG_CMD_END_LEN 4 - -struct ioreg_cfg { - u8 length; - u8 cmd_id; - __le16 address; - __le32 data; - __le32 mask; -}; - -enum ioreg_cmd { - IOREG_CMD_LLT = 0x01, - IOREG_CMD_REFUSE = 0x02, - IOREG_CMD_EFUSE_PATH = 0x03, - IOREG_CMD_WB_REG = 0x04, - IOREG_CMD_WW_REG = 0x05, - IOREG_CMD_WD_REG = 0x06, - IOREG_CMD_W_RF = 0x07, - IOREG_CMD_DELAY_US = 0x10, - IOREG_CMD_DELAY_MS = 0x11, - IOREG_CMD_END = 0xFF, -}; - bool rtw_IOL_applied(struct adapter *adapter); #endif /* __RTW_IOL_H_ */ -- GitLab From e7e7068f60d9570613f9737f4f94e3158322cf6e Mon Sep 17 00:00:00 2001 From: navin patidar Date: Sun, 10 Aug 2014 20:14:35 +0530 Subject: [PATCH 0640/9167] staging: rtl8188eu: Declare Efuse_GetCurrentSize() as a static function Signed-off-by: navin patidar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/core/rtw_efuse.c | 2 +- drivers/staging/rtl8188eu/include/rtw_efuse.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_efuse.c b/drivers/staging/rtl8188eu/core/rtw_efuse.c index 5b997b2b404a..7006088d1ad0 100644 --- a/drivers/staging/rtl8188eu/core/rtw_efuse.c +++ b/drivers/staging/rtl8188eu/core/rtw_efuse.c @@ -440,7 +440,7 @@ u8 Efuse_WordEnableDataWrite(struct adapter *pAdapter, u16 efuse_addr, u8 word_e return badworden; } -u16 Efuse_GetCurrentSize(struct adapter *pAdapter) +static u16 Efuse_GetCurrentSize(struct adapter *pAdapter) { int bContinual = true; u16 efuse_addr = 0; diff --git a/drivers/staging/rtl8188eu/include/rtw_efuse.h b/drivers/staging/rtl8188eu/include/rtw_efuse.h index 720f9ea24d52..5660eed7196b 100644 --- a/drivers/staging/rtl8188eu/include/rtw_efuse.h +++ b/drivers/staging/rtl8188eu/include/rtw_efuse.h @@ -99,7 +99,6 @@ struct efuse_hal { u8 fakeBTEfuseModifiedMap[EFUSE_BT_MAX_MAP_LEN]; }; -u16 Efuse_GetCurrentSize(struct adapter *adapter); u8 Efuse_CalculateWordCnts(u8 word_en); void EFUSE_GetEfuseDefinition(struct adapter *adapt, u8 type, u8 type1, void *out); -- GitLab From 66ed681a304f2971f85b9d8c58d4c35f340e1af1 Mon Sep 17 00:00:00 2001 From: Adrian Remonda Date: Sun, 10 Aug 2014 20:39:56 +0200 Subject: [PATCH 0641/9167] Staging: rtl8188eu: Lines over 80 characters fixed. This is a patch to the hal/rtl8188eu_recv.c file that fixes up a "line over 80 characters" warning found by the checkpatch.pl tool. Signed-off-by: Adrian Remonda Signed-off-by: Greg Kroah-Hartman --- .../staging/rtl8188eu/hal/rtl8188eu_recv.c | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c index f25c87c63250..8be48194b180 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c @@ -41,15 +41,19 @@ int rtl8188eu_init_recv_priv(struct adapter *padapter) /* init recv_buf */ _rtw_init_queue(&precvpriv->free_recv_buf_queue); - precvpriv->pallocated_recv_buf = kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_KERNEL); + precvpriv->pallocated_recv_buf = + kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_KERNEL); if (precvpriv->pallocated_recv_buf == NULL) { res = _FAIL; - RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("alloc recv_buf fail!\n")); + RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, + ("alloc recv_buf fail!\n")); goto exit; } - memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF * sizeof(struct recv_buf) + 4); + memset(precvpriv->pallocated_recv_buf, 0, + NR_RECVBUFF * sizeof(struct recv_buf) + 4); - precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_recv_buf), 4); + precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((size_t) + (precvpriv->pallocated_recv_buf), 4); precvbuf = (struct recv_buf *)precvpriv->precv_buf; @@ -66,20 +70,23 @@ int rtl8188eu_init_recv_priv(struct adapter *padapter) { int i; size_t tmpaddr = 0; - size_t alignment = 0; + size_t alignm = 0; struct sk_buff *pskb = NULL; skb_queue_head_init(&precvpriv->free_recv_skb_queue); for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) { - pskb = __netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL); + pskb = __netdev_alloc_skb(padapter->pnetdev, + MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, + GFP_KERNEL); if (pskb) { pskb->dev = padapter->pnetdev; tmpaddr = (size_t)pskb->data; - alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1); - skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment)); + alignm = tmpaddr & (RECVBUFF_ALIGN_SZ-1); + skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignm)); - skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb); + skb_queue_tail(&precvpriv->free_recv_skb_queue, + pskb); } pskb = NULL; } @@ -109,7 +116,8 @@ void rtl8188eu_free_recv_priv(struct adapter *padapter) if (skb_queue_len(&precvpriv->free_recv_skb_queue)) - DBG_88E(KERN_WARNING "free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue)); + DBG_88E(KERN_WARNING "free_recv_skb_queue not empty, %d\n", + skb_queue_len(&precvpriv->free_recv_skb_queue)); skb_queue_purge(&precvpriv->free_recv_skb_queue); } -- GitLab From 4246e490b59bf68839f75fa4354e099105ff927a Mon Sep 17 00:00:00 2001 From: Adrian Remonda Date: Sun, 10 Aug 2014 20:39:57 +0200 Subject: [PATCH 0642/9167] Staging: rtl8188eu: Removed unneeded code. This patch removes some unneeded code. 1) kzalloc() allocates 4 extra bytes so that we can align the return value. But actually the return value is already aligned so we can remove the + 4 and the call to N_BYTE_ALIGMENT(). 2) The memset() isn't needed because kzalloc() zeroes the allocation. Suggested-by: Larry Finger Signed-off-by: Adrian Remonda Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c index 8be48194b180..bc275b2a7d37 100644 --- a/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c +++ b/drivers/staging/rtl8188eu/hal/rtl8188eu_recv.c @@ -42,18 +42,15 @@ int rtl8188eu_init_recv_priv(struct adapter *padapter) _rtw_init_queue(&precvpriv->free_recv_buf_queue); precvpriv->pallocated_recv_buf = - kzalloc(NR_RECVBUFF * sizeof(struct recv_buf) + 4, GFP_KERNEL); + kzalloc(NR_RECVBUFF * sizeof(struct recv_buf), GFP_KERNEL); if (precvpriv->pallocated_recv_buf == NULL) { res = _FAIL; RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("alloc recv_buf fail!\n")); goto exit; } - memset(precvpriv->pallocated_recv_buf, 0, - NR_RECVBUFF * sizeof(struct recv_buf) + 4); - precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((size_t) - (precvpriv->pallocated_recv_buf), 4); + precvpriv->precv_buf = precvpriv->pallocated_recv_buf; precvbuf = (struct recv_buf *)precvpriv->precv_buf; -- GitLab From d320c455cb726cc0618ad9852982debc8af535b3 Mon Sep 17 00:00:00 2001 From: Phong Tran Date: Wed, 13 Aug 2014 20:37:04 +0700 Subject: [PATCH 0643/9167] staging: android: ion: ion_dummy_driver.c Replace kzalloc() by kcalloc() This patch fix checkpatch.pl warning Tested by compilation only. Signed-off-by: Phong Tran Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/ion_dummy_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c index 3a45e79fe444..6d0a38aabc7a 100644 --- a/drivers/staging/android/ion/ion_dummy_driver.c +++ b/drivers/staging/android/ion/ion_dummy_driver.c @@ -68,7 +68,7 @@ static int __init ion_dummy_init(void) int i, err; idev = ion_device_create(NULL); - heaps = kzalloc(sizeof(struct ion_heap *) * dummy_ion_pdata.nr, + heaps = kcalloc(dummy_ion_pdata.nr, sizeof(struct ion_heap *), GFP_KERNEL); if (!heaps) return -ENOMEM; -- GitLab From 04e14356d549fd1c5487f8a5be13eb4a59802fb3 Mon Sep 17 00:00:00 2001 From: Phong Tran Date: Wed, 13 Aug 2014 20:37:05 +0700 Subject: [PATCH 0644/9167] staging: android: ion: ion.c Add a new blank line after decleration This patch fix checkpatch.pl warning Tested by compilation only. Signed-off-by: Phong Tran Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/ion.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 270360912b2c..cad76ae20d7e 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -805,6 +805,7 @@ struct ion_client *ion_client_create(struct ion_device *dev, client, &debug_client_fops); if (!client->debug_root) { char buf[256], *path; + path = dentry_path(dev->clients_debug_root, buf, 256); pr_err("Failed to create client debugfs at %s/%s\n", path, client->display_name); -- GitLab From b66157f36aff92ec3d93502471a7d26f10d39436 Mon Sep 17 00:00:00 2001 From: Phong Tran Date: Wed, 13 Aug 2014 20:37:06 +0700 Subject: [PATCH 0645/9167] staging: android: ion: Remove redundant return of void function This patch fix checkpatch.pl warning Tested by compilation only. Signed-off-by: Phong Tran Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/ion/ion.c | 1 - drivers/staging/android/ion/ion_carveout_heap.c | 1 - drivers/staging/android/ion/ion_chunk_heap.c | 1 - drivers/staging/android/ion/ion_dummy_driver.c | 2 -- drivers/staging/android/ion/ion_system_heap.c | 1 - 5 files changed, 6 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index cad76ae20d7e..56604f41ec48 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1057,7 +1057,6 @@ static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, void *ptr) { - return; } static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start, diff --git a/drivers/staging/android/ion/ion_carveout_heap.c b/drivers/staging/android/ion/ion_carveout_heap.c index dcb6f2196c87..9156d8238c97 100644 --- a/drivers/staging/android/ion/ion_carveout_heap.c +++ b/drivers/staging/android/ion/ion_carveout_heap.c @@ -133,7 +133,6 @@ static struct sg_table *ion_carveout_heap_map_dma(struct ion_heap *heap, static void ion_carveout_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - return; } static struct ion_heap_ops carveout_heap_ops = { diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c index 9c3e49aa204b..3e6ec2ee6802 100644 --- a/drivers/staging/android/ion/ion_chunk_heap.c +++ b/drivers/staging/android/ion/ion_chunk_heap.c @@ -126,7 +126,6 @@ static struct sg_table *ion_chunk_heap_map_dma(struct ion_heap *heap, static void ion_chunk_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - return; } static struct ion_heap_ops chunk_heap_ops = { diff --git a/drivers/staging/android/ion/ion_dummy_driver.c b/drivers/staging/android/ion/ion_dummy_driver.c index 6d0a38aabc7a..f3ea1c31e533 100644 --- a/drivers/staging/android/ion/ion_dummy_driver.c +++ b/drivers/staging/android/ion/ion_dummy_driver.c @@ -152,7 +152,5 @@ static void __exit ion_dummy_exit(void) dummy_heaps[ION_HEAP_TYPE_CHUNK].size); chunk_ptr = NULL; } - - return; } __exitcall(ion_dummy_exit); diff --git a/drivers/staging/android/ion/ion_system_heap.c b/drivers/staging/android/ion/ion_system_heap.c index 6b77c5195b4d..da2a63c0a9ba 100644 --- a/drivers/staging/android/ion/ion_system_heap.c +++ b/drivers/staging/android/ion/ion_system_heap.c @@ -205,7 +205,6 @@ static struct sg_table *ion_system_heap_map_dma(struct ion_heap *heap, static void ion_system_heap_unmap_dma(struct ion_heap *heap, struct ion_buffer *buffer) { - return; } static int ion_system_heap_shrink(struct ion_heap *heap, gfp_t gfp_mask, -- GitLab From 5dffac89e2480487e79bc2c3e773ee649cdf7f3c Mon Sep 17 00:00:00 2001 From: Ramesh Basukala Date: Thu, 14 Aug 2014 10:11:44 -0400 Subject: [PATCH 0646/9167] Staging: bmc: fix coding style warning This is a patch to the vendorspecificextn.c that fixes coding style warning message line over 80 characters found by checkpatch.pl script. I am submitting this patch as required by Eudyptula Challenge. Signed-off-by: Ramesh Basukala Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/vendorspecificextn.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/staging/bcm/vendorspecificextn.c b/drivers/staging/bcm/vendorspecificextn.c index 2c57a16788c0..1d9bef6e4273 100644 --- a/drivers/staging/bcm/vendorspecificextn.c +++ b/drivers/staging/bcm/vendorspecificextn.c @@ -11,7 +11,8 @@ * STATUS_SUCCESS/STATUS_FAILURE * */ -INT vendorextnGetSectionInfo(PVOID pContext, struct bcm_flash2x_vendor_info *pVendorInfo) +INT vendorextnGetSectionInfo(PVOID pContext, + struct bcm_flash2x_vendor_info *pVendorInfo) { return STATUS_FAILURE; } @@ -61,7 +62,8 @@ INT vendorextnExit(struct bcm_mini_adapter *Adapter) * arg -input parameter sent by vendor * * Returns: - * CONTINUE_COMMON_PATH in case it is not meant to be processed by vendor ioctls + * 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 */ @@ -88,8 +90,8 @@ INT vendorextnIoctl(struct bcm_mini_adapter *Adapter, UINT cmd, ULONG arg) * STATUS_SUCCESS/STATUS_FAILURE */ -INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes) +INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, + enum bcm_flash2x_section_val SectionVal, UINT offset, UINT numOfBytes) { return STATUS_FAILURE; } @@ -112,8 +114,9 @@ INT vendorextnReadSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_sect * Returns: * STATUS_SUCCESS/STATUS_FAILURE */ -INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes, bool bVerify) +INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, + enum bcm_flash2x_section_val SectionVal, UINT offset, + UINT numOfBytes, bool bVerify) { return STATUS_FAILURE; } @@ -135,8 +138,8 @@ INT vendorextnWriteSection(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_sec * Returns: * STATUS_SUCCESS/STATUS_FAILURE */ -INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, enum bcm_flash2x_section_val SectionVal, - UINT offset, UINT numOfBytes) +INT vendorextnWriteSectionWithoutErase(PVOID pContext, PUCHAR pBuffer, + enum bcm_flash2x_section_val SectionVal, UINT offset, UINT numOfBytes) { return STATUS_FAILURE; } -- GitLab From ecc33af33ea8f71e691db1c1000ead675dc4d34f Mon Sep 17 00:00:00 2001 From: Chase Southwood Date: Mon, 11 Aug 2014 21:02:58 -0500 Subject: [PATCH 0647/9167] staging: comedi: addi_apci_1564: remove apci1564_do_config The DO config function served the purpose of configuring the diagnostic interrupts for the board. As the driver currently does not support diagnostic interrupts, the digital output subdevice does not need an insn_config operation and this function can be safely removed. Signed-off-by: Chase Southwood Reviewed-by: Ian Abbott Cc: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 34 ------------------- .../staging/comedi/drivers/addi_apci_1564.c | 1 - 2 files changed, 35 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 8a613ae0acba..0ce1debf7e2a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -87,40 +87,6 @@ #define APCI1564_TCW_WARN_TIMEVAL_REG(x) (0x18 + ((x) * 0x20)) #define APCI1564_TCW_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20)) -/* - * Configures The Digital Output Subdevice. - * - * data[1] 0 = Disable VCC Interrupt, 1 = Enable VCC Interrupt - * data[2] 0 = Disable CC Interrupt, 1 = Enable CC Interrupt - */ -static int apci1564_do_config(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, - unsigned int *data) -{ - struct apci1564_private *devpriv = dev->private; - unsigned int ul_Command = 0; - - if ((data[0] != 0) && (data[0] != 1)) { - dev_err(dev->class_dev, "Data should be 1 or 0\n"); - return -EINVAL; - } - - if (data[1] == 1) - ul_Command = ul_Command | 0x1; - else - ul_Command = ul_Command & 0xFFFFFFFE; - - if (data[2] == 1) - ul_Command = ul_Command | 0x2; - else - ul_Command = ul_Command & 0xFFFFFFFD; - - outl(ul_Command, devpriv->amcc_iobase + APCI1564_DO_INT_CTRL_REG); - devpriv->tsk_current = current; - return insn->n; -} - /* * Configures The Timer, Counter or Watchdog * diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c index 543cb074213a..555e0a9f04c5 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -388,7 +388,6 @@ static int apci1564_auto_attach(struct comedi_device *dev, s->n_chan = 32; s->maxdata = 1; s->range_table = &range_digital; - s->insn_config = apci1564_do_config; s->insn_bits = apci1564_do_insn_bits; /* Change-Of-State (COS) interrupt subdevice */ -- GitLab From e3249b881e800d7374799b8aa551f498c5d39741 Mon Sep 17 00:00:00 2001 From: Chase Southwood Date: Mon, 11 Aug 2014 21:03:19 -0500 Subject: [PATCH 0648/9167] staging: comedi: addi_apci_1564: Remove in-driver watchdog support code Starting with commit 1496e5961113 ("staging: comedi: addi_apci_1564: use addi_watchdog module to init watchdog subdevice"), this driver uses the addi_watchdog module to provide support for the watchdog subdevice. Any remaining watchdog code in-driver can and should be removed. This will also make future work on the timer and counter subdevices easier. Signed-off-by: Chase Southwood Reviewed-by: Ian Abbott Cc: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 54 +++++-------------- 1 file changed, 12 insertions(+), 42 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index 0ce1debf7e2a..f8d8cc962408 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -88,9 +88,9 @@ #define APCI1564_TCW_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20)) /* - * Configures The Timer, Counter or Watchdog + * Configures The Timer or Counter * - * data[0] Configure as: 0 = Timer, 1 = Counter, 2 = Watchdog + * data[0] Configure as: 0 = Timer, 1 = Counter * data[1] 1 = Enable Interrupt, 0 = Disable Interrupt * data[2] Time Unit * data[3] Reload Value @@ -107,14 +107,7 @@ static int apci1564_timer_config(struct comedi_device *dev, unsigned int ul_Command1 = 0; devpriv->tsk_current = current; - if (data[0] == ADDIDATA_WATCHDOG) { - devpriv->timer_select_mode = ADDIDATA_WATCHDOG; - - /* Disable the watchdog */ - outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG); - /* Loading the Reload value */ - outl(data[3], devpriv->amcc_iobase + APCI1564_WDOG_RELOAD_REG); - } else if (data[0] == ADDIDATA_TIMER) { + if (data[0] == ADDIDATA_TIMER) { /* First Stop The Timer */ ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; @@ -187,14 +180,13 @@ static int apci1564_timer_config(struct comedi_device *dev, } else { dev_err(dev->class_dev, "Invalid subdevice.\n"); } - return insn->n; } /* - * Start / Stop The Selected Timer, Counter or Watchdog + * Start / Stop The Selected Timer or Counter * - * data[0] Configure as: 0 = Timer, 1 = Counter, 2 = Watchdog + * data[0] Configure as: 0 = Timer, 1 = Counter * data[1] 0 = Stop, 1 = Start, 2 = Trigger Clear (Only Counter) */ static int apci1564_timer_write(struct comedi_device *dev, @@ -205,23 +197,6 @@ static int apci1564_timer_write(struct comedi_device *dev, struct apci1564_private *devpriv = dev->private; unsigned int ul_Command1 = 0; - if (devpriv->timer_select_mode == ADDIDATA_WATCHDOG) { - switch (data[1]) { - case 0: /* stop the watchdog */ - /* disable the watchdog */ - outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG); - break; - case 1: /* start the watchdog */ - outl(0x0001, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG); - break; - case 2: /* Software trigger */ - outl(0x0201, devpriv->amcc_iobase + APCI1564_WDOG_CTRL_REG); - break; - default: - dev_err(dev->class_dev, "Specified functionality does not exist.\n"); - return -EINVAL; - } - } if (devpriv->timer_select_mode == ADDIDATA_TIMER) { if (data[1] == 1) { ul_Command1 = inl(devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); @@ -236,8 +211,7 @@ static int apci1564_timer_write(struct comedi_device *dev, ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; outl(ul_Command1, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); } - } - if (devpriv->timer_select_mode == ADDIDATA_COUNTER) { + } else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) { ul_Command1 = inl(dev->iobase + APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1)); @@ -254,12 +228,14 @@ static int apci1564_timer_write(struct comedi_device *dev, } outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1)); + } else { + dev_err(dev->class_dev, "Invalid subdevice.\n"); } return insn->n; } /* - * Read The Selected Timer, Counter or Watchdog + * Read The Selected Timer or Counter */ static int apci1564_timer_read(struct comedi_device *dev, struct comedi_subdevice *s, @@ -269,11 +245,7 @@ static int apci1564_timer_read(struct comedi_device *dev, struct apci1564_private *devpriv = dev->private; unsigned int ul_Command1 = 0; - if (devpriv->timer_select_mode == ADDIDATA_WATCHDOG) { - /* Stores the status of the Watchdog */ - data[0] = inl(devpriv->amcc_iobase + APCI1564_WDOG_STATUS_REG) & 0x1; - data[1] = inl(devpriv->amcc_iobase + APCI1564_WDOG_REG); - } else if (devpriv->timer_select_mode == ADDIDATA_TIMER) { + if (devpriv->timer_select_mode == ADDIDATA_TIMER) { /* Stores the status of the Timer */ data[0] = inl(devpriv->amcc_iobase + APCI1564_TIMER_STATUS_REG) & 0x1; @@ -299,10 +271,8 @@ static int apci1564_timer_read(struct comedi_device *dev, /* Get the overflow status */ data[4] = (unsigned char) ((ul_Command1 >> 0) & 1); - } else if ((devpriv->timer_select_mode != ADDIDATA_TIMER) - && (devpriv->timer_select_mode != ADDIDATA_WATCHDOG) - && (devpriv->timer_select_mode != ADDIDATA_COUNTER)) { - dev_err(dev->class_dev, "Invalid Subdevice!\n"); + } else { + dev_err(dev->class_dev, "Invalid subdevice.\n"); } return insn->n; } -- GitLab From 85d7c9ab5129e96d25b455d7bf45066c376e8e2d Mon Sep 17 00:00:00 2001 From: Chase Southwood Date: Mon, 11 Aug 2014 21:03:48 -0500 Subject: [PATCH 0649/9167] staging: comedi: addi_apci_1564: tidy register map defines This commit performs a final tidying of the register map defines, bringing them to a state that is ready for merging into addi_apci_1564.c when the time comes. Actions performed include: *Removes the APCI1564_ADDRESS_RANGE macro, which is no longer needed/used. *Renames the APCI1564_DIGITAL_OP_{VCC,CC}_INTERRUPT_{ENABLE,DISABLE} macros to shorter names which are more consistent with the digital input interrupt macros. *Fixes a typo in a comment (dev>iobase changed to dev->iobase). *Renames the APCI1564_TCW_* macros to APCI1564_COUNTER_* names to more accurately reflect that they are only offsets to counter registers (since only the counters are offset from dev->iobase). Signed-off-by: Chase Southwood Reviewed-by: Ian Abbott Cc: H Hartley Sweeten Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/addi-data/hwdrv_apci1564.c | 70 ++++++++++--------- .../staging/comedi/drivers/addi_apci_1564.c | 19 ++--- 2 files changed, 48 insertions(+), 41 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c index f8d8cc962408..198c6276e838 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c @@ -21,8 +21,6 @@ * */ -#define APCI1564_ADDRESS_RANGE 128 - /* Digital Input IRQ Function Selection */ #define APCI1564_DI_INT_OR (0 << 1) #define APCI1564_DI_INT_AND (1 << 1) @@ -32,10 +30,10 @@ #define APCI1564_DI_INT_DISABLE 0xfffffffb /* Digital Output Interrupt Enable Disable. */ -#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1 -#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xfffffffe -#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2 -#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xfffffffd +#define APCI1564_DO_VCC_INT_ENABLE 0x1 +#define APCI1564_DO_VCC_INT_DISABLE 0xfffffffe +#define APCI1564_DO_CC_INT_ENABLE 0x2 +#define APCI1564_DO_CC_IN_DISABLE 0xfffffffd /* TIMER COUNTER WATCHDOG DEFINES */ #define ADDIDATA_TIMER 0 @@ -76,16 +74,16 @@ #define APCI1564_TIMER_WARN_TIMEBASE_REG 0x64 /* - * dev>iobase Register Map + * dev->iobase Register Map */ -#define APCI1564_TCW_REG(x) (0x00 + ((x) * 0x20)) -#define APCI1564_TCW_RELOAD_REG(x) (0x04 + ((x) * 0x20)) -#define APCI1564_TCW_TIMEBASE_REG(x) (0x08 + ((x) * 0x20)) -#define APCI1564_TCW_CTRL_REG(x) (0x0c + ((x) * 0x20)) -#define APCI1564_TCW_STATUS_REG(x) (0x10 + ((x) * 0x20)) -#define APCI1564_TCW_IRQ_REG(x) (0x14 + ((x) * 0x20)) -#define APCI1564_TCW_WARN_TIMEVAL_REG(x) (0x18 + ((x) * 0x20)) -#define APCI1564_TCW_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20)) +#define APCI1564_COUNTER_REG(x) (0x00 + ((x) * 0x20)) +#define APCI1564_COUNTER_RELOAD_REG(x) (0x04 + ((x) * 0x20)) +#define APCI1564_COUNTER_TIMEBASE_REG(x) (0x08 + ((x) * 0x20)) +#define APCI1564_COUNTER_CTRL_REG(x) (0x0c + ((x) * 0x20)) +#define APCI1564_COUNTER_STATUS_REG(x) (0x10 + ((x) * 0x20)) +#define APCI1564_COUNTER_IRQ_REG(x) (0x14 + ((x) * 0x20)) +#define APCI1564_COUNTER_WARN_TIMEVAL_REG(x) (0x18 + ((x) * 0x20)) +#define APCI1564_COUNTER_WARN_TIMEBASE_REG(x) (0x1c + ((x) * 0x20)) /* * Configures The Timer or Counter @@ -121,14 +119,14 @@ static int apci1564_timer_config(struct comedi_device *dev, outl(0x0, devpriv->amcc_iobase + APCI1564_DI_IRQ_REG); outl(0x0, devpriv->amcc_iobase + APCI1564_DO_IRQ_REG); outl(0x0, devpriv->amcc_iobase + APCI1564_WDOG_IRQ_REG); - outl(0x0, - dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER1)); - outl(0x0, - dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER2)); - outl(0x0, - dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER3)); - outl(0x0, - dev->iobase + APCI1564_TCW_IRQ_REG(APCI1564_COUNTER4)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER1)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER2)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER3)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_IRQ_REG(APCI1564_COUNTER4)); } else { /* disable Timer interrupt */ outl(0x0, devpriv->amcc_iobase + APCI1564_TIMER_CTRL_REG); @@ -149,13 +147,16 @@ static int apci1564_timer_config(struct comedi_device *dev, devpriv->mode_select_register = data[5]; /* First Stop The Counter */ - ul_Command1 = inl(dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + ul_Command1 = inl(dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; /* Stop The Timer */ - outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + outl(ul_Command1, dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); /* Set the reload value */ - outl(data[3], dev->iobase + APCI1564_TCW_RELOAD_REG(data[5] - 1)); + outl(data[3], dev->iobase + + APCI1564_COUNTER_RELOAD_REG(data[5] - 1)); /* Set the mode : */ /* - Disable the hardware */ @@ -168,15 +169,18 @@ static int apci1564_timer_config(struct comedi_device *dev, ul_Command1 = (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL | (unsigned int) ((unsigned int) data[4] << 16UL); - outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + outl(ul_Command1, dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); /* Enable or Disable Interrupt */ ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1); - outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + outl(ul_Command1, dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); /* Set the Up/Down selection */ ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18); - outl(ul_Command1, dev->iobase + APCI1564_TCW_CTRL_REG(data[5] - 1)); + outl(ul_Command1, dev->iobase + + APCI1564_COUNTER_CTRL_REG(data[5] - 1)); } else { dev_err(dev->class_dev, "Invalid subdevice.\n"); } @@ -214,7 +218,7 @@ static int apci1564_timer_write(struct comedi_device *dev, } else if (devpriv->timer_select_mode == ADDIDATA_COUNTER) { ul_Command1 = inl(dev->iobase + - APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_CTRL_REG(devpriv->mode_select_register - 1)); if (data[1] == 1) { /* Start the Counter subdevice */ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; @@ -227,7 +231,7 @@ static int apci1564_timer_write(struct comedi_device *dev, ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400; } outl(ul_Command1, dev->iobase + - APCI1564_TCW_CTRL_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_CTRL_REG(devpriv->mode_select_register - 1)); } else { dev_err(dev->class_dev, "Invalid subdevice.\n"); } @@ -255,10 +259,10 @@ static int apci1564_timer_read(struct comedi_device *dev, /* Read the Counter Actual Value. */ data[0] = inl(dev->iobase + - APCI1564_TCW_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_REG(devpriv->mode_select_register - 1)); ul_Command1 = inl(dev->iobase + - APCI1564_TCW_STATUS_REG(devpriv->mode_select_register - 1)); + APCI1564_COUNTER_STATUS_REG(devpriv->mode_select_register - 1)); /* 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 555e0a9f04c5..16c02c855a65 100644 --- a/drivers/staging/comedi/drivers/addi_apci_1564.c +++ b/drivers/staging/comedi/drivers/addi_apci_1564.c @@ -42,10 +42,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_TCW_CTRL_REG(APCI1564_COUNTER1)); - outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER2)); - outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER3)); - outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(APCI1564_COUNTER4)); + 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)); return 0; } @@ -94,17 +94,20 @@ static irqreturn_t apci1564_interrupt(int irq, void *d) } for (chan = 0; chan < 4; chan++) { - status = inl(dev->iobase + APCI1564_TCW_IRQ_REG(chan)); + status = inl(dev->iobase + APCI1564_COUNTER_IRQ_REG(chan)); if (status & 0x01) { /* Disable Counter Interrupt */ - ctrl = inl(dev->iobase + APCI1564_TCW_CTRL_REG(chan)); - outl(0x0, dev->iobase + APCI1564_TCW_CTRL_REG(chan)); + ctrl = inl(dev->iobase + + APCI1564_COUNTER_CTRL_REG(chan)); + outl(0x0, dev->iobase + + APCI1564_COUNTER_CTRL_REG(chan)); /* Send a signal to from kernel to user space */ send_sig(SIGIO, devpriv->tsk_current, 0); /* Enable Counter Interrupt */ - outl(ctrl, dev->iobase + APCI1564_TCW_CTRL_REG(chan)); + outl(ctrl, dev->iobase + + APCI1564_COUNTER_CTRL_REG(chan)); } } -- GitLab From 849db1aacd223b25826246171519413fad601df6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:17:16 -0700 Subject: [PATCH 0650/9167] staging: comedi: amplc_dio200: tidy up comedi_driver declaration For aesthetics, add some whitespace to the declaration. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index e99012ee4109..83a99c3504ef 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -270,13 +270,13 @@ static void dio200_detach(struct comedi_device *dev) } static struct comedi_driver amplc_dio200_driver = { - .driver_name = "amplc_dio200", - .module = THIS_MODULE, - .attach = dio200_attach, - .detach = dio200_detach, - .board_name = &dio200_isa_boards[0].name, - .offset = sizeof(struct dio200_board), - .num_names = ARRAY_SIZE(dio200_isa_boards), + .driver_name = "amplc_dio200", + .module = THIS_MODULE, + .attach = dio200_attach, + .detach = dio200_detach, + .board_name = &dio200_isa_boards[0].name, + .offset = sizeof(struct dio200_board), + .num_names = ARRAY_SIZE(dio200_isa_boards), }; module_comedi_driver(amplc_dio200_driver); -- GitLab From 593d11c5a30f4049887dfad7ca2ac56a97c33c99 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:17:17 -0700 Subject: [PATCH 0651/9167] staging: comedi: amplc_dio200: tidy up {comedi, pci}_driver declarations For aesthetics, add some whitespace to these declarations. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../staging/comedi/drivers/amplc_dio200_pci.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index c69a43176173..397f04afc28f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -400,10 +400,10 @@ static void dio200_pci_detach(struct comedi_device *dev) } static struct comedi_driver dio200_pci_comedi_driver = { - .driver_name = "amplc_dio200_pci", - .module = THIS_MODULE, - .auto_attach = dio200_pci_auto_attach, - .detach = dio200_pci_detach, + .driver_name = "amplc_dio200_pci", + .module = THIS_MODULE, + .auto_attach = dio200_pci_auto_attach, + .detach = dio200_pci_detach, }; static const struct pci_device_id dio200_pci_table[] = { @@ -424,10 +424,10 @@ static int dio200_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) } static struct pci_driver dio200_pci_pci_driver = { - .name = "amplc_dio200_pci", - .id_table = dio200_pci_table, - .probe = dio200_pci_probe, - .remove = comedi_pci_auto_unconfig, + .name = "amplc_dio200_pci", + .id_table = dio200_pci_table, + .probe = dio200_pci_probe, + .remove = comedi_pci_auto_unconfig, }; module_comedi_pci_driver(dio200_pci_comedi_driver, dio200_pci_pci_driver); -- GitLab From f6ce09504ddc81aec07ddfcb16ad3c5b80ab19d0 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:17:18 -0700 Subject: [PATCH 0652/9167] staging: comedi: amplc_dio200.h: remove struct dio200_layout definition This struct is used to provide part of the boardinfo data. Using the extra indirection does not provide any additional clarity to the driver. Absorb the members from dio200_layout into dio200_board and remove the extra 'layout' indirection. For aesthetics, rename all the local variables used for the boardinfo pointer to 'board'. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 78 ++++++------- drivers/staging/comedi/drivers/amplc_dio200.h | 16 +-- .../comedi/drivers/amplc_dio200_common.c | 96 +++++++--------- .../staging/comedi/drivers/amplc_dio200_pci.c | 105 +++++++++--------- 4 files changed, 135 insertions(+), 160 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 83a99c3504ef..9b5efb7990a5 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -202,53 +202,47 @@ */ static const struct dio200_board dio200_isa_boards[] = { { - .name = "pc212e", - .layout = { - .n_subdevs = 6, - .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254, sd_8254, - sd_intr}, - .sdinfo = {0x00, 0x08, 0x0C, 0x10, 0x14, 0x3F}, - .has_int_sce = true, - .has_clk_gat_sce = true, + .name = "pc212e", + .n_subdevs = 6, + .sdtype = { + sd_8255, sd_8254, sd_8254, sd_8254, sd_8254, sd_intr }, - }, - { - .name = "pc214e", - .layout = { - .n_subdevs = 4, - .sdtype = {sd_8255, sd_8255, sd_8254, sd_intr}, - .sdinfo = {0x00, 0x08, 0x10, 0x01}, + .sdinfo = { 0x00, 0x08, 0x0c, 0x10, 0x14, 0x3f }, + .has_int_sce = true, + .has_clk_gat_sce = true, + }, { + .name = "pc214e", + .n_subdevs = 4, + .sdtype = { + sd_8255, sd_8255, sd_8254, sd_intr }, - }, - { - .name = "pc215e", - .layout = { - .n_subdevs = 5, - .sdtype = {sd_8255, sd_8255, sd_8254, sd_8254, sd_intr}, - .sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F}, - .has_int_sce = true, - .has_clk_gat_sce = true, + .sdinfo = { 0x00, 0x08, 0x10, 0x01 }, + }, { + .name = "pc215e", + .n_subdevs = 5, + .sdtype = { + sd_8255, sd_8255, sd_8254, sd_8254, sd_intr }, - }, - { - .name = "pc218e", - .layout = { - .n_subdevs = 7, - .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254, sd_8254, - sd_intr}, - .sdinfo = {0x00, 0x04, 0x08, 0x0C, 0x10, 0x14, 0x3F}, - .has_int_sce = true, - .has_clk_gat_sce = true, + .sdinfo = { 0x00, 0x08, 0x10, 0x14, 0x3f }, + .has_int_sce = true, + .has_clk_gat_sce = true, + }, { + .name = "pc218e", + .n_subdevs = 7, + .sdtype = { + sd_8254, sd_8254, sd_8255, sd_8254, sd_8254, sd_intr }, - }, - { - .name = "pc272e", - .layout = { - .n_subdevs = 4, - .sdtype = {sd_8255, sd_8255, sd_8255, sd_intr}, - .sdinfo = {0x00, 0x08, 0x10, 0x3F}, - .has_int_sce = true, + .sdinfo = { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x3f }, + .has_int_sce = true, + .has_clk_gat_sce = true, + }, { + .name = "pc272e", + .n_subdevs = 4, + .sdtype = { + sd_8255, sd_8255, sd_8255, sd_intr }, + .sdinfo = { 0x00, 0x08, 0x10, 0x3f }, + .has_int_sce = true, }, }; diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index e51261b006e1..60b7ae1a6423 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -31,11 +31,10 @@ enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer }; #define DIO200_MAX_SUBDEVS 8 #define DIO200_MAX_ISNS 6 -/* - * Board descriptions. - */ - -struct dio200_layout { +struct dio200_board { + const char *name; + unsigned char mainbar; + unsigned char mainshift; unsigned short n_subdevs; /* number of subdevices */ unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */ unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */ @@ -44,13 +43,6 @@ struct dio200_layout { bool has_enhancements:1; /* has enhanced features */ }; -struct dio200_board { - const char *name; - struct dio200_layout layout; - unsigned char mainbar; - unsigned char mainshift; -}; - int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, unsigned long req_irq_flags); diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 775263c1471e..519d91298656 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -132,27 +132,15 @@ struct dio200_subdev_intr { bool active:1; }; -static inline const struct dio200_layout * -dio200_board_layout(const struct dio200_board *board) -{ - return &board->layout; -} - -static inline const struct dio200_layout * -dio200_dev_layout(struct comedi_device *dev) -{ - return dio200_board_layout(comedi_board(dev)); -} - /* * Read 8-bit register. */ static unsigned char dio200_read8(struct comedi_device *dev, unsigned int offset) { - const struct dio200_board *thisboard = comedi_board(dev); + const struct dio200_board *board = comedi_board(dev); - offset <<= thisboard->mainshift; + offset <<= board->mainshift; if (dev->mmio) return readb(dev->mmio + offset); @@ -165,9 +153,9 @@ static unsigned char dio200_read8(struct comedi_device *dev, static void dio200_write8(struct comedi_device *dev, unsigned int offset, unsigned char val) { - const struct dio200_board *thisboard = comedi_board(dev); + const struct dio200_board *board = comedi_board(dev); - offset <<= thisboard->mainshift; + offset <<= board->mainshift; if (dev->mmio) writeb(val, dev->mmio + offset); @@ -181,9 +169,9 @@ static void dio200_write8(struct comedi_device *dev, unsigned int offset, static unsigned int dio200_read32(struct comedi_device *dev, unsigned int offset) { - const struct dio200_board *thisboard = comedi_board(dev); + const struct dio200_board *board = comedi_board(dev); - offset <<= thisboard->mainshift; + offset <<= board->mainshift; if (dev->mmio) return readl(dev->mmio + offset); @@ -196,9 +184,9 @@ static unsigned int dio200_read32(struct comedi_device *dev, static void dio200_write32(struct comedi_device *dev, unsigned int offset, unsigned int val) { - const struct dio200_board *thisboard = comedi_board(dev); + const struct dio200_board *board = comedi_board(dev); - offset <<= thisboard->mainshift; + offset <<= board->mainshift; if (dev->mmio) writel(val, dev->mmio + offset); @@ -214,10 +202,10 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_intr *subpriv = s->private; - if (layout->has_int_sce) { + if (board->has_int_sce) { /* Just read the interrupt status register. */ data[1] = dio200_read8(dev, subpriv->ofs) & subpriv->valid_isns; } else { @@ -234,12 +222,12 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, static void dio200_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_intr *subpriv = s->private; subpriv->active = false; subpriv->enabled_isns = 0; - if (layout->has_int_sce) + if (board->has_int_sce) dio200_write8(dev, subpriv->ofs, 0); } @@ -249,11 +237,11 @@ static void dio200_stop_intr(struct comedi_device *dev, static int dio200_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { - unsigned int n; - unsigned isn_bits; - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_intr *subpriv = s->private; struct comedi_cmd *cmd = &s->async->cmd; + unsigned int n; + unsigned isn_bits; int retval = 0; if (cmd->stop_src == TRIG_COUNT && subpriv->stopcount == 0) { @@ -271,7 +259,7 @@ static int dio200_start_intr(struct comedi_device *dev, isn_bits &= subpriv->valid_isns; /* Enable interrupt sources. */ subpriv->enabled_isns = isn_bits; - if (layout->has_int_sce) + if (board->has_int_sce) dio200_write8(dev, subpriv->ofs, isn_bits); } @@ -347,7 +335,7 @@ static void dio200_read_scan_intr(struct comedi_device *dev, static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subdevice *s) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_intr *subpriv = s->private; unsigned triggered; unsigned intstat; @@ -359,7 +347,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, spin_lock_irqsave(&subpriv->spinlock, flags); oldevents = s->async->events; - if (layout->has_int_sce) { + if (board->has_int_sce) { /* * Collect interrupt sources that have triggered and disable * them temporarily. Loop around until no extra interrupt @@ -393,7 +381,7 @@ static int dio200_handle_read_intr(struct comedi_device *dev, * Reenable them NOW to minimize the time they are disabled. */ cur_enabled = subpriv->enabled_isns; - if (layout->has_int_sce) + if (board->has_int_sce) dio200_write8(dev, subpriv->ofs, cur_enabled); if (subpriv->active) { @@ -533,7 +521,7 @@ static int dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int offset, unsigned valid_isns) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_intr *subpriv; subpriv = comedi_alloc_spriv(s, sizeof(*subpriv)); @@ -544,13 +532,13 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, subpriv->valid_isns = valid_isns; spin_lock_init(&subpriv->spinlock); - if (layout->has_int_sce) + if (board->has_int_sce) /* Disable interrupt sources. */ dio200_write8(dev, subpriv->ofs, 0); s->type = COMEDI_SUBD_DI; s->subdev_flags = SDF_READABLE | SDF_CMD_READ; - if (layout->has_int_sce) { + if (board->has_int_sce) { s->n_chan = DIO200_MAX_ISNS; s->len_chanlist = DIO200_MAX_ISNS; } else { @@ -701,15 +689,15 @@ dio200_subdev_8254_set_gate_src(struct comedi_device *dev, unsigned int counter_number, unsigned int gate_src) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv = s->private; unsigned char byte; - if (!layout->has_clk_gat_sce) + if (!board->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; - if (gate_src > (layout->has_enhancements ? 31 : 7)) + if (gate_src > (board->has_enhancements ? 31 : 7)) return -1; subpriv->gate_src[counter_number] = gate_src; @@ -727,10 +715,10 @@ dio200_subdev_8254_get_gate_src(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int counter_number) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv = s->private; - if (!layout->has_clk_gat_sce) + if (!board->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; @@ -747,15 +735,15 @@ dio200_subdev_8254_set_clock_src(struct comedi_device *dev, unsigned int counter_number, unsigned int clock_src) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv = s->private; unsigned char byte; - if (!layout->has_clk_gat_sce) + if (!board->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; - if (clock_src > (layout->has_enhancements ? 31 : 7)) + if (clock_src > (board->has_enhancements ? 31 : 7)) return -1; subpriv->clock_src[counter_number] = clock_src; @@ -774,11 +762,11 @@ dio200_subdev_8254_get_clock_src(struct comedi_device *dev, unsigned int counter_number, unsigned int *period_ns) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv = s->private; unsigned clock_src; - if (!layout->has_clk_gat_sce) + if (!board->has_clk_gat_sce) return -1; if (counter_number > 2) return -1; @@ -852,7 +840,7 @@ static int dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int offset) { - const struct dio200_layout *layout = dio200_dev_layout(dev); + const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv; unsigned int chan; @@ -870,7 +858,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, spin_lock_init(&subpriv->spinlock); subpriv->ofs = offset; - if (layout->has_clk_gat_sce) { + if (board->has_clk_gat_sce) { /* Derive CLK_SCE and GAT_SCE register offsets from * 8254 offset. */ subpriv->clk_sce_ofs = DIO200_XCLK_SCE + (offset >> 3); @@ -882,7 +870,7 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, for (chan = 0; chan < 3; chan++) { dio200_subdev_8254_set_mode(dev, s, chan, I8254_MODE0 | I8254_BINARY); - if (layout->has_clk_gat_sce) { + if (board->has_clk_gat_sce) { /* Gate source 0 is VCC (logic 1). */ dio200_subdev_8254_set_gate_src(dev, s, chan, 0); /* Clock source 0 is the dedicated clock input. */ @@ -1115,30 +1103,29 @@ EXPORT_SYMBOL_GPL(amplc_dio200_set_enhance); int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, unsigned long req_irq_flags) { - const struct dio200_board *thisboard = comedi_board(dev); - const struct dio200_layout *layout = dio200_board_layout(thisboard); + const struct dio200_board *board = comedi_board(dev); struct comedi_subdevice *s; unsigned int n; int ret; - ret = comedi_alloc_subdevices(dev, layout->n_subdevs); + ret = comedi_alloc_subdevices(dev, board->n_subdevs); if (ret) return ret; for (n = 0; n < dev->n_subdevices; n++) { s = &dev->subdevices[n]; - switch (layout->sdtype[n]) { + switch (board->sdtype[n]) { case sd_8254: /* counter subdevice (8254) */ ret = dio200_subdev_8254_init(dev, s, - layout->sdinfo[n]); + board->sdinfo[n]); if (ret < 0) return ret; break; case sd_8255: /* digital i/o subdevice (8255) */ ret = dio200_subdev_8255_init(dev, s, - layout->sdinfo[n]); + board->sdinfo[n]); if (ret < 0) return ret; break; @@ -1147,8 +1134,7 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, if (irq && !dev->read_subdev) { ret = dio200_subdev_intr_init(dev, s, DIO200_INT_SCE, - layout->sdinfo[n] - ); + board->sdinfo[n]); if (ret < 0) return ret; dev->read_subdev = s; diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index 397f04afc28f..e3d6a73604fb 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -242,70 +242,73 @@ enum dio200_pci_model { static const struct dio200_board dio200_pci_boards[] = { [pci215_model] = { - .name = "pci215", - .mainbar = 2, - .layout = { - .n_subdevs = 5, - .sdtype = {sd_8255, sd_8255, sd_8254, sd_8254, sd_intr}, - .sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F}, - .has_int_sce = true, - .has_clk_gat_sce = true, + .name = "pci215", + .mainbar = 2, + .n_subdevs = 5, + .sdtype = { + sd_8255, sd_8255, sd_8254, sd_8254, sd_intr }, + .sdinfo = { 0x00, 0x08, 0x10, 0x14, 0x3f }, + .has_int_sce = true, + .has_clk_gat_sce = true, }, [pci272_model] = { - .name = "pci272", - .mainbar = 2, - .layout = { - .n_subdevs = 4, - .sdtype = {sd_8255, sd_8255, sd_8255, sd_intr}, - .sdinfo = {0x00, 0x08, 0x10, 0x3F}, - .has_int_sce = true, + .name = "pci272", + .mainbar = 2, + .n_subdevs = 4, + .sdtype = { + sd_8255, sd_8255, sd_8255, sd_intr }, + .sdinfo = { 0x00, 0x08, 0x10, 0x3f }, + .has_int_sce = true, }, [pcie215_model] = { - .name = "pcie215", - .mainbar = 1, - .mainshift = 3, - .layout = { - .n_subdevs = 8, - .sdtype = {sd_8255, sd_none, sd_8255, sd_none, - sd_8254, sd_8254, sd_timer, sd_intr}, - .sdinfo = {0x00, 0x00, 0x08, 0x00, - 0x10, 0x14, 0x00, 0x3F}, - .has_int_sce = true, - .has_clk_gat_sce = true, - .has_enhancements = true, + .name = "pcie215", + .mainbar = 1, + .mainshift = 3, + .n_subdevs = 8, + .sdtype = { + sd_8255, sd_none, sd_8255, sd_none, + sd_8254, sd_8254, sd_timer, sd_intr }, + .sdinfo = { + 0x00, 0x00, 0x08, 0x00, 0x10, 0x14, 0x00, 0x3f + }, + .has_int_sce = true, + .has_clk_gat_sce = true, + .has_enhancements = true, }, [pcie236_model] = { - .name = "pcie236", - .mainbar = 1, - .mainshift = 3, - .layout = { - .n_subdevs = 8, - .sdtype = {sd_8255, sd_none, sd_none, sd_none, - sd_8254, sd_8254, sd_timer, sd_intr}, - .sdinfo = {0x00, 0x00, 0x00, 0x00, - 0x10, 0x14, 0x00, 0x3F}, - .has_int_sce = true, - .has_clk_gat_sce = true, - .has_enhancements = true, + .name = "pcie236", + .mainbar = 1, + .mainshift = 3, + .n_subdevs = 8, + .sdtype = { + sd_8255, sd_none, sd_none, sd_none, + sd_8254, sd_8254, sd_timer, sd_intr + }, + .sdinfo = { + 0x00, 0x00, 0x00, 0x00, 0x10, 0x14, 0x00, 0x3f }, + .has_int_sce = true, + .has_clk_gat_sce = true, + .has_enhancements = true, }, [pcie296_model] = { - .name = "pcie296", - .mainbar = 1, - .mainshift = 3, - .layout = { - .n_subdevs = 8, - .sdtype = {sd_8255, sd_8255, sd_8255, sd_8255, - sd_8254, sd_8254, sd_timer, sd_intr}, - .sdinfo = {0x00, 0x04, 0x08, 0x0C, - 0x10, 0x14, 0x00, 0x3F}, - .has_int_sce = true, - .has_clk_gat_sce = true, - .has_enhancements = true, + .name = "pcie296", + .mainbar = 1, + .mainshift = 3, + .n_subdevs = 8, + .sdtype = { + sd_8255, sd_8255, sd_8255, sd_8255, + sd_8254, sd_8254, sd_timer, sd_intr + }, + .sdinfo = { + 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x00, 0x3f }, + .has_int_sce = true, + .has_clk_gat_sce = true, + .has_enhancements = true, }, }; -- GitLab From 42c6767bf3f92ab2aca1845fadd2ae5c204fc951 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:17:19 -0700 Subject: [PATCH 0653/9167] staging: comedi: amplc_dio200.h: remove unnecessary function comment descriptions The function names provide enough description. The extra comments are not necessary. Remove them. Also, tidy up some of the function declarations. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/amplc_dio200_common.c | 225 +++++------------- 1 file changed, 59 insertions(+), 166 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 519d91298656..275795dbf6e9 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -132,9 +132,6 @@ struct dio200_subdev_intr { bool active:1; }; -/* - * Read 8-bit register. - */ static unsigned char dio200_read8(struct comedi_device *dev, unsigned int offset) { @@ -147,11 +144,8 @@ static unsigned char dio200_read8(struct comedi_device *dev, return inb(dev->iobase + offset); } -/* - * Write 8-bit register. - */ -static void dio200_write8(struct comedi_device *dev, unsigned int offset, - unsigned char val) +static void dio200_write8(struct comedi_device *dev, + unsigned int offset, unsigned char val) { const struct dio200_board *board = comedi_board(dev); @@ -163,9 +157,6 @@ static void dio200_write8(struct comedi_device *dev, unsigned int offset, outb(val, dev->iobase + offset); } -/* - * Read 32-bit register. - */ static unsigned int dio200_read32(struct comedi_device *dev, unsigned int offset) { @@ -178,11 +169,8 @@ static unsigned int dio200_read32(struct comedi_device *dev, return inl(dev->iobase + offset); } -/* - * Write 32-bit register. - */ -static void dio200_write32(struct comedi_device *dev, unsigned int offset, - unsigned int val) +static void dio200_write32(struct comedi_device *dev, + unsigned int offset, unsigned int val) { const struct dio200_board *board = comedi_board(dev); @@ -194,13 +182,10 @@ static void dio200_write32(struct comedi_device *dev, unsigned int offset, outl(val, dev->iobase + offset); } -/* - * 'insn_bits' function for an 'INTERRUPT' subdevice. - */ -static int -dio200_subdev_intr_insn_bits(struct comedi_device *dev, - struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int dio200_subdev_intr_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_intr *subpriv = s->private; @@ -216,9 +201,6 @@ dio200_subdev_intr_insn_bits(struct comedi_device *dev, return insn->n; } -/* - * Called to stop acquisition for an 'INTERRUPT' subdevice. - */ static void dio200_stop_intr(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -231,9 +213,6 @@ static void dio200_stop_intr(struct comedi_device *dev, dio200_write8(dev, subpriv->ofs, 0); } -/* - * Called to start acquisition for an 'INTERRUPT' subdevice. - */ static int dio200_start_intr(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -328,10 +307,6 @@ static void dio200_read_scan_intr(struct comedi_device *dev, } } -/* - * This is called from the interrupt service routine to handle a read - * scan on an 'INTERRUPT' subdevice. - */ static int dio200_handle_read_intr(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -405,9 +380,6 @@ static int dio200_handle_read_intr(struct comedi_device *dev, return (triggered != 0); } -/* - * 'cancel' function for an 'INTERRUPT' subdevice. - */ static int dio200_subdev_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -423,12 +395,9 @@ static int dio200_subdev_intr_cancel(struct comedi_device *dev, return 0; } -/* - * 'do_cmdtest' function for an 'INTERRUPT' subdevice. - */ -static int -dio200_subdev_intr_cmdtest(struct comedi_device *dev, - struct comedi_subdevice *s, struct comedi_cmd *cmd) +static int dio200_subdev_intr_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) { int err = 0; @@ -481,9 +450,6 @@ dio200_subdev_intr_cmdtest(struct comedi_device *dev, return 0; } -/* - * 'do_cmd' function for an 'INTERRUPT' subdevice. - */ static int dio200_subdev_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -514,12 +480,10 @@ static int dio200_subdev_intr_cmd(struct comedi_device *dev, return 0; } -/* - * This function initializes an 'INTERRUPT' subdevice. - */ -static int -dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int offset, unsigned valid_isns) +static int dio200_subdev_intr_init(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int offset, + unsigned valid_isns) { const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_intr *subpriv; @@ -556,9 +520,6 @@ dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, return 0; } -/* - * Interrupt service routine. - */ static irqreturn_t dio200_interrupt(int irq, void *d) { struct comedi_device *dev = d; @@ -573,12 +534,9 @@ static irqreturn_t dio200_interrupt(int irq, void *d) return IRQ_RETVAL(handled); } -/* - * Read an '8254' counter subdevice channel. - */ -static unsigned int -dio200_subdev_8254_read_chan(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int chan) +static unsigned int dio200_subdev_8254_read_chan(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int chan) { struct dio200_subdev_8254 *subpriv = s->private; unsigned int val; @@ -592,13 +550,10 @@ dio200_subdev_8254_read_chan(struct comedi_device *dev, return val; } -/* - * Write an '8254' subdevice channel. - */ -static void -dio200_subdev_8254_write_chan(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int chan, - unsigned int count) +static void dio200_subdev_8254_write_chan(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int chan, + unsigned int count) { struct dio200_subdev_8254 *subpriv = s->private; @@ -607,13 +562,10 @@ dio200_subdev_8254_write_chan(struct comedi_device *dev, dio200_write8(dev, subpriv->ofs + chan, (count >> 8) & 0xff); } -/* - * Set mode of an '8254' subdevice channel. - */ -static void -dio200_subdev_8254_set_mode(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int chan, - unsigned int mode) +static void dio200_subdev_8254_set_mode(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int chan, + unsigned int mode) { struct dio200_subdev_8254 *subpriv = s->private; unsigned int byte; @@ -624,12 +576,9 @@ dio200_subdev_8254_set_mode(struct comedi_device *dev, dio200_write8(dev, subpriv->ofs + i8254_control_reg, byte); } -/* - * Read status byte of an '8254' counter subdevice channel. - */ -static unsigned int -dio200_subdev_8254_status(struct comedi_device *dev, - struct comedi_subdevice *s, unsigned int chan) +static unsigned int dio200_subdev_8254_status(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int chan) { struct dio200_subdev_8254 *subpriv = s->private; @@ -640,12 +589,10 @@ dio200_subdev_8254_status(struct comedi_device *dev, return dio200_read8(dev, subpriv->ofs + chan); } -/* - * Handle 'insn_read' for an '8254' counter subdevice. - */ -static int -dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int dio200_subdev_8254_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct dio200_subdev_8254 *subpriv = s->private; int chan = CR_CHAN(insn->chanspec); @@ -660,12 +607,10 @@ dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s, return insn->n; } -/* - * Handle 'insn_write' for an '8254' counter subdevice. - */ -static int -dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int dio200_subdev_8254_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct dio200_subdev_8254 *subpriv = s->private; int chan = CR_CHAN(insn->chanspec); @@ -680,14 +625,10 @@ dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s, return insn->n; } -/* - * Set gate source for an '8254' counter subdevice channel. - */ -static int -dio200_subdev_8254_set_gate_src(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int counter_number, - unsigned int gate_src) +static int dio200_subdev_8254_set_gate_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int gate_src) { const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv = s->private; @@ -707,13 +648,9 @@ dio200_subdev_8254_set_gate_src(struct comedi_device *dev, return 0; } -/* - * Get gate source for an '8254' counter subdevice channel. - */ -static int -dio200_subdev_8254_get_gate_src(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int counter_number) +static int dio200_subdev_8254_get_gate_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number) { const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv = s->private; @@ -726,14 +663,10 @@ dio200_subdev_8254_get_gate_src(struct comedi_device *dev, return subpriv->gate_src[counter_number]; } -/* - * Set clock source for an '8254' counter subdevice channel. - */ -static int -dio200_subdev_8254_set_clock_src(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int counter_number, - unsigned int clock_src) +static int dio200_subdev_8254_set_clock_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int clock_src) { const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv = s->private; @@ -753,14 +686,10 @@ dio200_subdev_8254_set_clock_src(struct comedi_device *dev, return 0; } -/* - * Get clock source for an '8254' counter subdevice channel. - */ -static int -dio200_subdev_8254_get_clock_src(struct comedi_device *dev, - struct comedi_subdevice *s, - unsigned int counter_number, - unsigned int *period_ns) +static int dio200_subdev_8254_get_clock_src(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int counter_number, + unsigned int *period_ns) { const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv = s->private; @@ -776,12 +705,10 @@ dio200_subdev_8254_get_clock_src(struct comedi_device *dev, return clock_src; } -/* - * Handle 'insn_config' for an '8254' counter subdevice. - */ -static int -dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, - struct comedi_insn *insn, unsigned int *data) +static int dio200_subdev_8254_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) { struct dio200_subdev_8254 *subpriv = s->private; int ret = 0; @@ -833,12 +760,9 @@ dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, return ret < 0 ? ret : insn->n; } -/* - * This function initializes an '8254' counter subdevice. - */ -static int -dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, - unsigned int offset) +static int dio200_subdev_8254_init(struct comedi_device *dev, + struct comedi_subdevice *s, + unsigned int offset) { const struct dio200_board *board = comedi_board(dev); struct dio200_subdev_8254 *subpriv; @@ -881,9 +805,6 @@ dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, return 0; } -/* - * This function sets I/O directions for an '8255' DIO subdevice. - */ static void dio200_subdev_8255_set_dir(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -933,9 +854,6 @@ static int dio200_subdev_8255_bits(struct comedi_device *dev, return insn->n; } -/* - * Handle 'insn_config' for an '8255' DIO subdevice. - */ static int dio200_subdev_8255_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -963,11 +881,6 @@ static int dio200_subdev_8255_config(struct comedi_device *dev, return insn->n; } -/* - * This function initializes an '8255' DIO subdevice. - * - * offset is the offset to the 8255 chip. - */ static int dio200_subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int offset) @@ -991,9 +904,6 @@ static int dio200_subdev_8255_init(struct comedi_device *dev, return 0; } -/* - * Handle 'insn_read' for a timer subdevice. - */ static int dio200_subdev_timer_read(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -1006,9 +916,6 @@ static int dio200_subdev_timer_read(struct comedi_device *dev, return n; } -/* - * Reset timer subdevice. - */ static void dio200_subdev_timer_reset(struct comedi_device *dev, struct comedi_subdevice *s) { @@ -1019,9 +926,6 @@ static void dio200_subdev_timer_reset(struct comedi_device *dev, dio200_write32(dev, DIO200_TS_CONFIG, clock); } -/* - * Get timer subdevice clock source and period. - */ static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int *src, @@ -1035,9 +939,6 @@ static void dio200_subdev_timer_get_clock_src(struct comedi_device *dev, ts_clock_period[clk] : 0; } -/* - * Set timer subdevice clock source. - */ static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev, struct comedi_subdevice *s, unsigned int src) @@ -1048,9 +949,6 @@ static int dio200_subdev_timer_set_clock_src(struct comedi_device *dev, return 0; } -/* - * Handle 'insn_config' for a timer subdevice. - */ static int dio200_subdev_timer_config(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -1077,11 +975,6 @@ static int dio200_subdev_timer_config(struct comedi_device *dev, return ret < 0 ? ret : insn->n; } -/* - * This function initializes a timer subdevice. - * - * Uses the timestamp timer registers. There is only one timestamp timer. - */ static int dio200_subdev_timer_init(struct comedi_device *dev, struct comedi_subdevice *s) { -- GitLab From c1b0cccc59a30df185a23938dbd761650ef12337 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:17:20 -0700 Subject: [PATCH 0654/9167] staging: comedi: amplc_dio200.h: rename 'has_enhancements' in boardinfo This member of the boardinfor is only set for the PCIE boards. For aeshetics, rename it to 'is_pcie'. For clarity, use this flag in the (*auto_attach) to determine if the dio200_pcie_board_setup() function needs to be called instead of using the switch (context_model). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.h | 2 +- .../comedi/drivers/amplc_dio200_common.c | 4 +-- .../staging/comedi/drivers/amplc_dio200_pci.c | 28 ++++++++----------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index 60b7ae1a6423..306a9d68b2f6 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -40,7 +40,7 @@ struct dio200_board { unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */ bool has_int_sce:1; /* has interrupt enable/status reg */ bool has_clk_gat_sce:1; /* has clock/gate selection registers */ - bool has_enhancements:1; /* has enhanced features */ + bool is_pcie:1; /* has enhanced features */ }; int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 275795dbf6e9..2b33df716cc6 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -638,7 +638,7 @@ static int dio200_subdev_8254_set_gate_src(struct comedi_device *dev, return -1; if (counter_number > 2) return -1; - if (gate_src > (board->has_enhancements ? 31 : 7)) + if (gate_src > (board->is_pcie ? 31 : 7)) return -1; subpriv->gate_src[counter_number] = gate_src; @@ -676,7 +676,7 @@ static int dio200_subdev_8254_set_clock_src(struct comedi_device *dev, return -1; if (counter_number > 2) return -1; - if (clock_src > (board->has_enhancements ? 31 : 7)) + if (clock_src > (board->is_pcie ? 31 : 7)) return -1; subpriv->clock_src[counter_number] = clock_src; diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index e3d6a73604fb..4030c702455f 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -276,7 +276,7 @@ static const struct dio200_board dio200_pci_boards[] = { }, .has_int_sce = true, .has_clk_gat_sce = true, - .has_enhancements = true, + .is_pcie = true, }, [pcie236_model] = { .name = "pcie236", @@ -292,7 +292,7 @@ static const struct dio200_board dio200_pci_boards[] = { }, .has_int_sce = true, .has_clk_gat_sce = true, - .has_enhancements = true, + .is_pcie = true, }, [pcie296_model] = { .name = "pcie296", @@ -308,7 +308,7 @@ static const struct dio200_board dio200_pci_boards[] = { }, .has_int_sce = true, .has_clk_gat_sce = true, - .has_enhancements = true, + .is_pcie = true, }, }; @@ -351,16 +351,16 @@ static int dio200_pci_auto_attach(struct comedi_device *dev, unsigned long context_model) { struct pci_dev *pci_dev = comedi_to_pci_dev(dev); - const struct dio200_board *thisboard = NULL; + const struct dio200_board *board = NULL; unsigned int bar; int ret; if (context_model < ARRAY_SIZE(dio200_pci_boards)) - thisboard = &dio200_pci_boards[context_model]; - if (!thisboard) + board = &dio200_pci_boards[context_model]; + if (!board) return -EINVAL; - dev->board_ptr = thisboard; - dev->board_name = thisboard->name; + dev->board_ptr = board; + dev->board_name = board->name; dev_info(dev->class_dev, "%s: attach pci %s (%s)\n", dev->driver->driver_name, pci_name(pci_dev), dev->board_name); @@ -369,7 +369,7 @@ static int dio200_pci_auto_attach(struct comedi_device *dev, if (ret) return ret; - bar = thisboard->mainbar; + bar = board->mainbar; if (pci_resource_flags(pci_dev, bar) & IORESOURCE_MEM) { dev->mmio = pci_ioremap_bar(pci_dev, bar); if (!dev->mmio) { @@ -380,17 +380,13 @@ static int dio200_pci_auto_attach(struct comedi_device *dev, } else { dev->iobase = pci_resource_start(pci_dev, bar); } - switch (context_model) { - case pcie215_model: - case pcie236_model: - case pcie296_model: + + if (board->is_pcie) { ret = dio200_pcie_board_setup(dev); if (ret < 0) return ret; - break; - default: - break; } + return amplc_dio200_common_attach(dev, pci_dev->irq, IRQF_SHARED); } -- GitLab From c3f6aa33ed102cc36c3e2308c81f10fec62439f9 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:17:21 -0700 Subject: [PATCH 0655/9167] staging: comedi: amplc_dio200.h: remove boardinfo 'mainshift' This member of the boardinfo is only set for the PCIE boards. Use the 'is_pcie' flag to determine if the offset needs to be shifted when reading/writing the registers. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.h | 1 - drivers/staging/comedi/drivers/amplc_dio200_common.c | 12 ++++++++---- drivers/staging/comedi/drivers/amplc_dio200_pci.c | 3 --- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index 306a9d68b2f6..d87539c34283 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -34,7 +34,6 @@ enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254, sd_timer }; struct dio200_board { const char *name; unsigned char mainbar; - unsigned char mainshift; unsigned short n_subdevs; /* number of subdevices */ unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */ unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */ diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 2b33df716cc6..5835e27c1842 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -137,7 +137,8 @@ static unsigned char dio200_read8(struct comedi_device *dev, { const struct dio200_board *board = comedi_board(dev); - offset <<= board->mainshift; + if (board->is_pcie) + offset <<= 3; if (dev->mmio) return readb(dev->mmio + offset); @@ -149,7 +150,8 @@ static void dio200_write8(struct comedi_device *dev, { const struct dio200_board *board = comedi_board(dev); - offset <<= board->mainshift; + if (board->is_pcie) + offset <<= 3; if (dev->mmio) writeb(val, dev->mmio + offset); @@ -162,7 +164,8 @@ static unsigned int dio200_read32(struct comedi_device *dev, { const struct dio200_board *board = comedi_board(dev); - offset <<= board->mainshift; + if (board->is_pcie) + offset <<= 3; if (dev->mmio) return readl(dev->mmio + offset); @@ -174,7 +177,8 @@ static void dio200_write32(struct comedi_device *dev, { const struct dio200_board *board = comedi_board(dev); - offset <<= board->mainshift; + if (board->is_pcie) + offset <<= 3; if (dev->mmio) writel(val, dev->mmio + offset); diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index 4030c702455f..2dfdcaf3612c 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -265,7 +265,6 @@ static const struct dio200_board dio200_pci_boards[] = { [pcie215_model] = { .name = "pcie215", .mainbar = 1, - .mainshift = 3, .n_subdevs = 8, .sdtype = { sd_8255, sd_none, sd_8255, sd_none, @@ -281,7 +280,6 @@ static const struct dio200_board dio200_pci_boards[] = { [pcie236_model] = { .name = "pcie236", .mainbar = 1, - .mainshift = 3, .n_subdevs = 8, .sdtype = { sd_8255, sd_none, sd_none, sd_none, @@ -297,7 +295,6 @@ static const struct dio200_board dio200_pci_boards[] = { [pcie296_model] = { .name = "pcie296", .mainbar = 1, - .mainshift = 3, .n_subdevs = 8, .sdtype = { sd_8255, sd_8255, sd_8255, sd_8255, -- GitLab From 294de579db53a810cb179fb06909c2dbdf17b74d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:17:22 -0700 Subject: [PATCH 0656/9167] staging: comedi: amplc_dio200: absorb dio200_subdev_timer_init() This function is only called by amplc_dio200_common_attach() and it can never fail. For aesthetics, absorb it into that function. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- .../comedi/drivers/amplc_dio200_common.c | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 5835e27c1842..ba449029e16d 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -979,18 +979,6 @@ static int dio200_subdev_timer_config(struct comedi_device *dev, return ret < 0 ? ret : insn->n; } -static int dio200_subdev_timer_init(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - s->type = COMEDI_SUBD_TIMER; - s->subdev_flags = SDF_READABLE | SDF_LSAMPL; - s->n_chan = 1; - s->maxdata = 0xFFFFFFFF; - s->insn_read = dio200_subdev_timer_read; - s->insn_config = dio200_subdev_timer_config; - return 0; -} - void amplc_dio200_set_enhance(struct comedi_device *dev, unsigned char val) { dio200_write8(dev, DIO200_ENHANCE, val); @@ -1040,9 +1028,12 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, } break; case sd_timer: - ret = dio200_subdev_timer_init(dev, s); - if (ret < 0) - return ret; + s->type = COMEDI_SUBD_TIMER; + s->subdev_flags = SDF_READABLE | SDF_LSAMPL; + s->n_chan = 1; + s->maxdata = 0xffffffff; + s->insn_read = dio200_subdev_timer_read; + s->insn_config = dio200_subdev_timer_config; break; default: s->type = COMEDI_SUBD_UNUSED; -- GitLab From bb83abed7dd79ae1f0471c53144934efa57d7919 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:17:23 -0700 Subject: [PATCH 0657/9167] staging: comedi: amplc_dio200: remove dio200_common_detach() This exported function just does a free_irq() to release the interrupt handler for the legacy and PCI dio200 drivers. The legacy driver also calls comedi_legacy_detach() which would also do the free_irq(). For that driver the just use comedi_legacy_detach() directly for the (*detach). For the PCI driver, add the free_irq() to the private (*datach) function. Remove the, then unused, dio200_common_detach() function. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_dio200.c | 8 +------- drivers/staging/comedi/drivers/amplc_dio200.h | 2 -- drivers/staging/comedi/drivers/amplc_dio200_common.c | 9 --------- drivers/staging/comedi/drivers/amplc_dio200_pci.c | 3 ++- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 9b5efb7990a5..4fe118380218 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c @@ -257,17 +257,11 @@ static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) return amplc_dio200_common_attach(dev, it->options[1], 0); } -static void dio200_detach(struct comedi_device *dev) -{ - amplc_dio200_common_detach(dev); - comedi_legacy_detach(dev); -} - static struct comedi_driver amplc_dio200_driver = { .driver_name = "amplc_dio200", .module = THIS_MODULE, .attach = dio200_attach, - .detach = dio200_detach, + .detach = comedi_legacy_detach, .board_name = &dio200_isa_boards[0].name, .offset = sizeof(struct dio200_board), .num_names = ARRAY_SIZE(dio200_isa_boards), diff --git a/drivers/staging/comedi/drivers/amplc_dio200.h b/drivers/staging/comedi/drivers/amplc_dio200.h index d87539c34283..d6d6a265c461 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.h +++ b/drivers/staging/comedi/drivers/amplc_dio200.h @@ -45,8 +45,6 @@ struct dio200_board { int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, unsigned long req_irq_flags); -void amplc_dio200_common_detach(struct comedi_device *dev); - /* Used by initialization of PCIe boards. */ void amplc_dio200_set_enhance(struct comedi_device *dev, unsigned char val); diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index ba449029e16d..87c01692d800 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -1055,15 +1055,6 @@ int amplc_dio200_common_attach(struct comedi_device *dev, unsigned int irq, } EXPORT_SYMBOL_GPL(amplc_dio200_common_attach); -void amplc_dio200_common_detach(struct comedi_device *dev) -{ - if (dev->irq) { - free_irq(dev->irq, dev); - dev->irq = 0; - } -} -EXPORT_SYMBOL_GPL(amplc_dio200_common_detach); - static int __init amplc_dio200_common_init(void) { return 0; diff --git a/drivers/staging/comedi/drivers/amplc_dio200_pci.c b/drivers/staging/comedi/drivers/amplc_dio200_pci.c index 2dfdcaf3612c..423b6249d4f1 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_pci.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_pci.c @@ -389,7 +389,8 @@ static int dio200_pci_auto_attach(struct comedi_device *dev, static void dio200_pci_detach(struct comedi_device *dev) { - amplc_dio200_common_detach(dev); + if (dev->irq) + free_irq(dev->irq, dev); if (dev->mmio) iounmap(dev->mmio); comedi_pci_disable(dev); -- GitLab From 3a94180cf224cf0c3136c09b3cde69561ba94bda Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:15 -0700 Subject: [PATCH 0658/9167] staging: comedi: cb_pcidas: use dev->iobase for PCI bar 3 Currently the base address of the 8254 and 8255 devices, found in PCI bar 3, is saved in the private data as 'pacer_counter_dio'. The 'iobase' in the comedi_device is currently unused. Save the address from PCI bar 3 in the comedi_device and remove the unnecessary member from the private data. This will help with some cleanup of the 8255 module. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index 4a7bd4e5dd72..b48540b3b66c 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -342,7 +342,6 @@ struct cb_pcidas_private { unsigned long s5933_config; unsigned long control_status; unsigned long adc_fifo; - unsigned long pacer_counter_dio; unsigned long ao_registers; /* divisors of master clock for analog input pacing */ unsigned int divisor1; @@ -942,7 +941,7 @@ static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, static void cb_pcidas_ai_load_counters(struct comedi_device *dev) { struct cb_pcidas_private *devpriv = dev->private; - unsigned long timer_base = devpriv->pacer_counter_dio + ADC8254; + unsigned long timer_base = dev->iobase + ADC8254; i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY); i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY); @@ -1194,7 +1193,7 @@ static int cb_pcidas_ao_inttrig(struct comedi_device *dev, static void cb_pcidas_ao_load_counters(struct comedi_device *dev) { struct cb_pcidas_private *devpriv = dev->private; - unsigned long timer_base = devpriv->pacer_counter_dio + DAC8254; + unsigned long timer_base = dev->iobase + DAC8254; i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY); i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY); @@ -1463,7 +1462,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, devpriv->s5933_config = pci_resource_start(pcidev, 0); devpriv->control_status = pci_resource_start(pcidev, 1); devpriv->adc_fifo = pci_resource_start(pcidev, 2); - devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3); + dev->iobase = pci_resource_start(pcidev, 3); if (thisboard->ao_nchan) devpriv->ao_registers = pci_resource_start(pcidev, 4); @@ -1529,8 +1528,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, /* 8255 */ s = &dev->subdevices[2]; - ret = subdev_8255_init(dev, s, NULL, - devpriv->pacer_counter_dio + DIO_8255); + ret = subdev_8255_init(dev, s, NULL, dev->iobase + DIO_8255); if (ret) return ret; -- GitLab From 49fca95c403c01d2a91119fa64b86d4291324d17 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:16 -0700 Subject: [PATCH 0659/9167] staging: comedi: cb_pcimdas: refactor iobase addresses This driver uses three iobase addresses, found in PCI bars 2, 3, and 4. Currently, the address in PCI bar 2 is saved in the comedi_device as the 'iobase', the PCI bar 3 address is saved in the private data as 'BADR3' and the one in PCI bar 4 is just passed to subdev_8255_init() as the 'iobase' parameter. Flip the saving of the PCI bar 2 and 4 base addresses. Save the address from PCI bar 2 in the private data as the 'daqio' and the address from PCI bar 4 in the comedi_device as the 'iobase'. This will help with some cleanup of the 8255 module. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcimdas.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index ccb9c72bc0c3..d049a7f27239 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -77,6 +77,7 @@ See http://www.mccdaq.com/PDFs/Manuals/pcim-das1602-16.pdf for more details. */ struct cb_pcimdas_private { /* base addresses */ + unsigned long daqio; unsigned long BADR3; /* Used for AO readback */ @@ -143,7 +144,7 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, /* convert n samples */ for (n = 0; n < insn->n; n++) { /* trigger conversion */ - outw(0, dev->iobase + 0); + outw(0, devpriv->daqio + 0); /* wait for conversion to end */ ret = comedi_timeout(dev, s, insn, cb_pcimdas_ai_eoc, 0); @@ -151,7 +152,7 @@ static int cb_pcimdas_ai_rinsn(struct comedi_device *dev, return ret; /* read data */ - data[n] = inw(dev->iobase + 0); + data[n] = inw(devpriv->daqio + 0); } /* return the number of samples read/written */ @@ -171,10 +172,10 @@ static int cb_pcimdas_ao_winsn(struct comedi_device *dev, for (i = 0; i < insn->n; i++) { switch (chan) { case 0: - outw(data[i] & 0x0FFF, dev->iobase + DAC0_OFFSET); + outw(data[i] & 0x0FFF, devpriv->daqio + DAC0_OFFSET); break; case 1: - outw(data[i] & 0x0FFF, dev->iobase + DAC1_OFFSET); + outw(data[i] & 0x0FFF, devpriv->daqio + DAC1_OFFSET); break; default: return -1; @@ -208,7 +209,6 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, struct pci_dev *pcidev = comedi_to_pci_dev(dev); struct cb_pcimdas_private *devpriv; struct comedi_subdevice *s; - unsigned long iobase_8255; int ret; devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); @@ -219,9 +219,9 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, 2); + devpriv->daqio = pci_resource_start(pcidev, 2); devpriv->BADR3 = pci_resource_start(pcidev, 3); - iobase_8255 = pci_resource_start(pcidev, 4); + dev->iobase = pci_resource_start(pcidev, 4); ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -252,7 +252,7 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, s = &dev->subdevices[2]; /* digital i/o subdevice */ - ret = subdev_8255_init(dev, s, NULL, iobase_8255); + ret = subdev_8255_init(dev, s, NULL, dev->iobase); if (ret) return ret; -- GitLab From f254029bfda3924b5b3dfece85c3bb77b3c9c0c3 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:17 -0700 Subject: [PATCH 0660/9167] staging: comedi: cb_pcidda: refactor iobase addresses This driver uses two iobase addresses, found in PCI bars 2 and 3. Currently, the address in PCI bar 3 is saved in the comedi_device as the 'iobase' and the one in PCI bar 2 is just passed to subdev_8255_init() as the 'iobase' parameter. Save the PCI bar 3 address in the private data as 'daqio' and the address from PCI bar 2 in the comedi_device as the 'iobase'. This will help with some cleanup of the 8255 module. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidda.c | 27 ++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 901dc5d1bb72..9c9c58049e01 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -154,6 +154,7 @@ static const struct cb_pcidda_board cb_pcidda_boards[] = { }; struct cb_pcidda_private { + unsigned long daqio; /* bits last written to da calibration register 1 */ unsigned int dac_cal1_bits; /* current range settings for output channels */ @@ -164,13 +165,14 @@ struct cb_pcidda_private { /* lowlevel read from eeprom */ static unsigned int cb_pcidda_serial_in(struct comedi_device *dev) { + struct cb_pcidda_private *devpriv = dev->private; unsigned int value = 0; int i; const int value_width = 16; /* number of bits wide values are */ for (i = 1; i <= value_width; i++) { /* read bits most significant bit first */ - if (inw_p(dev->iobase + DACALIBRATION1) & SERIAL_OUT_BIT) + if (inw_p(devpriv->daqio + DACALIBRATION1) & SERIAL_OUT_BIT) value |= 1 << (value_width - i); } @@ -190,7 +192,7 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, devpriv->dac_cal1_bits |= SERIAL_IN_BIT; else devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT; - outw_p(devpriv->dac_cal1_bits, dev->iobase + DACALIBRATION1); + outw_p(devpriv->dac_cal1_bits, devpriv->daqio + DACALIBRATION1); } } @@ -198,6 +200,7 @@ static void cb_pcidda_serial_out(struct comedi_device *dev, unsigned int value, static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, unsigned int address) { + struct cb_pcidda_private *devpriv = dev->private; unsigned int i; unsigned int cal2_bits; unsigned int value; @@ -213,7 +216,7 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, /* deactivate caldacs (one caldac for every two channels) */ for (i = 0; i < max_num_caldacs; i++) cal2_bits |= DESELECT_CALDAC_BIT(i); - outw_p(cal2_bits, dev->iobase + DACALIBRATION2); + outw_p(cal2_bits, devpriv->daqio + DACALIBRATION2); /* tell eeprom we want to read */ cb_pcidda_serial_out(dev, read_instruction, instruction_length); @@ -224,7 +227,7 @@ static unsigned int cb_pcidda_read_eeprom(struct comedi_device *dev, /* deactivate eeprom */ cal2_bits &= ~SELECT_EEPROM_BIT; - outw_p(cal2_bits, dev->iobase + DACALIBRATION2); + outw_p(cal2_bits, devpriv->daqio + DACALIBRATION2); return value; } @@ -234,6 +237,7 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, unsigned int caldac, unsigned int channel, unsigned int value) { + struct cb_pcidda_private *devpriv = dev->private; unsigned int cal2_bits; unsigned int i; /* caldacs use 3 bit channel specification */ @@ -256,10 +260,10 @@ static void cb_pcidda_write_caldac(struct comedi_device *dev, cal2_bits |= DESELECT_CALDAC_BIT(i); /* activate the caldac we want */ cal2_bits &= ~DESELECT_CALDAC_BIT(caldac); - outw_p(cal2_bits, dev->iobase + DACALIBRATION2); + outw_p(cal2_bits, devpriv->daqio + DACALIBRATION2); /* deactivate caldac */ cal2_bits |= DESELECT_CALDAC_BIT(caldac); - outw_p(cal2_bits, dev->iobase + DACALIBRATION2); + outw_p(cal2_bits, devpriv->daqio + DACALIBRATION2); } /* set caldacs to eeprom values for given channel and range */ @@ -324,9 +328,9 @@ static int cb_pcidda_ao_insn_write(struct comedi_device *dev, if (range > 2) ctrl |= CB_DDA_DA_CTRL_UNIP; - outw(ctrl, dev->iobase + CB_DDA_DA_CTRL_REG); + outw(ctrl, devpriv->daqio + CB_DDA_DA_CTRL_REG); - outw(data[0], dev->iobase + CB_DDA_DA_DATA_REG(channel)); + outw(data[0], devpriv->daqio + CB_DDA_DA_DATA_REG(channel)); return insn->n; } @@ -338,7 +342,6 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev, const struct cb_pcidda_board *thisboard = NULL; struct cb_pcidda_private *devpriv; struct comedi_subdevice *s; - unsigned long iobase_8255; int i; int ret; @@ -356,8 +359,8 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev, ret = comedi_pci_enable(dev); if (ret) return ret; - dev->iobase = pci_resource_start(pcidev, 3); - iobase_8255 = pci_resource_start(pcidev, 2); + dev->iobase = pci_resource_start(pcidev, 2); + devpriv->daqio = pci_resource_start(pcidev, 3); ret = comedi_alloc_subdevices(dev, 3); if (ret) @@ -375,7 +378,7 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev, /* two 8255 digital io subdevices */ for (i = 0; i < 2; i++) { s = &dev->subdevices[1 + i]; - ret = subdev_8255_init(dev, s, NULL, iobase_8255 + (i * 4)); + ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); if (ret) return ret; } -- GitLab From 4f9c63fe5333b27ab23ed399830c7977f6970744 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:18 -0700 Subject: [PATCH 0661/9167] staging: comedi: amplc_pci230: refactor iobase addresses This driver uses two iobase addresses, found in PCI bars 2 and 3. Currently, the address in PCI bar 2 is saved in the private data as 'iobase1' and the address in PCI bar 3 is saved in the comedi_device as the 'iobase'. The 'iobase' is the base address of the daq registers (ai/ao) of the board. The 'iobase1' address is the base address of the 8255, 8254, configuration, and interrupt registers. Flip the saving of these base addresses. Save the address from PCI bar 2 in the comedi_device 'iobase' and the address from PCI bar 3 in the private data as 'daqio'. This will help with some cleanup of the 8255 module. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/amplc_pci230.c | 161 +++++++++--------- 1 file changed, 77 insertions(+), 84 deletions(-) diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 684275d76e8c..7b56f68b3b4f 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -513,8 +513,8 @@ struct pci230_private { spinlock_t res_spinlock; /* Shared resources spin lock */ 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 long state; /* State flags */ - unsigned long iobase1; /* PCI230's I/O space 1 */ unsigned int ao_readback[2]; /* Used for AO readback */ unsigned int ai_scan_count; /* Number of AI scans remaining */ unsigned int ai_scan_pos; /* Current position within AI scan */ @@ -579,7 +579,7 @@ static unsigned short pci230_ai_read(struct comedi_device *dev) unsigned short data; /* Read sample. */ - data = inw(dev->iobase + PCI230_ADCDATA); + data = inw(devpriv->daqio + PCI230_ADCDATA); /* * PCI230 is 12 bit - stored in upper bits of 16 bit register * (lower four bits reserved for expansion). PCI230+ is 16 bit AI. @@ -628,7 +628,7 @@ static inline void pci230_ao_write_nofifo(struct comedi_device *dev, /* Write mangled datum to appropriate DACOUT register. */ outw(pci230_ao_mangle_datum(dev, datum), - dev->iobase + (((chan) == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2)); + devpriv->daqio + ((chan) == 0) ? PCI230_DACOUT1 : PCI230_DACOUT2); } static inline void pci230_ao_write_fifo(struct comedi_device *dev, @@ -641,7 +641,7 @@ static inline void pci230_ao_write_fifo(struct comedi_device *dev, /* Write mangled datum to appropriate DACDATA register. */ outw(pci230_ao_mangle_datum(dev, datum), - dev->iobase + PCI230P2_DACDATA); + devpriv->daqio + PCI230P2_DACDATA); } static int get_resources(struct comedi_device *dev, unsigned int res_mask, @@ -770,29 +770,25 @@ static void pci230_ct_setup_ns_mode(struct comedi_device *dev, unsigned int ct, unsigned int mode, uint64_t ns, unsigned int flags) { - struct pci230_private *devpriv = dev->private; unsigned int clk_src; unsigned int count; /* Set mode. */ - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode); + i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, ct, mode); /* Determine clock source and count. */ clk_src = pci230_choose_clk_count(ns, &count, flags); /* Program clock source. */ - outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE); + outb(CLK_CONFIG(ct, clk_src), dev->iobase + PCI230_ZCLK_SCE); /* Set initial count. */ if (count >= 65536) count = 0; - i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count); + i8254_write(dev->iobase + PCI230_Z2_CT_BASE, 0, ct, count); } static void pci230_cancel_ct(struct comedi_device *dev, unsigned int ct) { - struct pci230_private *devpriv = dev->private; - - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, - I8254_MODE1); + i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, ct, I8254_MODE1); /* Counter ct, 8254 mode 1, initial count not written. */ } @@ -801,9 +797,10 @@ static int pci230_ai_eoc(struct comedi_device *dev, struct comedi_insn *insn, unsigned long context) { + struct pci230_private *devpriv = dev->private; unsigned int status; - status = inw(dev->iobase + PCI230_ADCCON); + status = inw(devpriv->daqio + PCI230_ADCCON); if ((status & PCI230_ADC_FIFO_EMPTY) == 0) return 0; return -EBUSY; @@ -842,7 +839,7 @@ static int pci230_ai_rinsn(struct comedi_device *dev, */ adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN; /* Set Z2-CT2 output low to avoid any false triggers. */ - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0); + i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0); devpriv->ai_bipolar = pci230_ai_bipolar[range]; if (aref == AREF_DIFF) { /* Differential. */ @@ -879,14 +876,14 @@ static int pci230_ai_rinsn(struct comedi_device *dev, * Enable only this channel in the scan list - otherwise by default * we'll get one sample from each channel. */ - outw(adcen, dev->iobase + PCI230_ADCEN); + outw(adcen, devpriv->daqio + PCI230_ADCEN); /* Set gain for channel. */ - outw(devpriv->adcg, dev->iobase + PCI230_ADCG); + outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); /* Specify uni/bip, se/diff, conversion source, and reset FIFO. */ devpriv->adccon = adccon; - outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON); + outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); /* Convert n samples */ for (n = 0; n < insn->n; n++) { @@ -894,10 +891,10 @@ static int pci230_ai_rinsn(struct comedi_device *dev, * Trigger conversion by toggling Z2-CT2 output * (finish with output high). */ - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, - I8254_MODE0); - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, - I8254_MODE1); + i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, + 2, I8254_MODE0); + i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, + 2, I8254_MODE1); /* wait for conversion to end */ ret = comedi_timeout(dev, s, insn, pci230_ai_eoc, 0); @@ -932,7 +929,7 @@ static int pci230_ao_winsn(struct comedi_device *dev, * 1 => bipolar +/-10V range scale */ devpriv->ao_bipolar = pci230_ao_bipolar[range]; - outw(range, dev->iobase + PCI230_DACCON); + outw(range, devpriv->daqio + PCI230_DACCON); /* * Writing a list of values to an AO channel is probably not @@ -1160,7 +1157,7 @@ static void pci230_ao_stop(struct comedi_device *dev, } if (devpriv->ier != devpriv->int_en) { devpriv->ier = devpriv->int_en; - outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); + outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); } spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); if (devpriv->hwver >= 2) { @@ -1171,7 +1168,7 @@ static void pci230_ao_stop(struct comedi_device *dev, devpriv->daccon &= PCI230_DAC_OR_MASK; outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR, - dev->iobase + PCI230_DACCON); + devpriv->daqio + PCI230_DACCON); } /* Release resources. */ put_all_resources(dev, OWNER_AOCMD); @@ -1227,7 +1224,7 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, int running; /* Get DAC FIFO status. */ - dacstat = inw(dev->iobase + PCI230_DACCON); + 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); if (cmd->stop_src == TRIG_COUNT) { @@ -1295,11 +1292,11 @@ static int pci230_handle_ao_fifo(struct comedi_device *dev, ~PCI230P2_DAC_INT_FIFO_MASK) | PCI230P2_DAC_INT_FIFO_EMPTY; outw(devpriv->daccon, - dev->iobase + PCI230_DACCON); + devpriv->daqio + PCI230_DACCON); } } /* Check if FIFO underrun occurred while writing to FIFO. */ - dacstat = inw(dev->iobase + PCI230_DACCON); + dacstat = inw(devpriv->daqio + PCI230_DACCON); if (dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) { dev_err(dev->class_dev, "AO FIFO underrun\n"); events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR; @@ -1338,7 +1335,7 @@ static int pci230_ao_inttrig_scan_begin(struct comedi_device *dev, } else { /* Using DAC FIFO. */ /* Read DACSWTRIG register to trigger conversion. */ - inw(dev->iobase + PCI230P2_DACSWTRIG); + inw(devpriv->daqio + PCI230P2_DACSWTRIG); spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags); } @@ -1405,7 +1402,7 @@ static void pci230_ao_start(struct comedi_device *dev, devpriv->daccon = (devpriv->daccon & ~PCI230P2_DAC_TRIG_MASK) | scantrig; - outw(devpriv->daccon, dev->iobase + PCI230_DACCON); + outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); } switch (cmd->scan_begin_src) { case TRIG_TIMER: @@ -1417,13 +1414,13 @@ static void pci230_ao_start(struct comedi_device *dev, devpriv->int_en |= PCI230_INT_ZCLK_CT1; devpriv->ier |= PCI230_INT_ZCLK_CT1; outb(devpriv->ier, - devpriv->iobase1 + PCI230_INT_SCE); + dev->iobase + PCI230_INT_SCE); spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); } /* Set CT1 gate high to start counting. */ outb(GAT_CONFIG(1, GAT_VCC), - devpriv->iobase1 + PCI230_ZGAT_SCE); + dev->iobase + PCI230_ZGAT_SCE); break; case TRIG_INT: async->inttrig = pci230_ao_inttrig_scan_begin; @@ -1434,7 +1431,7 @@ static void pci230_ao_start(struct comedi_device *dev, spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); devpriv->int_en |= PCI230P2_INT_DAC; devpriv->ier |= PCI230P2_INT_DAC; - outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); + outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); } @@ -1494,7 +1491,7 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) dacen |= 1 << CR_CHAN(cmd->chanlist[i]); /* Set channel scan list. */ - outw(dacen, dev->iobase + PCI230P2_DACEN); + outw(dacen, devpriv->daqio + PCI230P2_DACEN); /* * Enable DAC FIFO. * Set DAC scan source to 'none'. @@ -1509,7 +1506,7 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } /* Set DACCON. */ - outw(daccon, dev->iobase + PCI230_DACCON); + outw(daccon, devpriv->daqio + PCI230_DACCON); /* Preserve most of DACCON apart from write-only, transient bits. */ devpriv->daccon = daccon & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR); @@ -1520,8 +1517,7 @@ static int pci230_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * cmd->scan_begin_arg is sampling period in ns. * Gate it off for now. */ - outb(GAT_CONFIG(1, GAT_GND), - devpriv->iobase1 + PCI230_ZGAT_SCE); + outb(GAT_CONFIG(1, GAT_GND), dev->iobase + PCI230_ZGAT_SCE); pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3, cmd->scan_begin_arg, cmd->flags); @@ -1900,7 +1896,7 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev, /* PCI230+/260+ programmable FIFO interrupt level. */ if (devpriv->adcfifothresh != wake) { devpriv->adcfifothresh = wake; - outw(wake, dev->iobase + PCI230P_ADCFFTH); + outw(wake, devpriv->daqio + PCI230P_ADCFFTH); } triglev = PCI230P_ADC_INT_FIFO_THRESH; } else { @@ -1910,7 +1906,7 @@ static void pci230_ai_update_fifo_trigger_level(struct comedi_device *dev, adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev; if (adccon != devpriv->adccon) { devpriv->adccon = adccon; - outw(adccon, dev->iobase + PCI230_ADCCON); + outw(adccon, devpriv->daqio + PCI230_ADCCON); } } @@ -1932,10 +1928,10 @@ static int pci230_ai_inttrig_convert(struct comedi_device *dev, * Trigger conversion by toggling Z2-CT2 output. * Finish with output high. */ - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, - I8254_MODE0); - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, - I8254_MODE1); + i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, + 2, I8254_MODE0); + i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, + 2, I8254_MODE1); /* * Delay. Should driver be responsible for this? An * alternative would be to wait until conversion is complete, @@ -1975,9 +1971,9 @@ static int pci230_ai_inttrig_scan_begin(struct comedi_device *dev, if (test_bit(AI_CMD_STARTED, &devpriv->state)) { /* Trigger scan by waggling CT0 gate source. */ zgat = GAT_CONFIG(0, GAT_GND); - outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE); + outb(zgat, dev->iobase + PCI230_ZGAT_SCE); zgat = GAT_CONFIG(0, GAT_VCC); - outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE); + outb(zgat, dev->iobase + PCI230_ZGAT_SCE); } spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags); @@ -2018,7 +2014,7 @@ static void pci230_ai_stop(struct comedi_device *dev, } if (devpriv->ier != devpriv->int_en) { devpriv->ier = devpriv->int_en; - outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); + outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); } spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); /* @@ -2029,7 +2025,7 @@ static void pci230_ai_stop(struct comedi_device *dev, (devpriv->adccon & (PCI230_ADC_IR_MASK | PCI230_ADC_IM_MASK)) | PCI230_ADC_TRIG_NONE; outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, - dev->iobase + PCI230_ADCCON); + devpriv->daqio + PCI230_ADCCON); /* Release resources. */ put_all_resources(dev, OWNER_AICMD); } @@ -2054,7 +2050,7 @@ static void pci230_ai_start(struct comedi_device *dev, spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); devpriv->int_en |= PCI230_INT_ADC; devpriv->ier |= PCI230_INT_ADC; - outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); + outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); /* @@ -2099,7 +2095,7 @@ static void pci230_ai_start(struct comedi_device *dev, } devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK) | conv; - outw(devpriv->adccon, dev->iobase + PCI230_ADCCON); + outw(devpriv->adccon, devpriv->daqio + PCI230_ADCCON); if (cmd->convert_src == TRIG_INT) async->inttrig = pci230_ai_inttrig_convert; @@ -2125,7 +2121,7 @@ static void pci230_ai_start(struct comedi_device *dev, */ zgat = GAT_CONFIG(2, GAT_VCC); } - outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE); + outb(zgat, dev->iobase + PCI230_ZGAT_SCE); if (cmd->scan_begin_src != TRIG_FOLLOW) { /* Set monostable CT0 trigger source. */ switch (cmd->scan_begin_src) { @@ -2161,7 +2157,7 @@ static void pci230_ai_start(struct comedi_device *dev, zgat = GAT_CONFIG(0, GAT_VCC); break; } - outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE); + outb(zgat, dev->iobase + PCI230_ZGAT_SCE); switch (cmd->scan_begin_src) { case TRIG_TIMER: /* @@ -2169,8 +2165,8 @@ static void pci230_ai_start(struct comedi_device *dev, * gated on to start counting. */ zgat = GAT_CONFIG(1, GAT_VCC); - outb(zgat, devpriv->iobase1 + - PCI230_ZGAT_SCE); + outb(zgat, + dev->iobase + PCI230_ZGAT_SCE); break; case TRIG_INT: async->inttrig = @@ -2233,7 +2229,7 @@ static void pci230_handle_ai(struct comedi_device *dev, for (i = 0; i < todo; i++) { if (fifoamount == 0) { /* Read FIFO state. */ - status_fifo = inw(dev->iobase + PCI230_ADCCON); + status_fifo = inw(devpriv->daqio + PCI230_ADCCON); if (status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) { /* * Report error otherwise FIFO overruns will go @@ -2252,8 +2248,8 @@ static void pci230_handle_ai(struct comedi_device *dev, /* FIFO not empty. */ if (devpriv->hwver > 0) { /* Read PCI230+/260+ ADC FIFO level. */ - fifoamount = - inw(dev->iobase + PCI230P_ADCFFLEV); + fifoamount = inw(devpriv->daqio + + PCI230P_ADCFFLEV); if (fifoamount == 0) { /* Shouldn't happen. */ break; @@ -2404,16 +2400,16 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) } /* Set channel scan list. */ - outw(adcen, dev->iobase + PCI230_ADCEN); + outw(adcen, devpriv->daqio + PCI230_ADCEN); /* Set channel gains. */ - outw(devpriv->adcg, dev->iobase + PCI230_ADCG); + outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); /* * Set counter/timer 2 output high for use as the initial start * conversion source. */ - i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1); + i8254_set_mode(dev->iobase + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1); /* * Temporarily use CT2 output as conversion trigger source and @@ -2429,7 +2425,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * PCI230/260, but that will be dealt with later. */ devpriv->adccon = adccon; - outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON); + outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); /* * Delay - @@ -2443,7 +2439,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) usleep_range(25, 100); /* Reset FIFO again. */ - outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON); + outw(adccon | PCI230_ADC_FIFO_RESET, devpriv->daqio + PCI230_ADCCON); if (cmd->convert_src == TRIG_TIMER) { /* @@ -2452,7 +2448,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * connector: PCI230 pin 21, PCI260 pin 18. */ zgat = GAT_CONFIG(2, GAT_GND); - outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE); + outb(zgat, dev->iobase + PCI230_ZGAT_SCE); /* Set counter/timer 2 to the specified conversion period. */ pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg, cmd->flags); @@ -2470,7 +2466,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * source will be changed later. */ zgat = GAT_CONFIG(0, GAT_VCC); - outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE); + outb(zgat, dev->iobase + PCI230_ZGAT_SCE); pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1, ((uint64_t)cmd->convert_arg * cmd->scan_end_arg), @@ -2483,7 +2479,7 @@ static int pci230_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) * Set up CT1 but gate it off for now. */ zgat = GAT_CONFIG(1, GAT_GND); - outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE); + outb(zgat, dev->iobase + PCI230_ZGAT_SCE); pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3, cmd->scan_begin_arg, cmd->flags); @@ -2516,7 +2512,7 @@ static irqreturn_t pci230_interrupt(int irq, void *d) unsigned long irqflags; /* Read interrupt status/enable register. */ - status_int = inb(devpriv->iobase1 + PCI230_INT_STAT); + status_int = inb(dev->iobase + PCI230_INT_STAT); if (status_int == PCI230_INT_DISABLE) return IRQ_NONE; @@ -2530,7 +2526,7 @@ static irqreturn_t pci230_interrupt(int irq, void *d) * handler). */ devpriv->ier = devpriv->int_en & ~status_int; - outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); + outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); devpriv->intr_running = 1; devpriv->intr_cpuid = THISCPU; spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); @@ -2565,7 +2561,7 @@ static irqreturn_t pci230_interrupt(int irq, void *d) spin_lock_irqsave(&devpriv->isr_spinlock, irqflags); if (devpriv->ier != devpriv->int_en) { devpriv->ier = devpriv->int_en; - outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE); + outb(devpriv->ier, dev->iobase + PCI230_INT_SCE); } devpriv->intr_running = 0; spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags); @@ -2665,8 +2661,6 @@ static int pci230_attach_common(struct comedi_device *dev, const struct pci230_board *thisboard = comedi_board(dev); struct pci230_private *devpriv = dev->private; struct comedi_subdevice *s; - unsigned long iobase1, iobase2; - /* PCI230's I/O spaces 1 and 2 respectively. */ int rc; comedi_set_hw_dev(dev, &pci_dev->dev); @@ -2681,15 +2675,14 @@ static int pci230_attach_common(struct comedi_device *dev, * Read base addresses of the PCI230's two I/O regions from PCI * configuration register. */ - iobase1 = pci_resource_start(pci_dev, 2); - iobase2 = pci_resource_start(pci_dev, 3); + dev->iobase = pci_resource_start(pci_dev, 2); + devpriv->daqio = pci_resource_start(pci_dev, 3); dev_dbg(dev->class_dev, "%s I/O region 1 0x%04lx I/O region 2 0x%04lx\n", - dev->board_name, iobase1, iobase2); - devpriv->iobase1 = iobase1; - dev->iobase = iobase2; + dev->board_name, dev->iobase, devpriv->daqio); /* Read bits of DACCON register - only the output range. */ - devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK; + devpriv->daccon = inw(devpriv->daqio + PCI230_DACCON) & + PCI230_DAC_OR_MASK; /* * Read hardware version register and set extended function register * if they exist. @@ -2697,7 +2690,7 @@ static int pci230_attach_common(struct comedi_device *dev, if (pci_resource_len(pci_dev, 3) >= 32) { unsigned short extfunc = 0; - devpriv->hwver = inw(dev->iobase + PCI230P_HWVER); + devpriv->hwver = inw(devpriv->daqio + PCI230P_HWVER); if (devpriv->hwver < thisboard->min_hwver) { dev_err(dev->class_dev, "%s - bad hardware version - got %u, need %u\n", @@ -2722,7 +2715,7 @@ static int pci230_attach_common(struct comedi_device *dev, extfunc |= PCI230P2_EXTFUNC_DACFIFO; } } - outw(extfunc, dev->iobase + PCI230P_EXTFUNC); + outw(extfunc, devpriv->daqio + PCI230P_EXTFUNC); if (extfunc & PCI230P2_EXTFUNC_DACFIFO) { /* * Temporarily enable DAC FIFO, reset it and disable @@ -2730,23 +2723,23 @@ static int pci230_attach_common(struct comedi_device *dev, */ outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET, - dev->iobase + PCI230_DACCON); + devpriv->daqio + PCI230_DACCON); /* Clear DAC FIFO channel enable register. */ - outw(0, dev->iobase + PCI230P2_DACEN); + outw(0, devpriv->daqio + PCI230P2_DACEN); /* Disable DAC FIFO. */ - outw(devpriv->daccon, dev->iobase + PCI230_DACCON); + outw(devpriv->daccon, devpriv->daqio + PCI230_DACCON); } } /* Disable board's interrupts. */ - outb(0, devpriv->iobase1 + PCI230_INT_SCE); + outb(0, dev->iobase + PCI230_INT_SCE); /* Set ADC to a reasonable state. */ devpriv->adcg = 0; devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE | PCI230_ADC_IR_BIP; - outw(1 << 0, dev->iobase + PCI230_ADCEN); - outw(devpriv->adcg, dev->iobase + PCI230_ADCG); + outw(1 << 0, devpriv->daqio + PCI230_ADCEN); + outw(devpriv->adcg, devpriv->daqio + PCI230_ADCG); outw(devpriv->adccon | PCI230_ADC_FIFO_RESET, - dev->iobase + PCI230_ADCCON); + devpriv->daqio + PCI230_ADCCON); if (pci_dev->irq) { rc = request_irq(pci_dev->irq, pci230_interrupt, IRQF_SHARED, @@ -2802,7 +2795,7 @@ static int pci230_attach_common(struct comedi_device *dev, /* digital i/o subdevice */ if (thisboard->have_dio) { rc = subdev_8255_init(dev, s, NULL, - devpriv->iobase1 + PCI230_PPI_X_BASE); + dev->iobase + PCI230_PPI_X_BASE); if (rc) return rc; } else { -- GitLab From 09d6dd7490ee7f1dda926e309df370e28679a71c Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:19 -0700 Subject: [PATCH 0662/9167] staging: comedi: 8255: add a comedi_device param to the (*io) callback The 8255 driver uses an (*io) callback to read/write the registers of the 8255 device. The default callback provided by the driver uses inb()/outb() calls to access to registers based on an 'iobase' that was initialized during the subdev_8255_init() and a 'port' value. The users of this module can optionally provide a custom (*io) callback to handle the read/write in another manner. Make the (*io) callback a bit more flexible by also passing the comedi_device pointer as a parameter. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 33 ++++++++++--------- drivers/staging/comedi/drivers/8255.h | 6 ++-- drivers/staging/comedi/drivers/8255_pci.c | 3 +- drivers/staging/comedi/drivers/cb_pcidas64.c | 6 ++-- drivers/staging/comedi/drivers/daqboard2000.c | 3 +- drivers/staging/comedi/drivers/ni_labpc.c | 3 +- .../staging/comedi/drivers/ni_mio_common.c | 3 +- drivers/staging/comedi/drivers/pcl724.c | 3 +- 8 files changed, 36 insertions(+), 24 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index a33a19622745..212e547ba77f 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -94,10 +94,11 @@ I/O port base address can be found in the output of 'lspci -v'. struct subdev_8255_private { unsigned long iobase; - int (*io)(int, int, int, unsigned long); + int (*io)(struct comedi_device *, int, int, int, unsigned long); }; -static int subdev_8255_io(int dir, int port, int data, unsigned long iobase) +static int subdev_8255_io(struct comedi_device *dev, + int dir, int port, int data, unsigned long iobase) { if (dir) { outb(data, iobase + port); @@ -113,8 +114,8 @@ void subdev_8255_interrupt(struct comedi_device *dev, unsigned long iobase = spriv->iobase; unsigned short d; - d = spriv->io(0, _8255_DATA, 0, iobase); - d |= (spriv->io(0, _8255_DATA + 1, 0, iobase) << 8); + d = spriv->io(dev, 0, _8255_DATA, 0, iobase); + d |= (spriv->io(dev, 0, _8255_DATA + 1, 0, iobase) << 8); comedi_buf_put(s, d); s->async->events |= COMEDI_CB_EOS; @@ -136,18 +137,18 @@ static int subdev_8255_insn(struct comedi_device *dev, mask = comedi_dio_update_state(s, data); if (mask) { if (mask & 0xff) - spriv->io(1, _8255_DATA, s->state & 0xff, iobase); + spriv->io(dev, 1, _8255_DATA, s->state & 0xff, iobase); if (mask & 0xff00) - spriv->io(1, _8255_DATA + 1, (s->state >> 8) & 0xff, - iobase); + spriv->io(dev, 1, _8255_DATA + 1, + (s->state >> 8) & 0xff, iobase); if (mask & 0xff0000) - spriv->io(1, _8255_DATA + 2, (s->state >> 16) & 0xff, - iobase); + spriv->io(dev, 1, _8255_DATA + 2, + (s->state >> 16) & 0xff, iobase); } - v = spriv->io(0, _8255_DATA, 0, iobase); - v |= (spriv->io(0, _8255_DATA + 1, 0, iobase) << 8); - v |= (spriv->io(0, _8255_DATA + 2, 0, iobase) << 16); + v = spriv->io(dev, 0, _8255_DATA, 0, iobase); + v |= (spriv->io(dev, 0, _8255_DATA + 1, 0, iobase) << 8); + v |= (spriv->io(dev, 0, _8255_DATA + 2, 0, iobase) << 16); data[1] = v; @@ -172,7 +173,7 @@ static void subdev_8255_do_config(struct comedi_device *dev, if (!(s->io_bits & 0xf00000)) config |= CR_C_HI_IO; - spriv->io(1, _8255_CR, config, iobase); + spriv->io(dev, 1, _8255_CR, config, iobase); } static int subdev_8255_insn_config(struct comedi_device *dev, @@ -261,7 +262,8 @@ static int subdev_8255_cancel(struct comedi_device *dev, } int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(int, int, int, unsigned long), + int (*io)(struct comedi_device *, + int, int, int, unsigned long), unsigned long iobase) { struct subdev_8255_private *spriv; @@ -288,7 +290,8 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, EXPORT_SYMBOL_GPL(subdev_8255_init); int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(int, int, int, unsigned long), + int (*io)(struct comedi_device *, + int, int, int, unsigned long), unsigned long iobase) { int ret; diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index 795d232a6c02..c2c20db2f1d0 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -22,10 +22,12 @@ #include "../comedidev.h" int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(int, int, int, unsigned long), + int (*io)(struct comedi_device *, + int, int, int, unsigned long), unsigned long iobase); int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(int, int, int, unsigned long), + int (*io)(struct comedi_device *, + int, int, int, unsigned long), unsigned long iobase); void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s); diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index f21e6567ac2f..cee3d18370fa 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -190,7 +190,8 @@ static int pci_8255_mite_init(struct pci_dev *pcidev) return 0; } -static int pci_8255_mmio(int dir, int port, int data, unsigned long iobase) +static int pci_8255_mmio(struct comedi_device *dev, + int dir, int port, int data, unsigned long iobase) { void __iomem *mmio_base = (void __iomem *)iobase; diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index fa12614cef2a..fafde70cbb51 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3369,7 +3369,8 @@ static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static int dio_callback(int dir, int port, int data, unsigned long arg) +static int dio_callback(struct comedi_device *dev, + int dir, int port, int data, unsigned long arg) { void __iomem *iobase = (void __iomem *)arg; @@ -3380,7 +3381,8 @@ static int dio_callback(int dir, int port, int data, unsigned long arg) return readb(iobase + port); } -static int dio_callback_4020(int dir, int port, int data, unsigned long arg) +static int dio_callback_4020(struct comedi_device *dev, + int dir, int port, int data, unsigned long arg) { void __iomem *iobase = (void __iomem *)arg; diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index cd369cd40114..d728fbd6d3a0 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -651,7 +651,8 @@ static void daqboard2000_initializeDac(struct comedi_device *dev) daqboard2000_dacDisarm(dev); } -static int daqboard2000_8255_cb(int dir, int port, int data, +static int daqboard2000_8255_cb(struct comedi_device *dev, + int dir, int port, int data, unsigned long ioaddr) { void __iomem *mmio_base = (void __iomem *)ioaddr; diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 126d65cb39f2..fa108b9dd603 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1035,7 +1035,8 @@ static int labpc_ao_insn_read(struct comedi_device *dev, return 1; } -static int labpc_8255_mmio(int dir, int port, int data, unsigned long arg) +static int labpc_8255_mmio(struct comedi_device *cdev, + int dir, int port, int data, unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 297c95d2e0a3..07659053f4d3 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -4176,7 +4176,8 @@ static int ni_freq_out_insn_config(struct comedi_device *dev, return insn->n; } -static int ni_8255_callback(int dir, int port, int data, unsigned long arg) +static int ni_8255_callback(struct comedi_device *cdev, + int dir, int port, int data, unsigned long arg) { struct comedi_device *dev = (struct comedi_device *)arg; diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index c7f8eb1cf8de..946b058eee6f 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -81,7 +81,8 @@ static const struct pcl724_board boardtypes[] = { }, }; -static int pcl724_8255mapped_io(int dir, int port, int data, +static int pcl724_8255mapped_io(struct comedi_device *dev, + int dir, int port, int data, unsigned long iobase) { int movport = SIZE_8255 * (iobase >> 12); -- GitLab From 67393c4fef245f46863f50bc8a553f0608d7a05d Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:20 -0700 Subject: [PATCH 0663/9167] staging: comedi: ni_mio_common: tidy up ni_8255_callback() The 8255 driver (*io) callback now includes the comedi_device pointer. Instead of passing the (cast) pointer to subdev_8255_init(), pass the 'iobase' of the 8255 registers (Port_A). 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, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c index 07659053f4d3..8b3ba40cb74c 100644 --- a/drivers/staging/comedi/drivers/ni_mio_common.c +++ b/drivers/staging/comedi/drivers/ni_mio_common.c @@ -4176,17 +4176,15 @@ static int ni_freq_out_insn_config(struct comedi_device *dev, return insn->n; } -static int ni_8255_callback(struct comedi_device *cdev, - int dir, int port, int data, unsigned long arg) +static int ni_8255_callback(struct comedi_device *dev, + int dir, int port, int data, unsigned long iobase) { - struct comedi_device *dev = (struct comedi_device *)arg; - if (dir) { - ni_writeb(dev, data, Port_A + 2 * port); + ni_writeb(dev, data, iobase + 2 * port); return 0; } - return ni_readb(dev, Port_A + 2 * port); + return ni_readb(dev, iobase + 2 * port); } static int ni_get_pwm_config(struct comedi_device *dev, unsigned int *data) @@ -5561,8 +5559,7 @@ static int ni_E_init(struct comedi_device *dev, /* 8255 device */ s = &dev->subdevices[NI_8255_DIO_SUBDEV]; if (board->has_8255) { - ret = subdev_8255_init(dev, s, ni_8255_callback, - (unsigned long)dev); + ret = subdev_8255_init(dev, s, ni_8255_callback, Port_A); if (ret) return ret; } else { -- GitLab From ed8c80d0a4c65c062ee520cd167649b80afce16f Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:21 -0700 Subject: [PATCH 0664/9167] staging: comedi: ni_labpc: tidy up labpc_8255_mmio() The 8255 driver (*io) callback now includes the comedi_device pointer. Instead of passing the (cast) pointer to subdev_8255_init(), pass the 'iobase' of the 8255 registers (DIO_BASE_REG). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_labpc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index fa108b9dd603..15ead2715926 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1035,17 +1035,15 @@ static int labpc_ao_insn_read(struct comedi_device *dev, return 1; } -static int labpc_8255_mmio(struct comedi_device *cdev, - int dir, int port, int data, unsigned long arg) +static int labpc_8255_mmio(struct comedi_device *dev, + int dir, int port, int data, unsigned long iobase) { - struct comedi_device *dev = (struct comedi_device *)arg; - if (dir) { - writeb(data, dev->mmio + DIO_BASE_REG + port); + writeb(data, dev->mmio + iobase + port); return 0; } - return readb(dev->mmio + DIO_BASE_REG + port); + return readb(dev->mmio + iobase + port); } /* lowlevel write to eeprom/dac */ @@ -1405,7 +1403,7 @@ int labpc_common_attach(struct comedi_device *dev, s = &dev->subdevices[2]; if (dev->mmio) { ret = subdev_8255_init(dev, s, labpc_8255_mmio, - (unsigned long)dev); + DIO_BASE_REG); } else { ret = subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG); -- GitLab From f4e29703c790ee1045a0c0b7181c948b9a45636a Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:22 -0700 Subject: [PATCH 0665/9167] staging: comedi: daqboard2000: tidy up daqboard2000_8255_cb() The 8255 driver (*io) callback now includes the comedi_device pointer. Using this we can get the ioremap'ed base address. Instead of passing the (cast) mmio address to subdev_8255_init(), pass the 'iobase' of the 8255 registers (dioP2ExpansionIO8Bit). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/daqboard2000.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index d728fbd6d3a0..90fbb25e55ab 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c @@ -653,15 +653,13 @@ static void daqboard2000_initializeDac(struct comedi_device *dev) static int daqboard2000_8255_cb(struct comedi_device *dev, int dir, int port, int data, - unsigned long ioaddr) + unsigned long iobase) { - void __iomem *mmio_base = (void __iomem *)ioaddr; - if (dir) { - writew(data, mmio_base + port * 2); + writew(data, dev->mmio + iobase + port * 2); return 0; } - return readw(mmio_base + port * 2); + return readw(dev->mmio + iobase + port * 2); } static const void *daqboard2000_find_boardinfo(struct comedi_device *dev, @@ -745,7 +743,7 @@ static int daqboard2000_auto_attach(struct comedi_device *dev, s = &dev->subdevices[2]; result = subdev_8255_init(dev, s, daqboard2000_8255_cb, - (unsigned long)(dev->mmio + dioP2ExpansionIO8Bit)); + dioP2ExpansionIO8Bit); if (result) return result; -- GitLab From 27fdf38574e63f21c14098b11f36d932cb3aaf25 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:23 -0700 Subject: [PATCH 0666/9167] staging: comedi: cb_pcidas64: tidy up dio_callback() The 8255 driver (*io) callback now includes the comedi_device pointer. Using this we can get the ioremap'ed base address. Instead of passing the (cast) mmio address to subdev_8255_init(), pass the 'iobase' of the 8255 registers (DIO_8255_OFFSET). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index fafde70cbb51..61cb560e1bec 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3370,15 +3370,13 @@ static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) } static int dio_callback(struct comedi_device *dev, - int dir, int port, int data, unsigned long arg) + int dir, int port, int data, unsigned long iobase) { - void __iomem *iobase = (void __iomem *)arg; - if (dir) { - writeb(data, iobase + port); + writeb(data, dev->mmio + iobase + port); return 0; } - return readb(iobase + port); + return readb(dev->mmio + iobase + port); } static int dio_callback_4020(struct comedi_device *dev, @@ -3846,9 +3844,8 @@ static int setup_subdevices(struct comedi_device *dev) ret = subdev_8255_init(dev, s, dio_callback_4020, (unsigned long)dio_8255_iobase); } else { - dio_8255_iobase = dev->mmio + DIO_8255_OFFSET; ret = subdev_8255_init(dev, s, dio_callback, - (unsigned long)dio_8255_iobase); + DIO_8255_OFFSET); } if (ret) return ret; -- GitLab From da261e1d38f5ed4baaebc45f51e628e7d84a2560 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:24 -0700 Subject: [PATCH 0667/9167] staging: comedi: cb_pcidas64: tidy up dio_callback_4020() The 8255 driver (*io) callback now includes the comedi_device pointer. Using this we can get the ioremap'ed base address. Instead of passing the (cast) mmio address to subdev_8255_init(), pass the 'iobase' of the 8255 registers (I8255_4020_REG). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/cb_pcidas64.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index 61cb560e1bec..e3bfbd4c5def 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3380,15 +3380,15 @@ static int dio_callback(struct comedi_device *dev, } static int dio_callback_4020(struct comedi_device *dev, - int dir, int port, int data, unsigned long arg) + int dir, int port, int data, unsigned long iobase) { - void __iomem *iobase = (void __iomem *)arg; + struct pcidas64_private *devpriv = dev->private; if (dir) { - writew(data, iobase + 2 * port); + writew(data, devpriv->main_iobase + iobase + 2 * port); return 0; } - return readw(iobase + 2 * port); + return readw(devpriv->main_iobase + iobase + 2 * port); } static int di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, @@ -3751,7 +3751,6 @@ static int setup_subdevices(struct comedi_device *dev) const struct pcidas64_board *thisboard = comedi_board(dev); struct pcidas64_private *devpriv = dev->private; struct comedi_subdevice *s; - void __iomem *dio_8255_iobase; int i; int ret; @@ -3840,9 +3839,8 @@ static int setup_subdevices(struct comedi_device *dev) s = &dev->subdevices[4]; if (thisboard->has_8255) { if (thisboard->layout == LAYOUT_4020) { - dio_8255_iobase = devpriv->main_iobase + I8255_4020_REG; ret = subdev_8255_init(dev, s, dio_callback_4020, - (unsigned long)dio_8255_iobase); + I8255_4020_REG); } else { ret = subdev_8255_init(dev, s, dio_callback, DIO_8255_OFFSET); -- GitLab From 2b1a3fcfdf4067290cafffb5bc348c158e170fd7 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:25 -0700 Subject: [PATCH 0668/9167] staging: comedi: 8255_pci: tidy up pci_8255_mmio() The 8255 driver (*io) callback now includes the comedi_device pointer. Using this we can get the ioremap'ed base address. Instead of passing the (cast) mmio address to subdev_8255_init(), pass the 'iobase' of the 8255 registers (i * 4). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255_pci.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index cee3d18370fa..1a3deec57381 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -193,13 +193,11 @@ static int pci_8255_mite_init(struct pci_dev *pcidev) static int pci_8255_mmio(struct comedi_device *dev, int dir, int port, int data, unsigned long iobase) { - void __iomem *mmio_base = (void __iomem *)iobase; - if (dir) { - writeb(data, mmio_base + port); + writeb(data, dev->mmio + iobase + port); return 0; } - return readb(mmio_base + port); + return readb(dev->mmio + iobase + port); } static int pci_8255_auto_attach(struct comedi_device *dev, @@ -253,8 +251,7 @@ static int pci_8255_auto_attach(struct comedi_device *dev, s = &dev->subdevices[i]; if (is_mmio) { - iobase = (unsigned long)(dev->mmio + (i * 4)); - ret = subdev_8255_init(dev, s, pci_8255_mmio, iobase); + ret = subdev_8255_init(dev, s, pci_8255_mmio, i * 4); } else { iobase = dev->iobase + (i * 4); ret = subdev_8255_init(dev, s, NULL, iobase); -- GitLab From 4085e93b9fecfad454159694c19efc36e7ac1cdf Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:26 -0700 Subject: [PATCH 0669/9167] staging: comedi: 8255: refactor how the (*io) function works Currently, all users of is module that use the default (*io) function pass an 'iobase' to subdev_8255_init() of the form: dev->iobase + OFFSET_TO_8255_BASE_REG Now that the (*io) callback includes the comedi_device 'dev' pointer the 'dev->iobase' does not need to be included. Modify the default (*io) function, subdev_8255_io(), to automatically add the dev->iobase to the address when reading/writing the port. For aesthetics, rename the subdevice private data member to 'regbase'. Also, rename the local variables in this module that are used to access this member. Add a comment in dev_8255_attach() about the 'iobase' that is passed to subdev_8255_init(). For manually attached 8255 devices the io region is requested with __comedi_request_region() which does not set dev->iobase. For these devices the 'regbase' is actually the 'iobase'. Remove the, now unnecessary, dev->iobase from all the callers of subdev_8255_init(). There are a couple drivers that only passed the dev->iobase. For those drivers pass a 'regbase' of 0x00. Note that the das16m1 driver is a bit goofy. The devpriv->extra_iobase is requested using __comedi_request_region() which does not set the dev->iobase. But the starting address passed is dev->iobase + DAS16M1_82C55 so a 'regbase' of DAS16M1_82C55 is passed to subdev_8255_init(). Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 51 +++++++++++-------- drivers/staging/comedi/drivers/8255.h | 4 +- drivers/staging/comedi/drivers/8255_pci.c | 10 ++-- drivers/staging/comedi/drivers/adv_pci_dio.c | 1 - drivers/staging/comedi/drivers/aio_aio12_8.c | 3 +- .../comedi/drivers/amplc_pc236_common.c | 2 +- drivers/staging/comedi/drivers/amplc_pci230.c | 3 +- drivers/staging/comedi/drivers/cb_pcidas.c | 2 +- drivers/staging/comedi/drivers/cb_pcidda.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdas.c | 2 +- drivers/staging/comedi/drivers/cb_pcimdda.c | 3 +- drivers/staging/comedi/drivers/das08.c | 3 +- drivers/staging/comedi/drivers/das16.c | 3 +- drivers/staging/comedi/drivers/das16m1.c | 2 +- drivers/staging/comedi/drivers/ni_atmio16d.c | 2 +- drivers/staging/comedi/drivers/ni_daq_dio24.c | 2 +- drivers/staging/comedi/drivers/ni_labpc.c | 3 +- drivers/staging/comedi/drivers/pcl724.c | 3 +- drivers/staging/comedi/drivers/pcm3724.c | 3 +- 19 files changed, 49 insertions(+), 55 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 212e547ba77f..39cf12eeabc9 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -93,29 +93,29 @@ I/O port base address can be found in the output of 'lspci -v'. #define CR_CW 0x80 struct subdev_8255_private { - unsigned long iobase; + unsigned long regbase; int (*io)(struct comedi_device *, int, int, int, unsigned long); }; static int subdev_8255_io(struct comedi_device *dev, - int dir, int port, int data, unsigned long iobase) + int dir, int port, int data, unsigned long regbase) { if (dir) { - outb(data, iobase + port); + outb(data, dev->iobase + regbase + port); return 0; } - return inb(iobase + port); + return inb(dev->iobase + regbase + port); } void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) { struct subdev_8255_private *spriv = s->private; - unsigned long iobase = spriv->iobase; + unsigned long regbase = spriv->regbase; unsigned short d; - d = spriv->io(dev, 0, _8255_DATA, 0, iobase); - d |= (spriv->io(dev, 0, _8255_DATA + 1, 0, iobase) << 8); + d = spriv->io(dev, 0, _8255_DATA, 0, regbase); + d |= (spriv->io(dev, 0, _8255_DATA + 1, 0, regbase) << 8); comedi_buf_put(s, d); s->async->events |= COMEDI_CB_EOS; @@ -130,25 +130,25 @@ static int subdev_8255_insn(struct comedi_device *dev, unsigned int *data) { struct subdev_8255_private *spriv = s->private; - unsigned long iobase = spriv->iobase; + unsigned long regbase = spriv->regbase; unsigned int mask; unsigned int v; mask = comedi_dio_update_state(s, data); if (mask) { if (mask & 0xff) - spriv->io(dev, 1, _8255_DATA, s->state & 0xff, iobase); + spriv->io(dev, 1, _8255_DATA, s->state & 0xff, regbase); if (mask & 0xff00) spriv->io(dev, 1, _8255_DATA + 1, - (s->state >> 8) & 0xff, iobase); + (s->state >> 8) & 0xff, regbase); if (mask & 0xff0000) spriv->io(dev, 1, _8255_DATA + 2, - (s->state >> 16) & 0xff, iobase); + (s->state >> 16) & 0xff, regbase); } - v = spriv->io(dev, 0, _8255_DATA, 0, iobase); - v |= (spriv->io(dev, 0, _8255_DATA + 1, 0, iobase) << 8); - v |= (spriv->io(dev, 0, _8255_DATA + 2, 0, iobase) << 16); + v = spriv->io(dev, 0, _8255_DATA, 0, regbase); + v |= (spriv->io(dev, 0, _8255_DATA + 1, 0, regbase) << 8); + v |= (spriv->io(dev, 0, _8255_DATA + 2, 0, regbase) << 16); data[1] = v; @@ -159,7 +159,7 @@ static void subdev_8255_do_config(struct comedi_device *dev, struct comedi_subdevice *s) { struct subdev_8255_private *spriv = s->private; - unsigned long iobase = spriv->iobase; + unsigned long regbase = spriv->regbase; int config; config = CR_CW; @@ -173,7 +173,7 @@ static void subdev_8255_do_config(struct comedi_device *dev, if (!(s->io_bits & 0xf00000)) config |= CR_C_HI_IO; - spriv->io(dev, 1, _8255_CR, config, iobase); + spriv->io(dev, 1, _8255_CR, config, regbase); } static int subdev_8255_insn_config(struct comedi_device *dev, @@ -264,7 +264,7 @@ static int subdev_8255_cancel(struct comedi_device *dev, int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*io)(struct comedi_device *, int, int, int, unsigned long), - unsigned long iobase) + unsigned long regbase) { struct subdev_8255_private *spriv; @@ -272,7 +272,7 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, if (!spriv) return -ENOMEM; - spriv->iobase = iobase; + spriv->regbase = regbase; spriv->io = io ? io : subdev_8255_io; s->type = COMEDI_SUBD_DIO; @@ -292,11 +292,11 @@ EXPORT_SYMBOL_GPL(subdev_8255_init); int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, int (*io)(struct comedi_device *, int, int, int, unsigned long), - unsigned long iobase) + unsigned long regbase) { int ret; - ret = subdev_8255_init(dev, s, io, iobase); + ret = subdev_8255_init(dev, s, io, regbase); if (ret) return ret; @@ -319,8 +319,8 @@ static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig *it) { struct comedi_subdevice *s; - int ret; unsigned long iobase; + int ret; int i; for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) { @@ -341,6 +341,13 @@ static int dev_8255_attach(struct comedi_device *dev, s = &dev->subdevices[i]; iobase = it->options[i]; + /* + * __comedi_request_region() does not set dev->iobase. + * + * For 8255 devices that are manually attached using + * comedi_config, the 'iobase' is the actual I/O port + * base address of the chip. + */ ret = __comedi_request_region(dev, iobase, _8255_SIZE); if (ret) { s->type = COMEDI_SUBD_UNUSED; @@ -364,7 +371,7 @@ static void dev_8255_detach(struct comedi_device *dev) s = &dev->subdevices[i]; if (s->type != COMEDI_SUBD_UNUSED) { spriv = s->private; - release_region(spriv->iobase, _8255_SIZE); + release_region(spriv->regbase, _8255_SIZE); } } } diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index c2c20db2f1d0..978f0a7f8c1f 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -24,11 +24,11 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*io)(struct comedi_device *, int, int, int, unsigned long), - unsigned long iobase); + unsigned long regbase); int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, int (*io)(struct comedi_device *, int, int, int, unsigned long), - unsigned long iobase); + unsigned long regbase); void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice *s); diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 1a3deec57381..15e85b6e67bd 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -247,15 +247,11 @@ static int pci_8255_auto_attach(struct comedi_device *dev, return ret; for (i = 0; i < board->n_8255; i++) { - unsigned long iobase; - s = &dev->subdevices[i]; - if (is_mmio) { + if (is_mmio) ret = subdev_8255_init(dev, s, pci_8255_mmio, i * 4); - } else { - iobase = dev->iobase + (i * 4); - ret = subdev_8255_init(dev, s, NULL, iobase); - } + else + ret = subdev_8255_init(dev, s, NULL, i * 4); if (ret) return ret; } diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index b8c7d9145a54..596d17c832e0 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -1132,7 +1132,6 @@ static int pci_dio_auto_attach(struct comedi_device *dev, for (j = 0; j < this_board->sdio[i].regs; j++) { s = &dev->subdevices[subdev]; ret = subdev_8255_init(dev, s, NULL, - dev->iobase + this_board->sdio[i].addr + SIZE_8255 * j); if (ret) diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c index 324746b14931..848b95decabe 100644 --- a/drivers/staging/comedi/drivers/aio_aio12_8.c +++ b/drivers/staging/comedi/drivers/aio_aio12_8.c @@ -244,8 +244,7 @@ static int aio_aio12_8_attach(struct comedi_device *dev, s = &dev->subdevices[2]; /* 8255 Digital i/o subdevice */ - ret = subdev_8255_init(dev, s, NULL, - dev->iobase + AIO12_8_8255_BASE_REG); + ret = subdev_8255_init(dev, s, NULL, AIO12_8_8255_BASE_REG); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/amplc_pc236_common.c b/drivers/staging/comedi/drivers/amplc_pc236_common.c index 18e237cca419..974b72392d0a 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236_common.c +++ b/drivers/staging/comedi/drivers/amplc_pc236_common.c @@ -160,7 +160,7 @@ int amplc_pc236_common_attach(struct comedi_device *dev, unsigned long iobase, s = &dev->subdevices[0]; /* digital i/o subdevice (8255) */ - ret = subdev_8255_init(dev, s, NULL, iobase); + ret = subdev_8255_init(dev, s, NULL, 0x00); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 7b56f68b3b4f..0fd212f5fa2a 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -2794,8 +2794,7 @@ static int pci230_attach_common(struct comedi_device *dev, s = &dev->subdevices[2]; /* digital i/o subdevice */ if (thisboard->have_dio) { - rc = subdev_8255_init(dev, s, NULL, - dev->iobase + PCI230_PPI_X_BASE); + rc = subdev_8255_init(dev, s, NULL, PCI230_PPI_X_BASE); if (rc) return rc; } else { diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c index b48540b3b66c..f372b0306b38 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas.c +++ b/drivers/staging/comedi/drivers/cb_pcidas.c @@ -1528,7 +1528,7 @@ static int cb_pcidas_auto_attach(struct comedi_device *dev, /* 8255 */ s = &dev->subdevices[2]; - ret = subdev_8255_init(dev, s, NULL, dev->iobase + DIO_8255); + ret = subdev_8255_init(dev, s, NULL, DIO_8255); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 9c9c58049e01..2ffb9ca17995 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -378,7 +378,7 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev, /* two 8255 digital io subdevices */ for (i = 0; i < 2; i++) { s = &dev->subdevices[1 + i]; - ret = subdev_8255_init(dev, s, NULL, dev->iobase + (i * 4)); + ret = subdev_8255_init(dev, s, NULL, i * 4); if (ret) return ret; } diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c index d049a7f27239..f1c0dafb98dd 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdas.c +++ b/drivers/staging/comedi/drivers/cb_pcimdas.c @@ -252,7 +252,7 @@ static int cb_pcimdas_auto_attach(struct comedi_device *dev, s = &dev->subdevices[2]; /* digital i/o subdevice */ - ret = subdev_8255_init(dev, s, NULL, dev->iobase); + ret = subdev_8255_init(dev, s, NULL, 0x00); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c index 4a2b200de01b..49b24d032436 100644 --- a/drivers/staging/comedi/drivers/cb_pcimdda.c +++ b/drivers/staging/comedi/drivers/cb_pcimdda.c @@ -182,8 +182,7 @@ static int cb_pcimdda_auto_attach(struct comedi_device *dev, s = &dev->subdevices[1]; /* digital i/o subdevice */ - ret = subdev_8255_init(dev, s, NULL, - dev->iobase + PCIMDDA_8255_BASE_REG); + ret = subdev_8255_init(dev, s, NULL, PCIMDDA_8255_BASE_REG); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index fcf916a80c8d..03b2c71df8f8 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c @@ -536,8 +536,7 @@ int das08_common_attach(struct comedi_device *dev, unsigned long iobase) s = &dev->subdevices[4]; /* 8255 */ if (thisboard->i8255_offset != 0) { - ret = subdev_8255_init(dev, s, NULL, - dev->iobase + thisboard->i8255_offset); + ret = subdev_8255_init(dev, s, NULL, thisboard->i8255_offset); if (ret) return ret; } else { diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c index 057bc16f8ddc..a347bcdff29c 100644 --- a/drivers/staging/comedi/drivers/das16.c +++ b/drivers/staging/comedi/drivers/das16.c @@ -1191,8 +1191,7 @@ static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* 8255 Digital I/O subdevice */ if (board->has_8255) { s = &dev->subdevices[4]; - ret = subdev_8255_init(dev, s, NULL, - dev->iobase + board->i8255_offset); + ret = subdev_8255_init(dev, s, NULL, board->i8255_offset); if (ret) return ret; } diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c index 5b6998b54060..1bf5be8c0313 100644 --- a/drivers/staging/comedi/drivers/das16m1.c +++ b/drivers/staging/comedi/drivers/das16m1.c @@ -608,7 +608,7 @@ static int das16m1_attach(struct comedi_device *dev, s = &dev->subdevices[3]; /* 8255 */ - ret = subdev_8255_init(dev, s, NULL, devpriv->extra_iobase); + ret = subdev_8255_init(dev, s, NULL, DAS16M1_82C55); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c index 9c08da9508f4..f1acca6cd12f 100644 --- a/drivers/staging/comedi/drivers/ni_atmio16d.c +++ b/drivers/staging/comedi/drivers/ni_atmio16d.c @@ -722,7 +722,7 @@ static int atmio16d_attach(struct comedi_device *dev, /* 8255 subdevice */ s = &dev->subdevices[3]; if (board->has_8255) { - ret = subdev_8255_init(dev, s, NULL, dev->iobase); + ret = subdev_8255_init(dev, s, NULL, 0x00); if (ret) return ret; } else { diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c index 925e82c65b2d..8cfabdbaa30c 100644 --- a/drivers/staging/comedi/drivers/ni_daq_dio24.c +++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c @@ -59,7 +59,7 @@ static int dio24_auto_attach(struct comedi_device *dev, /* 8255 dio */ s = &dev->subdevices[0]; - ret = subdev_8255_init(dev, s, NULL, dev->iobase); + ret = subdev_8255_init(dev, s, NULL, 0x00); if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 15ead2715926..8f914de1c153 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1405,8 +1405,7 @@ int labpc_common_attach(struct comedi_device *dev, ret = subdev_8255_init(dev, s, labpc_8255_mmio, DIO_BASE_REG); } else { - ret = subdev_8255_init(dev, s, NULL, - dev->iobase + DIO_BASE_REG); + ret = subdev_8255_init(dev, s, NULL, DIO_BASE_REG); } if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 946b058eee6f..3acbbc65ca64 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -133,8 +133,7 @@ static int pcl724_attach(struct comedi_device *dev, ret = subdev_8255_init(dev, s, pcl724_8255mapped_io, iobase); } else { - iobase = dev->iobase + (i * SIZE_8255); - ret = subdev_8255_init(dev, s, NULL, iobase); + ret = subdev_8255_init(dev, s, NULL, i * SIZE_8255); } if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index 6e0d78f6095b..f6acf5de59bf 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -211,8 +211,7 @@ static int pcm3724_attach(struct comedi_device *dev, for (i = 0; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; - ret = subdev_8255_init(dev, s, NULL, - dev->iobase + SIZE_8255 * i); + ret = subdev_8255_init(dev, s, NULL, i * SIZE_8255); if (ret) return ret; s->insn_config = subdev_3724_insn_config; -- GitLab From 9067983867516a425d3382cb2eeeb234a2e8e3b6 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:27 -0700 Subject: [PATCH 0670/9167] staging: comedi: 8255: remove incomplete async command support The async command support in this module is incomplete and nothing has ever used it. Just remove it. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 95 --------------------------- drivers/staging/comedi/drivers/8255.h | 6 -- 2 files changed, 101 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 39cf12eeabc9..456c07b3f6cc 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -107,23 +107,6 @@ static int subdev_8255_io(struct comedi_device *dev, return inb(dev->iobase + regbase + port); } -void subdev_8255_interrupt(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - struct subdev_8255_private *spriv = s->private; - unsigned long regbase = spriv->regbase; - unsigned short d; - - d = spriv->io(dev, 0, _8255_DATA, 0, regbase); - d |= (spriv->io(dev, 0, _8255_DATA + 1, 0, regbase) << 8); - - comedi_buf_put(s, d); - s->async->events |= COMEDI_CB_EOS; - - comedi_event(dev, s); -} -EXPORT_SYMBOL_GPL(subdev_8255_interrupt); - static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -203,64 +186,6 @@ static int subdev_8255_insn_config(struct comedi_device *dev, return insn->n; } -static int subdev_8255_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); - err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); - err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); - err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); - err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_NONE); - - if (err) - return 1; - - /* 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); - err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); - err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0); - err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); - err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); - - if (err) - return 3; - - /* step 4 */ - - if (err) - return 4; - - return 0; -} - -static int subdev_8255_cmd(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - /* FIXME */ - - return 0; -} - -static int subdev_8255_cancel(struct comedi_device *dev, - struct comedi_subdevice *s) -{ - /* FIXME */ - - return 0; -} - int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*io)(struct comedi_device *, int, int, int, unsigned long), @@ -289,26 +214,6 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, } EXPORT_SYMBOL_GPL(subdev_8255_init); -int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(struct comedi_device *, - int, int, int, unsigned long), - unsigned long regbase) -{ - int ret; - - ret = subdev_8255_init(dev, s, io, regbase); - if (ret) - return ret; - - s->len_chanlist = 1; - s->do_cmdtest = subdev_8255_cmdtest; - s->do_cmd = subdev_8255_cmd; - s->cancel = subdev_8255_cancel; - - return 0; -} -EXPORT_SYMBOL_GPL(subdev_8255_init_irq); - /* Start of the 8255 standalone device diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index 978f0a7f8c1f..30848977d421 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -25,11 +25,5 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*io)(struct comedi_device *, int, int, int, unsigned long), unsigned long regbase); -int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(struct comedi_device *, - int, int, int, unsigned long), - unsigned long regbase); -void subdev_8255_interrupt(struct comedi_device *dev, - struct comedi_subdevice *s); #endif -- GitLab From 5c19084bbd4ef7c0a10e5b01145b940edf872a63 Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:28 -0700 Subject: [PATCH 0671/9167] staging: comedi: 8255: handle memory mapped io The drivers that use this module with memory mapped io all have the ioremap'ed base address stored in the comedi_device 'mmio' member. Introduce a default (*io) function that does 8-bit memory mapped io. Modify subdev_8255_init() so that it takes a flag parameter indicating if the io is port or memory mapped. Make the function static and rename it to __subdev_8255_init(). Introduce two exported wrappers for __subdev_8255_init(): subdev_8255_init() - for drivers that do 8-bit port io subdev_8255_mm_init() - for drivers that do 8-bit memory mapped io Use subdev_8255_mm_init() in the drivers that do 8-bit memory mapped io and remove the private (*io) functions. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 43 +++++++++++++++++--- drivers/staging/comedi/drivers/8255.h | 7 +++- drivers/staging/comedi/drivers/8255_pci.c | 19 ++------- drivers/staging/comedi/drivers/cb_pcidas64.c | 14 +------ drivers/staging/comedi/drivers/ni_labpc.c | 14 +------ 5 files changed, 50 insertions(+), 47 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index 456c07b3f6cc..be56e167cfd5 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -107,6 +107,16 @@ static int subdev_8255_io(struct comedi_device *dev, return inb(dev->iobase + regbase + port); } +static int subdev_8255_mmio(struct comedi_device *dev, + int dir, int port, int data, unsigned long regbase) +{ + if (dir) { + writeb(data, dev->mmio + regbase + port); + return 0; + } + return readb(dev->mmio + regbase + port); +} + static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, @@ -186,10 +196,12 @@ static int subdev_8255_insn_config(struct comedi_device *dev, return insn->n; } -int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, - int (*io)(struct comedi_device *, - int, int, int, unsigned long), - unsigned long regbase) +static int __subdev_8255_init(struct comedi_device *dev, + struct comedi_subdevice *s, + int (*io)(struct comedi_device *, + int, int, int, unsigned long), + unsigned long regbase, + bool is_mmio) { struct subdev_8255_private *spriv; @@ -197,8 +209,13 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, if (!spriv) return -ENOMEM; + if (io) + spriv->io = io; + else if (is_mmio) + spriv->io = subdev_8255_mmio; + else + spriv->io = subdev_8255_io; spriv->regbase = regbase; - spriv->io = io ? io : subdev_8255_io; s->type = COMEDI_SUBD_DIO; s->subdev_flags = SDF_READABLE | SDF_WRITABLE; @@ -212,8 +229,24 @@ int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, return 0; } + +int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, + int (*io)(struct comedi_device *, + int, int, int, unsigned long), + unsigned long regbase) +{ + return __subdev_8255_init(dev, s, io, regbase, false); +} EXPORT_SYMBOL_GPL(subdev_8255_init); +int subdev_8255_mm_init(struct comedi_device *dev, struct comedi_subdevice *s, + int (*io)(struct comedi_device *, + int, int, int, unsigned long), + unsigned long regbase) +{ + return __subdev_8255_init(dev, s, io, regbase, true); +} +EXPORT_SYMBOL_GPL(subdev_8255_mm_init); /* Start of the 8255 standalone device diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index 30848977d421..c7c6deeed026 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -21,9 +21,14 @@ #include "../comedidev.h" -int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice *s, +int subdev_8255_init(struct comedi_device *, struct comedi_subdevice *, int (*io)(struct comedi_device *, int, int, int, unsigned long), unsigned long regbase); +int subdev_8255_mm_init(struct comedi_device *, struct comedi_subdevice *, + int (*io)(struct comedi_device *, + int, int, int, unsigned long), + unsigned long regbase); + #endif diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index 15e85b6e67bd..eb1ca0e85912 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -190,23 +190,12 @@ static int pci_8255_mite_init(struct pci_dev *pcidev) return 0; } -static int pci_8255_mmio(struct comedi_device *dev, - int dir, int port, int data, unsigned long iobase) -{ - if (dir) { - writeb(data, dev->mmio + iobase + port); - return 0; - } - return readb(dev->mmio + iobase + port); -} - static int pci_8255_auto_attach(struct comedi_device *dev, unsigned long context) { struct pci_dev *pcidev = comedi_to_pci_dev(dev); const struct pci_8255_boardinfo *board = NULL; struct comedi_subdevice *s; - bool is_mmio; int ret; int i; @@ -227,9 +216,7 @@ static int pci_8255_auto_attach(struct comedi_device *dev, return ret; } - is_mmio = (pci_resource_flags(pcidev, board->dio_badr) & - IORESOURCE_MEM) != 0; - if (is_mmio) { + if ((pci_resource_flags(pcidev, board->dio_badr) & IORESOURCE_MEM)) { dev->mmio = pci_ioremap_bar(pcidev, board->dio_badr); if (!dev->mmio) return -ENOMEM; @@ -248,8 +235,8 @@ static int pci_8255_auto_attach(struct comedi_device *dev, for (i = 0; i < board->n_8255; i++) { s = &dev->subdevices[i]; - if (is_mmio) - ret = subdev_8255_init(dev, s, pci_8255_mmio, i * 4); + if (dev->mmio) + ret = subdev_8255_mm_init(dev, s, NULL, i * 4); else ret = subdev_8255_init(dev, s, NULL, i * 4); if (ret) diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c index e3bfbd4c5def..77b028452d93 100644 --- a/drivers/staging/comedi/drivers/cb_pcidas64.c +++ b/drivers/staging/comedi/drivers/cb_pcidas64.c @@ -3369,16 +3369,6 @@ static int ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s) return 0; } -static int dio_callback(struct comedi_device *dev, - int dir, int port, int data, unsigned long iobase) -{ - if (dir) { - writeb(data, dev->mmio + iobase + port); - return 0; - } - return readb(dev->mmio + iobase + port); -} - static int dio_callback_4020(struct comedi_device *dev, int dir, int port, int data, unsigned long iobase) { @@ -3842,8 +3832,8 @@ static int setup_subdevices(struct comedi_device *dev) ret = subdev_8255_init(dev, s, dio_callback_4020, I8255_4020_REG); } else { - ret = subdev_8255_init(dev, s, dio_callback, - DIO_8255_OFFSET); + ret = subdev_8255_mm_init(dev, s, NULL, + DIO_8255_OFFSET); } if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 8f914de1c153..c9c090e15e85 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -1035,17 +1035,6 @@ static int labpc_ao_insn_read(struct comedi_device *dev, return 1; } -static int labpc_8255_mmio(struct comedi_device *dev, - int dir, int port, int data, unsigned long iobase) -{ - if (dir) { - writeb(data, dev->mmio + iobase + port); - return 0; - } - - return readb(dev->mmio + iobase + port); -} - /* lowlevel write to eeprom/dac */ static void labpc_serial_out(struct comedi_device *dev, unsigned int value, unsigned int value_width) @@ -1402,8 +1391,7 @@ int labpc_common_attach(struct comedi_device *dev, /* 8255 dio */ s = &dev->subdevices[2]; if (dev->mmio) { - ret = subdev_8255_init(dev, s, labpc_8255_mmio, - DIO_BASE_REG); + ret = subdev_8255_mm_init(dev, s, NULL, DIO_BASE_REG); } else { ret = subdev_8255_init(dev, s, NULL, DIO_BASE_REG); } -- GitLab From f01620914699679a26212affa358e5bbc5ede63e Mon Sep 17 00:00:00 2001 From: H Hartley Sweeten Date: Tue, 12 Aug 2014 11:41:29 -0700 Subject: [PATCH 0672/9167] staging: comedi: 8255: provide common defines for registers There are a couple comedi drivers that duplicate some of the register defines used by the 8255 module. Move these defines into the header so the duplication can be removed. Signed-off-by: H Hartley Sweeten Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/8255.c | 42 +++++++------------ drivers/staging/comedi/drivers/8255.h | 14 +++++++ drivers/staging/comedi/drivers/8255_pci.c | 4 +- drivers/staging/comedi/drivers/adv_pci_dio.c | 3 +- .../comedi/drivers/amplc_dio200_common.c | 35 +++++++--------- drivers/staging/comedi/drivers/cb_pcidda.c | 2 +- drivers/staging/comedi/drivers/pcl724.c | 6 +-- drivers/staging/comedi/drivers/pcm3724.c | 26 ++++-------- 8 files changed, 56 insertions(+), 76 deletions(-) diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c index be56e167cfd5..34d4d8b5f31e 100644 --- a/drivers/staging/comedi/drivers/8255.c +++ b/drivers/staging/comedi/drivers/8255.c @@ -79,19 +79,6 @@ I/O port base address can be found in the output of 'lspci -v'. #include "comedi_fc.h" #include "8255.h" -#define _8255_SIZE 4 - -#define _8255_DATA 0 -#define _8255_CR 3 - -#define CR_C_LO_IO 0x01 -#define CR_B_IO 0x02 -#define CR_B_MODE 0x04 -#define CR_C_HI_IO 0x08 -#define CR_A_IO 0x10 -#define CR_A_MODE(a) ((a)<<5) -#define CR_CW 0x80 - struct subdev_8255_private { unsigned long regbase; int (*io)(struct comedi_device *, int, int, int, unsigned long); @@ -130,18 +117,19 @@ static int subdev_8255_insn(struct comedi_device *dev, mask = comedi_dio_update_state(s, data); if (mask) { if (mask & 0xff) - spriv->io(dev, 1, _8255_DATA, s->state & 0xff, regbase); + spriv->io(dev, 1, I8255_DATA_A_REG, + s->state & 0xff, regbase); if (mask & 0xff00) - spriv->io(dev, 1, _8255_DATA + 1, + spriv->io(dev, 1, I8255_DATA_B_REG, (s->state >> 8) & 0xff, regbase); if (mask & 0xff0000) - spriv->io(dev, 1, _8255_DATA + 2, + spriv->io(dev, 1, I8255_DATA_C_REG, (s->state >> 16) & 0xff, regbase); } - v = spriv->io(dev, 0, _8255_DATA, 0, regbase); - v |= (spriv->io(dev, 0, _8255_DATA + 1, 0, regbase) << 8); - v |= (spriv->io(dev, 0, _8255_DATA + 2, 0, regbase) << 16); + v = spriv->io(dev, 0, I8255_DATA_A_REG, 0, regbase); + v |= (spriv->io(dev, 0, I8255_DATA_B_REG, 0, regbase) << 8); + v |= (spriv->io(dev, 0, I8255_DATA_C_REG, 0, regbase) << 16); data[1] = v; @@ -155,18 +143,18 @@ static void subdev_8255_do_config(struct comedi_device *dev, unsigned long regbase = spriv->regbase; int config; - config = CR_CW; + config = I8255_CTRL_CW; /* 1 in io_bits indicates output, 1 in config indicates input */ if (!(s->io_bits & 0x0000ff)) - config |= CR_A_IO; + config |= I8255_CTRL_A_IO; if (!(s->io_bits & 0x00ff00)) - config |= CR_B_IO; + config |= I8255_CTRL_B_IO; if (!(s->io_bits & 0x0f0000)) - config |= CR_C_LO_IO; + config |= I8255_CTRL_C_LO_IO; if (!(s->io_bits & 0xf00000)) - config |= CR_C_HI_IO; + config |= I8255_CTRL_C_HI_IO; - spriv->io(dev, 1, _8255_CR, config, regbase); + spriv->io(dev, 1, I8255_CTRL_REG, config, regbase); } static int subdev_8255_insn_config(struct comedi_device *dev, @@ -286,7 +274,7 @@ static int dev_8255_attach(struct comedi_device *dev, * comedi_config, the 'iobase' is the actual I/O port * base address of the chip. */ - ret = __comedi_request_region(dev, iobase, _8255_SIZE); + ret = __comedi_request_region(dev, iobase, I8255_SIZE); if (ret) { s->type = COMEDI_SUBD_UNUSED; } else { @@ -309,7 +297,7 @@ static void dev_8255_detach(struct comedi_device *dev) s = &dev->subdevices[i]; if (s->type != COMEDI_SUBD_UNUSED) { spriv = s->private; - release_region(spriv->regbase, _8255_SIZE); + release_region(spriv->regbase, I8255_SIZE); } } } diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h index c7c6deeed026..5985c8e0330f 100644 --- a/drivers/staging/comedi/drivers/8255.h +++ b/drivers/staging/comedi/drivers/8255.h @@ -21,6 +21,20 @@ #include "../comedidev.h" +#define I8255_SIZE 0x04 + +#define I8255_DATA_A_REG 0x00 +#define I8255_DATA_B_REG 0x01 +#define I8255_DATA_C_REG 0x02 +#define I8255_CTRL_REG 0x03 +#define I8255_CTRL_C_LO_IO (1 << 0) +#define I8255_CTRL_B_IO (1 << 1) +#define I8255_CTRL_B_MODE (1 << 2) +#define I8255_CTRL_C_HI_IO (1 << 3) +#define I8255_CTRL_A_IO (1 << 4) +#define I8255_CTRL_A_MODE(x) ((x) << 5) +#define I8255_CTRL_CW (1 << 7) + int subdev_8255_init(struct comedi_device *, struct comedi_subdevice *, int (*io)(struct comedi_device *, int, int, int, unsigned long), diff --git a/drivers/staging/comedi/drivers/8255_pci.c b/drivers/staging/comedi/drivers/8255_pci.c index eb1ca0e85912..8bcb1e0e6a71 100644 --- a/drivers/staging/comedi/drivers/8255_pci.c +++ b/drivers/staging/comedi/drivers/8255_pci.c @@ -236,9 +236,9 @@ static int pci_8255_auto_attach(struct comedi_device *dev, for (i = 0; i < board->n_8255; i++) { s = &dev->subdevices[i]; if (dev->mmio) - ret = subdev_8255_mm_init(dev, s, NULL, i * 4); + ret = subdev_8255_mm_init(dev, s, NULL, i * I8255_SIZE); else - ret = subdev_8255_init(dev, s, NULL, i * 4); + ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); if (ret) return ret; } diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 596d17c832e0..f3e2268d4fee 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -66,7 +66,6 @@ enum hw_io_access { * subdevice) */ #define SIZE_8254 4 /* 8254 IO space length */ -#define SIZE_8255 4 /* 8255 IO space length */ #define PCIDIO_MAINREG 2 /* main I/O region for all Advantech cards? */ @@ -1133,7 +1132,7 @@ static int pci_dio_auto_attach(struct comedi_device *dev, s = &dev->subdevices[subdev]; ret = subdev_8255_init(dev, s, NULL, this_board->sdio[i].addr + - SIZE_8255 * j); + j * I8255_SIZE); if (ret) return ret; subdev++; diff --git a/drivers/staging/comedi/drivers/amplc_dio200_common.c b/drivers/staging/comedi/drivers/amplc_dio200_common.c index 87c01692d800..6cadf7e19c94 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200_common.c +++ b/drivers/staging/comedi/drivers/amplc_dio200_common.c @@ -27,15 +27,7 @@ #include "amplc_dio200.h" #include "comedi_fc.h" #include "8253.h" - -/* 8255 control register bits */ -#define CR_C_LO_IO 0x01 -#define CR_B_IO 0x02 -#define CR_B_MODE 0x04 -#define CR_C_HI_IO 0x08 -#define CR_A_IO 0x10 -#define CR_A_MODE(a) ((a)<<5) -#define CR_CW 0x80 +#include "8255.h" /* only for register defines */ /* 200 series registers */ #define DIO200_IO_SIZE 0x20 @@ -815,17 +807,17 @@ static void dio200_subdev_8255_set_dir(struct comedi_device *dev, struct dio200_subdev_8255 *subpriv = s->private; int config; - config = CR_CW; + config = I8255_CTRL_CW; /* 1 in io_bits indicates output, 1 in config indicates input */ if (!(s->io_bits & 0x0000ff)) - config |= CR_A_IO; + config |= I8255_CTRL_A_IO; if (!(s->io_bits & 0x00ff00)) - config |= CR_B_IO; + config |= I8255_CTRL_B_IO; if (!(s->io_bits & 0x0f0000)) - config |= CR_C_LO_IO; + config |= I8255_CTRL_C_LO_IO; if (!(s->io_bits & 0xf00000)) - config |= CR_C_HI_IO; - dio200_write8(dev, subpriv->ofs + 3, config); + config |= I8255_CTRL_C_HI_IO; + dio200_write8(dev, subpriv->ofs + I8255_CTRL_REG, config); } static int dio200_subdev_8255_bits(struct comedi_device *dev, @@ -840,18 +832,19 @@ static int dio200_subdev_8255_bits(struct comedi_device *dev, mask = comedi_dio_update_state(s, data); if (mask) { if (mask & 0xff) - dio200_write8(dev, subpriv->ofs, s->state & 0xff); + dio200_write8(dev, subpriv->ofs + I8255_DATA_A_REG, + s->state & 0xff); if (mask & 0xff00) - dio200_write8(dev, subpriv->ofs + 1, + dio200_write8(dev, subpriv->ofs + I8255_DATA_B_REG, (s->state >> 8) & 0xff); if (mask & 0xff0000) - dio200_write8(dev, subpriv->ofs + 2, + dio200_write8(dev, subpriv->ofs + I8255_DATA_C_REG, (s->state >> 16) & 0xff); } - val = dio200_read8(dev, subpriv->ofs); - val |= dio200_read8(dev, subpriv->ofs + 1) << 8; - val |= dio200_read8(dev, subpriv->ofs + 2) << 16; + val = dio200_read8(dev, subpriv->ofs + I8255_DATA_A_REG); + val |= dio200_read8(dev, subpriv->ofs + I8255_DATA_B_REG) << 8; + val |= dio200_read8(dev, subpriv->ofs + I8255_DATA_C_REG) << 16; data[1] = val; diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c index 2ffb9ca17995..91ba90b5ceae 100644 --- a/drivers/staging/comedi/drivers/cb_pcidda.c +++ b/drivers/staging/comedi/drivers/cb_pcidda.c @@ -378,7 +378,7 @@ static int cb_pcidda_auto_attach(struct comedi_device *dev, /* two 8255 digital io subdevices */ for (i = 0; i < 2; i++) { s = &dev->subdevices[1 + i]; - ret = subdev_8255_init(dev, s, NULL, i * 4); + ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); if (ret) return ret; } diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c index 3acbbc65ca64..84c768fefffb 100644 --- a/drivers/staging/comedi/drivers/pcl724.c +++ b/drivers/staging/comedi/drivers/pcl724.c @@ -32,8 +32,6 @@ #include "8255.h" -#define SIZE_8255 4 - struct pcl724_board { const char *name; unsigned int io_range; @@ -85,7 +83,7 @@ static int pcl724_8255mapped_io(struct comedi_device *dev, int dir, int port, int data, unsigned long iobase) { - int movport = SIZE_8255 * (iobase >> 12); + int movport = I8255_SIZE * (iobase >> 12); iobase &= 0x0fff; @@ -133,7 +131,7 @@ static int pcl724_attach(struct comedi_device *dev, ret = subdev_8255_init(dev, s, pcl724_8255mapped_io, iobase); } else { - ret = subdev_8255_init(dev, s, NULL, i * SIZE_8255); + ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); } if (ret) return ret; diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c index f6acf5de59bf..6176dfa24801 100644 --- a/drivers/staging/comedi/drivers/pcm3724.c +++ b/drivers/staging/comedi/drivers/pcm3724.c @@ -33,8 +33,6 @@ Copy/pasted/hacked from pcm724.c #include "8255.h" -#define SIZE_8255 4 - #define BUF_C0 0x1 #define BUF_B0 0x2 #define BUF_A0 0x4 @@ -49,16 +47,6 @@ Copy/pasted/hacked from pcm724.c #define GATE_B1 0x10 #define GATE_C1 0x8 -/* from 8255.c */ -#define CR_CW 0x80 -#define _8255_CR 3 -#define CR_B_IO 0x02 -#define CR_B_MODE 0x04 -#define CR_C_IO 0x09 -#define CR_A_IO 0x10 -#define CR_A_MODE(a) ((a)<<5) -#define CR_CW 0x80 - /* used to track configured dios */ struct priv_pcm3724 { int dio_1; @@ -98,26 +86,26 @@ static void do_3724_config(struct comedi_device *dev, int buffer_config; unsigned long port_8255_cfg; - config = CR_CW; + config = I8255_CTRL_CW; buffer_config = 0; /* 1 in io_bits indicates output, 1 in config indicates input */ if (!(s->io_bits & 0x0000ff)) - config |= CR_A_IO; + config |= I8255_CTRL_A_IO; if (!(s->io_bits & 0x00ff00)) - config |= CR_B_IO; + config |= I8255_CTRL_B_IO; if (!(s->io_bits & 0xff0000)) - config |= CR_C_IO; + config |= I8255_CTRL_C_HI_IO | I8255_CTRL_C_LO_IO; buffer_config = compute_buffer(0, 0, s_dio1); buffer_config = compute_buffer(buffer_config, 1, s_dio2); if (s == s_dio1) - port_8255_cfg = dev->iobase + _8255_CR; + port_8255_cfg = dev->iobase + I8255_CTRL_REG; else - port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR; + port_8255_cfg = dev->iobase + I8255_SIZE + I8255_CTRL_REG; outb(buffer_config, dev->iobase + 8); /* update buffer register */ @@ -211,7 +199,7 @@ static int pcm3724_attach(struct comedi_device *dev, for (i = 0; i < dev->n_subdevices; i++) { s = &dev->subdevices[i]; - ret = subdev_8255_init(dev, s, NULL, i * SIZE_8255); + ret = subdev_8255_init(dev, s, NULL, i * I8255_SIZE); if (ret) return ret; s->insn_config = subdev_3724_insn_config; -- GitLab From 72267c27fd5780e70d6ec4e920f8e3e27cafcbb7 Mon Sep 17 00:00:00 2001 From: vibi sreenivasan Date: Tue, 12 Aug 2014 14:39:27 +0000 Subject: [PATCH 0673/9167] staging/mt29f_spinand: coding style fixes This patch fixes the coding style error : "WARNING: else is not generally useful after a break or return" reported by checkpatch.pl Signed-off-by: Vibi Sreenivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/mt29f_spinand/mt29f_spinand.c | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c index 3464e0c521e6..3628bcb840c3 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c @@ -252,15 +252,13 @@ static int spinand_enable_ecc(struct spi_device *spi_nand) if (retval < 0) return retval; - if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) { + if ((otp & OTP_ECC_MASK) == OTP_ECC_MASK) return 0; - } else { - otp |= OTP_ECC_MASK; - retval = spinand_set_otp(spi_nand, &otp); - if (retval < 0) - return retval; - return spinand_get_otp(spi_nand, &otp); - } + otp |= OTP_ECC_MASK; + retval = spinand_set_otp(spi_nand, &otp); + if (retval < 0) + return retval; + return spinand_get_otp(spi_nand, &otp); } #endif @@ -279,8 +277,8 @@ static int spinand_disable_ecc(struct spi_device *spi_nand) if (retval < 0) return retval; return spinand_get_otp(spi_nand, &otp); - } else - return 0; + } + return 0; } /** @@ -529,8 +527,8 @@ static int spinand_program_page(struct spi_device *spi_nand, dev_err(&spi_nand->dev, "program error, page %d\n", page_id); return -1; - } else - break; + } + break; } } #ifdef CONFIG_MTD_SPINAND_ONDIEECC @@ -605,8 +603,8 @@ static int spinand_erase_block(struct spi_device *spi_nand, u16 block_id) dev_err(&spi_nand->dev, "erase error, block %d\n", block_id); return -1; - } else - break; + } + break; } } return 0; -- GitLab From d41b7b74cfab08cf7a5c07fafac474af9dd51d9c Mon Sep 17 00:00:00 2001 From: Artemiy Volkov Date: Thu, 14 Aug 2014 16:20:09 +1000 Subject: [PATCH 0674/9167] Staging: wlan-ng: Merge string literals on adjacent lines in prism2fw.c This patch fixes the 'quoted string split across lines' checkpatch.pl warning in prism2fw.c. Signed-off-by: Artemiy Volkov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2fw.c | 60 +++++++++++++----------------- 1 file changed, 25 insertions(+), 35 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c index 3f5f7cc105f8..6c38f797d1ab 100644 --- a/drivers/staging/wlan-ng/prism2fw.c +++ b/drivers/staging/wlan-ng/prism2fw.c @@ -413,9 +413,7 @@ static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, break; } if (c >= nfchunks) { - pr_err("Failed to find chunk for " - "crcrec[%d], addr=0x%06x len=%d , " - "aborting crc.\n", + pr_err("Failed to find chunk for crcrec[%d], addr=0x%06x len=%d , aborting crc.\n", i, s3crc[i].addr, s3crc[i].len); return 1; } @@ -628,8 +626,8 @@ static int mkpdrlist(struct pda *pda) } if (curroff >= (HFA384x_PDA_LEN_MAX / 2)) { - pr_err("no end record found or invalid lengths in " - "PDR data, exiting. %x %d\n", curroff, pda->nrec); + pr_err("no end record found or invalid lengths in PDR data, exiting. %x %d\n", + curroff, pda->nrec); return 1; } if (le16_to_cpu(pda16[curroff + 1]) == HFA384x_PDR_END_OF_PDA) { @@ -685,8 +683,8 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, j = -1; } if (j >= pda->nrec && j != -1) { /* if no matching PDR, fail */ - pr_warn("warning: Failed to find PDR for " - "plugrec 0x%04x.\n", s3plug[i].itemcode); + pr_warn("warning: Failed to find PDR for plugrec 0x%04x.\n", + s3plug[i].itemcode); continue; /* and move on to the next PDR */ #if 0 /* MSM: They swear that unless it's the MAC address, @@ -703,8 +701,7 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, /* Validate plug len against PDR len */ if (j != -1 && s3plug[i].len < le16_to_cpu(pda->rec[j]->len)) { - pr_err("error: Plug vs. PDR len mismatch for " - "plugrec 0x%04x, abort plugging.\n", + pr_err("error: Plug vs. PDR len mismatch for plugrec 0x%04x, abort plugging.\n", s3plug[i].itemcode); result = 1; continue; @@ -718,8 +715,8 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, break; } if (c >= nfchunks) { - pr_err("error: Failed to find image chunk for " - "plugrec 0x%04x.\n", s3plug[i].itemcode); + pr_err("error: Failed to find image chunk for plugrec 0x%04x.\n", + s3plug[i].itemcode); result = 1; continue; } @@ -727,8 +724,7 @@ static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, /* Plug data */ chunkoff = pstart - cstart; dest = fchunk[c].data + chunkoff; - pr_debug("Plugging item 0x%04x @ 0x%06x, len=%d, " - "cnum=%d coff=0x%06x\n", + pr_debug("Plugging item 0x%04x @ 0x%06x, len=%d, cnum=%d coff=0x%06x\n", s3plug[i].itemcode, pstart, s3plug[i].len, c, chunkoff); @@ -881,8 +877,7 @@ static int read_fwfile(const struct ihex_binrec *record) switch (addr) { case S3ADDR_START: startaddr = *ptr32; - pr_debug(" S7 start addr, record=%d " - " addr=0x%08x\n", + pr_debug(" S7 start addr, record=%d addr=0x%08x\n", rcnt, startaddr); break; @@ -891,8 +886,7 @@ static int read_fwfile(const struct ihex_binrec *record) s3plug[ns3plug].addr = *(ptr32 + 1); s3plug[ns3plug].len = *(ptr32 + 2); - pr_debug(" S3 plugrec, record=%d " - "itemcode=0x%08x addr=0x%08x len=%d\n", + pr_debug(" S3 plugrec, record=%d itemcode=0x%08x addr=0x%08x len=%d\n", rcnt, s3plug[ns3plug].itemcode, s3plug[ns3plug].addr, @@ -909,8 +903,7 @@ static int read_fwfile(const struct ihex_binrec *record) s3crc[ns3crc].len = *(ptr32 + 1); s3crc[ns3crc].dowrite = *(ptr32 + 2); - pr_debug(" S3 crcrec, record=%d " - "addr=0x%08x len=%d write=0x%08x\n", + pr_debug(" S3 crcrec, record=%d addr=0x%08x len=%d write=0x%08x\n", rcnt, s3crc[ns3crc].addr, s3crc[ns3crc].len, @@ -925,8 +918,7 @@ static int read_fwfile(const struct ihex_binrec *record) s3info[ns3info].len = *ptr16; s3info[ns3info].type = *(ptr16 + 1); - pr_debug(" S3 inforec, record=%d " - "len=0x%04x type=0x%04x\n", + pr_debug(" S3 inforec, record=%d len=0x%04x type=0x%04x\n", rcnt, s3info[ns3info].len, s3info[ns3info].type); @@ -1000,8 +992,7 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, kfree(rstmsg); kfree(rwrmsg); netdev_err(wlandev->netdev, - "writeimage: no memory for firmware download, " - "aborting download\n"); + "writeimage: no memory for firmware download, aborting download\n"); return -ENOMEM; } @@ -1045,15 +1036,15 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { netdev_err(wlandev->netdev, - "writeimage state enable failed w/ result=%d, " - "aborting download\n", result); + "writeimage state enable failed w/ result=%d, aborting download\n", + result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { netdev_err(wlandev->netdev, - "writeimage()->xxxdl_state msg indicates failure, " - "w/ resultcode=%d, aborting download.\n", resultcode); + "writeimage()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", + resultcode); result = 1; goto free_result; } @@ -1089,14 +1080,13 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, /* Check the results */ if (result) { netdev_err(wlandev->netdev, - "writeimage chunk write failed w/ " - "result=%d, aborting download\n", result); + "writeimage chunk write failed w/ result=%d, aborting download\n", + result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { - pr_err("writeimage()->xxxdl_write msg indicates failure, " - "w/ resultcode=%d, aborting download.\n", + pr_err("writeimage()->xxxdl_write msg indicates failure, w/ resultcode=%d, aborting download.\n", resultcode); result = 1; goto free_result; @@ -1113,15 +1103,15 @@ static int writeimage(wlandevice_t *wlandev, struct imgchunk *fchunk, result = prism2mgmt_ramdl_state(wlandev, rstmsg); if (result) { netdev_err(wlandev->netdev, - "writeimage state disable failed w/ result=%d, " - "aborting download\n", result); + "writeimage state disable failed w/ result=%d, aborting download\n", + result); goto free_result; } resultcode = rstmsg->resultcode.data; if (resultcode != P80211ENUM_resultcode_success) { netdev_err(wlandev->netdev, - "writeimage()->xxxdl_state msg indicates failure, " - "w/ resultcode=%d, aborting download.\n", resultcode); + "writeimage()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", + resultcode); result = 1; goto free_result; } -- GitLab From 356649ab6d6412b256a2ff789e50ddbe5d78aaec Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 7 Aug 2014 16:38:02 +0900 Subject: [PATCH 0675/9167] ARM: dts: rockchip: unuse the slot-node and deprecate the supports-highspeed for dw-mmc dw-mmc controller can support multiple slots. But, there are no use-cases anywhere. So we don't need to support the slot-node for dw-mmc controller. And "supports-highspeed" property in dw-mmc is deprecated. "supports-highspeed" property can be replaced with "cap-sd/mmc-highspeed". Signed-off-by: Jaehoon Chung Reviewed-by: Tushar Behera Reviewed-by: Ulf Hansson Reviewed-by: Heiko Stuebner Acked-by: Seungwon Jeon Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3066a-bqcurie2.dts | 15 ++++----------- arch/arm/boot/dts/rk3188-radxarock.dts | 7 ++----- 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index 042f821d9e4d..665dd56f4f79 100644 --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts @@ -150,12 +150,8 @@ num-slots = <1>; status = "okay"; vmmc-supply = <&vcc_sd0>; - - slot@0 { - reg = <0>; - bus-width = <4>; - disable-wp; - }; + bus-width = <4>; + disable-wp; }; &mmc1 { /* wifi */ @@ -166,11 +162,8 @@ pinctrl-names = "default"; pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus4>; - slot@0 { - reg = <0>; - bus-width = <4>; - disable-wp; - }; + bus-width = <4>; + disable-wp; }; &uart0 { diff --git a/arch/arm/boot/dts/rk3188-radxarock.dts b/arch/arm/boot/dts/rk3188-radxarock.dts index 171b610db709..ef72faf9059a 100644 --- a/arch/arm/boot/dts/rk3188-radxarock.dts +++ b/arch/arm/boot/dts/rk3188-radxarock.dts @@ -181,11 +181,8 @@ status = "okay"; vmmc-supply = <&vcc_sd0>; - slot@0 { - reg = <0>; - bus-width = <4>; - disable-wp; - }; + bus-width = <4>; + disable-wp; }; &pinctrl { -- GitLab From 85095bf30f028f6dcb7d8177ab9b00425c11ca58 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Tue, 12 Aug 2014 16:21:13 -0700 Subject: [PATCH 0676/9167] ARM: dts: Add emmc and sdmmc to the rk3288 device tree This adds support for the sdmmc and emmc ports on the rk3288. Signed-off-by: Doug Anderson Acked-by: Arnd Bergmann Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288.dtsi | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 5950b0a53224..36be7bb55a01 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -78,6 +78,26 @@ clock-frequency = <24000000>; }; + sdmmc: dwmmc@ff0c0000 { + compatible = "rockchip,rk3288-dw-mshc"; + clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>; + clock-names = "biu", "ciu"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0xff0c0000 0x4000>; + status = "disabled"; + }; + + emmc: dwmmc@ff0f0000 { + compatible = "rockchip,rk3288-dw-mshc"; + clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>; + clock-names = "biu", "ciu"; + fifo-depth = <0x100>; + interrupts = ; + reg = <0xff0f0000 0x4000>; + status = "disabled"; + }; + i2c1: i2c@ff140000 { compatible = "rockchip,rk3288-i2c"; reg = <0xff140000 0x1000>; -- GitLab From 2c31d9498cb85dcf37806237870e8ccf4dbf84e0 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Tue, 12 Aug 2014 16:21:14 -0700 Subject: [PATCH 0677/9167] ARM: dts: Enable emmc and sdmmc on the rk3288-evb boards This enables basic SD and eMMC support. Things are not yet running at the fastest speed and we don't have the regulators specified, but we can at least use the eMMC and SD cards now. A note: * Though MMC DDR50 mode is partially supported in the dw_mmc rk3288-specific code in Addy's patch, Addy's patch doesn't add tuning support. That means DDR50 mode is not reliable. From the 3288 TRM: "Tuning is required for other speed modes-such as DDR50-even though the output delay from the card is less than one cycle." Thus, we don't enable MMC DDR50 mode in this patch. Signed-off-by: Doug Anderson Acked-by: Arnd Bergmann Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288-evb.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index 4f572093c8b4..ebce49a66a12 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -49,6 +49,30 @@ }; }; +&emmc { + broken-cd; + bus-width = <8>; + cap-mmc-highspeed; + disable-wp; + non-removable; + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + card-detect-delay = <200>; + disable-wp; /* wp not hooked up */ + num-slots = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>; + status = "okay"; +}; + &i2c0 { status = "okay"; }; -- GitLab From 91ff8cd8c3aae34a26b517506cc1ff809401a490 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Mon, 11 Aug 2014 11:47:29 -0700 Subject: [PATCH 0678/9167] ARM: dts: Move the PMIC interrupt pinctrl line to rk3288-evb common The PMIC interrupt pinctrl line was added to the rk3288-evb-act8846, but it's the same line on both the ACT8846 version and the RK808 version. This makes a lot of sense since they share the same SoC daugherboard. Move the pinctrl definition to the common file so we can use it for the RK808 version. NOTE: The PMIC interrupt doesn't _actually_ go to the PMIC on the ACT8846 version of the board (it does on the RK808), but our convention is to label things as they're labelled on the schematics. In the very least you can argue that this is the interrupt from the PMIC daughtercard even if it doesn't actually go to the PMIC chip. Signed-off-by: Doug Anderson Signed-off-by: Heiko Stuebner --- arch/arm/boot/dts/rk3288-evb-act8846.dts | 10 +--------- arch/arm/boot/dts/rk3288-evb.dtsi | 6 ++++++ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/rk3288-evb-act8846.dts b/arch/arm/boot/dts/rk3288-evb-act8846.dts index 7d59ff4de408..a76dd44adb53 100644 --- a/arch/arm/boot/dts/rk3288-evb-act8846.dts +++ b/arch/arm/boot/dts/rk3288-evb-act8846.dts @@ -26,7 +26,7 @@ interrupts = <4 IRQ_TYPE_EDGE_FALLING>; pinctrl-names = "default"; - pinctrl-0 = <&hym8563_int>; + pinctrl-0 = <&pmic_int>; #clock-cells = <0>; clock-output-names = "xin32k"; @@ -124,11 +124,3 @@ }; }; }; - -&pinctrl { - hym8563 { - hym8563_int: hym8563-int { - rockchip,pins = ; - }; - }; -}; diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi index ebce49a66a12..2964370aed90 100644 --- a/arch/arm/boot/dts/rk3288-evb.dtsi +++ b/arch/arm/boot/dts/rk3288-evb.dtsi @@ -108,6 +108,12 @@ }; }; + pmic { + pmic_int: pmic-int { + rockchip,pins = ; + }; + }; + usb { host_vbus_drv: host-vbus-drv { rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>; -- GitLab From 5cdeb2c837ddcf5b67692816952d0f38e29c2d7b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 16 Aug 2014 12:31:11 +0100 Subject: [PATCH 0679/9167] regulator: Restore L: linux-kernel@vger.kernel.org entry As with commit 981c3a4ff85 (MAINTAINERS: Restore "L: linux-kernel@vger.kernel.org" entries) restore the mailing list entry for the regulator framework in order to assist users in finding the list if they read the file instead of using get_maintainers.pl. Signed-off-by: Mark Brown --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index aefa94841ff3..c42f647a5fe9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9827,6 +9827,7 @@ F: drivers/scsi/vmw_pvscsi.h VOLTAGE AND CURRENT REGULATOR FRAMEWORK M: Liam Girdwood M: Mark Brown +L: linux-kernel@vger.kernel.org W: http://opensource.wolfsonmicro.com/node/15 W: http://www.slimlogic.co.uk/?p=48 T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git -- GitLab From 005547e0828ce9064afebb1e6d56a18efd80e7a3 Mon Sep 17 00:00:00 2001 From: James Ban Date: Fri, 8 Aug 2014 14:27:04 +0900 Subject: [PATCH 0680/9167] regulator: da9211: support DA9213 This is a patch for supporting DA9213. Signed-off-by: James Ban Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 9 +-- drivers/regulator/da9211-regulator.c | 95 ++++++++++++++++++++++------ drivers/regulator/da9211-regulator.h | 7 +- include/linux/regulator/da9211.h | 7 +- 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc8289e5dba..1344aa83b438 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -199,13 +199,14 @@ config REGULATOR_DA9210 interface. config REGULATOR_DA9211 - tristate "Dialog Semiconductor DA9211/DA9212 regulator" + tristate "Dialog Semiconductor DA9211/DA9212/DA9213/DA9214 regulator" depends on I2C select REGMAP_I2C help - Say y here to support for the Dialog Semiconductor DA9211/DA9212. - The DA9211/DA9212 is a multi-phase synchronous step down - converter 12A DC-DC Buck controlled through an I2C + Say y here to support for the Dialog Semiconductor DA9211/DA9212 + /DA9213/DA9214. + The DA9211/DA9212/DA9213/DA9214 is a multi-phase synchronous + step down converter 12A or 16A DC-DC Buck controlled through an I2C interface. config REGULATOR_DBX500_PRCMU diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index 1482adafa1ad..ccc2e362d751 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -1,5 +1,5 @@ /* - * da9211-regulator.c - Regulator device driver for DA9211 + * da9211-regulator.c - Regulator device driver for DA9211/DA9213 * Copyright (C) 2014 Dialog Semiconductor Ltd. * * This library is free software; you can redistribute it and/or @@ -27,6 +27,10 @@ #include #include "da9211-regulator.h" +/* DEVICE IDs */ +#define DA9211_DEVICE_ID 0x22 +#define DA9213_DEVICE_ID 0x23 + #define DA9211_BUCK_MODE_SLEEP 1 #define DA9211_BUCK_MODE_SYNC 2 #define DA9211_BUCK_MODE_AUTO 3 @@ -42,6 +46,7 @@ struct da9211 { struct regulator_dev *rdev[DA9211_MAX_REGULATORS]; int num_regulator; int chip_irq; + int chip_id; }; static const struct regmap_range_cfg da9211_regmap_range[] = { @@ -52,14 +57,14 @@ static const struct regmap_range_cfg da9211_regmap_range[] = { .window_start = 0, .window_len = 256, .range_min = 0, - .range_max = 2*256, + .range_max = 5*128, }, }; static const struct regmap_config da9211_regmap_config = { .reg_bits = 8, .val_bits = 8, - .max_register = 2 * 256, + .max_register = 5 * 128, .ranges = da9211_regmap_range, .num_ranges = ARRAY_SIZE(da9211_regmap_range), }; @@ -69,11 +74,20 @@ static const struct regmap_config da9211_regmap_config = { #define DA9211_MAX_MV 1570 #define DA9211_STEP_MV 10 -/* Current limits for buck (uA) indices corresponds with register values */ +/* Current limits for DA9211 buck (uA) indices + * corresponds with register values + */ static const int da9211_current_limits[] = { 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000 }; +/* Current limits for DA9213 buck (uA) indices + * corresponds with register values + */ +static const int da9213_current_limits[] = { + 3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000, + 4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000 +}; static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev) { @@ -129,12 +143,26 @@ static int da9211_set_current_limit(struct regulator_dev *rdev, int min, { int id = rdev_get_id(rdev); struct da9211 *chip = rdev_get_drvdata(rdev); - int i; + int i, max_size; + const int *current_limits; + + switch (chip->chip_id) { + case DA9211: + current_limits = da9211_current_limits; + max_size = ARRAY_SIZE(da9211_current_limits)-1; + break; + case DA9213: + current_limits = da9213_current_limits; + max_size = ARRAY_SIZE(da9213_current_limits)-1; + break; + default: + return -EINVAL; + } /* search for closest to maximum */ - for (i = ARRAY_SIZE(da9211_current_limits)-1; i >= 0; i--) { - if (min <= da9211_current_limits[i] && - max >= da9211_current_limits[i]) { + for (i = max_size; i >= 0; i--) { + if (min <= current_limits[i] && + max >= current_limits[i]) { return regmap_update_bits(chip->regmap, DA9211_REG_BUCK_ILIM, (0x0F << id*4), (i << id*4)); @@ -150,14 +178,28 @@ static int da9211_get_current_limit(struct regulator_dev *rdev) struct da9211 *chip = rdev_get_drvdata(rdev); unsigned int data; int ret; + const int *current_limits; + + switch (chip->chip_id) { + case DA9211: + current_limits = da9211_current_limits; + break; + case DA9213: + current_limits = da9213_current_limits; + break; + default: + return -EINVAL; + } ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data); if (ret < 0) return ret; - /* select one of 16 values: 0000 (2000mA) to 1111 (5000mA) */ + /* select one of 16 values: 0000 (2000mA or 3000mA) + * to 1111 (5000mA or 6000mA). + */ data = (data >> id*4) & 0x0F; - return da9211_current_limits[data]; + return current_limits[data]; } static struct regulator_ops da9211_buck_ops = { @@ -264,10 +306,7 @@ static int da9211_regulator_init(struct da9211 *chip) } for (i = 0; i < chip->num_regulator; i++) { - if (chip->pdata) - config.init_data = - &(chip->pdata->init_data[i]); - + config.init_data = &(chip->pdata->init_data[i]); config.dev = chip->dev; config.driver_data = chip; config.regmap = chip->regmap; @@ -301,6 +340,7 @@ static int da9211_i2c_probe(struct i2c_client *i2c, { struct da9211 *chip; int error, ret; + unsigned int data; chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL); @@ -308,7 +348,7 @@ static int da9211_i2c_probe(struct i2c_client *i2c, chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config); if (IS_ERR(chip->regmap)) { error = PTR_ERR(chip->regmap); - dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + dev_err(chip->dev, "Failed to allocate register map: %d\n", error); return error; } @@ -316,8 +356,22 @@ static int da9211_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, chip); chip->pdata = i2c->dev.platform_data; - if (!chip->pdata) { - dev_err(&i2c->dev, "No platform init data supplied\n"); + + ret = regmap_read(chip->regmap, DA9211_REG_DEVICE_ID, &data); + if (ret < 0) { + dev_err(chip->dev, "Failed to read DEVICE_ID reg: %d\n", ret); + return ret; + } + + switch (data) { + case DA9211_DEVICE_ID: + chip->chip_id = DA9211; + break; + case DA9213_DEVICE_ID: + chip->chip_id = DA9213; + break; + default: + dev_err(chip->dev, "Unsupported device id = 0x%x.\n", data); return -ENODEV; } @@ -340,13 +394,14 @@ static int da9211_i2c_probe(struct i2c_client *i2c, ret = da9211_regulator_init(chip); if (ret < 0) - dev_err(&i2c->dev, "Failed to initialize regulator: %d\n", ret); + dev_err(chip->dev, "Failed to initialize regulator: %d\n", ret); return ret; } static const struct i2c_device_id da9211_i2c_id[] = { - {"da9211", 0}, + {"da9211", DA9211}, + {"da9213", DA9213}, {}, }; @@ -364,5 +419,5 @@ static struct i2c_driver da9211_regulator_driver = { module_i2c_driver(da9211_regulator_driver); MODULE_AUTHOR("James Ban "); -MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211"); +MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211/DA9213"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h index 88b1769e8058..93fa9df2721c 100644 --- a/drivers/regulator/da9211-regulator.h +++ b/drivers/regulator/da9211-regulator.h @@ -1,5 +1,5 @@ /* - * da9211-regulator.h - Regulator definitions for DA9211 + * da9211-regulator.h - Regulator definitions for DA9211/DA9213 * Copyright (C) 2014 Dialog Semiconductor Ltd. * * This library is free software; you can redistribute it and/or @@ -53,12 +53,15 @@ /* BUCK Phase Selection*/ #define DA9211_REG_CONFIG_E 0x147 +/* Device ID */ +#define DA9211_REG_DEVICE_ID 0x201 + /* * Registers bits */ /* DA9211_REG_PAGE_CON (addr=0x00) */ #define DA9211_REG_PAGE_SHIFT 1 -#define DA9211_REG_PAGE_MASK 0x02 +#define DA9211_REG_PAGE_MASK 0x06 /* On I2C registers 0x00 - 0xFF */ #define DA9211_REG_PAGE0 0 /* On I2C registers 0x100 - 0x1FF */ diff --git a/include/linux/regulator/da9211.h b/include/linux/regulator/da9211.h index 0981ce0e72cc..658c3c33f4c0 100644 --- a/include/linux/regulator/da9211.h +++ b/include/linux/regulator/da9211.h @@ -1,5 +1,5 @@ /* - * da9211.h - Regulator device driver for DA9211 + * da9211.h - Regulator device driver for DA9211/DA9213 * Copyright (C) 2014 Dialog Semiconductor Ltd. * * This library is free software; you can redistribute it and/or @@ -20,6 +20,11 @@ #define DA9211_MAX_REGULATORS 2 +enum da9211_chip_id { + DA9211, + DA9213, +}; + struct da9211_pdata { /* * Number of buck -- GitLab From 0e4f417857083f399769491f6e7773d111debd0f Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Tue, 15 Jul 2014 16:32:51 +0530 Subject: [PATCH 0681/9167] regulator: s2mpxxx: Move regulator min/step voltages in common place This is a cleanup patch and moves min/step voltages in a common samsung header file so that they can be used by other s2mpxxx PMIC drivers. Only few required macros are added currently and others can be added if needed. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Amit Daniel Kachhap Acked-by: Lee Jones Signed-off-by: Mark Brown --- drivers/regulator/s2mpa01.c | 32 +++++++++--------- drivers/regulator/s2mps11.c | 50 ++++++++++++++--------------- include/linux/mfd/samsung/core.h | 21 ++++++++++++ include/linux/mfd/samsung/s2mpa01.h | 12 ------- include/linux/mfd/samsung/s2mps11.h | 9 ------ include/linux/mfd/samsung/s2mps14.h | 10 ------ 6 files changed, 62 insertions(+), 72 deletions(-) diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index ee83b4876420..962c5f192f7c 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -241,8 +241,8 @@ static struct regulator_ops s2mpa01_buck_ops = { .ops = &s2mpa01_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPA01_LDO_MIN, \ - .uV_step = S2MPA01_LDO_STEP1, \ + .min_uV = MIN_800_MV, \ + .uV_step = STEP_50_MV, \ .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ @@ -255,8 +255,8 @@ static struct regulator_ops s2mpa01_buck_ops = { .ops = &s2mpa01_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPA01_LDO_MIN, \ - .uV_step = S2MPA01_LDO_STEP2, \ + .min_uV = MIN_800_MV, \ + .uV_step = STEP_25_MV, \ .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ @@ -270,8 +270,8 @@ static struct regulator_ops s2mpa01_buck_ops = { .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPA01_BUCK_MIN1, \ - .uV_step = S2MPA01_BUCK_STEP1, \ + .min_uV = MIN_600_MV, \ + .uV_step = STEP_6_25_MV, \ .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPA01_RAMP_DELAY, \ .vsel_reg = S2MPA01_REG_B1CTRL2 + (num - 1) * 2, \ @@ -286,8 +286,8 @@ static struct regulator_ops s2mpa01_buck_ops = { .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPA01_BUCK_MIN2, \ - .uV_step = S2MPA01_BUCK_STEP1, \ + .min_uV = MIN_800_MV, \ + .uV_step = STEP_6_25_MV, \ .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPA01_RAMP_DELAY, \ .vsel_reg = S2MPA01_REG_B5CTRL2, \ @@ -302,8 +302,8 @@ static struct regulator_ops s2mpa01_buck_ops = { .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPA01_BUCK_MIN1, \ - .uV_step = S2MPA01_BUCK_STEP1, \ + .min_uV = MIN_600_MV, \ + .uV_step = STEP_6_25_MV, \ .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPA01_RAMP_DELAY, \ .vsel_reg = S2MPA01_REG_B6CTRL2 + (num - 6) * 2, \ @@ -318,8 +318,8 @@ static struct regulator_ops s2mpa01_buck_ops = { .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPA01_BUCK_MIN2, \ - .uV_step = S2MPA01_BUCK_STEP2, \ + .min_uV = MIN_800_MV, \ + .uV_step = STEP_12_5_MV, \ .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPA01_RAMP_DELAY, \ .vsel_reg = S2MPA01_REG_B8CTRL2, \ @@ -334,8 +334,8 @@ static struct regulator_ops s2mpa01_buck_ops = { .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPA01_BUCK_MIN4, \ - .uV_step = S2MPA01_BUCK_STEP2, \ + .min_uV = MIN_1500_MV, \ + .uV_step = STEP_12_5_MV, \ .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPA01_RAMP_DELAY, \ .vsel_reg = S2MPA01_REG_B9CTRL2, \ @@ -350,8 +350,8 @@ static struct regulator_ops s2mpa01_buck_ops = { .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPA01_BUCK_MIN3, \ - .uV_step = S2MPA01_BUCK_STEP2, \ + .min_uV = MIN_1000_MV, \ + .uV_step = STEP_12_5_MV, \ .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPA01_RAMP_DELAY, \ .vsel_reg = S2MPA01_REG_B10CTRL2, \ diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index b16c53a8272f..3dede776a837 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -255,14 +255,14 @@ static struct regulator_ops s2mps11_buck_ops = { .set_ramp_delay = s2mps11_set_ramp_delay, }; -#define regulator_desc_s2mps11_ldo1(num) { \ +#define regulator_desc_s2mps11_ldo1(num) { \ .name = "LDO"#num, \ .id = S2MPS11_LDO##num, \ .ops = &s2mps11_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS11_LDO_MIN, \ - .uV_step = S2MPS11_LDO_STEP1, \ + .min_uV = MIN_800_MV, \ + .uV_step = STEP_50_MV, \ .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ @@ -275,8 +275,8 @@ static struct regulator_ops s2mps11_buck_ops = { .ops = &s2mps11_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS11_LDO_MIN, \ - .uV_step = S2MPS11_LDO_STEP2, \ + .min_uV = MIN_800_MV, \ + .uV_step = STEP_25_MV, \ .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ @@ -290,8 +290,8 @@ static struct regulator_ops s2mps11_buck_ops = { .ops = &s2mps11_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN1, \ - .uV_step = S2MPS11_BUCK_STEP1, \ + .min_uV = MIN_600_MV, \ + .uV_step = STEP_6_25_MV, \ .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPS11_RAMP_DELAY, \ .vsel_reg = S2MPS11_REG_B1CTRL2 + (num - 1) * 2, \ @@ -306,8 +306,8 @@ static struct regulator_ops s2mps11_buck_ops = { .ops = &s2mps11_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN1, \ - .uV_step = S2MPS11_BUCK_STEP1, \ + .min_uV = MIN_600_MV, \ + .uV_step = STEP_6_25_MV, \ .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPS11_RAMP_DELAY, \ .vsel_reg = S2MPS11_REG_B5CTRL2, \ @@ -322,8 +322,8 @@ static struct regulator_ops s2mps11_buck_ops = { .ops = &s2mps11_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN1, \ - .uV_step = S2MPS11_BUCK_STEP1, \ + .min_uV = MIN_600_MV, \ + .uV_step = STEP_6_25_MV, \ .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPS11_RAMP_DELAY, \ .vsel_reg = S2MPS11_REG_B6CTRL2 + (num - 6) * 2, \ @@ -338,8 +338,8 @@ static struct regulator_ops s2mps11_buck_ops = { .ops = &s2mps11_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN3, \ - .uV_step = S2MPS11_BUCK_STEP3, \ + .min_uV = MIN_3000_MV, \ + .uV_step = STEP_25_MV, \ .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPS11_RAMP_DELAY, \ .vsel_reg = S2MPS11_REG_B9CTRL2, \ @@ -354,8 +354,8 @@ static struct regulator_ops s2mps11_buck_ops = { .ops = &s2mps11_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS11_BUCK_MIN2, \ - .uV_step = S2MPS11_BUCK_STEP2, \ + .min_uV = MIN_750_MV, \ + .uV_step = STEP_12_5_MV, \ .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPS11_RAMP_DELAY, \ .vsel_reg = S2MPS11_REG_B10CTRL2, \ @@ -516,8 +516,8 @@ static struct regulator_ops s2mps14_reg_ops = { .ops = &s2mps14_reg_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS14_LDO_MIN_800MV, \ - .uV_step = S2MPS14_LDO_STEP_25MV, \ + .min_uV = MIN_800_MV, \ + .uV_step = STEP_25_MV, \ .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ @@ -530,8 +530,8 @@ static struct regulator_ops s2mps14_reg_ops = { .ops = &s2mps14_reg_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS14_LDO_MIN_1800MV, \ - .uV_step = S2MPS14_LDO_STEP_25MV, \ + .min_uV = MIN_1800_MV, \ + .uV_step = STEP_25_MV, \ .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ @@ -544,8 +544,8 @@ static struct regulator_ops s2mps14_reg_ops = { .ops = &s2mps14_reg_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS14_LDO_MIN_800MV, \ - .uV_step = S2MPS14_LDO_STEP_12_5MV, \ + .min_uV = MIN_800_MV, \ + .uV_step = STEP_12_5_MV, \ .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ @@ -558,8 +558,8 @@ static struct regulator_ops s2mps14_reg_ops = { .ops = &s2mps14_reg_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS14_BUCK1235_MIN_600MV, \ - .uV_step = S2MPS14_BUCK1235_STEP_6_25MV, \ + .min_uV = MIN_600_MV, \ + .uV_step = STEP_6_25_MV, \ .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ @@ -574,8 +574,8 @@ static struct regulator_ops s2mps14_reg_ops = { .ops = &s2mps14_reg_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = S2MPS14_BUCK4_MIN_1400MV, \ - .uV_step = S2MPS14_BUCK4_STEP_12_5MV, \ + .min_uV = MIN_1400_MV, \ + .uV_step = STEP_12_5_MV, \ .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ .linear_min_sel = S2MPS14_BUCK4_START_SEL, \ .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ diff --git a/include/linux/mfd/samsung/core.h b/include/linux/mfd/samsung/core.h index b5f73de81aad..1825edacbda7 100644 --- a/include/linux/mfd/samsung/core.h +++ b/include/linux/mfd/samsung/core.h @@ -14,6 +14,27 @@ #ifndef __LINUX_MFD_SEC_CORE_H #define __LINUX_MFD_SEC_CORE_H +/* Macros to represent minimum voltages for LDO/BUCK */ +#define MIN_3000_MV 3000000 +#define MIN_2500_MV 2500000 +#define MIN_2000_MV 2000000 +#define MIN_1800_MV 1800000 +#define MIN_1500_MV 1500000 +#define MIN_1400_MV 1400000 +#define MIN_1000_MV 1000000 + +#define MIN_900_MV 900000 +#define MIN_850_MV 850000 +#define MIN_800_MV 800000 +#define MIN_750_MV 750000 +#define MIN_600_MV 600000 + +/* Macros to represent steps for LDO/BUCK */ +#define STEP_50_MV 50000 +#define STEP_25_MV 25000 +#define STEP_12_5_MV 12500 +#define STEP_6_25_MV 6250 + enum sec_device_type { S5M8751X, S5M8763X, diff --git a/include/linux/mfd/samsung/s2mpa01.h b/include/linux/mfd/samsung/s2mpa01.h index fbc63bc0d6a2..2766108bca2f 100644 --- a/include/linux/mfd/samsung/s2mpa01.h +++ b/include/linux/mfd/samsung/s2mpa01.h @@ -155,18 +155,6 @@ enum s2mpa01_regulators { S2MPA01_REGULATOR_MAX, }; -#define S2MPA01_BUCK_MIN1 600000 -#define S2MPA01_BUCK_MIN2 800000 -#define S2MPA01_BUCK_MIN3 1000000 -#define S2MPA01_BUCK_MIN4 1500000 -#define S2MPA01_LDO_MIN 800000 - -#define S2MPA01_BUCK_STEP1 6250 -#define S2MPA01_BUCK_STEP2 12500 - -#define S2MPA01_LDO_STEP1 50000 -#define S2MPA01_LDO_STEP2 25000 - #define S2MPA01_LDO_VSEL_MASK 0x3F #define S2MPA01_BUCK_VSEL_MASK 0xFF #define S2MPA01_ENABLE_MASK (0x03 << S2MPA01_ENABLE_SHIFT) diff --git a/include/linux/mfd/samsung/s2mps11.h b/include/linux/mfd/samsung/s2mps11.h index b3ddf98dec37..7981a9d77d3f 100644 --- a/include/linux/mfd/samsung/s2mps11.h +++ b/include/linux/mfd/samsung/s2mps11.h @@ -171,15 +171,6 @@ enum s2mps11_regulators { S2MPS11_REGULATOR_MAX, }; -#define S2MPS11_BUCK_MIN1 600000 -#define S2MPS11_BUCK_MIN2 750000 -#define S2MPS11_BUCK_MIN3 3000000 -#define S2MPS11_LDO_MIN 800000 -#define S2MPS11_BUCK_STEP1 6250 -#define S2MPS11_BUCK_STEP2 12500 -#define S2MPS11_BUCK_STEP3 25000 -#define S2MPS11_LDO_STEP1 50000 -#define S2MPS11_LDO_STEP2 25000 #define S2MPS11_LDO_VSEL_MASK 0x3F #define S2MPS11_BUCK_VSEL_MASK 0xFF #define S2MPS11_ENABLE_MASK (0x03 << S2MPS11_ENABLE_SHIFT) diff --git a/include/linux/mfd/samsung/s2mps14.h b/include/linux/mfd/samsung/s2mps14.h index 900cd7a04314..c92f4782afb5 100644 --- a/include/linux/mfd/samsung/s2mps14.h +++ b/include/linux/mfd/samsung/s2mps14.h @@ -123,10 +123,6 @@ enum s2mps14_regulators { }; /* Regulator constraints for BUCKx */ -#define S2MPS14_BUCK1235_MIN_600MV 600000 -#define S2MPS14_BUCK4_MIN_1400MV 1400000 -#define S2MPS14_BUCK1235_STEP_6_25MV 6250 -#define S2MPS14_BUCK4_STEP_12_5MV 12500 #define S2MPS14_BUCK1235_START_SEL 0x20 #define S2MPS14_BUCK4_START_SEL 0x40 /* @@ -136,12 +132,6 @@ enum s2mps14_regulators { */ #define S2MPS14_BUCK_RAMP_DELAY 12500 -/* Regulator constraints for different types of LDOx */ -#define S2MPS14_LDO_MIN_800MV 800000 -#define S2MPS14_LDO_MIN_1800MV 1800000 -#define S2MPS14_LDO_STEP_12_5MV 12500 -#define S2MPS14_LDO_STEP_25MV 25000 - #define S2MPS14_LDO_VSEL_MASK 0x3F #define S2MPS14_BUCK_VSEL_MASK 0xFF #define S2MPS14_ENABLE_MASK (0x03 << S2MPS14_ENABLE_SHIFT) -- GitLab From d264fd4541753bf3fe2613805b3cab95b54a3f32 Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Tue, 15 Jul 2014 16:32:52 +0530 Subject: [PATCH 0682/9167] regulator: s2mpa01: Optimize the regulator description macro This patch makes the regulator description macro take minimum and steps voltage as parameter. In this way many repeated macros can be removed. Now these macros are repeated only if the the LDO/BUCK ctrl registers have non-linear positions. The good thing is these ctrl registers are mostly linear so they are not passed as parameters. This patch reduces the code size and also allow easy addition of more s2mpxxx PMIC drivers which differs a lot in minimum/step voltages. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Amit Daniel Kachhap Signed-off-by: Mark Brown --- drivers/regulator/s2mpa01.c | 134 ++++++++++-------------------------- 1 file changed, 36 insertions(+), 98 deletions(-) diff --git a/drivers/regulator/s2mpa01.c b/drivers/regulator/s2mpa01.c index 962c5f192f7c..4acefa6b462e 100644 --- a/drivers/regulator/s2mpa01.c +++ b/drivers/regulator/s2mpa01.c @@ -235,28 +235,14 @@ static struct regulator_ops s2mpa01_buck_ops = { .set_ramp_delay = s2mpa01_set_ramp_delay, }; -#define regulator_desc_ldo1(num) { \ +#define regulator_desc_ldo(num, step) { \ .name = "LDO"#num, \ .id = S2MPA01_LDO##num, \ .ops = &s2mpa01_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ .min_uV = MIN_800_MV, \ - .uV_step = STEP_50_MV, \ - .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ - .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ - .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ - .enable_reg = S2MPA01_REG_L1CTRL + num - 1, \ - .enable_mask = S2MPA01_ENABLE_MASK \ -} -#define regulator_desc_ldo2(num) { \ - .name = "LDO"#num, \ - .id = S2MPA01_LDO##num, \ - .ops = &s2mpa01_ldo_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_800_MV, \ - .uV_step = STEP_25_MV, \ + .uV_step = step, \ .n_voltages = S2MPA01_LDO_N_VOLTAGES, \ .vsel_reg = S2MPA01_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPA01_LDO_VSEL_MASK, \ @@ -296,14 +282,14 @@ static struct regulator_ops s2mpa01_buck_ops = { .enable_mask = S2MPA01_ENABLE_MASK \ } -#define regulator_desc_buck6_7(num) { \ +#define regulator_desc_buck6_10(num, min, step) { \ .name = "BUCK"#num, \ .id = S2MPA01_BUCK##num, \ .ops = &s2mpa01_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = MIN_600_MV, \ - .uV_step = STEP_6_25_MV, \ + .min_uV = min, \ + .uV_step = step, \ .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPA01_RAMP_DELAY, \ .vsel_reg = S2MPA01_REG_B6CTRL2 + (num - 6) * 2, \ @@ -312,91 +298,43 @@ static struct regulator_ops s2mpa01_buck_ops = { .enable_mask = S2MPA01_ENABLE_MASK \ } -#define regulator_desc_buck8 { \ - .name = "BUCK8", \ - .id = S2MPA01_BUCK8, \ - .ops = &s2mpa01_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_800_MV, \ - .uV_step = STEP_12_5_MV, \ - .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ - .ramp_delay = S2MPA01_RAMP_DELAY, \ - .vsel_reg = S2MPA01_REG_B8CTRL2, \ - .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ - .enable_reg = S2MPA01_REG_B8CTRL1, \ - .enable_mask = S2MPA01_ENABLE_MASK \ -} - -#define regulator_desc_buck9 { \ - .name = "BUCK9", \ - .id = S2MPA01_BUCK9, \ - .ops = &s2mpa01_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_1500_MV, \ - .uV_step = STEP_12_5_MV, \ - .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ - .ramp_delay = S2MPA01_RAMP_DELAY, \ - .vsel_reg = S2MPA01_REG_B9CTRL2, \ - .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ - .enable_reg = S2MPA01_REG_B9CTRL1, \ - .enable_mask = S2MPA01_ENABLE_MASK \ -} - -#define regulator_desc_buck10 { \ - .name = "BUCK10", \ - .id = S2MPA01_BUCK10, \ - .ops = &s2mpa01_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_1000_MV, \ - .uV_step = STEP_12_5_MV, \ - .n_voltages = S2MPA01_BUCK_N_VOLTAGES, \ - .ramp_delay = S2MPA01_RAMP_DELAY, \ - .vsel_reg = S2MPA01_REG_B10CTRL2, \ - .vsel_mask = S2MPA01_BUCK_VSEL_MASK, \ - .enable_reg = S2MPA01_REG_B10CTRL1, \ - .enable_mask = S2MPA01_ENABLE_MASK \ -} - static struct regulator_desc regulators[] = { - regulator_desc_ldo2(1), - regulator_desc_ldo1(2), - regulator_desc_ldo1(3), - regulator_desc_ldo1(4), - regulator_desc_ldo1(5), - regulator_desc_ldo2(6), - regulator_desc_ldo1(7), - regulator_desc_ldo1(8), - regulator_desc_ldo1(9), - regulator_desc_ldo1(10), - regulator_desc_ldo2(11), - regulator_desc_ldo1(12), - regulator_desc_ldo1(13), - regulator_desc_ldo1(14), - regulator_desc_ldo1(15), - regulator_desc_ldo1(16), - regulator_desc_ldo1(17), - regulator_desc_ldo1(18), - regulator_desc_ldo1(19), - regulator_desc_ldo1(20), - regulator_desc_ldo1(21), - regulator_desc_ldo2(22), - regulator_desc_ldo2(23), - regulator_desc_ldo1(24), - regulator_desc_ldo1(25), - regulator_desc_ldo1(26), + regulator_desc_ldo(1, STEP_25_MV), + regulator_desc_ldo(2, STEP_50_MV), + regulator_desc_ldo(3, STEP_50_MV), + regulator_desc_ldo(4, STEP_50_MV), + regulator_desc_ldo(5, STEP_50_MV), + regulator_desc_ldo(6, STEP_25_MV), + regulator_desc_ldo(7, STEP_50_MV), + regulator_desc_ldo(8, STEP_50_MV), + regulator_desc_ldo(9, STEP_50_MV), + regulator_desc_ldo(10, STEP_50_MV), + regulator_desc_ldo(11, STEP_25_MV), + regulator_desc_ldo(12, STEP_50_MV), + regulator_desc_ldo(13, STEP_50_MV), + regulator_desc_ldo(14, STEP_50_MV), + regulator_desc_ldo(15, STEP_50_MV), + regulator_desc_ldo(16, STEP_50_MV), + regulator_desc_ldo(17, STEP_50_MV), + regulator_desc_ldo(18, STEP_50_MV), + regulator_desc_ldo(19, STEP_50_MV), + regulator_desc_ldo(20, STEP_50_MV), + regulator_desc_ldo(21, STEP_50_MV), + regulator_desc_ldo(22, STEP_25_MV), + regulator_desc_ldo(23, STEP_25_MV), + regulator_desc_ldo(24, STEP_50_MV), + regulator_desc_ldo(25, STEP_50_MV), + regulator_desc_ldo(26, STEP_50_MV), regulator_desc_buck1_4(1), regulator_desc_buck1_4(2), regulator_desc_buck1_4(3), regulator_desc_buck1_4(4), regulator_desc_buck5, - regulator_desc_buck6_7(6), - regulator_desc_buck6_7(7), - regulator_desc_buck8, - regulator_desc_buck9, - regulator_desc_buck10, + regulator_desc_buck6_10(6, MIN_600_MV, STEP_6_25_MV), + regulator_desc_buck6_10(7, MIN_600_MV, STEP_6_25_MV), + regulator_desc_buck6_10(8, MIN_800_MV, STEP_12_5_MV), + regulator_desc_buck6_10(9, MIN_1500_MV, STEP_12_5_MV), + regulator_desc_buck6_10(10, MIN_1000_MV, STEP_12_5_MV), }; static int s2mpa01_pmic_probe(struct platform_device *pdev) -- GitLab From 5a867cf288934c26f3034ace189bda25700c68fa Mon Sep 17 00:00:00 2001 From: Amit Daniel Kachhap Date: Tue, 15 Jul 2014 16:32:53 +0530 Subject: [PATCH 0683/9167] regulator: s2mps11: Optimize the regulator description macro This patch makes the regulator description macro take minimum and steps voltage as parameter. In this way many repeated macros can be removed. Now these macros are repeated only if the the LDO/BUCK ctrl registers have non-linear positions. The good thing is these ctrl registers are mostly linear so they are not passed as parameters. This patch reduces the code size and also allow easy addition of more s2mpxxx PMIC drivers which differs a lot in minimum/step voltages. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Amit Daniel Kachhap Signed-off-by: Mark Brown --- drivers/regulator/s2mps11.c | 259 ++++++++++++------------------------ 1 file changed, 85 insertions(+), 174 deletions(-) diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 3dede776a837..adab82d5279f 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -255,28 +255,14 @@ static struct regulator_ops s2mps11_buck_ops = { .set_ramp_delay = s2mps11_set_ramp_delay, }; -#define regulator_desc_s2mps11_ldo1(num) { \ +#define regulator_desc_s2mps11_ldo(num, step) { \ .name = "LDO"#num, \ .id = S2MPS11_LDO##num, \ .ops = &s2mps11_ldo_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ .min_uV = MIN_800_MV, \ - .uV_step = STEP_50_MV, \ - .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ - .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ - .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_L1CTRL + num - 1, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} -#define regulator_desc_s2mps11_ldo2(num) { \ - .name = "LDO"#num, \ - .id = S2MPS11_LDO##num, \ - .ops = &s2mps11_ldo_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_800_MV, \ - .uV_step = STEP_25_MV, \ + .uV_step = step, \ .n_voltages = S2MPS11_LDO_N_VOLTAGES, \ .vsel_reg = S2MPS11_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPS11_LDO_VSEL_MASK, \ @@ -316,14 +302,14 @@ static struct regulator_ops s2mps11_buck_ops = { .enable_mask = S2MPS11_ENABLE_MASK \ } -#define regulator_desc_s2mps11_buck6_8(num) { \ +#define regulator_desc_s2mps11_buck6_10(num, min, step) { \ .name = "BUCK"#num, \ .id = S2MPS11_BUCK##num, \ .ops = &s2mps11_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = MIN_600_MV, \ - .uV_step = STEP_6_25_MV, \ + .min_uV = min, \ + .uV_step = step, \ .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ .ramp_delay = S2MPS11_RAMP_DELAY, \ .vsel_reg = S2MPS11_REG_B6CTRL2 + (num - 6) * 2, \ @@ -332,87 +318,55 @@ static struct regulator_ops s2mps11_buck_ops = { .enable_mask = S2MPS11_ENABLE_MASK \ } -#define regulator_desc_s2mps11_buck9 { \ - .name = "BUCK9", \ - .id = S2MPS11_BUCK9, \ - .ops = &s2mps11_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_3000_MV, \ - .uV_step = STEP_25_MV, \ - .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ - .ramp_delay = S2MPS11_RAMP_DELAY, \ - .vsel_reg = S2MPS11_REG_B9CTRL2, \ - .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_B9CTRL1, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} - -#define regulator_desc_s2mps11_buck10 { \ - .name = "BUCK10", \ - .id = S2MPS11_BUCK10, \ - .ops = &s2mps11_buck_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_750_MV, \ - .uV_step = STEP_12_5_MV, \ - .n_voltages = S2MPS11_BUCK_N_VOLTAGES, \ - .ramp_delay = S2MPS11_RAMP_DELAY, \ - .vsel_reg = S2MPS11_REG_B10CTRL2, \ - .vsel_mask = S2MPS11_BUCK_VSEL_MASK, \ - .enable_reg = S2MPS11_REG_B10CTRL1, \ - .enable_mask = S2MPS11_ENABLE_MASK \ -} - static const struct regulator_desc s2mps11_regulators[] = { - regulator_desc_s2mps11_ldo2(1), - regulator_desc_s2mps11_ldo1(2), - regulator_desc_s2mps11_ldo1(3), - regulator_desc_s2mps11_ldo1(4), - regulator_desc_s2mps11_ldo1(5), - regulator_desc_s2mps11_ldo2(6), - regulator_desc_s2mps11_ldo1(7), - regulator_desc_s2mps11_ldo1(8), - regulator_desc_s2mps11_ldo1(9), - regulator_desc_s2mps11_ldo1(10), - regulator_desc_s2mps11_ldo2(11), - regulator_desc_s2mps11_ldo1(12), - regulator_desc_s2mps11_ldo1(13), - regulator_desc_s2mps11_ldo1(14), - regulator_desc_s2mps11_ldo1(15), - regulator_desc_s2mps11_ldo1(16), - regulator_desc_s2mps11_ldo1(17), - regulator_desc_s2mps11_ldo1(18), - regulator_desc_s2mps11_ldo1(19), - regulator_desc_s2mps11_ldo1(20), - regulator_desc_s2mps11_ldo1(21), - regulator_desc_s2mps11_ldo2(22), - regulator_desc_s2mps11_ldo2(23), - regulator_desc_s2mps11_ldo1(24), - regulator_desc_s2mps11_ldo1(25), - regulator_desc_s2mps11_ldo1(26), - regulator_desc_s2mps11_ldo2(27), - regulator_desc_s2mps11_ldo1(28), - regulator_desc_s2mps11_ldo1(29), - regulator_desc_s2mps11_ldo1(30), - regulator_desc_s2mps11_ldo1(31), - regulator_desc_s2mps11_ldo1(32), - regulator_desc_s2mps11_ldo1(33), - regulator_desc_s2mps11_ldo1(34), - regulator_desc_s2mps11_ldo1(35), - regulator_desc_s2mps11_ldo1(36), - regulator_desc_s2mps11_ldo1(37), - regulator_desc_s2mps11_ldo1(38), + regulator_desc_s2mps11_ldo(1, STEP_25_MV), + regulator_desc_s2mps11_ldo(2, STEP_50_MV), + regulator_desc_s2mps11_ldo(3, STEP_50_MV), + regulator_desc_s2mps11_ldo(4, STEP_50_MV), + regulator_desc_s2mps11_ldo(5, STEP_50_MV), + regulator_desc_s2mps11_ldo(6, STEP_25_MV), + regulator_desc_s2mps11_ldo(7, STEP_50_MV), + regulator_desc_s2mps11_ldo(8, STEP_50_MV), + regulator_desc_s2mps11_ldo(9, STEP_50_MV), + regulator_desc_s2mps11_ldo(10, STEP_50_MV), + regulator_desc_s2mps11_ldo(11, STEP_25_MV), + regulator_desc_s2mps11_ldo(12, STEP_50_MV), + regulator_desc_s2mps11_ldo(13, STEP_50_MV), + regulator_desc_s2mps11_ldo(14, STEP_50_MV), + regulator_desc_s2mps11_ldo(15, STEP_50_MV), + regulator_desc_s2mps11_ldo(16, STEP_50_MV), + regulator_desc_s2mps11_ldo(17, STEP_50_MV), + regulator_desc_s2mps11_ldo(18, STEP_50_MV), + regulator_desc_s2mps11_ldo(19, STEP_50_MV), + regulator_desc_s2mps11_ldo(20, STEP_50_MV), + regulator_desc_s2mps11_ldo(21, STEP_50_MV), + regulator_desc_s2mps11_ldo(22, STEP_25_MV), + regulator_desc_s2mps11_ldo(23, STEP_25_MV), + regulator_desc_s2mps11_ldo(24, STEP_50_MV), + regulator_desc_s2mps11_ldo(25, STEP_50_MV), + regulator_desc_s2mps11_ldo(26, STEP_50_MV), + regulator_desc_s2mps11_ldo(27, STEP_25_MV), + regulator_desc_s2mps11_ldo(28, STEP_50_MV), + regulator_desc_s2mps11_ldo(29, STEP_50_MV), + regulator_desc_s2mps11_ldo(30, STEP_50_MV), + regulator_desc_s2mps11_ldo(31, STEP_50_MV), + regulator_desc_s2mps11_ldo(32, STEP_50_MV), + regulator_desc_s2mps11_ldo(33, STEP_50_MV), + regulator_desc_s2mps11_ldo(34, STEP_50_MV), + regulator_desc_s2mps11_ldo(35, STEP_50_MV), + regulator_desc_s2mps11_ldo(36, STEP_50_MV), + regulator_desc_s2mps11_ldo(37, STEP_50_MV), + regulator_desc_s2mps11_ldo(38, STEP_50_MV), regulator_desc_s2mps11_buck1_4(1), regulator_desc_s2mps11_buck1_4(2), regulator_desc_s2mps11_buck1_4(3), regulator_desc_s2mps11_buck1_4(4), regulator_desc_s2mps11_buck5, - regulator_desc_s2mps11_buck6_8(6), - regulator_desc_s2mps11_buck6_8(7), - regulator_desc_s2mps11_buck6_8(8), - regulator_desc_s2mps11_buck9, - regulator_desc_s2mps11_buck10, + regulator_desc_s2mps11_buck6_10(6, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps11_buck6_10(7, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps11_buck6_10(8, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps11_buck6_10(9, MIN_3000_MV, STEP_25_MV), + regulator_desc_s2mps11_buck6_10(10, MIN_750_MV, STEP_12_5_MV), }; static int s2mps14_regulator_enable(struct regulator_dev *rdev) @@ -510,56 +464,29 @@ static struct regulator_ops s2mps14_reg_ops = { .set_suspend_disable = s2mps14_regulator_set_suspend_disable, }; -#define regulator_desc_s2mps14_ldo1(num) { \ +#define regulator_desc_s2mps14_ldo(num, min, step) { \ .name = "LDO"#num, \ .id = S2MPS14_LDO##num, \ .ops = &s2mps14_reg_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = MIN_800_MV, \ - .uV_step = STEP_25_MV, \ + .min_uV = min, \ + .uV_step = step, \ .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ .enable_mask = S2MPS14_ENABLE_MASK \ } -#define regulator_desc_s2mps14_ldo2(num) { \ - .name = "LDO"#num, \ - .id = S2MPS14_LDO##num, \ - .ops = &s2mps14_reg_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_1800_MV, \ - .uV_step = STEP_25_MV, \ - .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ - .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ - .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ - .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ - .enable_mask = S2MPS14_ENABLE_MASK \ -} -#define regulator_desc_s2mps14_ldo3(num) { \ - .name = "LDO"#num, \ - .id = S2MPS14_LDO##num, \ - .ops = &s2mps14_reg_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_800_MV, \ - .uV_step = STEP_12_5_MV, \ - .n_voltages = S2MPS14_LDO_N_VOLTAGES, \ - .vsel_reg = S2MPS14_REG_L1CTRL + num - 1, \ - .vsel_mask = S2MPS14_LDO_VSEL_MASK, \ - .enable_reg = S2MPS14_REG_L1CTRL + num - 1, \ - .enable_mask = S2MPS14_ENABLE_MASK \ -} -#define regulator_desc_s2mps14_buck1235(num) { \ + +#define regulator_desc_s2mps14_buck(num, min, step) { \ .name = "BUCK"#num, \ .id = S2MPS14_BUCK##num, \ .ops = &s2mps14_reg_ops, \ .type = REGULATOR_VOLTAGE, \ .owner = THIS_MODULE, \ - .min_uV = MIN_600_MV, \ - .uV_step = STEP_6_25_MV, \ + .min_uV = min, \ + .uV_step = step, \ .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ .linear_min_sel = S2MPS14_BUCK1235_START_SEL, \ .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ @@ -568,54 +495,38 @@ static struct regulator_ops s2mps14_reg_ops = { .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ .enable_mask = S2MPS14_ENABLE_MASK \ } -#define regulator_desc_s2mps14_buck4(num) { \ - .name = "BUCK"#num, \ - .id = S2MPS14_BUCK##num, \ - .ops = &s2mps14_reg_ops, \ - .type = REGULATOR_VOLTAGE, \ - .owner = THIS_MODULE, \ - .min_uV = MIN_1400_MV, \ - .uV_step = STEP_12_5_MV, \ - .n_voltages = S2MPS14_BUCK_N_VOLTAGES, \ - .linear_min_sel = S2MPS14_BUCK4_START_SEL, \ - .ramp_delay = S2MPS14_BUCK_RAMP_DELAY, \ - .vsel_reg = S2MPS14_REG_B1CTRL2 + (num - 1) * 2, \ - .vsel_mask = S2MPS14_BUCK_VSEL_MASK, \ - .enable_reg = S2MPS14_REG_B1CTRL1 + (num - 1) * 2, \ - .enable_mask = S2MPS14_ENABLE_MASK \ -} static const struct regulator_desc s2mps14_regulators[] = { - regulator_desc_s2mps14_ldo3(1), - regulator_desc_s2mps14_ldo3(2), - regulator_desc_s2mps14_ldo1(3), - regulator_desc_s2mps14_ldo1(4), - regulator_desc_s2mps14_ldo3(5), - regulator_desc_s2mps14_ldo3(6), - regulator_desc_s2mps14_ldo1(7), - regulator_desc_s2mps14_ldo2(8), - regulator_desc_s2mps14_ldo3(9), - regulator_desc_s2mps14_ldo3(10), - regulator_desc_s2mps14_ldo1(11), - regulator_desc_s2mps14_ldo2(12), - regulator_desc_s2mps14_ldo2(13), - regulator_desc_s2mps14_ldo2(14), - regulator_desc_s2mps14_ldo2(15), - regulator_desc_s2mps14_ldo2(16), - regulator_desc_s2mps14_ldo2(17), - regulator_desc_s2mps14_ldo2(18), - regulator_desc_s2mps14_ldo1(19), - regulator_desc_s2mps14_ldo1(20), - regulator_desc_s2mps14_ldo1(21), - regulator_desc_s2mps14_ldo3(22), - regulator_desc_s2mps14_ldo1(23), - regulator_desc_s2mps14_ldo2(24), - regulator_desc_s2mps14_ldo2(25), - regulator_desc_s2mps14_buck1235(1), - regulator_desc_s2mps14_buck1235(2), - regulator_desc_s2mps14_buck1235(3), - regulator_desc_s2mps14_buck4(4), - regulator_desc_s2mps14_buck1235(5), + regulator_desc_s2mps14_ldo(1, MIN_800_MV, STEP_12_5_MV), + regulator_desc_s2mps14_ldo(2, MIN_800_MV, STEP_12_5_MV), + regulator_desc_s2mps14_ldo(3, MIN_800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(4, MIN_800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(5, MIN_800_MV, STEP_12_5_MV), + regulator_desc_s2mps14_ldo(6, MIN_800_MV, STEP_12_5_MV), + regulator_desc_s2mps14_ldo(7, MIN_800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(8, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(9, MIN_800_MV, STEP_12_5_MV), + regulator_desc_s2mps14_ldo(10, MIN_800_MV, STEP_12_5_MV), + regulator_desc_s2mps14_ldo(11, MIN_800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(12, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(13, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(14, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(15, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(16, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(17, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(18, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(19, MIN_800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(20, MIN_800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(21, MIN_800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(22, MIN_800_MV, STEP_12_5_MV), + regulator_desc_s2mps14_ldo(23, MIN_800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(24, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_ldo(25, MIN_1800_MV, STEP_25_MV), + regulator_desc_s2mps14_buck(1, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps14_buck(2, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps14_buck(3, MIN_600_MV, STEP_6_25_MV), + regulator_desc_s2mps14_buck(4, MIN_1400_MV, STEP_12_5_MV), + regulator_desc_s2mps14_buck(5, MIN_600_MV, STEP_6_25_MV), }; static int s2mps14_pmic_enable_ext_control(struct s2mps11_info *s2mps11, -- GitLab From 9839d627c2a2c74facde9a9ee949f2ba0a1363b1 Mon Sep 17 00:00:00 2001 From: Gyungoh Yoo Date: Fri, 8 Aug 2014 18:10:22 +0900 Subject: [PATCH 0684/9167] regulator: sky81452: Adding Skyworks SKY81452 regulator driver Signed-off-by: Gyungoh Yoo Signed-off-by: Mark Brown --- .../bindings/regulator/sky81452-regulator.txt | 16 +++ drivers/regulator/Kconfig | 11 ++ drivers/regulator/Makefile | 1 + drivers/regulator/sky81452-regulator.c | 130 ++++++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/sky81452-regulator.txt create mode 100644 drivers/regulator/sky81452-regulator.c diff --git a/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt b/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt new file mode 100644 index 000000000000..882455e9b36d --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/sky81452-regulator.txt @@ -0,0 +1,16 @@ +SKY81452 voltage regulator + +Required properties: +- any required generic properties defined in regulator.txt + +Optional properties: +- any available generic properties defined in regulator.txt + +Example: + + regulator { + /* generic regulator properties */ + regulator-name = "touch_en"; + regulator-min-microvolt = <4500000>; + regulator-max-microvolt = <8000000>; + }; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc8289e5dba..f6bf208f0fca 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -483,6 +483,17 @@ config REGULATOR_S5M8767 via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and supports DVS mode with 8bits of output voltage control. +config REGULATOR_SKY81452 + tristate "Skyworks Solutions SKY81452 voltage regulator" + depends on SKY81452 + help + This driver supports Skyworks SKY81452 voltage output regulator + via I2C bus. SKY81452 has one voltage linear regulator can be + programmed from 4.5V to 20V. + + This driver can also be built as a module. If so, the module + will be called sky81452-regulator. + config REGULATOR_ST_PWM tristate "STMicroelectronics PWM voltage regulator" depends on ARCH_STI diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index aa4a6aa7b558..d8206ec63d15 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o +obj-$(CONFIG_REGULATOR_SKY81452) += sky81452-regulator.o obj-$(CONFIG_REGULATOR_ST_PWM) += st-pwm.o obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o diff --git a/drivers/regulator/sky81452-regulator.c b/drivers/regulator/sky81452-regulator.c new file mode 100644 index 000000000000..97aff0ccd65f --- /dev/null +++ b/drivers/regulator/sky81452-regulator.c @@ -0,0 +1,130 @@ +/* + * sky81452-regulator.c SKY81452 regulator driver + * + * Copyright 2014 Skyworks Solutions Inc. + * Author : Gyungoh Yoo + * + * 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; 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 + +/* registers */ +#define SKY81452_REG1 0x01 +#define SKY81452_REG3 0x03 + +/* bit mask */ +#define SKY81452_LEN 0x40 +#define SKY81452_LOUT 0x1F + +static struct regulator_ops sky81452_reg_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +static const struct regulator_linear_range sky81452_reg_ranges[] = { + REGULATOR_LINEAR_RANGE(4500000, 0, 14, 250000), + REGULATOR_LINEAR_RANGE(9000000, 15, 31, 1000000), +}; + +static const struct regulator_desc sky81452_reg = { + .name = "LOUT", + .ops = &sky81452_reg_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .n_voltages = SKY81452_LOUT + 1, + .linear_ranges = sky81452_reg_ranges, + .n_linear_ranges = ARRAY_SIZE(sky81452_reg_ranges), + .vsel_reg = SKY81452_REG3, + .vsel_mask = SKY81452_LOUT, + .enable_reg = SKY81452_REG1, + .enable_mask = SKY81452_LEN, +}; + +#ifdef CONFIG_OF +static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev) +{ + struct regulator_init_data *init_data; + struct device_node *np; + + np = of_get_child_by_name(dev->parent->of_node, "regulator"); + if (unlikely(!np)) { + dev_err(dev, "regulator node not found"); + return NULL; + } + + init_data = of_get_regulator_init_data(dev, np); + + of_node_put(np); + return init_data; +} +#else +static struct regulator_init_data *sky81452_reg_parse_dt(struct device *dev) +{ + return ERR_PTR(-EINVAL); +} +#endif + +static int sky81452_reg_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct regulator_init_data *init_data = dev_get_platdata(dev); + struct regulator_config config = { }; + struct regulator_dev *rdev; + + if (!init_data) { + init_data = sky81452_reg_parse_dt(dev); + if (IS_ERR(init_data)) + return PTR_ERR(init_data); + } + + config.dev = dev; + config.init_data = init_data; + config.of_node = dev->of_node; + config.regmap = dev_get_drvdata(dev->parent); + + rdev = devm_regulator_register(dev, &sky81452_reg, &config); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); + + platform_set_drvdata(pdev, rdev); + + return 0; +} + +static struct platform_driver sky81452_reg_driver = { + .driver = { + .name = "sky81452-regulator", + }, + .probe = sky81452_reg_probe, +}; + +module_platform_driver(sky81452_reg_driver); + +MODULE_DESCRIPTION("Skyworks SKY81452 Regulator driver"); +MODULE_AUTHOR("Gyungoh Yoo "); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0"); -- GitLab From 23b1134838efdb5872be7b75e86fae41e60ba629 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 18 Feb 2014 21:11:48 +0800 Subject: [PATCH 0685/9167] regulator: tps65910: Allow missing init_data for diagnostics The regulator core supports this to allow the configuration to be inspected at runtime even if no software management is enabled. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index fa7db8847578..20645070b779 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -1047,7 +1047,7 @@ static struct tps65910_board *tps65910_parse_dt_reg_data( *tps65910_reg_matches = matches; for (idx = 0; idx < count; idx++) { - if (!matches[idx].init_data || !matches[idx].of_node) + if (!matches[idx].of_node) continue; pmic_plat_data->tps65910_pmic_init_data[idx] = @@ -1077,7 +1077,6 @@ static int tps65910_probe(struct platform_device *pdev) struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; struct tps_info *info; - struct regulator_init_data *reg_data; struct regulator_dev *rdev; struct tps65910_reg *pmic; struct tps65910_board *pmic_plat_data; @@ -1140,14 +1139,6 @@ static int tps65910_probe(struct platform_device *pdev) for (i = 0; i < pmic->num_regulators && i < TPS65910_NUM_REGS; i++, info++) { - - reg_data = pmic_plat_data->tps65910_pmic_init_data[i]; - - /* Regulator API handles empty constraints but not NULL - * constraints */ - if (!reg_data) - continue; - /* Register the regulators */ pmic->info[i] = info; @@ -1199,7 +1190,7 @@ static int tps65910_probe(struct platform_device *pdev) pmic->desc[i].enable_mask = TPS65910_SUPPLY_STATE_ENABLED; config.dev = tps65910->dev; - config.init_data = reg_data; + config.init_data = pmic_plat_data->tps65910_pmic_init_data[i]; config.driver_data = pmic; config.regmap = tps65910->regmap; -- GitLab From 272e2315fac3bfca0edfa3252b8a643c425602af Mon Sep 17 00:00:00 2001 From: Guodong Xu Date: Wed, 13 Aug 2014 19:33:38 +0800 Subject: [PATCH 0686/9167] regulator: core: add const qualifier to ops in struct regulator_desc struct regulator_ops *ops is a member in struct regulator_desc, which gets its value from individual regulator driver upon regulator_register() and is used by regulator core APIs. It's not allowed for regulator core to modify any of these callbacks in *ops. Add 'const' qualifier to enforce that. Signed-off-by: Guodong Xu Signed-off-by: Mark Brown --- drivers/regulator/core.c | 24 ++++++++++++------------ include/linux/regulator/driver.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index a3c3785901f5..052e7f1f011d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -839,7 +839,7 @@ static void print_constraints(struct regulator_dev *rdev) static int machine_constraints_voltage(struct regulator_dev *rdev, struct regulation_constraints *constraints) { - struct regulator_ops *ops = rdev->desc->ops; + const struct regulator_ops *ops = rdev->desc->ops; int ret; /* do we need to apply the constraint voltage */ @@ -938,7 +938,7 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, static int machine_constraints_current(struct regulator_dev *rdev, struct regulation_constraints *constraints) { - struct regulator_ops *ops = rdev->desc->ops; + const struct regulator_ops *ops = rdev->desc->ops; int ret; if (!constraints->min_uA && !constraints->max_uA) @@ -982,7 +982,7 @@ static int set_machine_constraints(struct regulator_dev *rdev, const struct regulation_constraints *constraints) { int ret = 0; - struct regulator_ops *ops = rdev->desc->ops; + const struct regulator_ops *ops = rdev->desc->ops; if (constraints) rdev->constraints = kmemdup(constraints, sizeof(*constraints), @@ -2208,9 +2208,9 @@ EXPORT_SYMBOL_GPL(regulator_count_voltages); */ int regulator_list_voltage(struct regulator *regulator, unsigned selector) { - struct regulator_dev *rdev = regulator->rdev; - struct regulator_ops *ops = rdev->desc->ops; - int ret; + struct regulator_dev *rdev = regulator->rdev; + const struct regulator_ops *ops = rdev->desc->ops; + int ret; if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector) return rdev->desc->fixed_uV; @@ -2572,8 +2572,8 @@ EXPORT_SYMBOL_GPL(regulator_set_voltage); int regulator_set_voltage_time(struct regulator *regulator, int old_uV, int new_uV) { - struct regulator_dev *rdev = regulator->rdev; - struct regulator_ops *ops = rdev->desc->ops; + struct regulator_dev *rdev = regulator->rdev; + const struct regulator_ops *ops = rdev->desc->ops; int old_sel = -1; int new_sel = -1; int voltage; @@ -3336,9 +3336,9 @@ EXPORT_SYMBOL_GPL(regulator_mode_to_status); */ static int add_regulator_attributes(struct regulator_dev *rdev) { - struct device *dev = &rdev->dev; - struct regulator_ops *ops = rdev->desc->ops; - int status = 0; + struct device *dev = &rdev->dev; + const struct regulator_ops *ops = rdev->desc->ops; + int status = 0; /* some attributes need specific methods to be displayed */ if ((ops->get_voltage && ops->get_voltage(rdev) >= 0) || @@ -3905,7 +3905,7 @@ core_initcall(regulator_init); static int __init regulator_init_complete(void) { struct regulator_dev *rdev; - struct regulator_ops *ops; + const struct regulator_ops *ops; struct regulation_constraints *c; int enabled, ret; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index bbe03a1924c0..4b628139a9cb 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -245,7 +245,7 @@ struct regulator_desc { int id; bool continuous_voltage_range; unsigned n_voltages; - struct regulator_ops *ops; + const struct regulator_ops *ops; int irq; enum regulator_type type; struct module *owner; -- GitLab From 79fd114161a764dfa456191af89358b3f5201c87 Mon Sep 17 00:00:00 2001 From: Guodong Xu Date: Wed, 13 Aug 2014 19:33:39 +0800 Subject: [PATCH 0687/9167] regulator: core: factor out delay function from _regulator_do_enable A common delay function can be helpful when implementing new features. Factor it out to maximize code reusability. Signed-off-by: Guodong Xu Signed-off-by: Mark Brown --- drivers/regulator/core.c | 74 ++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 052e7f1f011d..dc0e9813b62d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1759,6 +1759,45 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) return 0; } +/** + * _regulator_enable_delay - a delay helper function + * @delay: time to delay in microseconds + * + * Delay for the requested amount of time as per the guidelines in: + * + * Documentation/timers/timers-howto.txt + * + * The assumption here is that regulators will never be enabled in + * atomic context and therefore sleeping functions can be used. + */ +static void _regulator_enable_delay(unsigned int delay) +{ + unsigned int ms = delay / 1000; + unsigned int us = delay % 1000; + + if (ms > 0) { + /* + * For small enough values, handle super-millisecond + * delays in the usleep_range() call below. + */ + if (ms < 20) + us += ms * 1000; + else + msleep(ms); + } + + /* + * Give the scheduler some room to coalesce with any other + * wakeup sources. For delays shorter than 10 us, don't even + * bother setting up high-resolution timers and just busy- + * loop. + */ + if (us >= 10) + usleep_range(us, us + 100); + else + udelay(us); +} + static int _regulator_do_enable(struct regulator_dev *rdev) { int ret, delay; @@ -1792,40 +1831,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) * together. */ trace_regulator_enable_delay(rdev_get_name(rdev)); - /* - * Delay for the requested amount of time as per the guidelines in: - * - * Documentation/timers/timers-howto.txt - * - * The assumption here is that regulators will never be enabled in - * atomic context and therefore sleeping functions can be used. - */ - if (delay) { - unsigned int ms = delay / 1000; - unsigned int us = delay % 1000; - - if (ms > 0) { - /* - * For small enough values, handle super-millisecond - * delays in the usleep_range() call below. - */ - if (ms < 20) - us += ms * 1000; - else - msleep(ms); - } - - /* - * Give the scheduler some room to coalesce with any other - * wakeup sources. For delays shorter than 10 us, don't even - * bother setting up high-resolution timers and just busy- - * loop. - */ - if (us >= 10) - usleep_range(us, us + 100); - else - udelay(us); - } + _regulator_enable_delay(delay); trace_regulator_enable_complete(rdev_get_name(rdev)); -- GitLab From 871f565055ed232e5751da18a331b73e8254adaf Mon Sep 17 00:00:00 2001 From: Guodong Xu Date: Wed, 13 Aug 2014 19:33:40 +0800 Subject: [PATCH 0688/9167] regulator: core: add guard delay between calling regulator_disable and _enable Some regulator require a minimum delay between its disable and next enable. This is to avoid damages when out-of-range frequent disable/enable of a single regulator can bring to the regulator chip. Add @off_on_delay to struct regulator_desc. Device drivers' can use this field to set this guard time. Add @last_off_jiffy to struct regulator_dev. When @off_on_delay is set by driver, regulator core can store its last off (disable) time into this field. Signed-off-by: Guodong Xu Signed-off-by: Mark Brown --- drivers/regulator/core.c | 31 +++++++++++++++++++++++++++++++ include/linux/regulator/driver.h | 6 ++++++ 2 files changed, 37 insertions(+) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index dc0e9813b62d..1e976b6320a2 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1813,6 +1813,31 @@ static int _regulator_do_enable(struct regulator_dev *rdev) trace_regulator_enable(rdev_get_name(rdev)); + if (rdev->desc->off_on_delay) { + /* if needed, keep a distance of off_on_delay from last time + * this regulator was disabled. + */ + unsigned long start_jiffy = jiffies; + unsigned long intended, max_delay, remaining; + + max_delay = usecs_to_jiffies(rdev->desc->off_on_delay); + intended = rdev->last_off_jiffy + max_delay; + + if (time_before(start_jiffy, intended)) { + /* calc remaining jiffies to deal with one-time + * timer wrapping. + * in case of multiple timer wrapping, either it can be + * detected by out-of-range remaining, or it cannot be + * detected and we gets a panelty of + * _regulator_enable_delay(). + */ + remaining = intended - start_jiffy; + if (remaining <= max_delay) + _regulator_enable_delay( + jiffies_to_usecs(remaining)); + } + } + if (rdev->ena_pin) { ret = regulator_ena_gpio_ctrl(rdev, true); if (ret < 0) @@ -1925,6 +1950,12 @@ static int _regulator_do_disable(struct regulator_dev *rdev) return ret; } + /* cares about last_off_jiffy only if off_on_delay is required by + * device. + */ + if (rdev->desc->off_on_delay) + rdev->last_off_jiffy = jiffies; + trace_regulator_disable_complete(rdev_get_name(rdev)); return 0; diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 4b628139a9cb..efe058f8f746 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -238,6 +238,7 @@ enum regulator_type { * @bypass_val_off: Disabling value for control when using regmap set_bypass * * @enable_time: Time taken for initial enable of regulator (in uS). + * @off_on_delay: guard time (in uS), before re-enabling a regulator */ struct regulator_desc { const char *name; @@ -276,6 +277,8 @@ struct regulator_desc { unsigned int bypass_val_off; unsigned int enable_time; + + unsigned int off_on_delay; }; /** @@ -348,6 +351,9 @@ struct regulator_dev { struct regulator_enable_gpio *ena_pin; unsigned int ena_gpio_state:1; + + /* time when this regulator was disabled last time */ + unsigned long last_off_jiffy; }; struct regulator_dev * -- GitLab From d647c199510c2c126ac03ecbea51086e10126a40 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Tue, 15 Jul 2014 12:23:02 +0800 Subject: [PATCH 0689/9167] regmap: add DT endianness binding support. For many drivers which will support rich endianness of Devices need define DT properties by itself with the binding support. The endianness using regmap: Index Device Properties if needs bytes-swap, or just ignore it ------------------------------------------------------------- 1 BE 'big-endian' 2 LE 'little-endian' The properties include all the register values and the buffers. And these properties are very usful for the MMIO devices: Such as: a memory-mapped device, on one SoC is in BE mode, while in another SoC will be in LE mode, and the CPU will always in LE mode. For the first case, we must use cpu_to_be32/be32_to_cpu for 32-bit registers accessing, so the 'big-endian' property is needed. For the second case, we can just ignore the bytes-swap functions like cpu_to_le32/le32_to_cpu, so the 'little-endian' property could be abscent. And vice versa... Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-i2c.c | 2 + drivers/base/regmap/regmap-spi.c | 2 + drivers/base/regmap/regmap.c | 117 ++++++++++++++++++++++++++++--- 3 files changed, 110 insertions(+), 11 deletions(-) diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index ca193d1ef47c..053150a7f9f2 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c @@ -168,6 +168,8 @@ static struct regmap_bus regmap_i2c = { .write = regmap_i2c_write, .gather_write = regmap_i2c_gather_write, .read = regmap_i2c_read, + .reg_format_endian_default = REGMAP_ENDIAN_BIG, + .val_format_endian_default = REGMAP_ENDIAN_BIG, }; static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c, diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 0eb3097c0d76..53d1148e80a0 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -109,6 +109,8 @@ static struct regmap_bus regmap_spi = { .async_alloc = regmap_spi_async_alloc, .read = regmap_spi_read, .read_flag_mask = 0x80, + .reg_format_endian_default = REGMAP_ENDIAN_BIG, + .val_format_endian_default = REGMAP_ENDIAN_BIG, }; /** diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 78f43fb2fe84..e4e567e82b84 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -448,6 +449,102 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, } EXPORT_SYMBOL_GPL(regmap_attach_dev); +enum regmap_endian_type { + REGMAP_ENDIAN_REG, + REGMAP_ENDIAN_VAL, +}; + +static int of_regmap_get_endian(struct device *dev, + const struct regmap_bus *bus, + const struct regmap_config *config, + enum regmap_endian_type type, + enum regmap_endian *endian) +{ + struct device_node *np = dev->of_node; + + if (!endian || !config) + return -EINVAL; + + /* + * Firstly, try to parse the endianness from driver's config, + * this is to be compatible with the none DT or the old drivers. + * From the driver's config the endianness value maybe: + * REGMAP_ENDIAN_BIG, + * REGMAP_ENDIAN_LITTLE, + * REGMAP_ENDIAN_NATIVE, + * REGMAP_ENDIAN_DEFAULT. + */ + switch (type) { + case REGMAP_ENDIAN_REG: + *endian = config->reg_format_endian; + break; + case REGMAP_ENDIAN_VAL: + *endian = config->val_format_endian; + break; + default: + return -EINVAL; + } + + /* + * If the endianness parsed from driver config is + * REGMAP_ENDIAN_DEFAULT, that means maybe we are using the DT + * node to specify the endianness information. + */ + if (*endian != REGMAP_ENDIAN_DEFAULT) + return 0; + + /* + * Secondly, try to parse the endianness from DT node if the + * driver config does not specify it. + * From the DT node the endianness value maybe: + * REGMAP_ENDIAN_BIG, + * REGMAP_ENDIAN_LITTLE, + * REGMAP_ENDIAN_NATIVE, + */ + switch (type) { + case REGMAP_ENDIAN_VAL: + if (of_property_read_bool(np, "big-endian")) + *endian = REGMAP_ENDIAN_BIG; + else if (of_property_read_bool(np, "little-endian")) + *endian = REGMAP_ENDIAN_LITTLE; + else + *endian = REGMAP_ENDIAN_NATIVE; + break; + case REGMAP_ENDIAN_REG: + break; + default: + return -EINVAL; + } + + /* + * If the endianness parsed from DT node is REGMAP_ENDIAN_NATIVE, that + * maybe means the DT does not care the endianness or it should use + * the regmap bus's default endianness, then we should try to check + * whether the regmap bus has specified the default endianness. + */ + if (*endian != REGMAP_ENDIAN_NATIVE) + return 0; + + /* + * Finally, try to parse the endianness from regmap bus config + * if in device's DT node the endianness property is absent. + */ + switch (type) { + case REGMAP_ENDIAN_REG: + if (bus && bus->reg_format_endian_default) + *endian = bus->reg_format_endian_default; + break; + case REGMAP_ENDIAN_VAL: + if (bus && bus->val_format_endian_default) + *endian = bus->val_format_endian_default; + break; + default: + return -EINVAL; + } + + return 0; +} + /** * regmap_init(): Initialise register map * @@ -551,17 +648,15 @@ struct regmap *regmap_init(struct device *dev, map->reg_read = _regmap_bus_read; } - reg_endian = config->reg_format_endian; - if (reg_endian == REGMAP_ENDIAN_DEFAULT) - reg_endian = bus->reg_format_endian_default; - if (reg_endian == REGMAP_ENDIAN_DEFAULT) - reg_endian = REGMAP_ENDIAN_BIG; - - val_endian = config->val_format_endian; - if (val_endian == REGMAP_ENDIAN_DEFAULT) - val_endian = bus->val_format_endian_default; - if (val_endian == REGMAP_ENDIAN_DEFAULT) - val_endian = REGMAP_ENDIAN_BIG; + ret = of_regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_REG, + ®_endian); + if (ret) + return ERR_PTR(ret); + + ret = of_regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_VAL, + &val_endian); + if (ret) + return ERR_PTR(ret); switch (config->reg_bits + map->reg_shift) { case 2: -- GitLab From 275876e208e28abf4b96ec89030e482b1331ee75 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Tue, 15 Jul 2014 12:23:03 +0800 Subject: [PATCH 0690/9167] regmap: Add the DT binding documentation for endianness Device-Tree binding for device endianness Index Device Endianness properties --------------------------------------------------- 1 BE 'big-endian' 2 LE 'little-endian' For one device driver, which will run in different scenarios above on different SoCs using the devicetree, we need one way to simplify this. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- .../devicetree/bindings/regmap/regmap.txt | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/regmap/regmap.txt diff --git a/Documentation/devicetree/bindings/regmap/regmap.txt b/Documentation/devicetree/bindings/regmap/regmap.txt new file mode 100644 index 000000000000..b494f8b8ef72 --- /dev/null +++ b/Documentation/devicetree/bindings/regmap/regmap.txt @@ -0,0 +1,47 @@ +Device-Tree binding for regmap + +The endianness mode of CPU & Device scenarios: +Index Device Endianness properties +--------------------------------------------------- +1 BE 'big-endian' +2 LE 'little-endian' + +For one device driver, which will run in different scenarios above +on different SoCs using the devicetree, we need one way to simplify +this. + +Required properties: +- {big,little}-endian: these are boolean properties, if absent + meaning that the CPU and the Device are in the same endianness mode, + these properties are for register values and all the buffers only. + +Examples: +Scenario 1 : CPU in LE mode & device in LE mode. +dev: dev@40031000 { + compatible = "name"; + reg = <0x40031000 0x1000>; + ... +}; + +Scenario 2 : CPU in LE mode & device in BE mode. +dev: dev@40031000 { + compatible = "name"; + reg = <0x40031000 0x1000>; + ... + big-endian; +}; + +Scenario 3 : CPU in BE mode & device in BE mode. +dev: dev@40031000 { + compatible = "name"; + reg = <0x40031000 0x1000>; + ... +}; + +Scenario 4 : CPU in BE mode & device in LE mode. +dev: dev@40031000 { + compatible = "name"; + reg = <0x40031000 0x1000>; + ... + little-endian; +}; -- GitLab From dd060bc92748ce77231b2cd2657510b77cd94dea Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 16 Aug 2014 12:30:58 +0100 Subject: [PATCH 0691/9167] regmap: Restore L: linux-kernel@vger.kernel.org entry As with commit 981c3a4ff85 (MAINTAINERS: Restore "L: linux-kernel@vger.kernel.org" entries) restore the mailing list entry for the regmap framework in order to assist users in finding the list if they read the file instead of using get_maintainers.pl. Signed-off-by: Mark Brown --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index aefa94841ff3..0bb827ac690b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7550,6 +7550,7 @@ F: fs/reiserfs/ REGISTER MAP ABSTRACTION M: Mark Brown +L: linux-kernel@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git S: Supported F: drivers/base/regmap/ -- GitLab From 87ca186f7eb663fc5e52b65452a91fe0fec170a0 Mon Sep 17 00:00:00 2001 From: Guodong Xu Date: Wed, 13 Aug 2014 19:33:42 +0800 Subject: [PATCH 0692/9167] regulator: add driver for hi6421 voltage regulator Add driver support for HiSilicon Hi6421 voltage regulators. Two rules for regulator enabling are defined in hi6421 spec: 1) Between disable and enable of each regulator (LDOs or BUCKs), there must be a protection gap. Use @off_on_delay of regulator core to implement this. 2) No two regulators can be enabled at the same time. Use mutex in hi6421_regulator_pdata to ensure this. A protection gap of 100us is added into each LDO/BUCK's .enable_time. Signed-off-by: Guodong Xu Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/hi6421-regulator.c | 657 +++++++++++++++++++++++++++ 3 files changed, 668 insertions(+) create mode 100644 drivers/regulator/hi6421-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc8289e5dba..e6b98ed4c12f 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -240,6 +240,16 @@ config REGULATOR_GPIO and the platform has to provide a mapping of GPIO-states to target volts/amps. +config REGULATOR_HI6421 + tristate "HiSilicon Hi6421 PMIC voltage regulator support" + depends on MFD_HI6421_PMIC && OF + help + This driver provides support for the voltage regulators on the + HiSilicon Hi6421 PMU / Codec IC. + Hi6421 is a multi-function device which, on regulator part, provides + 21 general purpose LDOs, 3 dedicated LDOs, and 5 BUCKs. All + of them come with support to either ECO (idle) or sleep mode. + config REGULATOR_ISL6271A tristate "Intersil ISL6271A Power regulator" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index aa4a6aa7b558..5513e2c141b1 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o +obj-$(CONFIG_REGULATOR_HI6421) += hi6421-regulator.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c new file mode 100644 index 000000000000..b40851eb5466 --- /dev/null +++ b/drivers/regulator/hi6421-regulator.c @@ -0,0 +1,657 @@ +/* + * Device driver for regulators in Hi6421 IC + * + * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd. + * http://www.hisilicon.com + * Copyright (c) <2013-2014> Linaro Ltd. + * http://www.linaro.org + * + * Author: Guodong Xu + * + * 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 + +/* + * struct hi6421_regulator_pdata - Hi6421 regulator data of platform device + * @lock: mutex to serialize regulator enable + */ +struct hi6421_regulator_pdata { + struct mutex lock; +}; + +/* + * struct hi6421_regulator_info - hi6421 regulator information + * @dev: device pointer + * @desc: regulator description + * @regulator: regulator device + * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep + * @eco_microamp: eco mode load upper limit (in mA), valid for LDOs only + * @valid_modes_mask: valid operating modes + */ +struct hi6421_regulator_info { + struct device *dev; + struct regulator_desc desc; + struct regulator_dev *regulator; + u8 mode_mask; + u32 eco_microamp; + unsigned int valid_modes_mask; +}; + +/* HI6421 regulators */ +enum hi6421_regulator_id { + HI6421_LDO0, + HI6421_LDO1, + HI6421_LDO2, + HI6421_LDO3, + HI6421_LDO4, + HI6421_LDO5, + HI6421_LDO6, + HI6421_LDO7, + HI6421_LDO8, + HI6421_LDO9, + HI6421_LDO10, + HI6421_LDO11, + HI6421_LDO12, + HI6421_LDO13, + HI6421_LDO14, + HI6421_LDO15, + HI6421_LDO16, + HI6421_LDO17, + HI6421_LDO18, + HI6421_LDO19, + HI6421_LDO20, + HI6421_LDOAUDIO, + HI6421_BUCK0, + HI6421_BUCK1, + HI6421_BUCK2, + HI6421_BUCK3, + HI6421_BUCK4, + HI6421_BUCK5, + HI6421_NUM_REGULATORS, +}; + +#define HI6421_REGULATOR_OF_MATCH(_name, id) \ +{ \ + .name = #_name, \ + .driver_data = (void *) HI6421_##id, \ +} + +static struct of_regulator_match hi6421_regulator_match[] = { + HI6421_REGULATOR_OF_MATCH(hi6421_vout0, LDO0), + HI6421_REGULATOR_OF_MATCH(hi6421_vout1, LDO1), + HI6421_REGULATOR_OF_MATCH(hi6421_vout2, LDO2), + HI6421_REGULATOR_OF_MATCH(hi6421_vout3, LDO3), + HI6421_REGULATOR_OF_MATCH(hi6421_vout4, LDO4), + HI6421_REGULATOR_OF_MATCH(hi6421_vout5, LDO5), + HI6421_REGULATOR_OF_MATCH(hi6421_vout6, LDO6), + HI6421_REGULATOR_OF_MATCH(hi6421_vout7, LDO7), + HI6421_REGULATOR_OF_MATCH(hi6421_vout8, LDO8), + HI6421_REGULATOR_OF_MATCH(hi6421_vout9, LDO9), + HI6421_REGULATOR_OF_MATCH(hi6421_vout10, LDO10), + HI6421_REGULATOR_OF_MATCH(hi6421_vout11, LDO11), + HI6421_REGULATOR_OF_MATCH(hi6421_vout12, LDO12), + HI6421_REGULATOR_OF_MATCH(hi6421_vout13, LDO13), + HI6421_REGULATOR_OF_MATCH(hi6421_vout14, LDO14), + HI6421_REGULATOR_OF_MATCH(hi6421_vout15, LDO15), + HI6421_REGULATOR_OF_MATCH(hi6421_vout16, LDO16), + HI6421_REGULATOR_OF_MATCH(hi6421_vout17, LDO17), + HI6421_REGULATOR_OF_MATCH(hi6421_vout18, LDO18), + HI6421_REGULATOR_OF_MATCH(hi6421_vout19, LDO19), + HI6421_REGULATOR_OF_MATCH(hi6421_vout20, LDO20), + HI6421_REGULATOR_OF_MATCH(hi6421_vout_audio, LDOAUDIO), + HI6421_REGULATOR_OF_MATCH(hi6421_buck0, BUCK0), + HI6421_REGULATOR_OF_MATCH(hi6421_buck1, BUCK1), + HI6421_REGULATOR_OF_MATCH(hi6421_buck2, BUCK2), + HI6421_REGULATOR_OF_MATCH(hi6421_buck3, BUCK3), + HI6421_REGULATOR_OF_MATCH(hi6421_buck4, BUCK4), + HI6421_REGULATOR_OF_MATCH(hi6421_buck5, BUCK5), +}; + +/* LDO 0, 4~7, 9~14, 16~20 have same voltage table. */ +static const unsigned int ldo_0_voltages[] = { + 1500000, 1800000, 2400000, 2500000, + 2600000, 2700000, 2850000, 3000000, +}; + +/* LDO 8, 15 have same voltage table. */ +static const unsigned int ldo_8_voltages[] = { + 1500000, 1800000, 2400000, 2600000, + 2700000, 2850000, 3000000, 3300000, +}; + +/* Ranges are sorted in ascending order. */ +static const struct regulator_linear_range ldo_audio_volt_range[] = { + REGULATOR_LINEAR_RANGE(2800000, 0, 3, 50000), + REGULATOR_LINEAR_RANGE(3000000, 4, 7, 100000), +}; + +static const unsigned int buck_3_voltages[] = { + 950000, 1050000, 1100000, 1117000, + 1134000, 1150000, 1167000, 1200000, +}; + +static const unsigned int buck_4_voltages[] = { + 1150000, 1200000, 1250000, 1350000, + 1700000, 1800000, 1900000, 2000000, +}; + +static const unsigned int buck_5_voltages[] = { + 1150000, 1200000, 1250000, 1350000, + 1600000, 1700000, 1800000, 1900000, +}; + +static const struct regulator_ops hi6421_ldo_ops; +static const struct regulator_ops hi6421_ldo_linear_ops; +static const struct regulator_ops hi6421_ldo_linear_range_ops; +static const struct regulator_ops hi6421_buck012_ops; +static const struct regulator_ops hi6421_buck345_ops; + +#define HI6421_LDO_ENABLE_TIME (350) +/* + * _id - LDO id name string + * v_table - voltage table + * vreg - voltage select register + * vmask - voltage select mask + * ereg - enable register + * emask - enable mask + * odelay - off/on delay time in uS + * ecomask - eco mode mask + * ecoamp - eco mode load uppler limit in mA + */ +#define HI6421_LDO(_id, v_table, vreg, vmask, ereg, emask, \ + odelay, ecomask, ecoamp) \ + [HI6421_##_id] = { \ + .desc = { \ + .name = #_id, \ + .ops = &hi6421_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = HI6421_##_id, \ + .owner = THIS_MODULE, \ + .n_voltages = ARRAY_SIZE(v_table), \ + .volt_table = v_table, \ + .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ + .vsel_mask = vmask, \ + .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ + .enable_mask = emask, \ + .enable_time = HI6421_LDO_ENABLE_TIME, \ + .off_on_delay = odelay, \ + }, \ + .mode_mask = ecomask, \ + .eco_microamp = ecoamp, \ + .valid_modes_mask = (REGULATOR_MODE_NORMAL \ + | REGULATOR_MODE_IDLE), \ + } + +/* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step + * + * _id - LDO id name string + * _min_uV - minimum voltage supported in uV + * n_volt - number of votages available + * vstep - voltage increase in each linear step in uV + * vreg - voltage select register + * vmask - voltage select mask + * ereg - enable register + * emask - enable mask + * odelay - off/on delay time in uS + * ecomask - eco mode mask + * ecoamp - eco mode load uppler limit in mA + */ +#define HI6421_LDO_LINEAR(_id, _min_uV, n_volt, vstep, vreg, vmask, \ + ereg, emask, odelay, ecomask, ecoamp) \ + [HI6421_##_id] = { \ + .desc = { \ + .name = #_id, \ + .ops = &hi6421_ldo_linear_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = HI6421_##_id, \ + .owner = THIS_MODULE, \ + .min_uV = _min_uV, \ + .n_voltages = n_volt, \ + .uV_step = vstep, \ + .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ + .vsel_mask = vmask, \ + .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ + .enable_mask = emask, \ + .enable_time = HI6421_LDO_ENABLE_TIME, \ + .off_on_delay = odelay, \ + }, \ + .mode_mask = ecomask, \ + .eco_microamp = ecoamp, \ + .valid_modes_mask = (REGULATOR_MODE_NORMAL \ + | REGULATOR_MODE_IDLE), \ + } + +/* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges + * + * _id - LDO id name string + * n_volt - number of votages available + * volt_ranges - array of regulator_linear_range + * vstep - voltage increase in each linear step in uV + * vreg - voltage select register + * vmask - voltage select mask + * ereg - enable register + * emask - enable mask + * odelay - off/on delay time in uS + * ecomask - eco mode mask + * ecoamp - eco mode load uppler limit in mA + */ +#define HI6421_LDO_LINEAR_RANGE(_id, n_volt, volt_ranges, vreg, vmask, \ + ereg, emask, odelay, ecomask, ecoamp) \ + [HI6421_##_id] = { \ + .desc = { \ + .name = #_id, \ + .ops = &hi6421_ldo_linear_range_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = HI6421_##_id, \ + .owner = THIS_MODULE, \ + .n_voltages = n_volt, \ + .linear_ranges = volt_ranges, \ + .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ + .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ + .vsel_mask = vmask, \ + .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ + .enable_mask = emask, \ + .enable_time = HI6421_LDO_ENABLE_TIME, \ + .off_on_delay = odelay, \ + }, \ + .mode_mask = ecomask, \ + .eco_microamp = ecoamp, \ + .valid_modes_mask = (REGULATOR_MODE_NORMAL \ + | REGULATOR_MODE_IDLE), \ + } + +/* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step + * + * _id - BUCK0/1/2 id name string + * vreg - voltage select register + * vmask - voltage select mask + * ereg - enable register + * emask - enable mask + * sleepmask - mask of sleep mode + * etime - enable time + * odelay - off/on delay time in uS + */ +#define HI6421_BUCK012(_id, vreg, vmask, ereg, emask, sleepmask, \ + etime, odelay) \ + [HI6421_##_id] = { \ + .desc = { \ + .name = #_id, \ + .ops = &hi6421_buck012_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = HI6421_##_id, \ + .owner = THIS_MODULE, \ + .min_uV = 700000, \ + .n_voltages = 128, \ + .uV_step = 7086, \ + .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ + .vsel_mask = vmask, \ + .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ + .enable_mask = emask, \ + .enable_time = etime, \ + .off_on_delay = odelay, \ + }, \ + .mode_mask = sleepmask, \ + .valid_modes_mask = (REGULATOR_MODE_NORMAL \ + | REGULATOR_MODE_STANDBY), \ + } + +/* HI6421 BUCK3/4/5 share similar configurations as LDOs, with exception + * that it supports SLEEP mode, so has different .ops. + * + * _id - LDO id name string + * v_table - voltage table + * vreg - voltage select register + * vmask - voltage select mask + * ereg - enable register + * emask - enable mask + * odelay - off/on delay time in uS + * sleepmask - mask of sleep mode + */ +#define HI6421_BUCK345(_id, v_table, vreg, vmask, ereg, emask, \ + odelay, sleepmask) \ + [HI6421_##_id] = { \ + .desc = { \ + .name = #_id, \ + .ops = &hi6421_buck345_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = HI6421_##_id, \ + .owner = THIS_MODULE, \ + .n_voltages = ARRAY_SIZE(v_table), \ + .volt_table = v_table, \ + .vsel_reg = HI6421_REG_TO_BUS_ADDR(vreg), \ + .vsel_mask = vmask, \ + .enable_reg = HI6421_REG_TO_BUS_ADDR(ereg), \ + .enable_mask = emask, \ + .enable_time = HI6421_LDO_ENABLE_TIME, \ + .off_on_delay = odelay, \ + }, \ + .mode_mask = sleepmask, \ + .valid_modes_mask = (REGULATOR_MODE_NORMAL \ + | REGULATOR_MODE_STANDBY), \ + } + +/* HI6421 regulator information */ +static struct hi6421_regulator_info + hi6421_regulator_info[HI6421_NUM_REGULATORS] = { + HI6421_LDO(LDO0, ldo_0_voltages, 0x20, 0x07, 0x20, 0x10, + 10000, 0x20, 8000), + HI6421_LDO_LINEAR(LDO1, 1700000, 4, 100000, 0x21, 0x03, 0x21, 0x10, + 10000, 0x20, 5000), + HI6421_LDO_LINEAR(LDO2, 1050000, 8, 50000, 0x22, 0x07, 0x22, 0x10, + 20000, 0x20, 8000), + HI6421_LDO_LINEAR(LDO3, 1050000, 8, 50000, 0x23, 0x07, 0x23, 0x10, + 20000, 0x20, 8000), + HI6421_LDO(LDO4, ldo_0_voltages, 0x24, 0x07, 0x24, 0x10, + 20000, 0x20, 8000), + HI6421_LDO(LDO5, ldo_0_voltages, 0x25, 0x07, 0x25, 0x10, + 20000, 0x20, 8000), + HI6421_LDO(LDO6, ldo_0_voltages, 0x26, 0x07, 0x26, 0x10, + 20000, 0x20, 8000), + HI6421_LDO(LDO7, ldo_0_voltages, 0x27, 0x07, 0x27, 0x10, + 20000, 0x20, 5000), + HI6421_LDO(LDO8, ldo_8_voltages, 0x28, 0x07, 0x28, 0x10, + 20000, 0x20, 8000), + HI6421_LDO(LDO9, ldo_0_voltages, 0x29, 0x07, 0x29, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO10, ldo_0_voltages, 0x2a, 0x07, 0x2a, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO11, ldo_0_voltages, 0x2b, 0x07, 0x2b, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO12, ldo_0_voltages, 0x2c, 0x07, 0x2c, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO13, ldo_0_voltages, 0x2d, 0x07, 0x2d, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO14, ldo_0_voltages, 0x2e, 0x07, 0x2e, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO15, ldo_8_voltages, 0x2f, 0x07, 0x2f, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO16, ldo_0_voltages, 0x30, 0x07, 0x30, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO17, ldo_0_voltages, 0x31, 0x07, 0x31, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO18, ldo_0_voltages, 0x32, 0x07, 0x32, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO19, ldo_0_voltages, 0x33, 0x07, 0x33, 0x10, + 40000, 0x20, 8000), + HI6421_LDO(LDO20, ldo_0_voltages, 0x34, 0x07, 0x34, 0x10, + 40000, 0x20, 8000), + HI6421_LDO_LINEAR_RANGE(LDOAUDIO, 8, ldo_audio_volt_range, 0x36, + 0x70, 0x36, 0x01, 40000, 0x02, 5000), + HI6421_BUCK012(BUCK0, 0x0d, 0x7f, 0x0c, 0x01, 0x10, 400, 20000), + HI6421_BUCK012(BUCK1, 0x0f, 0x7f, 0x0e, 0x01, 0x10, 400, 20000), + HI6421_BUCK012(BUCK2, 0x11, 0x7f, 0x10, 0x01, 0x10, 350, 100), + HI6421_BUCK345(BUCK3, buck_3_voltages, 0x13, 0x07, 0x12, 0x01, + 20000, 0x10), + HI6421_BUCK345(BUCK4, buck_4_voltages, 0x15, 0x07, 0x14, 0x01, + 20000, 0x10), + HI6421_BUCK345(BUCK5, buck_5_voltages, 0x17, 0x07, 0x16, 0x01, + 20000, 0x10), +}; + +static int hi6421_regulator_enable(struct regulator_dev *rdev) +{ + struct hi6421_regulator_pdata *pdata; + + pdata = dev_get_drvdata(rdev->dev.parent); + /* hi6421 spec requires regulator enablement must be serialized: + * - Because when BUCK, LDO switching from off to on, it will have + * a huge instantaneous current; so you can not turn on two or + * more LDO or BUCKs simultaneously, or it may burn the chip. + */ + mutex_lock(&pdata->lock); + + /* call regulator regmap helper */ + regulator_enable_regmap(rdev); + + mutex_unlock(&pdata->lock); + return 0; +} + +static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) +{ + struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); + u32 reg_val; + + regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); + if (reg_val & info->mode_mask) + return REGULATOR_MODE_IDLE; + else + return REGULATOR_MODE_NORMAL; +} + +static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) +{ + struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); + u32 reg_val; + + regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); + if (reg_val & info->mode_mask) + return REGULATOR_MODE_STANDBY; + else + return REGULATOR_MODE_NORMAL; +} + +static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); + u32 new_mode; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + new_mode = 0; + break; + case REGULATOR_MODE_IDLE: + new_mode = info->mode_mask; + break; + default: + return -EINVAL; + } + + /* set mode */ + regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + info->mode_mask, new_mode); + + return 0; +} + +static int hi6421_regulator_buck_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); + u32 new_mode; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + new_mode = 0; + break; + case REGULATOR_MODE_STANDBY: + new_mode = info->mode_mask; + break; + default: + return -EINVAL; + } + + /* set mode */ + regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + info->mode_mask, new_mode); + + return 0; +} + +unsigned int hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, + int input_uV, int output_uV, int load_uA) +{ + struct hi6421_regulator_info *info = rdev_get_drvdata(rdev); + + if (load_uA > info->eco_microamp) + return REGULATOR_MODE_NORMAL; + else + return REGULATOR_MODE_IDLE; +} + +static const struct regulator_ops hi6421_ldo_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = hi6421_regulator_enable, + .disable = regulator_disable_regmap, + .list_voltage = regulator_list_voltage_table, + .map_voltage = regulator_map_voltage_ascend, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_mode = hi6421_regulator_ldo_get_mode, + .set_mode = hi6421_regulator_ldo_set_mode, + .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode, +}; + +static const struct regulator_ops hi6421_ldo_linear_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = hi6421_regulator_enable, + .disable = regulator_disable_regmap, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_mode = hi6421_regulator_ldo_get_mode, + .set_mode = hi6421_regulator_ldo_set_mode, + .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode, +}; + +static const struct regulator_ops hi6421_ldo_linear_range_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = hi6421_regulator_enable, + .disable = regulator_disable_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_mode = hi6421_regulator_ldo_get_mode, + .set_mode = hi6421_regulator_ldo_set_mode, + .get_optimum_mode = hi6421_regulator_ldo_get_optimum_mode, +}; + +static const struct regulator_ops hi6421_buck012_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = hi6421_regulator_enable, + .disable = regulator_disable_regmap, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_mode = hi6421_regulator_buck_get_mode, + .set_mode = hi6421_regulator_buck_set_mode, +}; + +static const struct regulator_ops hi6421_buck345_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = hi6421_regulator_enable, + .disable = regulator_disable_regmap, + .list_voltage = regulator_list_voltage_table, + .map_voltage = regulator_map_voltage_ascend, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_mode = hi6421_regulator_buck_get_mode, + .set_mode = hi6421_regulator_buck_set_mode, +}; + +static int hi6421_regulator_register(struct platform_device *pdev, + struct regmap *rmap, + struct regulator_init_data *init_data, + int id, struct device_node *np) +{ + struct hi6421_regulator_info *info = NULL; + struct regulator_config config = { }; + + /* assign per-regulator data */ + info = &hi6421_regulator_info[id]; + info->dev = &pdev->dev; + + config.dev = &pdev->dev; + config.init_data = init_data; + config.driver_data = info; + config.regmap = rmap; + config.of_node = np; + + /* register regulator with framework */ + info->regulator = devm_regulator_register(&pdev->dev, &info->desc, + &config); + if (IS_ERR(info->regulator)) { + dev_err(&pdev->dev, "failed to register regulator %s\n", + info->desc.name); + return PTR_ERR(info->regulator); + } + + return 0; +} + +static int hi6421_regulator_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np; + struct hi6421_pmic *pmic; + struct hi6421_regulator_pdata *pdata; + int i, ret = 0; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + mutex_init(&pdata->lock); + platform_set_drvdata(pdev, pdata); + + np = of_get_child_by_name(dev->parent->of_node, "regulators"); + if (!np) + return -ENODEV; + + ret = of_regulator_match(dev, np, + hi6421_regulator_match, + ARRAY_SIZE(hi6421_regulator_match)); + of_node_put(np); + if (ret < 0) { + dev_err(dev, "Error parsing regulator init data: %d\n", ret); + return ret; + } + + pmic = dev_get_drvdata(dev->parent); + + for (i = 0; i < ARRAY_SIZE(hi6421_regulator_info); i++) { + ret = hi6421_regulator_register(pdev, pmic->regmap, + hi6421_regulator_match[i].init_data, i, + hi6421_regulator_match[i].of_node); + if (ret) + return ret; + } + + return 0; +} + +static struct platform_driver hi6421_regulator_driver = { + .driver = { + .name = "hi6421-regulator", + .owner = THIS_MODULE, + }, + .probe = hi6421_regulator_probe, +}; +module_platform_driver(hi6421_regulator_driver); + +MODULE_AUTHOR("Guodong Xu "); +MODULE_DESCRIPTION("Hi6421 regulator driver"); +MODULE_LICENSE("GPL v2"); -- GitLab From 8ad9f9efcc7656cafb56bbbcd545f817a742bf32 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Mon, 16 Jun 2014 16:33:46 +0200 Subject: [PATCH 0693/9167] ASoC: Drop const from struct snd_soc_dai_link *of_node members MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dropping the const qualifiers prevents "passing argument 1 of ‘of_node_put’ discards ‘const’ qualifier from pointer target type" type warnings when compiling the code dropping reference to cpu_of_node, codec_of_node or platform_of_node with with an of_node_put() function call. This lets us to avoid casting to struct device_node * or caching variables internally in drivers just to be able to properly drop a reference to the OF node on clean up paths. Signed-off-by: Sylwester Nawrocki 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 be6ecae247b0..fd58371c63ff 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -897,7 +897,7 @@ struct snd_soc_dai_link { * only for codec to codec links, or systems using device tree. */ const char *cpu_name; - const struct device_node *cpu_of_node; + struct device_node *cpu_of_node; /* * You MAY specify the DAI name of the CPU DAI. If this information is * omitted, the CPU-side DAI is matched using .cpu_name/.cpu_of_node @@ -909,7 +909,7 @@ struct snd_soc_dai_link { * DT/OF node, but not both. */ const char *codec_name; - const struct device_node *codec_of_node; + struct device_node *codec_of_node; /* You MUST specify the DAI name within the codec */ const char *codec_dai_name; @@ -922,7 +922,7 @@ struct snd_soc_dai_link { * do not need a platform. */ const char *platform_name; - const struct device_node *platform_of_node; + struct device_node *platform_of_node; int be_id; /* optional ID for machine driver BE identification */ const struct snd_soc_pcm_stream *params; -- GitLab From eef5bb2445ca49911c93c08ed0fb2ea7363ea945 Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Mon, 4 Aug 2014 15:11:16 -0500 Subject: [PATCH 0694/9167] ASoC: cs35l32: Add support for CS35L32 Boosted Amplifier This patch adds support for the Cirrus Logic CS35L32 Boosted Amplifier I2S output provides monitor data to the SOC/CODEC/DSP for speaker protection/enhancement algorithms Signed-off-by: Brian Austin Signed-off-by: Mark Brown --- include/dt-bindings/sound/cs35l32.h | 26 ++ sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/cs35l32.c | 647 ++++++++++++++++++++++++++++ sound/soc/codecs/cs35l32.h | 93 ++++ 5 files changed, 773 insertions(+) create mode 100644 include/dt-bindings/sound/cs35l32.h create mode 100644 sound/soc/codecs/cs35l32.c create mode 100644 sound/soc/codecs/cs35l32.h diff --git a/include/dt-bindings/sound/cs35l32.h b/include/dt-bindings/sound/cs35l32.h new file mode 100644 index 000000000000..0c6d6a3c15a2 --- /dev/null +++ b/include/dt-bindings/sound/cs35l32.h @@ -0,0 +1,26 @@ +#ifndef __DT_CS35L32_H +#define __DT_CS35L32_H + +#define CS35L32_BOOST_MGR_AUTO 0 +#define CS35L32_BOOST_MGR_AUTO_AUDIO 1 +#define CS35L32_BOOST_MGR_BYPASS 2 +#define CS35L32_BOOST_MGR_FIXED 3 + +#define CS35L32_DATA_CFG_LR_VP 0 +#define CS35L32_DATA_CFG_LR_STAT 1 +#define CS35L32_DATA_CFG_LR 2 +#define CS35L32_DATA_CFG_LR_VPSTAT 3 + +#define CS35L32_BATT_THRESH_3_1V 0 +#define CS35L32_BATT_THRESH_3_2V 1 +#define CS35L32_BATT_THRESH_3_3V 2 +#define CS35L32_BATT_THRESH_3_4V 3 + +#define CS35L32_BATT_RECOV_3_1V 0 +#define CS35L32_BATT_RECOV_3_2V 1 +#define CS35L32_BATT_RECOV_3_3V 2 +#define CS35L32_BATT_RECOV_3_4V 3 +#define CS35L32_BATT_RECOV_3_5V 4 +#define CS35L32_BATT_RECOV_3_6V 5 + +#endif /* __DT_CS35L32_H */ diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 8838838e25ed..77e5383b4361 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -43,6 +43,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_ALC5623 if I2C select SND_SOC_ALC5632 if I2C select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC + select SND_SOC_CS35L32 if I2C select SND_SOC_CS42L51_I2C if I2C select SND_SOC_CS42L52 if I2C && INPUT select SND_SOC_CS42L56 if I2C && INPUT @@ -323,6 +324,10 @@ config SND_SOC_ALC5632 config SND_SOC_CQ0093VC tristate +config SND_SOC_CS35L32 + tristate "Cirrus Logic CS35L32 CODEC" + depends on I2C + config SND_SOC_CS42L51 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 20afe0f0c5be..1dacefbdac3c 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -32,6 +32,7 @@ snd-soc-ak4671-objs := ak4671.o snd-soc-ak5386-objs := ak5386.o snd-soc-arizona-objs := arizona.o snd-soc-cq93vc-objs := cq93vc.o +snd-soc-cs35l32-objs := cs35l32.o snd-soc-cs42l51-objs := cs42l51.o snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o snd-soc-cs42l52-objs := cs42l52.o @@ -203,6 +204,7 @@ obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o +obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c new file mode 100644 index 000000000000..90565d59def7 --- /dev/null +++ b/sound/soc/codecs/cs35l32.c @@ -0,0 +1,647 @@ +/* + * cs35l32.c -- CS35L32 ALSA SoC audio driver + * + * Copyright 2014 CirrusLogic, Inc. + * + * Author: Brian Austin + * + * 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 +#include +#include +#include + +#include "cs35l32.h" + +#define CS35L32_NUM_SUPPLIES 2 +static const char *const cs35l32_supply_names[CS35L32_NUM_SUPPLIES] = { + "VA", + "VP", +}; + +struct cs35l32_private { + struct regmap *regmap; + struct snd_soc_codec *codec; + struct regulator_bulk_data supplies[CS35L32_NUM_SUPPLIES]; + struct cs35l32_platform_data pdata; + struct gpio_desc *reset_gpio; +}; + +static const struct reg_default cs35l32_reg_defaults[] = { + + { 0x06, 0x04 }, /* Power Ctl 1 */ + { 0x07, 0xE8 }, /* Power Ctl 2 */ + { 0x08, 0x40 }, /* Clock Ctl */ + { 0x09, 0x20 }, /* Low Battery Threshold */ + { 0x0A, 0x00 }, /* Voltage Monitor [RO] */ + { 0x0B, 0x40 }, /* Conv Peak Curr Protection CTL */ + { 0x0C, 0x07 }, /* IMON Scaling */ + { 0x0D, 0x03 }, /* Audio/LED Pwr Manager */ + { 0x0F, 0x20 }, /* Serial Port Control */ + { 0x10, 0x14 }, /* Class D Amp CTL */ + { 0x11, 0x00 }, /* Protection Release CTL */ + { 0x12, 0xFF }, /* Interrupt Mask 1 */ + { 0x13, 0xFF }, /* Interrupt Mask 2 */ + { 0x14, 0xFF }, /* Interrupt Mask 3 */ + { 0x19, 0x00 }, /* LED Flash Mode Current */ + { 0x1A, 0x00 }, /* LED Movie Mode Current */ + { 0x1B, 0x20 }, /* LED Flash Timer */ + { 0x1C, 0x00 }, /* LED Flash Inhibit Current */ +}; + +static bool cs35l32_readable_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L32_DEVID_AB: + case CS35L32_DEVID_CD: + case CS35L32_DEVID_E: + case CS35L32_FAB_ID: + case CS35L32_REV_ID: + case CS35L32_PWRCTL1: + case CS35L32_PWRCTL2: + case CS35L32_CLK_CTL: + case CS35L32_BATT_THRESHOLD: + case CS35L32_VMON: + case CS35L32_BST_CPCP_CTL: + case CS35L32_IMON_SCALING: + case CS35L32_AUDIO_LED_MNGR: + case CS35L32_ADSP_CTL: + case CS35L32_CLASSD_CTL: + case CS35L32_PROTECT_CTL: + case CS35L32_INT_MASK_1: + case CS35L32_INT_MASK_2: + case CS35L32_INT_MASK_3: + case CS35L32_INT_STATUS_1: + case CS35L32_INT_STATUS_2: + case CS35L32_INT_STATUS_3: + case CS35L32_LED_STATUS: + case CS35L32_FLASH_MODE: + case CS35L32_MOVIE_MODE: + case CS35L32_FLASH_TIMER: + case CS35L32_FLASH_INHIBIT: + return true; + default: + return false; + } +} + +static bool cs35l32_volatile_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L32_DEVID_AB: + case CS35L32_DEVID_CD: + case CS35L32_DEVID_E: + case CS35L32_FAB_ID: + case CS35L32_REV_ID: + case CS35L32_INT_STATUS_1: + case CS35L32_INT_STATUS_2: + case CS35L32_INT_STATUS_3: + case CS35L32_LED_STATUS: + return 1; + default: + return 0; + } +} + +static bool cs35l32_precious_register(struct device *dev, unsigned int reg) +{ + switch (reg) { + case CS35L32_INT_STATUS_1: + case CS35L32_INT_STATUS_2: + case CS35L32_INT_STATUS_3: + case CS35L32_LED_STATUS: + return 1; + default: + return 0; + } +} + +static DECLARE_TLV_DB_SCALE(classd_ctl_tlv, 900, 300, 0); + +static const struct snd_kcontrol_new imon_ctl = + SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 6, 1, 1); + +static const struct snd_kcontrol_new vmon_ctl = + SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 7, 1, 1); + +static const struct snd_kcontrol_new vpmon_ctl = + SOC_DAPM_SINGLE("Switch", CS35L32_PWRCTL2, 5, 1, 1); + +static const struct snd_kcontrol_new cs35l32_snd_controls[] = { + SOC_SINGLE_TLV("Speaker Volume", CS35L32_CLASSD_CTL, + 3, 0x04, 1, classd_ctl_tlv), + SOC_SINGLE("Zero Cross Switch", CS35L32_CLASSD_CTL, 2, 1, 0), + SOC_SINGLE("Gain Manager Switch", CS35L32_AUDIO_LED_MNGR, 3, 1, 0), +}; + +static const struct snd_soc_dapm_widget cs35l32_dapm_widgets[] = { + + SND_SOC_DAPM_SUPPLY("BOOST", CS35L32_PWRCTL1, 2, 1, NULL, 0), + SND_SOC_DAPM_OUT_DRV("Speaker", CS35L32_PWRCTL1, 7, 1, NULL, 0), + + SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L32_PWRCTL2, 3, 1), + + SND_SOC_DAPM_INPUT("VP"), + SND_SOC_DAPM_INPUT("ISENSE"), + SND_SOC_DAPM_INPUT("VSENSE"), + + SND_SOC_DAPM_SWITCH("VMON ADC", CS35L32_PWRCTL2, 7, 1, &vmon_ctl), + SND_SOC_DAPM_SWITCH("IMON ADC", CS35L32_PWRCTL2, 6, 1, &imon_ctl), + SND_SOC_DAPM_SWITCH("VPMON ADC", CS35L32_PWRCTL2, 5, 1, &vpmon_ctl), +}; + +static const struct snd_soc_dapm_route cs35l32_audio_map[] = { + + {"Speaker", NULL, "BOOST"}, + + {"VMON ADC", NULL, "VSENSE"}, + {"IMON ADC", NULL, "ISENSE"}, + {"VPMON ADC", NULL, "VP"}, + + {"SDOUT", "Switch", "VMON ADC"}, + {"SDOUT", "Switch", "IMON ADC"}, + {"SDOUT", "Switch", "VPMON ADC"}, + + {"Capture", NULL, "SDOUT"}, +}; + +static int cs35l32_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + snd_soc_update_bits(codec, CS35L32_ADSP_CTL, + CS35L32_ADSP_MASTER_MASK, + CS35L32_ADSP_MASTER_MASK); + break; + case SND_SOC_DAIFMT_CBS_CFS: + snd_soc_update_bits(codec, CS35L32_ADSP_CTL, + CS35L32_ADSP_MASTER_MASK, 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int cs35l32_set_tristate(struct snd_soc_dai *dai, int tristate) +{ + struct snd_soc_codec *codec = dai->codec; + + return snd_soc_update_bits(codec, CS35L32_PWRCTL2, + CS35L32_SDOUT_3ST, tristate << 3); +} + +static const struct snd_soc_dai_ops cs35l32_ops = { + .set_fmt = cs35l32_set_dai_fmt, + .set_tristate = cs35l32_set_tristate, +}; + +static struct snd_soc_dai_driver cs35l32_dai[] = { + { + .name = "cs35l32-monitor", + .id = 0, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = CS35L32_RATES, + .formats = CS35L32_FORMATS, + }, + .ops = &cs35l32_ops, + .symmetric_rates = 1, + } +}; + +static int cs35l32_codec_set_sysclk(struct snd_soc_codec *codec, + int clk_id, int source, unsigned int freq, int dir) +{ + + switch (freq) { + case 6000000: + snd_soc_update_bits(codec, CS35L32_CLK_CTL, + CS35L32_MCLK_DIV2_MASK, 0); + snd_soc_update_bits(codec, CS35L32_CLK_CTL, + CS35L32_MCLK_RATIO_MASK, + CS35L32_MCLK_RATIO); + break; + case 12000000: + snd_soc_update_bits(codec, CS35L32_CLK_CTL, + CS35L32_MCLK_DIV2_MASK, + CS35L32_MCLK_DIV2_MASK); + snd_soc_update_bits(codec, CS35L32_CLK_CTL, + CS35L32_MCLK_RATIO_MASK, + CS35L32_MCLK_RATIO); + break; + case 6144000: + snd_soc_update_bits(codec, CS35L32_CLK_CTL, + CS35L32_MCLK_DIV2_MASK, 0); + snd_soc_update_bits(codec, CS35L32_CLK_CTL, + CS35L32_MCLK_RATIO_MASK, 0); + break; + case 12288000: + snd_soc_update_bits(codec, CS35L32_CLK_CTL, + CS35L32_MCLK_DIV2_MASK, + CS35L32_MCLK_DIV2_MASK); + snd_soc_update_bits(codec, CS35L32_CLK_CTL, + CS35L32_MCLK_RATIO_MASK, 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_cs35l32 = { + .set_sysclk = cs35l32_codec_set_sysclk, + + .dapm_widgets = cs35l32_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(cs35l32_dapm_widgets), + .dapm_routes = cs35l32_audio_map, + .num_dapm_routes = ARRAY_SIZE(cs35l32_audio_map), + + .controls = cs35l32_snd_controls, + .num_controls = ARRAY_SIZE(cs35l32_snd_controls), +}; + +/* Current and threshold powerup sequence Pg37 in datasheet */ +static const struct reg_default cs35l32_monitor_patch[] = { + + { 0x00, 0x99 }, + { 0x48, 0x17 }, + { 0x49, 0x56 }, + { 0x43, 0x01 }, + { 0x3B, 0x62 }, + { 0x3C, 0x80 }, + { 0x00, 0x00 }, +}; + +static struct regmap_config cs35l32_regmap = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = CS35L32_MAX_REGISTER, + .reg_defaults = cs35l32_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(cs35l32_reg_defaults), + .volatile_reg = cs35l32_volatile_register, + .readable_reg = cs35l32_readable_register, + .precious_reg = cs35l32_precious_register, + .cache_type = REGCACHE_RBTREE, +}; + +static int cs35l32_handle_of_data(struct i2c_client *i2c_client, + struct cs35l32_platform_data *pdata) +{ + struct device_node *np = i2c_client->dev.of_node; + unsigned int val; + + if (of_property_read_u32(np, "cirrus,sdout-share", &val) >= 0) + pdata->sdout_share = val; + + of_property_read_u32(np, "cirrus,boost-manager", &val); + switch (val) { + case CS35L32_BOOST_MGR_AUTO: + case CS35L32_BOOST_MGR_AUTO_AUDIO: + case CS35L32_BOOST_MGR_BYPASS: + case CS35L32_BOOST_MGR_FIXED: + pdata->boost_mng = val; + break; + default: + dev_err(&i2c_client->dev, + "Wrong cirrus,boost-manager DT value %d\n", val); + pdata->boost_mng = CS35L32_BOOST_MGR_BYPASS; + } + + of_property_read_u32(np, "cirrus,sdout-datacfg", &val); + switch (val) { + case CS35L32_DATA_CFG_LR_VP: + case CS35L32_DATA_CFG_LR_STAT: + case CS35L32_DATA_CFG_LR: + case CS35L32_DATA_CFG_LR_VPSTAT: + pdata->sdout_datacfg = val; + break; + default: + dev_err(&i2c_client->dev, + "Wrong cirrus,sdout-datacfg DT value %d\n", val); + pdata->sdout_datacfg = CS35L32_DATA_CFG_LR; + } + + of_property_read_u32(np, "cirrus,battery-threshold", &val); + switch (val) { + case CS35L32_BATT_THRESH_3_1V: + case CS35L32_BATT_THRESH_3_2V: + case CS35L32_BATT_THRESH_3_3V: + case CS35L32_BATT_THRESH_3_4V: + pdata->batt_thresh = val; + break; + default: + dev_err(&i2c_client->dev, + "Wrong cirrus,battery-threshold DT value %d\n", val); + pdata->batt_thresh = CS35L32_BATT_THRESH_3_3V; + } + + of_property_read_u32(np, "cirrus,battery-recovery", &val); + switch (val) { + case CS35L32_BATT_RECOV_3_1V: + case CS35L32_BATT_RECOV_3_2V: + case CS35L32_BATT_RECOV_3_3V: + case CS35L32_BATT_RECOV_3_4V: + case CS35L32_BATT_RECOV_3_5V: + case CS35L32_BATT_RECOV_3_6V: + pdata->batt_recov = val; + break; + default: + dev_err(&i2c_client->dev, + "Wrong cirrus,battery-recovery DT value %d\n", val); + pdata->batt_recov = CS35L32_BATT_RECOV_3_4V; + } + + return 0; +} + +static int cs35l32_i2c_probe(struct i2c_client *i2c_client, + const struct i2c_device_id *id) +{ + struct cs35l32_private *cs35l32; + struct cs35l32_platform_data *pdata = + dev_get_platdata(&i2c_client->dev); + int ret, i; + unsigned int devid = 0; + unsigned int reg; + + + cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l32_private), + GFP_KERNEL); + if (!cs35l32) { + dev_err(&i2c_client->dev, "could not allocate codec\n"); + return -ENOMEM; + } + + i2c_set_clientdata(i2c_client, cs35l32); + + cs35l32->regmap = devm_regmap_init_i2c(i2c_client, &cs35l32_regmap); + if (IS_ERR(cs35l32->regmap)) { + ret = PTR_ERR(cs35l32->regmap); + dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); + return ret; + } + + if (pdata) { + cs35l32->pdata = *pdata; + } else { + pdata = devm_kzalloc(&i2c_client->dev, + sizeof(struct cs35l32_platform_data), + GFP_KERNEL); + if (!pdata) { + dev_err(&i2c_client->dev, "could not allocate pdata\n"); + return -ENOMEM; + } + if (i2c_client->dev.of_node) { + ret = cs35l32_handle_of_data(i2c_client, + &cs35l32->pdata); + if (ret != 0) + return ret; + } + } + + for (i = 0; i < ARRAY_SIZE(cs35l32->supplies); i++) + cs35l32->supplies[i].supply = cs35l32_supply_names[i]; + + ret = devm_regulator_bulk_get(&i2c_client->dev, + ARRAY_SIZE(cs35l32->supplies), + cs35l32->supplies); + if (ret != 0) { + dev_err(&i2c_client->dev, + "Failed to request supplies: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies), + cs35l32->supplies); + if (ret != 0) { + dev_err(&i2c_client->dev, + "Failed to enable supplies: %d\n", ret); + return ret; + } + + /* Reset the Device */ + cs35l32->reset_gpio = devm_gpiod_get(&i2c_client->dev, + "reset-gpios"); + if (IS_ERR(cs35l32->reset_gpio)) { + ret = PTR_ERR(cs35l32->reset_gpio); + if (ret != -ENOENT && ret != -ENOSYS) + return ret; + + cs35l32->reset_gpio = NULL; + } else { + ret = gpiod_direction_output(cs35l32->reset_gpio, 0); + if (ret) + return ret; + gpiod_set_value_cansleep(cs35l32->reset_gpio, 1); + } + + /* initialize codec */ + ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_AB, ®); + devid = (reg & 0xFF) << 12; + + ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_CD, ®); + devid |= (reg & 0xFF) << 4; + + ret = regmap_read(cs35l32->regmap, CS35L32_DEVID_E, ®); + devid |= (reg & 0xF0) >> 4; + + if (devid != CS35L32_CHIP_ID) { + ret = -ENODEV; + dev_err(&i2c_client->dev, + "CS35L32 Device ID (%X). Expected %X\n", + devid, CS35L32_CHIP_ID); + return ret; + } + + ret = regmap_read(cs35l32->regmap, CS35L32_REV_ID, ®); + if (ret < 0) { + dev_err(&i2c_client->dev, "Get Revision ID failed\n"); + return ret; + } + + ret = regmap_register_patch(cs35l32->regmap, cs35l32_monitor_patch, + ARRAY_SIZE(cs35l32_monitor_patch)); + if (ret < 0) { + dev_err(&i2c_client->dev, "Failed to apply errata patch\n"); + return ret; + } + + dev_info(&i2c_client->dev, + "Cirrus Logic CS35L32, Revision: %02X\n", reg & 0xFF); + + /* Setup VBOOST Management */ + if (cs35l32->pdata.boost_mng) + regmap_update_bits(cs35l32->regmap, CS35L32_AUDIO_LED_MNGR, + CS35L32_BOOST_MASK, + cs35l32->pdata.boost_mng); + + /* Setup ADSP Format Config */ + if (cs35l32->pdata.sdout_share) + regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL, + CS35L32_ADSP_SHARE_MASK, + cs35l32->pdata.sdout_share << 3); + + /* Setup ADSP Data Configuration */ + if (cs35l32->pdata.sdout_datacfg) + regmap_update_bits(cs35l32->regmap, CS35L32_ADSP_CTL, + CS35L32_ADSP_DATACFG_MASK, + cs35l32->pdata.sdout_datacfg << 4); + + /* Setup Low Battery Recovery */ + if (cs35l32->pdata.batt_recov) + regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD, + CS35L32_BATT_REC_MASK, + cs35l32->pdata.batt_recov << 1); + + /* Setup Low Battery Threshold */ + if (cs35l32->pdata.batt_thresh) + regmap_update_bits(cs35l32->regmap, CS35L32_BATT_THRESHOLD, + CS35L32_BATT_THRESH_MASK, + cs35l32->pdata.batt_thresh << 4); + + /* Power down the AMP */ + regmap_update_bits(cs35l32->regmap, CS35L32_PWRCTL1, CS35L32_PDN_AMP, + CS35L32_PDN_AMP); + + /* Clear MCLK Error Bit since we don't have the clock yet */ + ret = regmap_read(cs35l32->regmap, CS35L32_INT_STATUS_1, ®); + + ret = snd_soc_register_codec(&i2c_client->dev, + &soc_codec_dev_cs35l32, cs35l32_dai, + ARRAY_SIZE(cs35l32_dai)); + if (ret < 0) + goto err_disable; + + return 0; + +err_disable: + regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies), + cs35l32->supplies); +} + +static int cs35l32_i2c_remove(struct i2c_client *i2c_client) +{ + struct cs35l32_private *cs35l32 = i2c_get_clientdata(i2c_client); + + snd_soc_unregister_codec(&i2c_client->dev); + + /* Hold down reset */ + if (cs35l32->reset_gpio) + gpiod_set_value_cansleep(cs35l32->reset_gpio, 0); + + regulator_bulk_free(ARRAY_SIZE(cs35l32->supplies), cs35l32->supplies); + + return 0; +} + +#ifdef CONFIG_PM_RUNTIME +static int cs35l32_runtime_suspend(struct device *dev) +{ + struct cs35l32_private *cs35l32 = dev_get_drvdata(dev); + + regcache_cache_only(cs35l32->regmap, true); + regcache_mark_dirty(cs35l32->regmap); + + /* Hold down reset */ + if (cs35l32->reset_gpio) + gpiod_set_value_cansleep(cs35l32->reset_gpio, 0); + + /* remove power */ + regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies), + cs35l32->supplies); + + return 0; +} + +static int cs35l32_runtime_resume(struct device *dev) +{ + struct cs35l32_private *cs35l32 = dev_get_drvdata(dev); + int ret; + + /* Enable power */ + ret = regulator_bulk_enable(ARRAY_SIZE(cs35l32->supplies), + cs35l32->supplies); + if (ret != 0) { + dev_err(dev, "Failed to enable supplies: %d\n", + ret); + return ret; + } + + if (cs35l32->reset_gpio) + gpiod_set_value_cansleep(cs35l32->reset_gpio, 1); + + regcache_cache_only(cs35l32->regmap, false); + regcache_sync(cs35l32->regmap); + + return 0; +} +#endif + +static const struct dev_pm_ops cs35l32_runtime_pm = { + SET_RUNTIME_PM_OPS(cs35l32_runtime_suspend, cs35l32_runtime_resume, + NULL) +}; + +static const struct of_device_id cs35l32_of_match[] = { + { .compatible = "cirrus,cs35l32", }, + {}, +}; +MODULE_DEVICE_TABLE(of, cs35l32_of_match); + + +static const struct i2c_device_id cs35l32_id[] = { + {"cs35l32", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cs35l32_id); + +static struct i2c_driver cs35l32_i2c_driver = { + .driver = { + .name = "cs35l32", + .owner = THIS_MODULE, + .pm = &cs35l32_runtime_pm, + .of_match_table = cs35l32_of_match, + }, + .id_table = cs35l32_id, + .probe = cs35l32_i2c_probe, + .remove = cs35l32_i2c_remove, +}; + +module_i2c_driver(cs35l32_i2c_driver); + +MODULE_DESCRIPTION("ASoC CS35L32 driver"); +MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/cs35l32.h b/sound/soc/codecs/cs35l32.h new file mode 100644 index 000000000000..31ab804a22bc --- /dev/null +++ b/sound/soc/codecs/cs35l32.h @@ -0,0 +1,93 @@ +/* + * cs35l32.h -- CS35L32 ALSA SoC audio driver + * + * Copyright 2014 CirrusLogic, Inc. + * + * Author: Brian Austin + * + * 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 __CS35L32_H__ +#define __CS35L32_H__ + +struct cs35l32_platform_data { + /* Low Battery Threshold */ + unsigned int batt_thresh; + /* Low Battery Recovery */ + unsigned int batt_recov; + /* LED Current Management*/ + unsigned int led_mng; + /* Audio Gain w/ LED */ + unsigned int audiogain_mng; + /* Boost Management */ + unsigned int boost_mng; + /* Data CFG for DUAL device */ + unsigned int sdout_datacfg; + /* SDOUT Sharing */ + unsigned int sdout_share; +}; + +#define CS35L32_CHIP_ID 0x00035A32 +#define CS35L32_DEVID_AB 0x01 /* Device ID A & B [RO] */ +#define CS35L32_DEVID_CD 0x02 /* Device ID C & D [RO] */ +#define CS35L32_DEVID_E 0x03 /* Device ID E [RO] */ +#define CS35L32_FAB_ID 0x04 /* Fab ID [RO] */ +#define CS35L32_REV_ID 0x05 /* Revision ID [RO] */ +#define CS35L32_PWRCTL1 0x06 /* Power Ctl 1 */ +#define CS35L32_PWRCTL2 0x07 /* Power Ctl 2 */ +#define CS35L32_CLK_CTL 0x08 /* Clock Ctl */ +#define CS35L32_BATT_THRESHOLD 0x09 /* Low Battery Threshold */ +#define CS35L32_VMON 0x0A /* Voltage Monitor [RO] */ +#define CS35L32_BST_CPCP_CTL 0x0B /* Conv Peak Curr Protection CTL */ +#define CS35L32_IMON_SCALING 0x0C /* IMON Scaling */ +#define CS35L32_AUDIO_LED_MNGR 0x0D /* Audio/LED Pwr Manager */ +#define CS35L32_ADSP_CTL 0x0F /* Serial Port Control */ +#define CS35L32_CLASSD_CTL 0x10 /* Class D Amp CTL */ +#define CS35L32_PROTECT_CTL 0x11 /* Protection Release CTL */ +#define CS35L32_INT_MASK_1 0x12 /* Interrupt Mask 1 */ +#define CS35L32_INT_MASK_2 0x13 /* Interrupt Mask 2 */ +#define CS35L32_INT_MASK_3 0x14 /* Interrupt Mask 3 */ +#define CS35L32_INT_STATUS_1 0x15 /* Interrupt Status 1 [RO] */ +#define CS35L32_INT_STATUS_2 0x16 /* Interrupt Status 2 [RO] */ +#define CS35L32_INT_STATUS_3 0x17 /* Interrupt Status 3 [RO] */ +#define CS35L32_LED_STATUS 0x18 /* LED Lighting Status [RO] */ +#define CS35L32_FLASH_MODE 0x19 /* LED Flash Mode Current */ +#define CS35L32_MOVIE_MODE 0x1A /* LED Movie Mode Current */ +#define CS35L32_FLASH_TIMER 0x1B /* LED Flash Timer */ +#define CS35L32_FLASH_INHIBIT 0x1C /* LED Flash Inhibit Current */ +#define CS35L32_MAX_REGISTER 0x1C + +#define CS35L32_MCLK_DIV2 0x01 +#define CS35L32_MCLK_RATIO 0x01 +#define CS35L32_MCLKDIS 0x80 +#define CS35L32_PDN_ALL 0x01 +#define CS35L32_PDN_AMP 0x80 +#define CS35L32_PDN_BOOST 0x04 +#define CS35L32_PDN_IMON 0x40 +#define CS35L32_PDN_VMON 0x80 +#define CS35L32_PDN_VPMON 0x20 +#define CS35L32_PDN_ADSP 0x08 + +#define CS35L32_MCLK_DIV2_MASK 0x40 +#define CS35L32_MCLK_RATIO_MASK 0x01 +#define CS35L32_MCLK_MASK 0x41 +#define CS35L32_ADSP_MASTER_MASK 0x40 +#define CS35L32_BOOST_MASK 0x03 +#define CS35L32_GAIN_MGR_MASK 0x08 +#define CS35L32_ADSP_SHARE_MASK 0x08 +#define CS35L32_ADSP_DATACFG_MASK 0x30 +#define CS35L32_SDOUT_3ST 0x80 +#define CS35L32_BATT_REC_MASK 0x0E +#define CS35L32_BATT_THRESH_MASK 0x30 + +#define CS35L32_RATES (SNDRV_PCM_RATE_48000) +#define CS35L32_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + + +#endif -- GitLab From 9cf44690204db563ba065ed856546dc8a8b742a1 Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Mon, 4 Aug 2014 15:11:17 -0500 Subject: [PATCH 0695/9167] ASoC: cs35l32: Add bindings for CS35L32 The patch adds device tree bindings file for the Cirrus Logic CS35L32 Signed-off-by: Brian Austin Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/cs35l32.txt | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/cs35l32.txt diff --git a/Documentation/devicetree/bindings/sound/cs35l32.txt b/Documentation/devicetree/bindings/sound/cs35l32.txt new file mode 100644 index 000000000000..1417d3f5cc22 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs35l32.txt @@ -0,0 +1,62 @@ +CS35L32 audio CODEC + +Required properties: + + - compatible : "cirrus,cs35l32" + + - reg : the I2C address of the device for I2C. Address is determined by the level + of the AD0 pin. Level 0 is 0x40 while Level 1 is 0x41. + + - VA-supply, VP-supply : power supplies for the device, + as covered in Documentation/devicetree/bindings/regulator/regulator.txt. + +Optional properties: + + - reset-gpios : a GPIO spec for the reset pin. If specified, it will be + deasserted before communication to the codec starts. + + - cirrus,boost-manager : Boost voltage control. + 0 = Automatically managed. Boost-converter output voltage is the higher + of the two: Class G or adaptive LED voltage. + 1 = Automatically managed irrespective of audio, adapting for low-power + dissipation when LEDs are ON, and operating in Fixed-Boost Bypass Mode + if LEDs are OFF (VBST = VP). + 2 = (Default) Boost voltage fixed in Bypass Mode (VBST = VP). + 3 = Boost voltage fixed at 5 V. + + - cirrus,sdout-datacfg : Data configuration for dual CS35L32 applications only. + Determines the data packed in a two-CS35L32 configuration. + 0 = Left/right channels VMON[11:0], IMON[11:0], VPMON[7:0]. + 1 = Left/right channels VMON[11:0], IMON[11:0], STATUS. + 2 = (Default) left/right channels VMON[15:0], IMON [15:0]. + 3 = Left/right channels VPMON[7:0], STATUS. + + - cirrus,sdout-share : SDOUT sharing. Determines whether one or two CS35L32 + devices are on board sharing SDOUT. + 0 = (Default) One IC. + 1 = Two IC's. + + - cirrus,battery-recovery : Low battery nominal recovery threshold, rising VP. + 0 = 3.1V + 1 = 3.2V + 2 = 3.3V (Default) + 3 = 3.4V + + - cirrus,battery-threshold : Low battery nominal threshold, falling VP. + 0 = 3.1V + 1 = 3.2V + 2 = 3.3V + 3 = 3.4V (Default) + 4 = 3.5V + 5 = 3.6V + +Example: + +codec: codec@40 { + compatible = "cirrus,cs35l32"; + reg = <0x40>; + reset-gpios = <&gpio 10 0>; + cirrus,boost-manager = <0x03>; + cirrus,sdout-datacfg = <0x02>; + VA-supply = <®_audio>; +}; -- GitLab From 38f57532ede565a3c71da7b7727369f374c51acb Mon Sep 17 00:00:00 2001 From: Brian Austin Date: Thu, 7 Aug 2014 09:34:38 -0500 Subject: [PATCH 0696/9167] ASoC: cs35l32: fix compile warning for i2c_probe Forgot to add a return for err_disable goto statement. Causes compile warning of control reaching end of non-void Signed-off-by: Brian Austin Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 90565d59def7..9c6b2723d343 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c @@ -549,6 +549,7 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client, err_disable: regulator_bulk_disable(ARRAY_SIZE(cs35l32->supplies), cs35l32->supplies); + return ret; } static int cs35l32_i2c_remove(struct i2c_client *i2c_client) -- GitLab From 708b4351f08c08ea93f773fb9197bdd3f3b08273 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Wed, 30 Jul 2014 19:27:38 +0800 Subject: [PATCH 0697/9167] ASoC: fsl: Add Freescale Generic ASoC Sound Card with ASRC support The Freescale Generic ASoC Sound Card is a general ASoC DAI Link driver that can be used, ideally, for all Freescale CPU DAI drivers and external CODECs. The idea of this generic sound card is a bit like ASoC Simple Card. However, for Freescale SoCs (especially those released in recent years), most of them have ASRC (Documentation/devicetree/bindings/sound/fsl,asrc.txt) inside. And this is a specific feature that might be painstakingly controlled and merged into the Simple Card driver. So having this driver will allow all Freescale SoC users to benefit from the simplification to support a new card and the capability of wide sample rates support through ASRC. The driver is initially designed for sound card using I2S or PCM DAI formats. However, it's also possible to merge those non-I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, into this card as long as the merge will not break the original function and as long as there is something redundant that can be abstracted along with I2S type sound cards. As an initial version, it only supports three cards that I can test: imx-audio-cs42888, a new card that links ESAI with CS42888 CODEC imx-audio-sgtl5000, just like the old imx-sgtl5000.c driver imx-audio-wm8962, just like the old imx-wm8962.c driver The driver is also compatible with the old Device Tree bindings of WM8962 and SGTL5000. So we may consider to remove those two drivers after this driver is totally enabled. (It needs to be added into defconfig) Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../bindings/sound/fsl-asoc-card.txt | 82 +++ sound/soc/fsl/Kconfig | 16 + sound/soc/fsl/Makefile | 2 + sound/soc/fsl/fsl-asoc-card.c | 573 ++++++++++++++++++ 4 files changed, 673 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt create mode 100644 sound/soc/fsl/fsl-asoc-card.c diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt new file mode 100644 index 000000000000..a96774c194c8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt @@ -0,0 +1,82 @@ +Freescale Generic ASoC Sound Card with ASRC support + +The Freescale Generic ASoC Sound Card can be used, ideally, for all Freescale +SoCs connecting with external CODECs. + +The idea of this generic sound card is a bit like ASoC Simple Card. However, +for Freescale SoCs (especially those released in recent years), most of them +have ASRC (Documentation/devicetree/bindings/sound/fsl,asrc.txt) inside. And +this is a specific feature that might be painstakingly controlled and merged +into the Simple Card. + +So having this generic sound card allows all Freescale SoC users to benefit +from the simplification of a new card support and the capability of the wide +sample rates support through ASRC. + +Note: The card is initially designed for those sound cards who use I2S and + PCM DAI formats. However, it'll be also possible to support those non + I2S/PCM type sound cards, such as S/PDIF audio and HDMI audio, as long + as the driver has been properly upgraded. + + +The compatible list for this generic sound card currently: + "fsl,imx-audio-cs42888" + + "fsl,imx-audio-wm8962" + (compatible with Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt) + + "fsl,imx-audio-sgtl5000" + (compatible with Documentation/devicetree/bindings/sound/imx-audio-sgtl5000.txt) + +Required properties: + + - compatible : Contains one of entries in the compatible list. + + - model : The user-visible name of this sound complex + + - audio-cpu : The phandle of an CPU DAI controller + + - audio-codec : The phandle of an 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. There're a few pre-designed board connectors: + * Line Out Jack + * Line In Jack + * Headphone Jack + * Mic Jack + * Ext Spk + * AMIC (stands for Analog Microphone Jack) + * DMIC (stands for Digital Microphone Jack) + + Note: The "Mic Jack" and "AMIC" are redundant while + coexsiting in order to support the old bindings + of wm8962 and sgtl5000. + +Optional properties: + + - audio-asrc : The phandle of ASRC. It can be absent if there's no + need to add ASRC support via DPCM. + +Example: +sound-cs42888 { + compatible = "fsl,imx-audio-cs42888"; + model = "cs42888-audio"; + audio-cpu = <&esai>; + audio-asrc = <&asrc>; + audio-codec = <&cs42888>; + audio-routing = + "Line Out Jack", "AOUT1L", + "Line Out Jack", "AOUT1R", + "Line Out Jack", "AOUT2L", + "Line Out Jack", "AOUT2R", + "Line Out Jack", "AOUT3L", + "Line Out Jack", "AOUT3R", + "Line Out Jack", "AOUT4L", + "Line Out Jack", "AOUT4R", + "AIN1L", "Line In Jack", + "AIN1R", "Line In Jack", + "AIN2L", "Line In Jack", + "AIN2R", "Line In Jack"; +}; diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index f54a8fc99291..2b99a9e86899 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -59,6 +59,22 @@ config SND_SOC_FSL_ESAI config SND_SOC_FSL_UTILS tristate +config SND_SOC_FSL_ASOC_CARD + tristate "Generic ASoC Sound Card with ASRC support" + depends on OF && I2C + select SND_SOC_IMX_PCM_DMA + select SND_SOC_FSL_ESAI + select SND_SOC_FSL_SAI + select SND_SOC_FSL_SSI + select SND_SOC_CS42XX8_I2C + select SND_SOC_SGTL5000 + select SND_SOC_WM8962 + help + ALSA SoC Audio support with ASRC feature for Freescale SoCs that have + ESAI/SAI/SSI and connect with external CODECs such as WM8962, CS42888 + and SGTL5000. + Say Y if you want to add support for Freescale Generic ASoC Sound Card. + config SND_SOC_IMX_PCM_DMA tristate select SND_SOC_GENERIC_DMAENGINE_PCM diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 9ff59267eac9..8f6d84efa973 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -11,6 +11,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o # Freescale SSI/DMA/SAI/SPDIF Support +snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o snd-soc-fsl-sai-objs := fsl_sai.o snd-soc-fsl-ssi-y := fsl_ssi.o @@ -19,6 +20,7 @@ snd-soc-fsl-spdif-objs := fsl_spdif.o snd-soc-fsl-esai-objs := fsl_esai.o snd-soc-fsl-utils-objs := fsl_utils.o snd-soc-fsl-dma-objs := fsl_dma.o +obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c new file mode 100644 index 000000000000..cf3f1f47f1e8 --- /dev/null +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -0,0 +1,573 @@ +/* + * Freescale Generic ASoC Sound Card driver with ASRC + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * Author: Nicolin Chen + * + * 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 "fsl_esai.h" +#include "fsl_sai.h" +#include "imx-audmux.h" + +#include "../codecs/sgtl5000.h" +#include "../codecs/wm8962.h" + +#define RX 0 +#define TX 1 + +/* Default DAI format without Master and Slave flag */ +#define DAI_FMT_BASE (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF) + +/** + * CODEC private data + * + * @mclk_freq: Clock rate of MCLK + * @mclk_id: MCLK (or main clock) id for set_sysclk() + * @fll_id: FLL (or secordary clock) id for set_sysclk() + * @pll_id: PLL id for set_pll() + */ +struct codec_priv { + unsigned long mclk_freq; + u32 mclk_id; + u32 fll_id; + u32 pll_id; +}; + +/** + * CPU private data + * + * @sysclk_freq[2]: SYSCLK rates for set_sysclk() + * @sysclk_dir[2]: SYSCLK directions for set_sysclk() + * @sysclk_id[2]: SYSCLK ids for set_sysclk() + * + * Note: [1] for tx and [0] for rx + */ +struct cpu_priv { + unsigned long sysclk_freq[2]; + u32 sysclk_dir[2]; + u32 sysclk_id[2]; +}; + +/** + * Freescale Generic ASOC card private data + * + * @dai_link[3]: DAI link structure including normal one and DPCM link + * @pdev: platform device pointer + * @codec_priv: CODEC private data + * @cpu_priv: CPU private data + * @card: ASoC card structure + * @sample_rate: Current sample rate + * @sample_format: Current sample format + * @asrc_rate: ASRC sample rate used by Back-Ends + * @asrc_format: ASRC sample format used by Back-Ends + * @dai_fmt: DAI format between CPU and CODEC + * @name: Card name + */ + +struct fsl_asoc_card_priv { + struct snd_soc_dai_link dai_link[3]; + struct platform_device *pdev; + struct codec_priv codec_priv; + struct cpu_priv cpu_priv; + struct snd_soc_card card; + u32 sample_rate; + u32 sample_format; + u32 asrc_rate; + u32 asrc_format; + u32 dai_fmt; + char name[32]; +}; + +/** + * This dapm route map exsits for DPCM link only. + * The other routes shall go through Device Tree. + */ +static const struct snd_soc_dapm_route audio_map[] = { + {"CPU-Playback", NULL, "ASRC-Playback"}, + {"Playback", NULL, "CPU-Playback"}, + {"ASRC-Capture", NULL, "CPU-Capture"}, + {"CPU-Capture", NULL, "Capture"}, +}; + +/* Add all possible widgets into here without being redundant */ +static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = { + SND_SOC_DAPM_LINE("Line Out Jack", NULL), + SND_SOC_DAPM_LINE("Line In Jack", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_MIC("AMIC", NULL), + SND_SOC_DAPM_MIC("DMIC", NULL), +}; + +static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; + struct cpu_priv *cpu_priv = &priv->cpu_priv; + struct device *dev = rtd->card->dev; + int ret; + + priv->sample_rate = params_rate(params); + priv->sample_format = params_format(params); + + if (priv->card.set_bias_level) + return 0; + + /* Specific configurations of DAIs starts from here */ + ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, cpu_priv->sysclk_id[tx], + cpu_priv->sysclk_freq[tx], + cpu_priv->sysclk_dir[tx]); + if (ret) { + dev_err(dev, "failed to set sysclk for cpu dai\n"); + return ret; + } + + return 0; +} + +static struct snd_soc_ops fsl_asoc_card_ops = { + .hw_params = fsl_asoc_card_hw_params, +}; + +static int be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); + struct snd_interval *rate; + struct snd_mask *mask; + + rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); + rate->max = rate->min = priv->asrc_rate; + + mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); + snd_mask_none(mask); + snd_mask_set(mask, priv->asrc_format); + + return 0; +} + +static struct snd_soc_dai_link fsl_asoc_card_dai[] = { + /* Default ASoC DAI Link*/ + { + .name = "HiFi", + .stream_name = "HiFi", + .ops = &fsl_asoc_card_ops, + }, + /* DPCM Link between Front-End and Back-End (Optional) */ + { + .name = "HiFi-ASRC-FE", + .stream_name = "HiFi-ASRC-FE", + .codec_name = "snd-soc-dummy", + .codec_dai_name = "snd-soc-dummy-dai", + .dpcm_playback = 1, + .dpcm_capture = 1, + .dynamic = 1, + }, + { + .name = "HiFi-ASRC-BE", + .stream_name = "HiFi-ASRC-BE", + .platform_name = "snd-soc-dummy", + .be_hw_params_fixup = be_hw_params_fixup, + .ops = &fsl_asoc_card_ops, + .dpcm_playback = 1, + .dpcm_capture = 1, + .no_pcm = 1, + }, +}; + +static int fsl_asoc_card_set_bias_level(struct snd_soc_card *card, + struct snd_soc_dapm_context *dapm, + enum snd_soc_bias_level level) +{ + struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); + struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; + struct codec_priv *codec_priv = &priv->codec_priv; + struct device *dev = card->dev; + unsigned int pll_out; + int ret; + + if (dapm->dev != codec_dai->dev) + return 0; + + switch (level) { + case SND_SOC_BIAS_PREPARE: + if (dapm->bias_level != SND_SOC_BIAS_STANDBY) + break; + + if (priv->sample_format == SNDRV_PCM_FORMAT_S24_LE) + pll_out = priv->sample_rate * 384; + else + pll_out = priv->sample_rate * 256; + + ret = snd_soc_dai_set_pll(codec_dai, codec_priv->pll_id, + codec_priv->mclk_id, + codec_priv->mclk_freq, pll_out); + if (ret) { + dev_err(dev, "failed to start FLL: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->fll_id, + pll_out, SND_SOC_CLOCK_IN); + if (ret) { + dev_err(dev, "failed to set SYSCLK: %d\n", ret); + return ret; + } + break; + + case SND_SOC_BIAS_STANDBY: + if (dapm->bias_level != SND_SOC_BIAS_PREPARE) + break; + + ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id, + codec_priv->mclk_freq, + SND_SOC_CLOCK_IN); + if (ret) { + dev_err(dev, "failed to switch away from FLL: %d\n", ret); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, codec_priv->pll_id, 0, 0, 0); + if (ret) { + dev_err(dev, "failed to stop FLL: %d\n", ret); + return ret; + } + break; + + default: + break; + } + + return 0; +} + +static int fsl_asoc_card_audmux_init(struct device_node *np, + struct fsl_asoc_card_priv *priv) +{ + struct device *dev = &priv->pdev->dev; + u32 int_ptcr = 0, ext_ptcr = 0; + int int_port, ext_port; + int ret; + + ret = of_property_read_u32(np, "mux-int-port", &int_port); + if (ret) { + dev_err(dev, "mux-int-port missing or invalid\n"); + return ret; + } + ret = of_property_read_u32(np, "mux-ext-port", &ext_port); + if (ret) { + dev_err(dev, "mux-ext-port missing or invalid\n"); + return ret; + } + + /* + * The port numbering in the hardware manual starts at 1, while + * the AUDMUX API expects it starts at 0. + */ + int_port--; + ext_port--; + + /* + * Use asynchronous mode (6 wires) for all cases. + * If only 4 wires are needed, just set SSI into + * synchronous mode and enable 4 PADs in IOMUX. + */ + switch (priv->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + int_ptcr = IMX_AUDMUX_V2_PTCR_RFSEL(8 | ext_port) | + IMX_AUDMUX_V2_PTCR_RCSEL(8 | ext_port) | + IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) | + IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) | + IMX_AUDMUX_V2_PTCR_RFSDIR | + IMX_AUDMUX_V2_PTCR_RCLKDIR | + IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TCLKDIR; + break; + case SND_SOC_DAIFMT_CBM_CFS: + int_ptcr = IMX_AUDMUX_V2_PTCR_RCSEL(8 | ext_port) | + IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) | + IMX_AUDMUX_V2_PTCR_RCLKDIR | + IMX_AUDMUX_V2_PTCR_TCLKDIR; + ext_ptcr = IMX_AUDMUX_V2_PTCR_RFSEL(8 | int_port) | + IMX_AUDMUX_V2_PTCR_TFSEL(int_port) | + IMX_AUDMUX_V2_PTCR_RFSDIR | + IMX_AUDMUX_V2_PTCR_TFSDIR; + break; + case SND_SOC_DAIFMT_CBS_CFM: + int_ptcr = IMX_AUDMUX_V2_PTCR_RFSEL(8 | ext_port) | + IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) | + IMX_AUDMUX_V2_PTCR_RFSDIR | + IMX_AUDMUX_V2_PTCR_TFSDIR; + ext_ptcr = IMX_AUDMUX_V2_PTCR_RCSEL(8 | int_port) | + IMX_AUDMUX_V2_PTCR_TCSEL(int_port) | + IMX_AUDMUX_V2_PTCR_RCLKDIR | + IMX_AUDMUX_V2_PTCR_TCLKDIR; + break; + case SND_SOC_DAIFMT_CBS_CFS: + ext_ptcr = IMX_AUDMUX_V2_PTCR_RFSEL(8 | int_port) | + IMX_AUDMUX_V2_PTCR_RCSEL(8 | int_port) | + IMX_AUDMUX_V2_PTCR_TFSEL(int_port) | + IMX_AUDMUX_V2_PTCR_TCSEL(int_port) | + IMX_AUDMUX_V2_PTCR_RFSDIR | + IMX_AUDMUX_V2_PTCR_RCLKDIR | + IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TCLKDIR; + break; + default: + return -EINVAL; + } + + /* Asynchronous mode can not be set along with RCLKDIR */ + ret = imx_audmux_v2_configure_port(int_port, 0, + IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)); + if (ret) { + dev_err(dev, "audmux internal port setup failed\n"); + return ret; + } + + ret = imx_audmux_v2_configure_port(int_port, int_ptcr, + IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)); + if (ret) { + dev_err(dev, "audmux internal port setup failed\n"); + return ret; + } + + ret = imx_audmux_v2_configure_port(ext_port, 0, + IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); + if (ret) { + dev_err(dev, "audmux external port setup failed\n"); + return ret; + } + + ret = imx_audmux_v2_configure_port(ext_port, ext_ptcr, + IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); + if (ret) { + dev_err(dev, "audmux external port setup failed\n"); + return ret; + } + + return 0; +} + +static int fsl_asoc_card_late_probe(struct snd_soc_card *card) +{ + struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card); + struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; + struct codec_priv *codec_priv = &priv->codec_priv; + struct device *dev = card->dev; + int ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, codec_priv->mclk_id, + codec_priv->mclk_freq, SND_SOC_CLOCK_IN); + if (ret) { + dev_err(dev, "failed to set sysclk in %s\n", __func__); + return ret; + } + + return 0; +} + +static int fsl_asoc_card_probe(struct platform_device *pdev) +{ + struct device_node *cpu_np, *codec_np, *asrc_np; + struct device_node *np = pdev->dev.of_node; + struct platform_device *asrc_pdev = NULL; + struct platform_device *cpu_pdev; + struct fsl_asoc_card_priv *priv; + struct i2c_client *codec_dev; + struct clk *codec_clk; + u32 width; + int ret; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + cpu_np = of_parse_phandle(np, "audio-cpu", 0); + /* Give a chance to old DT binding */ + if (!cpu_np) + cpu_np = of_parse_phandle(np, "ssi-controller", 0); + codec_np = of_parse_phandle(np, "audio-codec", 0); + if (!cpu_np || !codec_np) { + dev_err(&pdev->dev, "phandle missing or invalid\n"); + ret = -EINVAL; + goto fail; + } + + cpu_pdev = of_find_device_by_node(cpu_np); + if (!cpu_pdev) { + dev_err(&pdev->dev, "failed to find CPU DAI device\n"); + ret = -EINVAL; + goto fail; + } + + codec_dev = of_find_i2c_device_by_node(codec_np); + if (!codec_dev) { + dev_err(&pdev->dev, "failed to find codec platform device\n"); + ret = -EINVAL; + goto fail; + } + + asrc_np = of_parse_phandle(np, "audio-asrc", 0); + if (asrc_np) + asrc_pdev = of_find_device_by_node(asrc_np); + + /* Get the MCLK rate only, and leave it controlled by CODEC drivers */ + codec_clk = clk_get(&codec_dev->dev, NULL); + if (!IS_ERR(codec_clk)) { + priv->codec_priv.mclk_freq = clk_get_rate(codec_clk); + clk_put(codec_clk); + } + + /* Default sample rate and format, will be updated in hw_params() */ + priv->sample_rate = 44100; + priv->sample_format = SNDRV_PCM_FORMAT_S16_LE; + + /* Assign a default DAI format, and allow each card to overwrite it */ + priv->dai_fmt = DAI_FMT_BASE; + + /* Diversify the card configurations */ + if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) { + priv->card.set_bias_level = NULL; + priv->cpu_priv.sysclk_freq[TX] = priv->codec_priv.mclk_freq; + 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->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; + priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; + } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8962")) { + priv->card.set_bias_level = fsl_asoc_card_set_bias_level; + priv->codec_priv.mclk_id = WM8962_SYSCLK_MCLK; + priv->codec_priv.fll_id = WM8962_SYSCLK_FLL; + priv->codec_priv.pll_id = WM8962_FLL; + priv->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM; + } else { + dev_err(&pdev->dev, "unknown Device Tree compatible\n"); + return -EINVAL; + } + + /* Common settings for corresponding Freescale CPU DAI driver */ + if (strstr(cpu_np->name, "ssi")) { + /* Only SSI needs to configure AUDMUX */ + ret = fsl_asoc_card_audmux_init(np, priv); + if (ret) { + dev_err(&pdev->dev, "failed to init audmux\n"); + goto fail; + } + } else if (strstr(cpu_np->name, "esai")) { + priv->cpu_priv.sysclk_id[1] = ESAI_HCKT_EXTAL; + priv->cpu_priv.sysclk_id[0] = ESAI_HCKR_EXTAL; + } else if (strstr(cpu_np->name, "sai")) { + priv->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1; + priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1; + } + + sprintf(priv->name, "%s-audio", codec_dev->name); + + /* Initialize sound card */ + priv->pdev = pdev; + priv->card.dev = &pdev->dev; + priv->card.name = priv->name; + priv->card.dai_link = priv->dai_link; + priv->card.dapm_routes = audio_map; + priv->card.late_probe = fsl_asoc_card_late_probe; + priv->card.num_dapm_routes = ARRAY_SIZE(audio_map); + priv->card.dapm_widgets = fsl_asoc_card_dapm_widgets; + priv->card.num_dapm_widgets = ARRAY_SIZE(fsl_asoc_card_dapm_widgets); + + memcpy(priv->dai_link, fsl_asoc_card_dai, + sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link)); + + /* Normal DAI Link */ + priv->dai_link[0].cpu_of_node = cpu_np; + priv->dai_link[0].codec_of_node = codec_np; + priv->dai_link[0].codec_dai_name = codec_dev->name; + priv->dai_link[0].platform_of_node = cpu_np; + priv->dai_link[0].dai_fmt = priv->dai_fmt; + priv->card.num_links = 1; + + if (asrc_pdev) { + /* DPCM DAI Links only if ASRC exsits */ + priv->dai_link[1].cpu_of_node = asrc_np; + priv->dai_link[1].platform_of_node = asrc_np; + priv->dai_link[2].codec_dai_name = codec_dev->name; + priv->dai_link[2].codec_of_node = codec_np; + priv->dai_link[2].cpu_of_node = cpu_np; + priv->dai_link[2].dai_fmt = priv->dai_fmt; + priv->card.num_links = 3; + + ret = of_property_read_u32(asrc_np, "fsl,asrc-rate", + &priv->asrc_rate); + if (ret) { + dev_err(&pdev->dev, "failed to get output rate\n"); + ret = -EINVAL; + goto fail; + } + + ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width); + if (ret) { + dev_err(&pdev->dev, "failed to get output rate\n"); + ret = -EINVAL; + goto fail; + } + + if (width == 24) + priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE; + else + priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE; + } + + /* Finish card registering */ + platform_set_drvdata(pdev, priv); + snd_soc_card_set_drvdata(&priv->card, priv); + + ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); + if (ret) + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); + +fail: + of_node_put(codec_np); + of_node_put(asrc_np); + of_node_put(cpu_np); + + return ret; +} + +static const struct of_device_id fsl_asoc_card_dt_ids[] = { + { .compatible = "fsl,imx-audio-cs42888", }, + { .compatible = "fsl,imx-audio-sgtl5000", }, + { .compatible = "fsl,imx-audio-wm8962", }, + {} +}; + +static struct platform_driver fsl_asoc_card_driver = { + .probe = fsl_asoc_card_probe, + .driver = { + .name = "fsl-asoc-card", + .pm = &snd_soc_pm_ops, + .of_match_table = fsl_asoc_card_dt_ids, + }, +}; +module_platform_driver(fsl_asoc_card_driver); + +MODULE_DESCRIPTION("Freescale Generic ASoC Sound Card driver with ASRC"); +MODULE_AUTHOR("Nicolin Chen "); +MODULE_ALIAS("platform:fsl-asoc-card"); +MODULE_LICENSE("GPL"); -- GitLab From de0d712a6dd1eed097dc6aa4f97ee461949414fe Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 8 Aug 2014 14:47:21 +0800 Subject: [PATCH 0698/9167] ASoC: fsl_esai: refine esai for TDM support Original driver didn't store the number of slots, just fix the slot number to 2, use this default number to calculate bclk and pins for TX/RX. In this patch, add one parameter for slots, and update the calculation of bclk and pins of TX/RX. Then driver will be compatible with slots > 2 in TDM mode. Signed-off-by: Shengjiu Wang Acked-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_esai.c | 14 +++++++++++--- sound/soc/fsl/fsl_esai.h | 8 ++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 72d154e7dd03..f252370073e5 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c @@ -38,6 +38,7 @@ * @fsysclk: system clock source to derive HCK, SCK and FS * @fifo_depth: depth of tx/rx FIFO * @slot_width: width of each DAI slot + * @slots: number of slots * @hck_rate: clock rate of desired HCKx clock * @sck_rate: clock rate of desired SCKx clock * @hck_dir: the direction of HCKx pads @@ -56,6 +57,7 @@ struct fsl_esai { struct clk *fsysclk; u32 fifo_depth; u32 slot_width; + u32 slots; u32 hck_rate[2]; u32 sck_rate[2]; bool hck_dir[2]; @@ -363,6 +365,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); esai_priv->slot_width = slot_width; + esai_priv->slots = slots; return 0; } @@ -510,10 +513,11 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u32 width = snd_pcm_format_width(params_format(params)); u32 channels = params_channels(params); + u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); u32 bclk, mask, val; int ret; - bclk = params_rate(params) * esai_priv->slot_width * 2; + bclk = params_rate(params) * esai_priv->slot_width * esai_priv->slots; ret = fsl_esai_set_bclk(dai, tx, bclk); if (ret) @@ -530,7 +534,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK | (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK); val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) | - (tx ? ESAI_xFCR_TE(channels) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(channels)); + (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins)); regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val); @@ -565,6 +569,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; u8 i, channels = substream->runtime->channels; + u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -579,7 +584,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, - tx ? ESAI_xCR_TE(channels) : ESAI_xCR_RE(channels)); + tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: @@ -783,6 +788,9 @@ static int fsl_esai_probe(struct platform_device *pdev) /* Set a default slot size */ esai_priv->slot_width = 32; + /* Set a default slot number */ + esai_priv->slots = 2; + /* Set a default master/slave state */ esai_priv->slave_mode = true; diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h index 75e14033e8d8..91a550f4a10d 100644 --- a/sound/soc/fsl/fsl_esai.h +++ b/sound/soc/fsl/fsl_esai.h @@ -130,8 +130,8 @@ #define ESAI_xFCR_RE_WIDTH 4 #define ESAI_xFCR_TE_MASK (((1 << ESAI_xFCR_TE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) #define ESAI_xFCR_RE_MASK (((1 << ESAI_xFCR_RE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) -#define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_TE_MASK) -#define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_RE_MASK) +#define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - x)) & ESAI_xFCR_TE_MASK) +#define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - x)) & ESAI_xFCR_RE_MASK) #define ESAI_xFCR_xFR_SHIFT 1 #define ESAI_xFCR_xFR_MASK (1 << ESAI_xFCR_xFR_SHIFT) #define ESAI_xFCR_xFR (1 << ESAI_xFCR_xFR_SHIFT) @@ -272,8 +272,8 @@ #define ESAI_xCR_RE_WIDTH 4 #define ESAI_xCR_TE_MASK (((1 << ESAI_xCR_TE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) #define ESAI_xCR_RE_MASK (((1 << ESAI_xCR_RE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) -#define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_TE_MASK) -#define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_RE_MASK) +#define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - x)) & ESAI_xCR_TE_MASK) +#define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - x)) & ESAI_xCR_RE_MASK) /* * Transmit Clock Control Register -- REG_ESAI_TCCR 0xD8 -- GitLab From 376d1a92ca587d3974d4791cdb99baa8b8e7f0dd Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 5 Aug 2014 17:20:21 +0800 Subject: [PATCH 0699/9167] ASoC: fsl_sai: Initialize with software reset This patch adds software reset code in dai_probe() so as to make a true init by clearing SAI's internal logic, including the bit clock generation, status flags, and FIFO pointers. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 9 +++++++-- sound/soc/fsl/fsl_sai.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index faa049797897..7b1eecbc4f60 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -437,8 +437,13 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) { struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); - regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0); - regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0); + /* Software Reset for both Tx and Rx */ + regmap_write(sai->regmap, FSL_SAI_TCSR, FSL_SAI_CSR_SR); + regmap_write(sai->regmap, FSL_SAI_RCSR, FSL_SAI_CSR_SR); + /* Clear SR bit to finish the reset */ + regmap_write(sai->regmap, FSL_SAI_TCSR, 0); + regmap_write(sai->regmap, FSL_SAI_RCSR, 0); + regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, FSL_SAI_MAXBURST_TX * 2); regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 0e6c9f595d75..8e1feab7c2a0 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -48,6 +48,7 @@ /* SAI Transmit/Recieve Control Register */ #define FSL_SAI_CSR_TERE BIT(31) #define FSL_SAI_CSR_FR BIT(25) +#define FSL_SAI_CSR_SR BIT(24) #define FSL_SAI_CSR_xF_SHIFT 16 #define FSL_SAI_CSR_xF_W_SHIFT 18 #define FSL_SAI_CSR_xF_MASK (0x1f << FSL_SAI_CSR_xF_SHIFT) -- GitLab From af96ff5b7448dc776dc24a5c4313c6ec1ee94e53 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Mon, 4 Aug 2014 15:07:25 +0800 Subject: [PATCH 0700/9167] ASoC: fsl_sai: Set SYNC bit of TCR2 to Asynchronous Mode There is one design rule according to SAI's reference manual: If the transmitter bit clock and frame sync are to be used by both transmitter and receiver, the transmitter must be configured for asynchronous operation and the receiver for synchronous operation. And SYNC of TCR2 is a 2-width control bit: 00 Asynchronous mode. 01 Synchronous with receiver. 10 Synchronous with another SAI transmitter. 11 Synchronous with another SAI receiver. So the driver should have set SYNC bit of TCR2 to 0x0, and meanwhile set SYNC bit of RCR2 to 0x1 (Synchronous with transmitter). Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 7b1eecbc4f60..3d865ad466ad 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -333,8 +333,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, * The transmitter bit clock and frame sync are to be * used by both the transmitter and receiver. */ - regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, - ~FSL_SAI_CR2_SYNC); + regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0); regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, FSL_SAI_CR2_SYNC); -- GitLab From 08fdf65e37d560581233e06a659f73deeb3766f9 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 5 Aug 2014 15:32:05 +0800 Subject: [PATCH 0701/9167] ASoC: fsl_sai: Add asynchronous mode support SAI supports these operation modes: 1) asynchronous mode Both Tx and Rx are set to be asynchronous. 2) synchronous mode (Rx sync with Tx) Tx is set to be asynchronous, Rx is set to be synchronous. 3) synchronous mode (Tx sync with Rx) Rx is set to be asynchronous, Tx is set to be synchronous. 4) synchronous mode (Tx/Rx sync with another SAI's Tx) 5) synchronous mode (Tx/Rx sync with another SAI's Rx) * 4) and 5) are beyond this patch because they are related with another SAI. As the initial version of this SAI driver, it supported 2) as default while the others were totally missing. So this patch just adds supports for 1) and 3). Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/fsl-sai.txt | 16 ++++++++++ sound/soc/fsl/fsl_sai.c | 30 ++++++++++++++++--- sound/soc/fsl/fsl_sai.h | 4 +++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 0f4e23828190..77864f4dd352 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -24,6 +24,22 @@ Required properties: - big-endian-data: If this property is absent, the little endian mode will be in use as default, or the big endian mode will be in use for all the fifo data. +- 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. + +Note: +- If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the + default synchronous mode (sync Rx with Tx) will be used, which means both + transimitter and receiver will send and receive data by following clocks + of transimitter. +- fsl,sai-asynchronous will be ignored if fsl,sai-synchronous-rx property is + already present. Example: sai2: sai@40031000 { diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 3d865ad466ad..ef7c758627b1 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -330,12 +330,14 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, u32 xcsr, count = 100; /* - * The transmitter bit clock and frame sync are to be - * used by both the transmitter and receiver. + * Asynchronous mode: Clear SYNC for both Tx and Rx. + * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. + * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. */ - regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0); + regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, + sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, - FSL_SAI_CR2_SYNC); + sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); /* * It is recommended that the transmitter is the last enabled @@ -625,6 +627,26 @@ static int fsl_sai_probe(struct platform_device *pdev) return ret; } + /* Sync Tx with Rx as default by following old DT binding */ + sai->synchronous[RX] = true; + sai->synchronous[TX] = false; + fsl_sai_dai.symmetric_rates = 1; + fsl_sai_dai.symmetric_channels = 1; + fsl_sai_dai.symmetric_samplebits = 1; + + if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) { + /* Sync Rx with Tx */ + sai->synchronous[RX] = false; + sai->synchronous[TX] = true; + } else if (of_find_property(np, "fsl,sai-asynchronous", NULL)) { + /* Discard all settings for asynchronous mode */ + sai->synchronous[RX] = false; + sai->synchronous[TX] = false; + fsl_sai_dai.symmetric_rates = 0; + fsl_sai_dai.symmetric_channels = 0; + fsl_sai_dai.symmetric_samplebits = 0; + } + sai->dma_params_rx.addr = res->start + FSL_SAI_RDR; sai->dma_params_tx.addr = res->start + FSL_SAI_TDR; sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX; diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index 8e1feab7c2a0..b3d8864cd5f2 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -136,9 +136,13 @@ struct fsl_sai { bool big_endian_data; bool is_dsp_mode; bool sai_on_imx; + bool synchronous[2]; struct snd_dmaengine_dai_dma_data dma_params_rx; struct snd_dmaengine_dai_dma_data dma_params_tx; }; +#define TX 1 +#define RX 0 + #endif /* __FSL_SAI_H */ -- GitLab From ce7344a4ebabe90e064d3e087727f45624cdc942 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Fri, 8 Aug 2014 18:41:19 +0800 Subject: [PATCH 0702/9167] ASoC: fsl_sai: Make Synchronous and Asynchronous modes exclusive The previous patch (ASoC: fsl_sai: Add asynchronous mode support) added new Device Tree bindings for Asynchronous and Synchronous modes support. However, these two shall not be present at the same time. So this patch just simply makes them exclusive so as to avoid incorrect Device Tree binding usage. Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/fsl-sai.txt | 3 +-- sound/soc/fsl/fsl_sai.c | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 77864f4dd352..dc9f9c356268 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt @@ -38,8 +38,7 @@ Note: default synchronous mode (sync Rx with Tx) will be used, which means both transimitter and receiver will send and receive data by following clocks of transimitter. -- fsl,sai-asynchronous will be ignored if fsl,sai-synchronous-rx property is - already present. +- fsl,sai-asynchronous and fsl,sai-synchronous-rx are exclusive. Example: sai2: sai@40031000 { diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index ef7c758627b1..4c9e71c2f52a 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -634,6 +634,13 @@ static int fsl_sai_probe(struct platform_device *pdev) fsl_sai_dai.symmetric_channels = 1; fsl_sai_dai.symmetric_samplebits = 1; + if (of_find_property(np, "fsl,sai-synchronous-rx", NULL) && + of_find_property(np, "fsl,sai-asynchronous", NULL)) { + /* error out if both synchronous and asynchronous are present */ + dev_err(&pdev->dev, "invalid binding for synchronous mode\n"); + return -EINVAL; + } + if (of_find_property(np, "fsl,sai-synchronous-rx", NULL)) { /* Sync Rx with Tx */ sai->synchronous[RX] = false; -- GitLab From ea5edfe2f1ce5b2254a5ec4c1bb224fac48c3153 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 4 Aug 2014 15:04:19 +0530 Subject: [PATCH 0703/9167] ASoC: Intel: Fix to use byte control interface Using a byte control interface instead of generic_params ioctl. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-mfld-platform.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h index 6c6a42c08e24..cc3a088df7dd 100644 --- a/sound/soc/intel/sst-mfld-platform.h +++ b/sound/soc/intel/sst-mfld-platform.h @@ -63,9 +63,7 @@ enum sst_controls { SST_SND_BUFFER_POINTER = 0x05, SST_SND_STREAM_INIT = 0x06, SST_SND_START = 0x07, - SST_SET_BYTE_STREAM = 0x100A, - SST_GET_BYTE_STREAM = 0x100B, - SST_MAX_CONTROLS = SST_GET_BYTE_STREAM, + SST_MAX_CONTROLS = 0x07, }; enum sst_stream_ops { @@ -129,7 +127,7 @@ struct compress_sst_ops { struct sst_ops { int (*open) (struct snd_sst_params *str_param); int (*device_control) (int cmd, void *arg); - int (*set_generic_params)(enum sst_controls cmd, void *arg); + int (*send_byte_stream)(struct snd_sst_bytes_v2 *bytes); int (*close) (unsigned int str_id); }; -- GitLab From 5981c2d6db2ef16d96ee4d1c4d3ddff4ad9d8ebc Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Mon, 4 Aug 2014 15:04:20 +0530 Subject: [PATCH 0704/9167] ASoC: Intel: mfld-pcm: Use function instead of ioctl Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-mfld-platform-pcm.c | 21 +++++++++------------ sound/soc/intel/sst-mfld-platform.h | 19 ++++++------------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index 706212a6a68c..42766a51c17e 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c @@ -314,8 +314,7 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream) stream->stream_info.arg = substream; stream->stream_info.buffer_ptr = 0; stream->stream_info.sfreq = substream->runtime->rate; - ret_val = stream->ops->device_control( - SST_SND_STREAM_INIT, &stream->stream_info); + ret_val = stream->ops->stream_init(&stream->stream_info); if (ret_val) pr_err("control_set ret error %d\n", ret_val); return ret_val; @@ -403,8 +402,7 @@ static int sst_media_prepare(struct snd_pcm_substream *substream, stream = substream->runtime->private_data; str_id = stream->stream_info.str_id; if (stream->stream_info.str_id) { - ret_val = stream->ops->device_control( - SST_SND_DROP, &str_id); + ret_val = stream->ops->stream_drop(str_id); return ret_val; } @@ -461,7 +459,7 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, { int ret_val = 0, str_id; struct sst_runtime_stream *stream; - int str_cmd, status; + int status; pr_debug("sst_platform_pcm_trigger called\n"); stream = substream->runtime->private_data; @@ -469,29 +467,29 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: pr_debug("sst: Trigger Start\n"); - str_cmd = SST_SND_START; status = SST_PLATFORM_RUNNING; stream->stream_info.arg = substream; + ret_val = stream->ops->stream_start(str_id); break; case SNDRV_PCM_TRIGGER_STOP: pr_debug("sst: in stop\n"); - str_cmd = SST_SND_DROP; status = SST_PLATFORM_DROPPED; + ret_val = stream->ops->stream_drop(str_id); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: pr_debug("sst: in pause\n"); - str_cmd = SST_SND_PAUSE; status = SST_PLATFORM_PAUSED; + ret_val = stream->ops->stream_pause(str_id); break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: pr_debug("sst: in pause release\n"); - str_cmd = SST_SND_RESUME; status = SST_PLATFORM_RUNNING; + ret_val = stream->ops->stream_pause_release(str_id); break; default: return -EINVAL; } - ret_val = stream->ops->device_control(str_cmd, &str_id); + if (!ret_val) sst_set_stream_status(stream, status); @@ -511,8 +509,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer if (status == SST_PLATFORM_INIT) return 0; str_info = &stream->stream_info; - ret_val = stream->ops->device_control( - SST_SND_BUFFER_POINTER, str_info); + ret_val = stream->ops->stream_read_tstamp(str_info); if (ret_val) { pr_err("sst: error code = %d\n", ret_val); return ret_val; diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h index cc3a088df7dd..2d6e65bbbc49 100644 --- a/sound/soc/intel/sst-mfld-platform.h +++ b/sound/soc/intel/sst-mfld-platform.h @@ -54,18 +54,6 @@ enum sst_drv_status { SST_PLATFORM_DROPPED, }; -enum sst_controls { - SST_SND_ALLOC = 0x00, - SST_SND_PAUSE = 0x01, - SST_SND_RESUME = 0x02, - SST_SND_DROP = 0x03, - SST_SND_FREE = 0x04, - SST_SND_BUFFER_POINTER = 0x05, - SST_SND_STREAM_INIT = 0x06, - SST_SND_START = 0x07, - SST_MAX_CONTROLS = 0x07, -}; - enum sst_stream_ops { STREAM_OPS_PLAYBACK = 0, STREAM_OPS_CAPTURE, @@ -126,7 +114,12 @@ struct compress_sst_ops { struct sst_ops { int (*open) (struct snd_sst_params *str_param); - int (*device_control) (int cmd, void *arg); + int (*stream_init) (struct pcm_stream_info *str_info); + int (*stream_start) (int str_id); + int (*stream_drop) (int str_id); + int (*stream_pause) (int str_id); + int (*stream_pause_release) (int str_id); + int (*stream_read_tstamp) (struct pcm_stream_info *str_info); int (*send_byte_stream)(struct snd_sst_bytes_v2 *bytes); int (*close) (unsigned int str_id); }; -- GitLab From b12b087c8715286b8759016f1d5c36cac0bb37f6 Mon Sep 17 00:00:00 2001 From: "Subhransu S. Prusty" Date: Mon, 4 Aug 2014 15:04:21 +0530 Subject: [PATCH 0705/9167] ASoC: Intel: mfld-pcm: Change sst_ops prototypes to take dev parameter sst_ops need to use the sst driver context. So pass sst device as argument, which can be used to retrieve sst context. Signed-off-by: Subhransu S. Prusty Signed-off-by: Vinod Koul Signed-off-by: Mark Brown --- sound/soc/intel/sst-mfld-platform-pcm.c | 19 +++++++++---------- sound/soc/intel/sst-mfld-platform.h | 18 +++++++++--------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index 42766a51c17e..a89ff7e18e1a 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c @@ -277,7 +277,7 @@ static int sst_platform_alloc_stream(struct snd_pcm_substream *substream, stream->stream_info.str_id = str_params.stream_id; - ret_val = stream->ops->open(&str_params); + ret_val = stream->ops->open(sst->dev, &str_params); if (ret_val <= 0) return ret_val; @@ -314,13 +314,12 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream) stream->stream_info.arg = substream; stream->stream_info.buffer_ptr = 0; stream->stream_info.sfreq = substream->runtime->rate; - ret_val = stream->ops->stream_init(&stream->stream_info); + ret_val = stream->ops->stream_init(sst->dev, &stream->stream_info); if (ret_val) pr_err("control_set ret error %d\n", ret_val); return ret_val; } -/* end -- helper functions */ static int sst_media_open(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) @@ -372,7 +371,7 @@ static void sst_media_close(struct snd_pcm_substream *substream, stream = substream->runtime->private_data; str_id = stream->stream_info.str_id; if (str_id) - ret_val = stream->ops->close(str_id); + ret_val = stream->ops->close(sst->dev, str_id); module_put(sst->dev->driver->owner); kfree(stream); } @@ -402,7 +401,7 @@ static int sst_media_prepare(struct snd_pcm_substream *substream, stream = substream->runtime->private_data; str_id = stream->stream_info.str_id; if (stream->stream_info.str_id) { - ret_val = stream->ops->stream_drop(str_id); + ret_val = stream->ops->stream_drop(sst->dev, str_id); return ret_val; } @@ -469,22 +468,22 @@ static int sst_platform_pcm_trigger(struct snd_pcm_substream *substream, pr_debug("sst: Trigger Start\n"); status = SST_PLATFORM_RUNNING; stream->stream_info.arg = substream; - ret_val = stream->ops->stream_start(str_id); + ret_val = stream->ops->stream_start(sst->dev, str_id); break; case SNDRV_PCM_TRIGGER_STOP: pr_debug("sst: in stop\n"); status = SST_PLATFORM_DROPPED; - ret_val = stream->ops->stream_drop(str_id); + ret_val = stream->ops->stream_drop(sst->dev, str_id); break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: pr_debug("sst: in pause\n"); status = SST_PLATFORM_PAUSED; - ret_val = stream->ops->stream_pause(str_id); + ret_val = stream->ops->stream_pause(sst->dev, str_id); break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: pr_debug("sst: in pause release\n"); status = SST_PLATFORM_RUNNING; - ret_val = stream->ops->stream_pause_release(str_id); + ret_val = stream->ops->stream_pause_release(sst->dev, str_id); break; default: return -EINVAL; @@ -509,7 +508,7 @@ static snd_pcm_uframes_t sst_platform_pcm_pointer if (status == SST_PLATFORM_INIT) return 0; str_info = &stream->stream_info; - ret_val = stream->ops->stream_read_tstamp(str_info); + ret_val = stream->ops->stream_read_tstamp(sst->dev, str_info); if (ret_val) { pr_err("sst: error code = %d\n", ret_val); return ret_val; diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h index 2d6e65bbbc49..d4c28b8fb471 100644 --- a/sound/soc/intel/sst-mfld-platform.h +++ b/sound/soc/intel/sst-mfld-platform.h @@ -113,15 +113,15 @@ struct compress_sst_ops { }; struct sst_ops { - int (*open) (struct snd_sst_params *str_param); - int (*stream_init) (struct pcm_stream_info *str_info); - int (*stream_start) (int str_id); - int (*stream_drop) (int str_id); - int (*stream_pause) (int str_id); - int (*stream_pause_release) (int str_id); - int (*stream_read_tstamp) (struct pcm_stream_info *str_info); - int (*send_byte_stream)(struct snd_sst_bytes_v2 *bytes); - int (*close) (unsigned int str_id); + int (*open) (struct device *dev, struct snd_sst_params *str_param); + int (*stream_init) (struct device *dev, struct pcm_stream_info *str_info); + int (*stream_start) (struct device *dev, int str_id); + int (*stream_drop) (struct device *dev, int str_id); + int (*stream_pause) (struct device *dev, int str_id); + int (*stream_pause_release) (struct device *dev, int str_id); + int (*stream_read_tstamp) (struct device *dev, struct pcm_stream_info *str_info); + int (*send_byte_stream)(struct device *dev, struct snd_sst_bytes_v2 *bytes); + int (*close) (struct device *dev, unsigned int str_id); }; struct sst_runtime_stream { -- GitLab From d8499c9b4b03ca88d7c7b4094cb09471658df7c2 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 4 Aug 2014 15:15:55 +0530 Subject: [PATCH 0706/9167] ASoC: Intel: add mrfld DSP defines We define the DSP commands,structures here which will be used to send the IPCs Signed-off-by: Vinod Koul Signed-off-by: Subhransu S. Prusty Signed-off-by: Mark Brown --- sound/soc/intel/Makefile | 3 +- sound/soc/intel/sst-atom-controls.c | 39 ++++ sound/soc/intel/sst-atom-controls.h | 286 +++++++++++++++++++++++- sound/soc/intel/sst-mfld-platform-pcm.c | 8 +- sound/soc/intel/sst-mfld-platform.h | 3 + 5 files changed, 335 insertions(+), 4 deletions(-) create mode 100644 sound/soc/intel/sst-atom-controls.c diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index 7acbfc43a0c6..f841786dad15 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile @@ -2,7 +2,8 @@ snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o snd-soc-sst-acpi-objs := sst-acpi.o -snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o sst-mfld-platform-compress.o +snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o \ + sst-mfld-platform-compress.o sst-atom-controls.o snd-soc-mfld-machine-objs := mfld_machine.o obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o diff --git a/sound/soc/intel/sst-atom-controls.c b/sound/soc/intel/sst-atom-controls.c new file mode 100644 index 000000000000..ace3c4a59b14 --- /dev/null +++ b/sound/soc/intel/sst-atom-controls.c @@ -0,0 +1,39 @@ +/* + * sst-atom-controls.c - Intel MID Platform driver DPCM ALSA controls for Mrfld + * + * Copyright (C) 2013-14 Intel Corp + * Author: Omair Mohammed Abdullah + * Vinod Koul + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include "sst-mfld-platform.h" +#include "sst-atom-controls.h" + +int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform) +{ + int ret = 0; + struct sst_data *drv = snd_soc_platform_get_drvdata(platform); + + drv->byte_stream = devm_kzalloc(platform->dev, + SST_MAX_BIN_BYTES, GFP_KERNEL); + if (!drv->byte_stream) + return -ENOMEM; + + return ret; +} diff --git a/sound/soc/intel/sst-atom-controls.h b/sound/soc/intel/sst-atom-controls.h index 14063ab8c7c5..8554889c0694 100644 --- a/sound/soc/intel/sst-atom-controls.h +++ b/sound/soc/intel/sst-atom-controls.h @@ -1,4 +1,6 @@ /* + * sst-atom-controls.h - Intel MID Platform driver header file + * * Copyright (C) 2013-14 Intel Corp * Author: Ramesh Babu * Omair M Abdullah @@ -18,13 +20,293 @@ * */ -#ifndef __SST_CONTROLS_V2_H__ -#define __SST_CONTROLS_V2_H__ +#ifndef __SST_ATOM_CONTROLS_H__ +#define __SST_ATOM_CONTROLS_H__ enum { MERR_DPCM_AUDIO = 0, MERR_DPCM_COMPR, }; +/* define a bit for each mixer input */ +#define SST_MIX_IP(x) (x) + +#define SST_IP_CODEC0 SST_MIX_IP(2) +#define SST_IP_CODEC1 SST_MIX_IP(3) +#define SST_IP_LOOP0 SST_MIX_IP(4) +#define SST_IP_LOOP1 SST_MIX_IP(5) +#define SST_IP_LOOP2 SST_MIX_IP(6) +#define SST_IP_PROBE SST_MIX_IP(7) +#define SST_IP_VOIP SST_MIX_IP(12) +#define SST_IP_PCM0 SST_MIX_IP(13) +#define SST_IP_PCM1 SST_MIX_IP(14) +#define SST_IP_MEDIA0 SST_MIX_IP(17) +#define SST_IP_MEDIA1 SST_MIX_IP(18) +#define SST_IP_MEDIA2 SST_MIX_IP(19) +#define SST_IP_MEDIA3 SST_MIX_IP(20) + +#define SST_IP_LAST SST_IP_MEDIA3 + +#define SST_SWM_INPUT_COUNT (SST_IP_LAST + 1) +#define SST_CMD_SWM_MAX_INPUTS 6 + +#define SST_PATH_ID_SHIFT 8 +#define SST_DEFAULT_LOCATION_ID 0xFFFF +#define SST_DEFAULT_CELL_NBR 0xFF +#define SST_DEFAULT_MODULE_ID 0xFFFF + +/* + * Audio DSP Path Ids. Specified by the audio DSP FW + */ +enum sst_path_index { + SST_PATH_INDEX_CODEC_OUT0 = (0x02 << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_CODEC_OUT1 = (0x03 << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_SPROT_LOOP_OUT = (0x04 << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_MEDIA_LOOP1_OUT = (0x05 << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_MEDIA_LOOP2_OUT = (0x06 << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_VOIP_OUT = (0x0C << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_PCM0_OUT = (0x0D << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_PCM1_OUT = (0x0E << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_PCM2_OUT = (0x0F << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_MEDIA0_OUT = (0x12 << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_MEDIA1_OUT = (0x13 << SST_PATH_ID_SHIFT), + + + /* Start of input paths */ + SST_PATH_INDEX_CODEC_IN0 = (0x82 << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_CODEC_IN1 = (0x83 << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_SPROT_LOOP_IN = (0x84 << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_MEDIA_LOOP1_IN = (0x85 << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_MEDIA_LOOP2_IN = (0x86 << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_VOIP_IN = (0x8C << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_PCM0_IN = (0x8D << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_PCM1_IN = (0x8E << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_MEDIA0_IN = (0x8F << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_MEDIA1_IN = (0x90 << SST_PATH_ID_SHIFT), + SST_PATH_INDEX_MEDIA2_IN = (0x91 << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_MEDIA3_IN = (0x9C << SST_PATH_ID_SHIFT), + + SST_PATH_INDEX_RESERVED = (0xFF << SST_PATH_ID_SHIFT), +}; + +/* + * path IDs + */ +enum sst_swm_inputs { + SST_SWM_IN_CODEC0 = (SST_PATH_INDEX_CODEC_IN0 | SST_DEFAULT_CELL_NBR), + SST_SWM_IN_CODEC1 = (SST_PATH_INDEX_CODEC_IN1 | SST_DEFAULT_CELL_NBR), + SST_SWM_IN_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_IN | SST_DEFAULT_CELL_NBR), + SST_SWM_IN_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_IN | SST_DEFAULT_CELL_NBR), + SST_SWM_IN_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_IN | SST_DEFAULT_CELL_NBR), + SST_SWM_IN_VOIP = (SST_PATH_INDEX_VOIP_IN | SST_DEFAULT_CELL_NBR), + SST_SWM_IN_PCM0 = (SST_PATH_INDEX_PCM0_IN | SST_DEFAULT_CELL_NBR), + SST_SWM_IN_PCM1 = (SST_PATH_INDEX_PCM1_IN | SST_DEFAULT_CELL_NBR), + SST_SWM_IN_MEDIA0 = (SST_PATH_INDEX_MEDIA0_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ + SST_SWM_IN_MEDIA1 = (SST_PATH_INDEX_MEDIA1_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ + SST_SWM_IN_MEDIA2 = (SST_PATH_INDEX_MEDIA2_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ + SST_SWM_IN_MEDIA3 = (SST_PATH_INDEX_MEDIA3_IN | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ + SST_SWM_IN_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR) +}; + +/* + * path IDs + */ +enum sst_swm_outputs { + SST_SWM_OUT_CODEC0 = (SST_PATH_INDEX_CODEC_OUT0 | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_CODEC1 = (SST_PATH_INDEX_CODEC_OUT1 | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_SPROT_LOOP = (SST_PATH_INDEX_SPROT_LOOP_OUT | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_MEDIA_LOOP1 = (SST_PATH_INDEX_MEDIA_LOOP1_OUT | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_MEDIA_LOOP2 = (SST_PATH_INDEX_MEDIA_LOOP2_OUT | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_VOIP = (SST_PATH_INDEX_VOIP_OUT | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_PCM0 = (SST_PATH_INDEX_PCM0_OUT | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_PCM1 = (SST_PATH_INDEX_PCM1_OUT | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_PCM2 = (SST_PATH_INDEX_PCM2_OUT | SST_DEFAULT_CELL_NBR), + SST_SWM_OUT_MEDIA0 = (SST_PATH_INDEX_MEDIA0_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ + SST_SWM_OUT_MEDIA1 = (SST_PATH_INDEX_MEDIA1_OUT | SST_DEFAULT_CELL_NBR), /* Part of Media Mixer */ + SST_SWM_OUT_END = (SST_PATH_INDEX_RESERVED | SST_DEFAULT_CELL_NBR), +}; + +enum sst_ipc_msg { + SST_IPC_IA_CMD = 1, + SST_IPC_IA_SET_PARAMS, + SST_IPC_IA_GET_PARAMS, +}; + +enum sst_cmd_type { + SST_CMD_BYTES_SET = 1, + SST_CMD_BYTES_GET = 2, +}; + +enum sst_task { + SST_TASK_SBA = 1, + SST_TASK_MMX, +}; + +enum sst_type { + SST_TYPE_CMD = 1, + SST_TYPE_PARAMS, +}; + +enum sst_flag { + SST_FLAG_BLOCKED = 1, + SST_FLAG_NONBLOCK, +}; + +/* + * Enumeration for indexing the gain cells in VB_SET_GAIN DSP command + */ +enum sst_gain_index { + /* GAIN IDs for SB task start here */ + SST_GAIN_INDEX_CODEC_OUT0, + SST_GAIN_INDEX_CODEC_OUT1, + SST_GAIN_INDEX_CODEC_IN0, + SST_GAIN_INDEX_CODEC_IN1, + + SST_GAIN_INDEX_SPROT_LOOP_OUT, + SST_GAIN_INDEX_MEDIA_LOOP1_OUT, + SST_GAIN_INDEX_MEDIA_LOOP2_OUT, + + SST_GAIN_INDEX_PCM0_IN_LEFT, + SST_GAIN_INDEX_PCM0_IN_RIGHT, + + SST_GAIN_INDEX_PCM1_OUT_LEFT, + SST_GAIN_INDEX_PCM1_OUT_RIGHT, + SST_GAIN_INDEX_PCM1_IN_LEFT, + SST_GAIN_INDEX_PCM1_IN_RIGHT, + SST_GAIN_INDEX_PCM2_OUT_LEFT, + + SST_GAIN_INDEX_PCM2_OUT_RIGHT, + SST_GAIN_INDEX_VOIP_OUT, + SST_GAIN_INDEX_VOIP_IN, + + /* Gain IDs for MMX task start here */ + SST_GAIN_INDEX_MEDIA0_IN_LEFT, + SST_GAIN_INDEX_MEDIA0_IN_RIGHT, + SST_GAIN_INDEX_MEDIA1_IN_LEFT, + SST_GAIN_INDEX_MEDIA1_IN_RIGHT, + + SST_GAIN_INDEX_MEDIA2_IN_LEFT, + SST_GAIN_INDEX_MEDIA2_IN_RIGHT, + + SST_GAIN_INDEX_GAIN_END +}; + +/* + * Audio DSP module IDs specified by FW spec + * TODO: Update with all modules + */ +enum sst_module_id { + SST_MODULE_ID_PCM = 0x0001, + SST_MODULE_ID_MP3 = 0x0002, + SST_MODULE_ID_MP24 = 0x0003, + SST_MODULE_ID_AAC = 0x0004, + SST_MODULE_ID_AACP = 0x0005, + SST_MODULE_ID_EAACP = 0x0006, + SST_MODULE_ID_WMA9 = 0x0007, + SST_MODULE_ID_WMA10 = 0x0008, + SST_MODULE_ID_WMA10P = 0x0009, + SST_MODULE_ID_RA = 0x000A, + SST_MODULE_ID_DDAC3 = 0x000B, + SST_MODULE_ID_TRUE_HD = 0x000C, + SST_MODULE_ID_HD_PLUS = 0x000D, + + SST_MODULE_ID_SRC = 0x0064, + SST_MODULE_ID_DOWNMIX = 0x0066, + SST_MODULE_ID_GAIN_CELL = 0x0067, + SST_MODULE_ID_SPROT = 0x006D, + SST_MODULE_ID_BASS_BOOST = 0x006E, + SST_MODULE_ID_STEREO_WDNG = 0x006F, + SST_MODULE_ID_AV_REMOVAL = 0x0070, + SST_MODULE_ID_MIC_EQ = 0x0071, + SST_MODULE_ID_SPL = 0x0072, + SST_MODULE_ID_ALGO_VTSV = 0x0073, + SST_MODULE_ID_NR = 0x0076, + SST_MODULE_ID_BWX = 0x0077, + SST_MODULE_ID_DRP = 0x0078, + SST_MODULE_ID_MDRP = 0x0079, + + SST_MODULE_ID_ANA = 0x007A, + SST_MODULE_ID_AEC = 0x007B, + SST_MODULE_ID_NR_SNS = 0x007C, + SST_MODULE_ID_SER = 0x007D, + SST_MODULE_ID_AGC = 0x007E, + + SST_MODULE_ID_CNI = 0x007F, + SST_MODULE_ID_CONTEXT_ALGO_AWARE = 0x0080, + SST_MODULE_ID_FIR_24 = 0x0081, + SST_MODULE_ID_IIR_24 = 0x0082, + + SST_MODULE_ID_ASRC = 0x0083, + SST_MODULE_ID_TONE_GEN = 0x0084, + SST_MODULE_ID_BMF = 0x0086, + SST_MODULE_ID_EDL = 0x0087, + SST_MODULE_ID_GLC = 0x0088, + + SST_MODULE_ID_FIR_16 = 0x0089, + SST_MODULE_ID_IIR_16 = 0x008A, + SST_MODULE_ID_DNR = 0x008B, + + SST_MODULE_ID_VIRTUALIZER = 0x008C, + SST_MODULE_ID_VISUALIZATION = 0x008D, + SST_MODULE_ID_LOUDNESS_OPTIMIZER = 0x008E, + SST_MODULE_ID_REVERBERATION = 0x008F, + + SST_MODULE_ID_CNI_TX = 0x0090, + SST_MODULE_ID_REF_LINE = 0x0091, + SST_MODULE_ID_VOLUME = 0x0092, + SST_MODULE_ID_FILT_DCR = 0x0094, + SST_MODULE_ID_SLV = 0x009A, + SST_MODULE_ID_NLF = 0x009B, + SST_MODULE_ID_TNR = 0x009C, + SST_MODULE_ID_WNR = 0x009D, + + SST_MODULE_ID_LOG = 0xFF00, + + SST_MODULE_ID_TASK = 0xFFFF, +}; + +enum sst_cmd { + SBA_IDLE = 14, + SBA_VB_SET_SPEECH_PATH = 26, + MMX_SET_GAIN = 33, + SBA_VB_SET_GAIN = 33, + FBA_VB_RX_CNI = 35, + MMX_SET_GAIN_TIMECONST = 36, + SBA_VB_SET_TIMECONST = 36, + SBA_VB_START = 85, + SBA_SET_SWM = 114, + SBA_SET_MDRP = 116, + SBA_HW_SET_SSP = 117, + SBA_SET_MEDIA_LOOP_MAP = 118, + SBA_SET_MEDIA_PATH = 119, + MMX_SET_MEDIA_PATH = 119, + SBA_VB_LPRO = 126, + SBA_VB_SET_FIR = 128, + SBA_VB_SET_IIR = 129, + SBA_SET_SSP_SLOT_MAP = 130, +}; + +enum sst_dsp_switch { + SST_SWITCH_OFF = 0, + SST_SWITCH_ON = 3, +}; + +enum sst_path_switch { + SST_PATH_OFF = 0, + SST_PATH_ON = 1, +}; + +enum sst_swm_state { + SST_SWM_OFF = 0, + SST_SWM_ON = 3, +}; #endif diff --git a/sound/soc/intel/sst-mfld-platform-pcm.c b/sound/soc/intel/sst-mfld-platform-pcm.c index a89ff7e18e1a..8e1e9bc27642 100644 --- a/sound/soc/intel/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c @@ -550,7 +550,13 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) return retval; } -static struct snd_soc_platform_driver sst_soc_platform_drv = { +static int sst_soc_probe(struct snd_soc_platform *platform) +{ + return sst_dsp_init_v2_dpcm(platform); +} + +static struct snd_soc_platform_driver sst_soc_platform_drv = { + .probe = sst_soc_probe, .ops = &sst_platform_ops, .compr_ops = &sst_platform_compr_ops, .pcm_new = sst_pcm_new, diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h index d4c28b8fb471..faaba10c1dff 100644 --- a/sound/soc/intel/sst-mfld-platform.h +++ b/sound/soc/intel/sst-mfld-platform.h @@ -143,6 +143,8 @@ struct sst_device { }; struct sst_data; + +int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform); 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); @@ -157,6 +159,7 @@ struct sst_algo_int_control_v2 { struct sst_data { struct platform_device *pdev; struct sst_platform_data *pdata; + char *byte_stream; struct mutex lock; }; int sst_register_dsp(struct sst_device *sst); -- GitLab From a493b6a637e9d8e828d7ed4be4bdf24dfd1f9250 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Fri, 8 Aug 2014 12:07:49 +0200 Subject: [PATCH 0707/9167] ASoC: rsnd: 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: Mark Brown --- sound/soc/sh/rcar/core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 19f78963e8b9..1922ec57d10a 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@ -798,10 +798,8 @@ if (name##_node) { \ mod_parse(src); mod_parse(dvc); - if (playback) - of_node_put(playback); - if (capture) - of_node_put(capture); + of_node_put(playback); + of_node_put(capture); } dai_i++; -- GitLab From 0d985b1c76623747107dbab1052044d6bac3866d Mon Sep 17 00:00:00 2001 From: Rongjun Ying Date: Wed, 13 Aug 2014 16:31:40 +0800 Subject: [PATCH 0708/9167] ASoC: sirf: usp: Add bitclock inversion support Signed-off-by: Rongjun Ying Signed-off-by: Mark Brown --- sound/soc/sirf/sirf-usp.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/sound/soc/sirf/sirf-usp.c b/sound/soc/sirf/sirf-usp.c index 3a730374e259..186dc7f33a55 100644 --- a/sound/soc/sirf/sirf-usp.c +++ b/sound/soc/sirf/sirf-usp.c @@ -100,6 +100,16 @@ static int sirf_usp_pcm_set_dai_fmt(struct snd_soc_dai *dai, return -EINVAL; } + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + usp->daifmt_format |= (fmt & SND_SOC_DAIFMT_INV_MASK); + break; + default: + return -EINVAL; + } + return 0; } @@ -177,7 +187,7 @@ static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream, shifter_len = data_len; - switch (usp->daifmt_format) { + switch (usp->daifmt_format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: regmap_update_bits(usp->regmap, USP_RX_FRAME_CTRL, USP_I2S_SYNC_CHG, USP_I2S_SYNC_CHG); @@ -193,6 +203,18 @@ static int sirf_usp_pcm_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } + switch (usp->daifmt_format & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + regmap_update_bits(usp->regmap, USP_MODE1, + USP_RXD_ACT_EDGE_FALLING | USP_TXD_ACT_EDGE_FALLING, + USP_RXD_ACT_EDGE_FALLING); + break; + default: + return -EINVAL; + } + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) regmap_update_bits(usp->regmap, USP_TX_FRAME_CTRL, USP_TXC_DATA_LEN_MASK | USP_TXC_FRAME_LEN_MASK -- GitLab From a7a8e994ddd004fbabfcf04c26c204297b5f826d Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Fri, 1 Aug 2014 10:57:04 -0500 Subject: [PATCH 0709/9167] ASoC: tas2552: Add DAPM calls for amp and PLL Add DAPM calls to enable/disable the Class D amp. Also add a DAPM call to turn off the PLL upon the stream completing. Signed-off-by: Dan Murphy Signed-off-by: Mark Brown --- sound/soc/codecs/tas2552.c | 68 +++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index 23b32960ff1d..1ed57a7e57b6 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -78,6 +78,43 @@ struct tas2552_data { unsigned int mclk; }; +/* Input mux controls */ +static const char *tas2552_input_texts[] = { + "Digital", "Analog" +}; + +static SOC_ENUM_SINGLE_DECL(tas2552_input_mux_enum, TAS2552_CFG_3, 7, + tas2552_input_texts); + +static const struct snd_kcontrol_new tas2552_input_mux_control[] = { + SOC_DAPM_ENUM("Input selection", tas2552_input_mux_enum) +}; + +static const struct snd_soc_dapm_widget tas2552_dapm_widgets[] = +{ + SND_SOC_DAPM_INPUT("IN"), + + /* MUX Controls */ + SND_SOC_DAPM_MUX("Input selection", SND_SOC_NOPM, 0, 0, + tas2552_input_mux_control), + + SND_SOC_DAPM_AIF_IN("DAC IN", "DAC Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_OUT_DRV("ClassD", TAS2552_CFG_2, 7, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("PLL", TAS2552_CFG_2, 3, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("OUT") +}; + +static const struct snd_soc_dapm_route tas2552_audio_map[] = { + {"DAC", NULL, "DAC IN"}, + {"Input selection", "Digital", "DAC"}, + {"Input selection", "Analog", "IN"}, + {"ClassD", NULL, "Input selection"}, + {"OUT", NULL, "ClassD"}, + {"ClassD", NULL, "PLL"}, +}; + static void tas2552_sw_shutdown(struct tas2552_data *tas_data, int sw_shutdown) { u8 cfg1_reg; @@ -101,10 +138,6 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream, int d; u8 p, j; - /* Turn on Class D amplifier */ - snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_CLASSD_EN_MASK, - TAS2552_CLASSD_EN); - if (!tas2552->mclk) return -EINVAL; @@ -147,9 +180,6 @@ static int tas2552_hw_params(struct snd_pcm_substream *substream, } - snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, - TAS2552_PLL_ENABLE); - return 0; } @@ -269,19 +299,10 @@ static const struct dev_pm_ops tas2552_pm = { NULL) }; -static void tas2552_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - - snd_soc_update_bits(codec, TAS2552_CFG_2, TAS2552_PLL_ENABLE, 0); -} - static struct snd_soc_dai_ops tas2552_speaker_dai_ops = { .hw_params = tas2552_hw_params, .set_sysclk = tas2552_set_dai_sysclk, .set_fmt = tas2552_set_dai_fmt, - .shutdown = tas2552_shutdown, .digital_mute = tas2552_mute, }; @@ -294,7 +315,7 @@ static struct snd_soc_dai_driver tas2552_dai[] = { { .name = "tas2552-amplifier", .playback = { - .stream_name = "Speaker", + .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_192000, @@ -312,6 +333,7 @@ static DECLARE_TLV_DB_SCALE(dac_tlv, -7, 100, 24); static const struct snd_kcontrol_new tas2552_snd_controls[] = { SOC_SINGLE_TLV("Speaker Driver Playback Volume", TAS2552_PGA_GAIN, 0, 0x1f, 1, dac_tlv), + SOC_DAPM_SINGLE("Playback AMP", SND_SOC_NOPM, 0, 1, 0), }; static const struct reg_default tas2552_init_regs[] = { @@ -321,6 +343,7 @@ static const struct reg_default tas2552_init_regs[] = { static int tas2552_codec_probe(struct snd_soc_codec *codec) { struct tas2552_data *tas2552 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; tas2552->codec = codec; @@ -362,9 +385,14 @@ static int tas2552_codec_probe(struct snd_soc_codec *codec) goto patch_fail; } - snd_soc_write(codec, TAS2552_CFG_2, TAS2552_CLASSD_EN | - TAS2552_BOOST_EN | TAS2552_APT_EN | - TAS2552_LIM_EN); + snd_soc_write(codec, TAS2552_CFG_2, TAS2552_BOOST_EN | + TAS2552_APT_EN | TAS2552_LIM_EN); + + snd_soc_dapm_new_controls(dapm, tas2552_dapm_widgets, + ARRAY_SIZE(tas2552_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, tas2552_audio_map, + ARRAY_SIZE(tas2552_audio_map)); + return 0; patch_fail: -- GitLab From dfe8f1f3f22f9922e773ae64f5621f290cb26023 Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Wed, 13 Aug 2014 10:05:45 +0100 Subject: [PATCH 0710/9167] ASoC: wm8994: Demux the microphone detection IRQ Current code only allows direct routing of the WM8994 microphone detection signal to a GPIO this change adds support to demux the interrupt from the main interrupt line of the codec. Signed-off-by: Nikesh Oswal Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6cc0566dc29a..1fcb9f3f3097 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -4082,17 +4082,23 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) switch (control->type) { case WM8994: - if (wm8994->micdet_irq) { + if (wm8994->micdet_irq) ret = request_threaded_irq(wm8994->micdet_irq, NULL, wm8994_mic_irq, IRQF_TRIGGER_RISING, "Mic1 detect", wm8994); - if (ret != 0) - dev_warn(codec->dev, - "Failed to request Mic1 detect IRQ: %d\n", - ret); - } + else + ret = wm8994_request_irq(wm8994->wm8994, + WM8994_IRQ_MIC1_DET, + wm8994_mic_irq, "Mic 1 detect", + wm8994); + + if (ret != 0) + dev_warn(codec->dev, + "Failed to request Mic1 detect IRQ: %d\n", + ret); + ret = wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_MIC1_SHRT, -- GitLab From e67f04c9187b76c9824c31b4aeb7b79dd36cb735 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 13 Aug 2014 13:52:40 +0200 Subject: [PATCH 0711/9167] spi: cadence: Remove .owner field for driver There is no need to init .owner field. Based on the patch from Peter Griffin "mmc: remove .owner field for drivers using module_platform_driver" This patch removes the superflous .owner field for drivers which use the module_platform_driver API, as this is overriden in platform_driver_register anyway." Signed-off-by: Michal Simek Signed-off-by: Mark Brown --- drivers/spi/spi-cadence.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/spi-cadence.c b/drivers/spi/spi-cadence.c index 562ff83debd9..7b811e38c7ad 100644 --- a/drivers/spi/spi-cadence.c +++ b/drivers/spi/spi-cadence.c @@ -677,7 +677,6 @@ static struct platform_driver cdns_spi_driver = { .remove = cdns_spi_remove, .driver = { .name = CDNS_SPI_NAME, - .owner = THIS_MODULE, .of_match_table = cdns_spi_of_match, .pm = &cdns_spi_dev_pm_ops, }, -- GitLab From 9f5b8b4f56dd194fd33021810636879036d2acdd Mon Sep 17 00:00:00 2001 From: Nick Krause Date: Wed, 6 Aug 2014 13:53:17 -0400 Subject: [PATCH 0712/9167] spi: omap-100k: Remove unused definitions Remove unused definition which cause the following warnings drivers/spi/spi-omap-100k.c:73:0: warning: "WRITE" redefined [enabled by default] include/linux/fs.h:193:0: note: this is the location of the previous definition drivers/spi/spi-omap-100k.c:74:0: warning: "READ" redefined [enabled by default] include/linux/fs.h:192:0: note: this is the location of the previous definition Signed-off-by: Nick Krause Acked-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi-omap-100k.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c index 5e91858f6f01..fb522765ce5a 100644 --- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -70,10 +70,6 @@ #define SPI_STATUS_WE (1UL << 1) #define SPI_STATUS_RD (1UL << 0) -#define WRITE 0 -#define READ 1 - - /* use PIO for small transfers, avoiding DMA setup/teardown overhead and * cache operations; better heuristics consider wordsize and bitrate. */ -- GitLab From d64b472678e17ef9afb251577f4f544793483fa9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:58:59 +0200 Subject: [PATCH 0713/9167] spi: rspi: Remove unneeded semicolon Introduced by commit 426ef76dd8a394a0e04d096941cd9acb49539a3e ("spi: rspi: Add DT support"). Reported-by: kbuild test robot Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi-rspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index ad87a98f8f68..a4d8d3cf2912 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -1084,7 +1084,7 @@ static int rspi_probe(struct platform_device *pdev) master->num_chipselect = rspi_pd->num_chipselect; else master->num_chipselect = 2; /* default */ - }; + } /* ops parameter check */ if (!ops->set_config_register) { -- GitLab From 43937455c9bf294cffc2f25c4a4d0a1b9bbd88e6 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:00 +0200 Subject: [PATCH 0714/9167] spi: rspi: Use devm_kasprintf() Use the devm_kasprintf() helper function instead of open coding error-prone buffer handling and string formatting. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi-rspi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index a4d8d3cf2912..aa1c6a893570 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -1046,12 +1046,11 @@ static int rspi_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, const char *suffix, void *dev_id) { - const char *base = dev_name(dev); - size_t len = strlen(base) + strlen(suffix) + 2; - char *name = devm_kzalloc(dev, len, GFP_KERNEL); + const char *name = devm_kasprintf(dev, GFP_KERNEL, "%s:%s", + dev_name(dev), suffix); if (!name) return -ENOMEM; - snprintf(name, len, "%s:%s", base, suffix); + return devm_request_irq(dev, irq, handler, 0, name, dev_id); } -- GitLab From a30b95a7d81cfc3442beb5a9635f22b19c97bbfc Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:01 +0200 Subject: [PATCH 0715/9167] spi: rspi: Configure DMA slave bus width to 8 bit The new Renesas R-Car Gen2 DMA Controller driver (rcar-dmac) requires explicit configuration of the DMA slave bus width. Hardcode the DMA transfer size to 1 byte for both directions, as that's the only supported configuration (16-bit DMA support was removed in commit 9c5de2c1754c2bb3c69c4d7bf0d0edc0a61d8232 ("spi: rspi: Remove unused 16-bit DMA support")). Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi-rspi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index aa1c6a893570..6a4eb2d7f644 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -919,10 +919,13 @@ static struct dma_chan *rspi_request_dma_chan(struct device *dev, memset(&cfg, 0, sizeof(cfg)); cfg.slave_id = id; cfg.direction = dir; - if (dir == DMA_MEM_TO_DEV) + if (dir == DMA_MEM_TO_DEV) { cfg.dst_addr = port_addr; - else + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + } else { cfg.src_addr = port_addr; + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + } ret = dmaengine_slave_config(chan, &cfg); if (ret) { -- GitLab From e825b8dd2b363e9134006fb141825518a11b2bf4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:02 +0200 Subject: [PATCH 0716/9167] spi: rspi: Add DT support to DMA setup Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-rspi.txt | 5 +++ drivers/spi/spi-rspi.c | 37 ++++++++++++------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-rspi.txt b/Documentation/devicetree/bindings/spi/spi-rspi.txt index d57d82a74054..f9929aceeacc 100644 --- a/Documentation/devicetree/bindings/spi/spi-rspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-rspi.txt @@ -30,6 +30,9 @@ Required properties: Optional properties: - clocks : Must contain a reference to the functional clock. +- dmas : Must contain a list of two references to DMA specifiers, + one for transmission, and one for reception. +- dma-names : Must contain a list of two DMA names, "tx" and "rx". Pinctrl properties might be needed, too. See Documentation/devicetree/bindings/pinctrl/renesas,*. @@ -58,4 +61,6 @@ Examples: num-cs = <1>; #address-cells = <1>; #size-cells = <0>; + dmas = <&dmac0 0x17>, <&dmac0 0x18>; + dma-names = "tx", "rx"; }; diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 6a4eb2d7f644..1da609e4491d 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c @@ -909,10 +909,11 @@ static struct dma_chan *rspi_request_dma_chan(struct device *dev, dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - chan = dma_request_channel(mask, shdma_chan_filter, - (void *)(unsigned long)id); + chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, + (void *)(unsigned long)id, dev, + dir == DMA_MEM_TO_DEV ? "tx" : "rx"); if (!chan) { - dev_warn(dev, "dma_request_channel failed\n"); + dev_warn(dev, "dma_request_slave_channel_compat failed\n"); return NULL; } @@ -941,22 +942,30 @@ static int rspi_request_dma(struct device *dev, struct spi_master *master, const struct resource *res) { const struct rspi_plat_data *rspi_pd = dev_get_platdata(dev); + unsigned int dma_tx_id, dma_rx_id; + + if (dev->of_node) { + /* In the OF case we will get the slave IDs from the DT */ + dma_tx_id = 0; + dma_rx_id = 0; + } else if (rspi_pd && rspi_pd->dma_tx_id && rspi_pd->dma_rx_id) { + dma_tx_id = rspi_pd->dma_tx_id; + dma_rx_id = rspi_pd->dma_rx_id; + } else { + /* The driver assumes no error. */ + return 0; + } - if (!rspi_pd || !rspi_pd->dma_rx_id || !rspi_pd->dma_tx_id) - return 0; /* The driver assumes no error. */ - - master->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, - rspi_pd->dma_rx_id, + master->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, dma_tx_id, res->start + RSPI_SPDR); - if (!master->dma_rx) + if (!master->dma_tx) return -ENODEV; - master->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, - rspi_pd->dma_tx_id, + master->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, dma_rx_id, res->start + RSPI_SPDR); - if (!master->dma_tx) { - dma_release_channel(master->dma_rx); - master->dma_rx = NULL; + if (!master->dma_rx) { + dma_release_channel(master->dma_tx); + master->dma_tx = NULL; return -ENODEV; } -- GitLab From 52fba2b85d30075490db023642632032371505c2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:04 +0200 Subject: [PATCH 0717/9167] spi: sh-msiof: Configure DMA slave bus width The new Renesas R-Car Gen2 DMA Controller driver (rcar-dmac) requires explicit configuration of the DMA slave bus width. Hardcode the DMA transfer size to 4 bytes, as MSIOF DMA is limited to 32-bit words. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/spi/spi-sh-msiof.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 887c2084130f..b19cbb4cb4a0 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -987,10 +987,13 @@ static struct dma_chan *sh_msiof_request_dma_chan(struct device *dev, memset(&cfg, 0, sizeof(cfg)); cfg.slave_id = id; cfg.direction = dir; - if (dir == DMA_MEM_TO_DEV) + if (dir == DMA_MEM_TO_DEV) { cfg.dst_addr = port_addr; - else + cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + } else { cfg.src_addr = port_addr; + cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + } ret = dmaengine_slave_config(chan, &cfg); if (ret) { -- GitLab From a6be4de6a24cbef6209e3a0fcddaee9e312a1f63 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:05 +0200 Subject: [PATCH 0718/9167] spi: sh-msiof: Add DT support to DMA setup Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/sh-msiof.txt | 17 ++++++++++--- drivers/spi/spi-sh-msiof.c | 25 +++++++++++++------ 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index f24baf3b6cc1..98e07f1c3dab 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt @@ -6,8 +6,13 @@ Required properties: "renesas,sh-mobile-msiof" for SH Mobile series. Examples with soctypes are: "renesas,msiof-r8a7790" (R-Car H2) - "renesas,msiof-r8a7791" (R-Car M2) -- reg : Offset and length of the register set for the device +- reg : A list of offsets and lengths of the register sets for + the device. + If only one register set is present, it is to be used + by both the CPU and the DMA engine. + If two register sets are present, the first is to be + used by the CPU, and the second is to be used by the + DMA engine. - interrupt-parent : The phandle for the interrupt controller that services interrupts for this device - interrupts : Interrupt specifier @@ -17,6 +22,10 @@ Required properties: Optional properties: - clocks : Must contain a reference to the functional clock. - num-cs : Total number of chip-selects (default is 1) +- dmas : Must contain a list of two references to DMA + specifiers, one for transmission, and one for + reception. +- dma-names : Must contain a list of two DMA names, "tx" and "rx". Optional properties, deprecated for soctype-specific bindings: - renesas,tx-fifo-size : Overrides the default tx fifo size given in words @@ -31,9 +40,11 @@ Example: msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7791"; - reg = <0 0xe6e20000 0 0x0064>; + reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>; interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; + dmas = <&dmac0 0x51>, <&dmac0 0x52>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index b19cbb4cb4a0..811a42dba92a 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -977,10 +977,11 @@ static struct dma_chan *sh_msiof_request_dma_chan(struct device *dev, dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - chan = dma_request_channel(mask, shdma_chan_filter, - (void *)(unsigned long)id); + chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, + (void *)(unsigned long)id, dev, + dir == DMA_MEM_TO_DEV ? "tx" : "rx"); if (!chan) { - dev_warn(dev, "dma_request_channel failed\n"); + dev_warn(dev, "dma_request_slave_channel_compat failed\n"); return NULL; } @@ -1010,12 +1011,22 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p) struct platform_device *pdev = p->pdev; struct device *dev = &pdev->dev; const struct sh_msiof_spi_info *info = dev_get_platdata(dev); + unsigned int dma_tx_id, dma_rx_id; const struct resource *res; struct spi_master *master; struct device *tx_dev, *rx_dev; - if (!info || !info->dma_tx_id || !info->dma_rx_id) - return 0; /* The driver assumes no error */ + if (dev->of_node) { + /* In the OF case we will get the slave IDs from the DT */ + dma_tx_id = 0; + dma_rx_id = 0; + } else if (info && info->dma_tx_id && info->dma_rx_id) { + dma_tx_id = info->dma_tx_id; + dma_rx_id = info->dma_rx_id; + } else { + /* The driver assumes no error */ + return 0; + } /* The DMA engine uses the second register set, if present */ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); @@ -1024,13 +1035,13 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p) master = p->master; master->dma_tx = sh_msiof_request_dma_chan(dev, DMA_MEM_TO_DEV, - info->dma_tx_id, + dma_tx_id, res->start + TFDR); if (!master->dma_tx) return -ENODEV; master->dma_rx = sh_msiof_request_dma_chan(dev, DMA_DEV_TO_MEM, - info->dma_rx_id, + dma_rx_id, res->start + RFDR); if (!master->dma_rx) goto free_tx_chan; -- GitLab From a5e7c719fe257214aeda3dadb502a4cf58209a61 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 7 Aug 2014 14:07:42 +0200 Subject: [PATCH 0719/9167] spi: sh-msiof: Return early in sh_msiof_dma_once() where possible Reported-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Mark Brown --- drivers/spi/spi-sh-msiof.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 811a42dba92a..daaa868e959f 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -642,18 +642,14 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, desc_rx = dmaengine_prep_slave_single(p->master->dma_rx, p->rx_dma_addr, len, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc_rx) { - ret = -EAGAIN; - goto no_dma_rx; - } + if (!desc_rx) + return -EAGAIN; desc_rx->callback = sh_msiof_dma_complete; desc_rx->callback_param = p; cookie = dmaengine_submit(desc_rx); - if (dma_submit_error(cookie)) { - ret = cookie; - goto no_dma_rx; - } + if (dma_submit_error(cookie)) + return cookie; } if (tx) { @@ -738,7 +734,6 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, if (rx) dmaengine_terminate_all(p->master->dma_rx); sh_msiof_write(p, IER, 0); -no_dma_rx: return ret; } -- GitLab From 7a9f957b395fc08edc47620c01e8bb5b798caddb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 7 Aug 2014 14:07:43 +0200 Subject: [PATCH 0720/9167] spi: sh-msiof: Fix transmit-only DMA transfers Fix tx/rx mixup, which broke transmit-only transfers. Introduced by commit 4240305f7cbdc7782aa8bc40cc702775d9ac0839 ("spi: sh-msiof: Fix leaking of unused DMA descriptors"). Reported-by: Laurent Pinchart Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Mark Brown --- drivers/spi/spi-sh-msiof.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index daaa868e959f..1165d418340f 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -689,9 +689,9 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, reinit_completion(&p->done); /* Now start DMA */ - if (tx) - dma_async_issue_pending(p->master->dma_rx); if (rx) + dma_async_issue_pending(p->master->dma_rx); + if (tx) dma_async_issue_pending(p->master->dma_tx); ret = sh_msiof_spi_start(p, rx); -- GitLab From 9c0b8fd1a5493d0c5ab2fb147e758ca556e80863 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 13 Aug 2014 13:52:39 +0200 Subject: [PATCH 0721/9167] spi: xilinx: Remove .owner field for driver There is no need to init .owner field. Based on the patch from Peter Griffin "mmc: remove .owner field for drivers using module_platform_driver" This patch removes the superflous .owner field for drivers which use the module_platform_driver API, as this is overriden in platform_driver_register anyway." Signed-off-by: Michal Simek Signed-off-by: Mark Brown --- drivers/spi/spi-xilinx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 4d8efb16573d..79bd84f43430 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -471,7 +471,6 @@ static struct platform_driver xilinx_spi_driver = { .remove = xilinx_spi_remove, .driver = { .name = XILINX_SPI_NAME, - .owner = THIS_MODULE, .of_match_table = xilinx_spi_of_match, }, }; -- GitLab From d4f7facde1796c8b3eb2f79e1fd903d7b776972f Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 31 Jul 2014 10:43:35 +0800 Subject: [PATCH 0722/9167] devicetree: bindings: Add Everest Semicodunctor Everest Semiconductor makes audio codecs. Signed-off-by: Sean Cross Signed-off-by: Mark Brown --- 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 ac7269f90764..34cc1bfcebfd 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -48,6 +48,7 @@ epfl Ecole Polytechnique Fédérale de Lausanne epson Seiko Epson Corp. est ESTeem Wireless Modems eukrea Eukréa Electromatique +everest Everest Semiconductor Co. Ltd. excito Excito fsl Freescale Semiconductor GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. -- GitLab From 567e4f98922ce5542f8c2aa469a0c6ddf182b6ea Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 31 Jul 2014 10:43:36 +0800 Subject: [PATCH 0723/9167] ASoC: add es8328 codec driver Add a codec driver for the Everest ES8328. It supports two separate audio outputs and two separate audio inputs. Signed-off-by: Sean Cross Signed-off-by: Mark Brown --- .../devicetree/bindings/sound/es8328.txt | 38 + sound/soc/codecs/Kconfig | 13 + sound/soc/codecs/Makefile | 6 + sound/soc/codecs/es8328-i2c.c | 60 ++ sound/soc/codecs/es8328-spi.c | 49 ++ sound/soc/codecs/es8328.c | 756 ++++++++++++++++++ sound/soc/codecs/es8328.h | 314 ++++++++ 7 files changed, 1236 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/es8328.txt create mode 100644 sound/soc/codecs/es8328-i2c.c create mode 100644 sound/soc/codecs/es8328-spi.c create mode 100644 sound/soc/codecs/es8328.c create mode 100644 sound/soc/codecs/es8328.h diff --git a/Documentation/devicetree/bindings/sound/es8328.txt b/Documentation/devicetree/bindings/sound/es8328.txt new file mode 100644 index 000000000000..30ea8a318ae9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/es8328.txt @@ -0,0 +1,38 @@ +Everest ES8328 audio CODEC + +This device supports both I2C and SPI. + +Required properties: + + - compatible : "everest,es8328" + - DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V + - AVDD-supply : Regulator providing analog supply voltage 3.3V + - PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V + - IPVDD-supply : Regulator providing analog output voltage 3.3V + - clocks : A 22.5792 or 11.2896 MHz clock + - reg : the I2C address of the device for I2C, the chip select number for SPI + +Pins on the device (for linking into audio routes): + + * LOUT1 + * LOUT2 + * ROUT1 + * ROUT2 + * LINPUT1 + * RINPUT1 + * LINPUT2 + * RINPUT2 + * Mic Bias + + +Example: + +codec: es8328@11 { + compatible = "everest,es8328"; + DVDD-supply = <®_3p3v>; + AVDD-supply = <®_3p3v>; + PVDD-supply = <®_3p3v>; + HPVDD-supply = <®_3p3v>; + clocks = <&clks 169>; + reg = <0x11>; +}; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 8838838e25ed..8bca6343d8a3 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -57,6 +57,8 @@ config SND_SOC_ALL_CODECS select SND_SOC_DA732X if I2C select SND_SOC_DA9055 if I2C select SND_SOC_BT_SCO + select SND_SOC_ES8328_SPI if SPI_MASTER + select SND_SOC_ES8328_I2C if I2C select SND_SOC_ISABELLE if I2C select SND_SOC_JZ4740_CODEC select SND_SOC_LM4857 if I2C @@ -405,6 +407,17 @@ config SND_SOC_DMIC config SND_SOC_HDMI_CODEC tristate "HDMI stub CODEC" +config SND_SOC_ES8328 + tristate "Everest Semi ES8328 CODEC" + +config SND_SOC_ES8328_I2C + tristate + select SND_SOC_ES8328 + +config SND_SOC_ES8328_SPI + tristate + select SND_SOC_ES8328 + config SND_SOC_ISABELLE tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 20afe0f0c5be..31a8283006d1 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -49,6 +49,9 @@ snd-soc-da732x-objs := da732x.o snd-soc-da9055-objs := da9055.o snd-soc-bt-sco-objs := bt-sco.o snd-soc-dmic-objs := dmic.o +snd-soc-es8328-objs := es8328.o +snd-soc-es8328-i2c-objs := es8328-i2c.o +snd-soc-es8328-spi-objs := es8328-spi.o snd-soc-isabelle-objs := isabelle.o snd-soc-jz4740-codec-objs := jz4740.o snd-soc-l3-objs := l3.o @@ -220,6 +223,9 @@ obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o +obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o +obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o +obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o diff --git a/sound/soc/codecs/es8328-i2c.c b/sound/soc/codecs/es8328-i2c.c new file mode 100644 index 000000000000..aae410d122ee --- /dev/null +++ b/sound/soc/codecs/es8328-i2c.c @@ -0,0 +1,60 @@ +/* + * es8328-i2c.c -- ES8328 ALSA SoC I2C Audio driver + * + * Copyright 2014 Sutajio Ko-Usagi PTE LTD + * + * Author: Sean Cross + * + * 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 "es8328.h" + +static const struct i2c_device_id es8328_id[] = { + { "everest,es8328", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, es8328_id); + +static const struct of_device_id es8328_of_match[] = { + { .compatible = "everest,es8328", }, + { } +}; +MODULE_DEVICE_TABLE(of, es8328_of_match); + +static int es8328_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + return es8328_probe(&i2c->dev, + devm_regmap_init_i2c(i2c, &es8328_regmap_config)); +} + +static int es8328_i2c_remove(struct i2c_client *i2c) +{ + snd_soc_unregister_codec(&i2c->dev); + return 0; +} + +static struct i2c_driver es8328_i2c_driver = { + .driver = { + .name = "es8328", + .of_match_table = es8328_of_match, + }, + .probe = es8328_i2c_probe, + .remove = es8328_i2c_remove, + .id_table = es8328_id, +}; + +module_i2c_driver(es8328_i2c_driver); + +MODULE_DESCRIPTION("ASoC ES8328 audio CODEC I2C driver"); +MODULE_AUTHOR("Sean Cross "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/es8328-spi.c b/sound/soc/codecs/es8328-spi.c new file mode 100644 index 000000000000..8fbd935e1c76 --- /dev/null +++ b/sound/soc/codecs/es8328-spi.c @@ -0,0 +1,49 @@ +/* + * es8328.c -- ES8328 ALSA SoC SPI Audio driver + * + * Copyright 2014 Sutajio Ko-Usagi PTE LTD + * + * Author: Sean Cross + * + * 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 "es8328.h" + +static const struct of_device_id es8328_of_match[] = { + { .compatible = "everest,es8328", }, + { } +}; +MODULE_DEVICE_TABLE(of, es8328_of_match); + +static int es8328_spi_probe(struct spi_device *spi) +{ + return es8328_probe(&spi->dev, + devm_regmap_init_spi(spi, &es8328_regmap_config)); +} + +static int es8328_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + return 0; +} + +static struct spi_driver es8328_spi_driver = { + .driver = { + .name = "es8328", + .of_match_table = es8328_of_match, + }, + .probe = es8328_spi_probe, + .remove = es8328_spi_remove, +}; + +module_spi_driver(es8328_spi_driver); +MODULE_DESCRIPTION("ASoC ES8328 audio CODEC SPI driver"); +MODULE_AUTHOR("Sean Cross "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/es8328.c b/sound/soc/codecs/es8328.c new file mode 100644 index 000000000000..7a9f65ad183d --- /dev/null +++ b/sound/soc/codecs/es8328.c @@ -0,0 +1,756 @@ +/* + * es8328.c -- ES8328 ALSA SoC Audio driver + * + * Copyright 2014 Sutajio Ko-Usagi PTE LTD + * + * Author: Sean Cross + * + * 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 "es8328.h" + +#define ES8328_SYSCLK_RATE_1X 11289600 +#define ES8328_SYSCLK_RATE_2X 22579200 + +/* Run the codec at 22.5792 or 11.2896 MHz to support these rates */ +static struct { + int rate; + u8 ratio; +} mclk_ratios[] = { + { 8000, 9 }, + {11025, 7 }, + {22050, 4 }, + {44100, 2 }, +}; + +/* regulator supplies for sgtl5000, VDDD is an optional external supply */ +enum sgtl5000_regulator_supplies { + DVDD, + AVDD, + PVDD, + HPVDD, + ES8328_SUPPLY_NUM +}; + +/* vddd is optional supply */ +static const char * const supply_names[ES8328_SUPPLY_NUM] = { + "DVDD", + "AVDD", + "PVDD", + "HPVDD", +}; + +#define ES8328_RATES (SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_22050 | \ + SNDRV_PCM_RATE_11025) +#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) + +struct es8328_priv { + struct regmap *regmap; + struct clk *clk; + int playback_fs; + bool deemph; + struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM]; +}; + +/* + * ES8328 Controls + */ + +static const char * const adcpol_txt[] = {"Normal", "L Invert", "R Invert", + "L + R Invert"}; +static SOC_ENUM_SINGLE_DECL(adcpol, + ES8328_ADCCONTROL6, 6, adcpol_txt); + +static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0); +static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0); +static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 300, 0); +static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); +static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0); + +static const int deemph_settings[] = { 0, 32000, 44100, 48000 }; + +static int es8328_set_deemph(struct snd_soc_codec *codec) +{ + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); + int val, i, best; + + /* + * If we're using deemphasis select the nearest available sample + * rate. + */ + if (es8328->deemph) { + best = 1; + for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) { + if (abs(deemph_settings[i] - es8328->playback_fs) < + abs(deemph_settings[best] - es8328->playback_fs)) + best = i; + } + + val = best << 1; + } else { + val = 0; + } + + dev_dbg(codec->dev, "Set deemphasis %d\n", val); + + return snd_soc_update_bits(codec, ES8328_DACCONTROL6, 0x6, val); +} + +static int es8328_get_deemph(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = es8328->deemph; + return 0; +} + +static int es8328_put_deemph(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); + int deemph = ucontrol->value.enumerated.item[0]; + int ret; + + if (deemph > 1) + return -EINVAL; + + ret = es8328_set_deemph(codec); + if (ret < 0) + return ret; + + es8328->deemph = deemph; + + return 0; +} + + + +static const struct snd_kcontrol_new es8328_snd_controls[] = { + SOC_DOUBLE_R_TLV("Capture Digital Volume", + ES8328_ADCCONTROL8, ES8328_ADCCONTROL9, + 0, 0xc0, 1, dac_adc_tlv), + SOC_SINGLE("Capture ZC Switch", ES8328_ADCCONTROL7, 6, 1, 0), + + SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0, + es8328_get_deemph, es8328_put_deemph), + + SOC_ENUM("Capture Polarity", adcpol), + + SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", + ES8328_DACCONTROL17, 3, 7, 1, bypass_tlv), + SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", + ES8328_DACCONTROL19, 3, 7, 1, bypass_tlv), + SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", + ES8328_DACCONTROL18, 3, 7, 1, bypass_tlv), + SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", + ES8328_DACCONTROL20, 3, 7, 1, bypass_tlv), + + SOC_DOUBLE_R_TLV("PCM Volume", + ES8328_LDACVOL, ES8328_RDACVOL, + 0, ES8328_DACVOL_MAX, 1, dac_adc_tlv), + + SOC_DOUBLE_R_TLV("Output 1 Playback Volume", + ES8328_LOUT1VOL, ES8328_ROUT1VOL, + 0, ES8328_OUT1VOL_MAX, 0, play_tlv), + + SOC_DOUBLE_R_TLV("Output 2 Playback Volume", + ES8328_LOUT2VOL, ES8328_ROUT2VOL, + 0, ES8328_OUT2VOL_MAX, 0, play_tlv), + + SOC_DOUBLE_TLV("Mic PGA Volume", ES8328_ADCCONTROL1, + 4, 0, 8, 0, mic_tlv), +}; + +/* + * DAPM Controls + */ + +static const char * const es8328_line_texts[] = { + "Line 1", "Line 2", "PGA", "Differential"}; + +static const struct soc_enum es8328_lline_enum = + SOC_ENUM_SINGLE(ES8328_DACCONTROL16, 3, + ARRAY_SIZE(es8328_line_texts), + es8328_line_texts); +static const struct snd_kcontrol_new es8328_left_line_controls = + SOC_DAPM_ENUM("Route", es8328_lline_enum); + +static const struct soc_enum es8328_rline_enum = + SOC_ENUM_SINGLE(ES8328_DACCONTROL16, 0, + ARRAY_SIZE(es8328_line_texts), + es8328_line_texts); +static const struct snd_kcontrol_new es8328_right_line_controls = + SOC_DAPM_ENUM("Route", es8328_lline_enum); + +/* Left Mixer */ +static const struct snd_kcontrol_new es8328_left_mixer_controls[] = { + SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 8, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 7, 1, 0), + SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 8, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 7, 1, 0), +}; + +/* Right Mixer */ +static const struct snd_kcontrol_new es8328_right_mixer_controls[] = { + SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 8, 1, 0), + SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 7, 1, 0), + SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 8, 1, 0), + SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 7, 1, 0), +}; + +static const char * const es8328_pga_sel[] = { + "Line 1", "Line 2", "Line 3", "Differential"}; + +/* Left PGA Mux */ +static const struct soc_enum es8328_lpga_enum = + SOC_ENUM_SINGLE(ES8328_ADCCONTROL2, 6, + ARRAY_SIZE(es8328_pga_sel), + es8328_pga_sel); +static const struct snd_kcontrol_new es8328_left_pga_controls = + SOC_DAPM_ENUM("Route", es8328_lpga_enum); + +/* Right PGA Mux */ +static const struct soc_enum es8328_rpga_enum = + SOC_ENUM_SINGLE(ES8328_ADCCONTROL2, 4, + ARRAY_SIZE(es8328_pga_sel), + es8328_pga_sel); +static const struct snd_kcontrol_new es8328_right_pga_controls = + SOC_DAPM_ENUM("Route", es8328_rpga_enum); + +/* Differential Mux */ +static const char * const es8328_diff_sel[] = {"Line 1", "Line 2"}; +static SOC_ENUM_SINGLE_DECL(diffmux, + ES8328_ADCCONTROL3, 7, es8328_diff_sel); +static const struct snd_kcontrol_new es8328_diffmux_controls = + SOC_DAPM_ENUM("Route", diffmux); + +/* Mono ADC Mux */ +static const char * const es8328_mono_mux[] = {"Stereo", "Mono (Left)", + "Mono (Right)", "Digital Mono"}; +static SOC_ENUM_SINGLE_DECL(monomux, + ES8328_ADCCONTROL3, 3, es8328_mono_mux); +static const struct snd_kcontrol_new es8328_monomux_controls = + SOC_DAPM_ENUM("Route", monomux); + +static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = { + SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, + &es8328_diffmux_controls), + SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, + &es8328_monomux_controls), + SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, + &es8328_monomux_controls), + + SND_SOC_DAPM_MUX("Left PGA Mux", ES8328_ADCPOWER, + ES8328_ADCPOWER_AINL_OFF, 1, + &es8328_left_pga_controls), + SND_SOC_DAPM_MUX("Right PGA Mux", ES8328_ADCPOWER, + ES8328_ADCPOWER_AINR_OFF, 1, + &es8328_right_pga_controls), + + SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, + &es8328_left_line_controls), + SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, + &es8328_right_line_controls), + + SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ES8328_ADCPOWER, + ES8328_ADCPOWER_ADCR_OFF, 1), + SND_SOC_DAPM_ADC("Left ADC", "Left Capture", ES8328_ADCPOWER, + ES8328_ADCPOWER_ADCL_OFF, 1), + + SND_SOC_DAPM_SUPPLY("Mic Bias", ES8328_ADCPOWER, + ES8328_ADCPOWER_MIC_BIAS_OFF, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("Mic Bias Gen", ES8328_ADCPOWER, + ES8328_ADCPOWER_ADC_BIAS_GEN_OFF, 1, NULL, 0), + + SND_SOC_DAPM_SUPPLY("DAC STM", ES8328_CHIPPOWER, + ES8328_CHIPPOWER_DACSTM_RESET, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("ADC STM", ES8328_CHIPPOWER, + ES8328_CHIPPOWER_ADCSTM_RESET, 1, NULL, 0), + + SND_SOC_DAPM_SUPPLY("DAC DIG", ES8328_CHIPPOWER, + ES8328_CHIPPOWER_DACDIG_OFF, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("ADC DIG", ES8328_CHIPPOWER, + ES8328_CHIPPOWER_ADCDIG_OFF, 1, NULL, 0), + + SND_SOC_DAPM_SUPPLY("DAC DLL", ES8328_CHIPPOWER, + ES8328_CHIPPOWER_DACDLL_OFF, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("ADC DLL", ES8328_CHIPPOWER, + ES8328_CHIPPOWER_ADCDLL_OFF, 1, NULL, 0), + + SND_SOC_DAPM_SUPPLY("ADC Vref", ES8328_CHIPPOWER, + ES8328_CHIPPOWER_ADCVREF_OFF, 1, NULL, 0), + SND_SOC_DAPM_SUPPLY("DAC Vref", ES8328_CHIPPOWER, + ES8328_CHIPPOWER_DACVREF_OFF, 1, NULL, 0), + + SND_SOC_DAPM_DAC("Right DAC", "Right Playback", ES8328_DACPOWER, + ES8328_DACPOWER_RDAC_OFF, 1), + SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER, + ES8328_DACPOWER_LDAC_OFF, 1), + + SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, + &es8328_left_mixer_controls[0], + ARRAY_SIZE(es8328_left_mixer_controls)), + SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, + &es8328_right_mixer_controls[0], + ARRAY_SIZE(es8328_right_mixer_controls)), + + SND_SOC_DAPM_PGA("Right Out 2", ES8328_DACPOWER, + ES8328_DACPOWER_ROUT2_ON, 0, NULL, 0), + SND_SOC_DAPM_PGA("Left Out 2", ES8328_DACPOWER, + ES8328_DACPOWER_LOUT2_ON, 0, NULL, 0), + SND_SOC_DAPM_PGA("Right Out 1", ES8328_DACPOWER, + ES8328_DACPOWER_ROUT1_ON, 0, NULL, 0), + SND_SOC_DAPM_PGA("Left Out 1", ES8328_DACPOWER, + ES8328_DACPOWER_LOUT1_ON, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("LOUT1"), + SND_SOC_DAPM_OUTPUT("ROUT1"), + SND_SOC_DAPM_OUTPUT("LOUT2"), + SND_SOC_DAPM_OUTPUT("ROUT2"), + + SND_SOC_DAPM_INPUT("LINPUT1"), + SND_SOC_DAPM_INPUT("LINPUT2"), + SND_SOC_DAPM_INPUT("RINPUT1"), + SND_SOC_DAPM_INPUT("RINPUT2"), +}; + +static const struct snd_soc_dapm_route es8328_dapm_routes[] = { + + { "Left Line Mux", "Line 1", "LINPUT1" }, + { "Left Line Mux", "Line 2", "LINPUT2" }, + { "Left Line Mux", "PGA", "Left PGA Mux" }, + { "Left Line Mux", "Differential", "Differential Mux" }, + + { "Right Line Mux", "Line 1", "RINPUT1" }, + { "Right Line Mux", "Line 2", "RINPUT2" }, + { "Right Line Mux", "PGA", "Right PGA Mux" }, + { "Right Line Mux", "Differential", "Differential Mux" }, + + { "Left PGA Mux", "Line 1", "LINPUT1" }, + { "Left PGA Mux", "Line 2", "LINPUT2" }, + { "Left PGA Mux", "Differential", "Differential Mux" }, + + { "Right PGA Mux", "Line 1", "RINPUT1" }, + { "Right PGA Mux", "Line 2", "RINPUT2" }, + { "Right PGA Mux", "Differential", "Differential Mux" }, + + { "Differential Mux", "Line 1", "LINPUT1" }, + { "Differential Mux", "Line 1", "RINPUT1" }, + { "Differential Mux", "Line 2", "LINPUT2" }, + { "Differential Mux", "Line 2", "RINPUT2" }, + + { "Left ADC Mux", "Stereo", "Left PGA Mux" }, + { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" }, + { "Left ADC Mux", "Digital Mono", "Left PGA Mux" }, + + { "Right ADC Mux", "Stereo", "Right PGA Mux" }, + { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" }, + { "Right ADC Mux", "Digital Mono", "Right PGA Mux" }, + + { "Left ADC", NULL, "Left ADC Mux" }, + { "Right ADC", NULL, "Right ADC Mux" }, + + { "ADC DIG", NULL, "ADC STM" }, + { "ADC DIG", NULL, "ADC Vref" }, + { "ADC DIG", NULL, "ADC DLL" }, + + { "Left ADC", NULL, "ADC DIG" }, + { "Right ADC", NULL, "ADC DIG" }, + + { "Mic Bias", NULL, "Mic Bias Gen" }, + + { "Left Line Mux", "Line 1", "LINPUT1" }, + { "Left Line Mux", "Line 2", "LINPUT2" }, + { "Left Line Mux", "PGA", "Left PGA Mux" }, + { "Left Line Mux", "Differential", "Differential Mux" }, + + { "Right Line Mux", "Line 1", "RINPUT1" }, + { "Right Line Mux", "Line 2", "RINPUT2" }, + { "Right Line Mux", "PGA", "Right PGA Mux" }, + { "Right Line Mux", "Differential", "Differential Mux" }, + + { "Left Out 1", NULL, "Left DAC" }, + { "Right Out 1", NULL, "Right DAC" }, + { "Left Out 2", NULL, "Left DAC" }, + { "Right Out 2", NULL, "Right DAC" }, + + { "Left Mixer", "Playback Switch", "Left DAC" }, + { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, + { "Left Mixer", "Right Playback Switch", "Right DAC" }, + { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "Right Mixer", "Left Playback Switch", "Left DAC" }, + { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, + { "Right Mixer", "Playback Switch", "Right DAC" }, + { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, + + { "DAC DIG", NULL, "DAC STM" }, + { "DAC DIG", NULL, "DAC Vref" }, + { "DAC DIG", NULL, "DAC DLL" }, + + { "Left DAC", NULL, "DAC DIG" }, + { "Right DAC", NULL, "DAC DIG" }, + + { "Left Out 1", NULL, "Left Mixer" }, + { "LOUT1", NULL, "Left Out 1" }, + { "Right Out 1", NULL, "Right Mixer" }, + { "ROUT1", NULL, "Right Out 1" }, + + { "Left Out 2", NULL, "Left Mixer" }, + { "LOUT2", NULL, "Left Out 2" }, + { "Right Out 2", NULL, "Right Mixer" }, + { "ROUT2", NULL, "Right Out 2" }, +}; + +static int es8328_mute(struct snd_soc_dai *dai, int mute) +{ + return snd_soc_update_bits(dai->codec, ES8328_DACCONTROL3, + ES8328_DACCONTROL3_DACMUTE, + mute ? ES8328_DACCONTROL3_DACMUTE : 0); +} + +static int es8328_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 es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); + int clk_rate; + int i; + int reg; + u8 ratio; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + reg = ES8328_DACCONTROL2; + else + reg = ES8328_ADCCONTROL5; + + clk_rate = clk_get_rate(es8328->clk); + + if ((clk_rate != ES8328_SYSCLK_RATE_1X) && + (clk_rate != ES8328_SYSCLK_RATE_2X)) { + dev_err(codec->dev, + "%s: clock is running at %d Hz, not %d or %d Hz\n", + __func__, clk_rate, + ES8328_SYSCLK_RATE_1X, ES8328_SYSCLK_RATE_2X); + return -EINVAL; + } + + /* find master mode MCLK to sampling frequency ratio */ + ratio = mclk_ratios[0].rate; + for (i = 1; i < ARRAY_SIZE(mclk_ratios); i++) + if (params_rate(params) <= mclk_ratios[i].rate) + ratio = mclk_ratios[i].ratio; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + es8328->playback_fs = params_rate(params); + es8328_set_deemph(codec); + } + + return snd_soc_update_bits(codec, reg, ES8328_RATEMASK, ratio); +} + +static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + struct es8328_priv *es8328 = snd_soc_codec_get_drvdata(codec); + int clk_rate; + u8 mode = ES8328_DACCONTROL1_DACWL_16; + + /* set master/slave audio interface */ + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBM_CFM) + return -EINVAL; + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + mode |= ES8328_DACCONTROL1_DACFORMAT_I2S; + break; + case SND_SOC_DAIFMT_RIGHT_J: + mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST; + break; + case SND_SOC_DAIFMT_LEFT_J: + mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) + return -EINVAL; + + snd_soc_write(codec, ES8328_DACCONTROL1, mode); + snd_soc_write(codec, ES8328_ADCCONTROL4, mode); + + /* Master serial port mode, with BCLK generated automatically */ + clk_rate = clk_get_rate(es8328->clk); + if (clk_rate == ES8328_SYSCLK_RATE_1X) + snd_soc_write(codec, ES8328_MASTERMODE, + ES8328_MASTERMODE_MSC); + else + snd_soc_write(codec, ES8328_MASTERMODE, + ES8328_MASTERMODE_MCLKDIV2 | + ES8328_MASTERMODE_MSC); + + return 0; +} + +static int es8328_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* VREF, VMID=2x50k, digital enabled */ + snd_soc_write(codec, ES8328_CHIPPOWER, 0); + snd_soc_update_bits(codec, ES8328_CONTROL1, + ES8328_CONTROL1_VMIDSEL_MASK | + ES8328_CONTROL1_ENREF, + ES8328_CONTROL1_VMIDSEL_50k | + ES8328_CONTROL1_ENREF); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + snd_soc_update_bits(codec, ES8328_CONTROL1, + ES8328_CONTROL1_VMIDSEL_MASK | + ES8328_CONTROL1_ENREF, + ES8328_CONTROL1_VMIDSEL_5k | + ES8328_CONTROL1_ENREF); + + /* Charge caps */ + msleep(100); + } + + snd_soc_write(codec, ES8328_CONTROL2, + ES8328_CONTROL2_OVERCURRENT_ON | + ES8328_CONTROL2_THERMAL_SHUTDOWN_ON); + + /* VREF, VMID=2*500k, digital stopped */ + snd_soc_update_bits(codec, ES8328_CONTROL1, + ES8328_CONTROL1_VMIDSEL_MASK | + ES8328_CONTROL1_ENREF, + ES8328_CONTROL1_VMIDSEL_500k | + ES8328_CONTROL1_ENREF); + break; + + case SND_SOC_BIAS_OFF: + snd_soc_update_bits(codec, ES8328_CONTROL1, + ES8328_CONTROL1_VMIDSEL_MASK | + ES8328_CONTROL1_ENREF, + 0); + break; + } + codec->dapm.bias_level = level; + return 0; +} + +static const struct snd_soc_dai_ops es8328_dai_ops = { + .hw_params = es8328_hw_params, + .digital_mute = es8328_mute, + .set_fmt = es8328_set_dai_fmt, +}; + +static struct snd_soc_dai_driver es8328_dai = { + .name = "es8328-hifi-analog", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = ES8328_RATES, + .formats = ES8328_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = ES8328_RATES, + .formats = ES8328_FORMATS, + }, + .ops = &es8328_dai_ops, +}; + +static int es8328_suspend(struct snd_soc_codec *codec) +{ + struct es8328_priv *es8328; + int ret; + + es8328 = snd_soc_codec_get_drvdata(codec); + + es8328_set_bias_level(codec, SND_SOC_BIAS_OFF); + + clk_disable_unprepare(es8328->clk); + + ret = regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), + es8328->supplies); + if (ret) { + dev_err(codec->dev, "unable to disable regulators\n"); + return ret; + } + return 0; +} + +static int es8328_resume(struct snd_soc_codec *codec) +{ + struct regmap *regmap = dev_get_regmap(codec->dev, NULL); + struct es8328_priv *es8328; + int ret; + + es8328 = snd_soc_codec_get_drvdata(codec); + + ret = clk_prepare_enable(es8328->clk); + if (ret) { + dev_err(codec->dev, "unable to enable clock\n"); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies), + es8328->supplies); + if (ret) { + dev_err(codec->dev, "unable to enable regulators\n"); + return ret; + } + + regcache_mark_dirty(regmap); + ret = regcache_sync(regmap); + if (ret) { + dev_err(codec->dev, "unable to sync regcache\n"); + return ret; + } + + es8328_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} + +static int es8328_codec_probe(struct snd_soc_codec *codec) +{ + struct es8328_priv *es8328; + int ret; + + es8328 = snd_soc_codec_get_drvdata(codec); + + ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies), + es8328->supplies); + if (ret) { + dev_err(codec->dev, "unable to enable regulators\n"); + return ret; + } + + /* Setup clocks */ + es8328->clk = devm_clk_get(codec->dev, NULL); + if (IS_ERR(es8328->clk)) { + dev_err(codec->dev, "codec clock missing or invalid\n"); + goto clk_fail; + } + + ret = clk_prepare_enable(es8328->clk); + if (ret) { + dev_err(codec->dev, "unable to prepare codec clk\n"); + goto clk_fail; + } + + return 0; + +clk_fail: + regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), + es8328->supplies); + return ret; +} + +static int es8328_remove(struct snd_soc_codec *codec) +{ + struct es8328_priv *es8328; + + es8328 = snd_soc_codec_get_drvdata(codec); + + if (es8328->clk) + clk_disable_unprepare(es8328->clk); + + regulator_bulk_disable(ARRAY_SIZE(es8328->supplies), + es8328->supplies); + + return 0; +} + +const struct regmap_config es8328_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = ES8328_REG_MAX, + .cache_type = REGCACHE_RBTREE, +}; +EXPORT_SYMBOL_GPL(es8328_regmap_config); + +static struct snd_soc_codec_driver es8328_codec_driver = { + .probe = es8328_codec_probe, + .suspend = es8328_suspend, + .resume = es8328_resume, + .remove = es8328_remove, + .set_bias_level = es8328_set_bias_level, + .controls = es8328_snd_controls, + .num_controls = ARRAY_SIZE(es8328_snd_controls), + .dapm_widgets = es8328_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets), + .dapm_routes = es8328_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes), +}; + +int es8328_probe(struct device *dev, struct regmap *regmap) +{ + struct es8328_priv *es8328; + int ret; + int i; + + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + es8328 = devm_kzalloc(dev, sizeof(*es8328), GFP_KERNEL); + if (es8328 == NULL) + return -ENOMEM; + + es8328->regmap = regmap; + + for (i = 0; i < ARRAY_SIZE(es8328->supplies); i++) + es8328->supplies[i].supply = supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(es8328->supplies), + es8328->supplies); + if (ret) { + dev_err(dev, "unable to get regulators\n"); + return ret; + } + + dev_set_drvdata(dev, es8328); + + return snd_soc_register_codec(dev, + &es8328_codec_driver, &es8328_dai, 1); +} +EXPORT_SYMBOL_GPL(es8328_probe); + +MODULE_DESCRIPTION("ASoC ES8328 driver"); +MODULE_AUTHOR("Sean Cross "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/es8328.h b/sound/soc/codecs/es8328.h new file mode 100644 index 000000000000..cb36afe10c0e --- /dev/null +++ b/sound/soc/codecs/es8328.h @@ -0,0 +1,314 @@ +/* + * es8328.h -- ES8328 ALSA SoC Audio driver + */ + +#ifndef _ES8328_H +#define _ES8328_H + +#include + +struct device; + +extern const struct regmap_config es8328_regmap_config; +int es8328_probe(struct device *dev, struct regmap *regmap); + +#define ES8328_DACLVOL 46 +#define ES8328_DACRVOL 47 +#define ES8328_DACCTL 28 +#define ES8328_RATEMASK (0x1f << 0) + +#define ES8328_CONTROL1 0x00 +#define ES8328_CONTROL1_VMIDSEL_OFF (0 << 0) +#define ES8328_CONTROL1_VMIDSEL_50k (1 << 0) +#define ES8328_CONTROL1_VMIDSEL_500k (2 << 0) +#define ES8328_CONTROL1_VMIDSEL_5k (3 << 0) +#define ES8328_CONTROL1_VMIDSEL_MASK (7 << 0) +#define ES8328_CONTROL1_ENREF (1 << 2) +#define ES8328_CONTROL1_SEQEN (1 << 3) +#define ES8328_CONTROL1_SAMEFS (1 << 4) +#define ES8328_CONTROL1_DACMCLK_ADC (0 << 5) +#define ES8328_CONTROL1_DACMCLK_DAC (1 << 5) +#define ES8328_CONTROL1_LRCM (1 << 6) +#define ES8328_CONTROL1_SCP_RESET (1 << 7) + +#define ES8328_CONTROL2 0x01 +#define ES8328_CONTROL2_VREF_BUF_OFF (1 << 0) +#define ES8328_CONTROL2_VREF_LOWPOWER (1 << 1) +#define ES8328_CONTROL2_IBIASGEN_OFF (1 << 2) +#define ES8328_CONTROL2_ANALOG_OFF (1 << 3) +#define ES8328_CONTROL2_VREF_BUF_LOWPOWER (1 << 4) +#define ES8328_CONTROL2_VCM_MOD_LOWPOWER (1 << 5) +#define ES8328_CONTROL2_OVERCURRENT_ON (1 << 6) +#define ES8328_CONTROL2_THERMAL_SHUTDOWN_ON (1 << 7) + +#define ES8328_CHIPPOWER 0x02 +#define ES8328_CHIPPOWER_DACVREF_OFF 0 +#define ES8328_CHIPPOWER_ADCVREF_OFF 1 +#define ES8328_CHIPPOWER_DACDLL_OFF 2 +#define ES8328_CHIPPOWER_ADCDLL_OFF 3 +#define ES8328_CHIPPOWER_DACSTM_RESET 4 +#define ES8328_CHIPPOWER_ADCSTM_RESET 5 +#define ES8328_CHIPPOWER_DACDIG_OFF 6 +#define ES8328_CHIPPOWER_ADCDIG_OFF 7 + +#define ES8328_ADCPOWER 0x03 +#define ES8328_ADCPOWER_INT1_LOWPOWER 0 +#define ES8328_ADCPOWER_FLASH_ADC_LOWPOWER 1 +#define ES8328_ADCPOWER_ADC_BIAS_GEN_OFF 2 +#define ES8328_ADCPOWER_MIC_BIAS_OFF 3 +#define ES8328_ADCPOWER_ADCR_OFF 4 +#define ES8328_ADCPOWER_ADCL_OFF 5 +#define ES8328_ADCPOWER_AINR_OFF 6 +#define ES8328_ADCPOWER_AINL_OFF 7 + +#define ES8328_DACPOWER 0x04 +#define ES8328_DACPOWER_OUT3_ON 0 +#define ES8328_DACPOWER_MONO_ON 1 +#define ES8328_DACPOWER_ROUT2_ON 2 +#define ES8328_DACPOWER_LOUT2_ON 3 +#define ES8328_DACPOWER_ROUT1_ON 4 +#define ES8328_DACPOWER_LOUT1_ON 5 +#define ES8328_DACPOWER_RDAC_OFF 6 +#define ES8328_DACPOWER_LDAC_OFF 7 + +#define ES8328_CHIPLOPOW1 0x05 +#define ES8328_CHIPLOPOW2 0x06 +#define ES8328_ANAVOLMANAG 0x07 + +#define ES8328_MASTERMODE 0x08 +#define ES8328_MASTERMODE_BCLKDIV (0 << 0) +#define ES8328_MASTERMODE_BCLK_INV (1 << 5) +#define ES8328_MASTERMODE_MCLKDIV2 (1 << 6) +#define ES8328_MASTERMODE_MSC (1 << 7) + +#define ES8328_ADCCONTROL1 0x09 +#define ES8328_ADCCONTROL2 0x0a +#define ES8328_ADCCONTROL3 0x0b +#define ES8328_ADCCONTROL4 0x0c +#define ES8328_ADCCONTROL5 0x0d +#define ES8328_ADCCONTROL5_RATEMASK (0x1f << 0) + +#define ES8328_ADCCONTROL6 0x0e + +#define ES8328_ADCCONTROL7 0x0f +#define ES8328_ADCCONTROL7_ADC_MUTE (1 << 2) +#define ES8328_ADCCONTROL7_ADC_LER (1 << 3) +#define ES8328_ADCCONTROL7_ADC_ZERO_CROSS (1 << 4) +#define ES8328_ADCCONTROL7_ADC_SOFT_RAMP (1 << 5) +#define ES8328_ADCCONTROL7_ADC_RAMP_RATE_4 (0 << 6) +#define ES8328_ADCCONTROL7_ADC_RAMP_RATE_8 (1 << 6) +#define ES8328_ADCCONTROL7_ADC_RAMP_RATE_16 (2 << 6) +#define ES8328_ADCCONTROL7_ADC_RAMP_RATE_32 (3 << 6) + +#define ES8328_ADCCONTROL8 0x10 +#define ES8328_ADCCONTROL9 0x11 +#define ES8328_ADCCONTROL10 0x12 +#define ES8328_ADCCONTROL11 0x13 +#define ES8328_ADCCONTROL12 0x14 +#define ES8328_ADCCONTROL13 0x15 +#define ES8328_ADCCONTROL14 0x16 + +#define ES8328_DACCONTROL1 0x17 +#define ES8328_DACCONTROL1_DACFORMAT_I2S (0 << 1) +#define ES8328_DACCONTROL1_DACFORMAT_LJUST (1 << 1) +#define ES8328_DACCONTROL1_DACFORMAT_RJUST (2 << 1) +#define ES8328_DACCONTROL1_DACFORMAT_PCM (3 << 1) +#define ES8328_DACCONTROL1_DACWL_24 (0 << 3) +#define ES8328_DACCONTROL1_DACWL_20 (1 << 3) +#define ES8328_DACCONTROL1_DACWL_18 (2 << 3) +#define ES8328_DACCONTROL1_DACWL_16 (3 << 3) +#define ES8328_DACCONTROL1_DACWL_32 (4 << 3) +#define ES8328_DACCONTROL1_DACLRP_I2S_POL_NORMAL (0 << 6) +#define ES8328_DACCONTROL1_DACLRP_I2S_POL_INV (1 << 6) +#define ES8328_DACCONTROL1_DACLRP_PCM_MSB_CLK2 (0 << 6) +#define ES8328_DACCONTROL1_DACLRP_PCM_MSB_CLK1 (1 << 6) +#define ES8328_DACCONTROL1_LRSWAP (1 << 7) + +#define ES8328_DACCONTROL2 0x18 +#define ES8328_DACCONTROL2_RATEMASK (0x1f << 0) +#define ES8328_DACCONTROL2_DOUBLESPEED (1 << 5) + +#define ES8328_DACCONTROL3 0x19 +#define ES8328_DACCONTROL3_AUTOMUTE (1 << 2) +#define ES8328_DACCONTROL3_DACMUTE (1 << 2) +#define ES8328_DACCONTROL3_LEFTGAINVOL (1 << 3) +#define ES8328_DACCONTROL3_DACZEROCROSS (1 << 4) +#define ES8328_DACCONTROL3_DACSOFTRAMP (1 << 5) +#define ES8328_DACCONTROL3_DACRAMPRATE (3 << 6) + +#define ES8328_LDACVOL 0x1a +#define ES8328_LDACVOL_MASK (0 << 0) +#define ES8328_LDACVOL_MAX (0xc0) + +#define ES8328_RDACVOL 0x1b +#define ES8328_RDACVOL_MASK (0 << 0) +#define ES8328_RDACVOL_MAX (0xc0) + +#define ES8328_DACVOL_MAX (0xc0) + +#define ES8328_DACCONTROL4 0x1a +#define ES8328_DACCONTROL5 0x1b + +#define ES8328_DACCONTROL6 0x1c +#define ES8328_DACCONTROL6_CLICKFREE (1 << 3) +#define ES8328_DACCONTROL6_DAC_INVR (1 << 4) +#define ES8328_DACCONTROL6_DAC_INVL (1 << 5) +#define ES8328_DACCONTROL6_DEEMPH_OFF (0 << 6) +#define ES8328_DACCONTROL6_DEEMPH_32k (1 << 6) +#define ES8328_DACCONTROL6_DEEMPH_44_1k (2 << 6) +#define ES8328_DACCONTROL6_DEEMPH_48k (3 << 6) + +#define ES8328_DACCONTROL7 0x1d +#define ES8328_DACCONTROL7_VPP_SCALE_3p5 (0 << 0) +#define ES8328_DACCONTROL7_VPP_SCALE_4p0 (1 << 0) +#define ES8328_DACCONTROL7_VPP_SCALE_3p0 (2 << 0) +#define ES8328_DACCONTROL7_VPP_SCALE_2p5 (3 << 0) +#define ES8328_DACCONTROL7_SHELVING_STRENGTH (1 << 2) /* In eights */ +#define ES8328_DACCONTROL7_MONO (1 << 5) +#define ES8328_DACCONTROL7_ZEROR (1 << 6) +#define ES8328_DACCONTROL7_ZEROL (1 << 7) + +/* Shelving filter */ +#define ES8328_DACCONTROL8 0x1e +#define ES8328_DACCONTROL9 0x1f +#define ES8328_DACCONTROL10 0x20 +#define ES8328_DACCONTROL11 0x21 +#define ES8328_DACCONTROL12 0x22 +#define ES8328_DACCONTROL13 0x23 +#define ES8328_DACCONTROL14 0x24 +#define ES8328_DACCONTROL15 0x25 + +#define ES8328_DACCONTROL16 0x26 +#define ES8328_DACCONTROL16_RMIXSEL_RIN1 (0 << 0) +#define ES8328_DACCONTROL16_RMIXSEL_RIN2 (1 << 0) +#define ES8328_DACCONTROL16_RMIXSEL_RIN3 (2 << 0) +#define ES8328_DACCONTROL16_RMIXSEL_RADC (3 << 0) +#define ES8328_DACCONTROL16_LMIXSEL_LIN1 (0 << 3) +#define ES8328_DACCONTROL16_LMIXSEL_LIN2 (1 << 3) +#define ES8328_DACCONTROL16_LMIXSEL_LIN3 (2 << 3) +#define ES8328_DACCONTROL16_LMIXSEL_LADC (3 << 3) + +#define ES8328_DACCONTROL17 0x27 +#define ES8328_DACCONTROL17_LI2LOVOL (7 << 3) +#define ES8328_DACCONTROL17_LI2LO (1 << 6) +#define ES8328_DACCONTROL17_LD2LO (1 << 7) + +#define ES8328_DACCONTROL18 0x28 +#define ES8328_DACCONTROL18_RI2LOVOL (7 << 3) +#define ES8328_DACCONTROL18_RI2LO (1 << 6) +#define ES8328_DACCONTROL18_RD2LO (1 << 7) + +#define ES8328_DACCONTROL19 0x29 +#define ES8328_DACCONTROL19_LI2ROVOL (7 << 3) +#define ES8328_DACCONTROL19_LI2RO (1 << 6) +#define ES8328_DACCONTROL19_LD2RO (1 << 7) + +#define ES8328_DACCONTROL20 0x2a +#define ES8328_DACCONTROL20_RI2ROVOL (7 << 3) +#define ES8328_DACCONTROL20_RI2RO (1 << 6) +#define ES8328_DACCONTROL20_RD2RO (1 << 7) + +#define ES8328_DACCONTROL21 0x2b +#define ES8328_DACCONTROL21_LI2MOVOL (7 << 3) +#define ES8328_DACCONTROL21_LI2MO (1 << 6) +#define ES8328_DACCONTROL21_LD2MO (1 << 7) + +#define ES8328_DACCONTROL22 0x2c +#define ES8328_DACCONTROL22_RI2MOVOL (7 << 3) +#define ES8328_DACCONTROL22_RI2MO (1 << 6) +#define ES8328_DACCONTROL22_RD2MO (1 << 7) + +#define ES8328_DACCONTROL23 0x2d +#define ES8328_DACCONTROL23_MOUTINV (1 << 1) +#define ES8328_DACCONTROL23_HPSWPOL (1 << 2) +#define ES8328_DACCONTROL23_HPSWEN (1 << 3) +#define ES8328_DACCONTROL23_VROI_1p5k (0 << 4) +#define ES8328_DACCONTROL23_VROI_40k (1 << 4) +#define ES8328_DACCONTROL23_OUT3_VREF (0 << 5) +#define ES8328_DACCONTROL23_OUT3_ROUT1 (1 << 5) +#define ES8328_DACCONTROL23_OUT3_MONOOUT (2 << 5) +#define ES8328_DACCONTROL23_OUT3_RIGHT_MIXER (3 << 5) +#define ES8328_DACCONTROL23_ROUT2INV (1 << 7) + +/* LOUT1 Amplifier */ +#define ES8328_LOUT1VOL 0x2e +#define ES8328_LOUT1VOL_MASK (0 << 5) +#define ES8328_LOUT1VOL_MAX (0x24) + +/* ROUT1 Amplifier */ +#define ES8328_ROUT1VOL 0x2f +#define ES8328_ROUT1VOL_MASK (0 << 5) +#define ES8328_ROUT1VOL_MAX (0x24) + +#define ES8328_OUT1VOL_MAX (0x24) + +/* LOUT2 Amplifier */ +#define ES8328_LOUT2VOL 0x30 +#define ES8328_LOUT2VOL_MASK (0 << 5) +#define ES8328_LOUT2VOL_MAX (0x24) + +/* ROUT2 Amplifier */ +#define ES8328_ROUT2VOL 0x31 +#define ES8328_ROUT2VOL_MASK (0 << 5) +#define ES8328_ROUT2VOL_MAX (0x24) + +#define ES8328_OUT2VOL_MAX (0x24) + +/* Mono Out Amplifier */ +#define ES8328_MONOOUTVOL 0x32 +#define ES8328_MONOOUTVOL_MASK (0 << 5) +#define ES8328_MONOOUTVOL_MAX (0x24) + +#define ES8328_DACCONTROL29 0x33 +#define ES8328_DACCONTROL30 0x34 + +#define ES8328_SYSCLK 0 + +#define ES8328_REG_MAX 0x35 + +#define ES8328_PLL1 0 +#define ES8328_PLL2 1 + +/* clock inputs */ +#define ES8328_MCLK 0 +#define ES8328_PCMCLK 1 + +/* clock divider id's */ +#define ES8328_PCMDIV 0 +#define ES8328_BCLKDIV 1 +#define ES8328_VXCLKDIV 2 + +/* PCM clock dividers */ +#define ES8328_PCM_DIV_1 (0 << 6) +#define ES8328_PCM_DIV_3 (2 << 6) +#define ES8328_PCM_DIV_5_5 (3 << 6) +#define ES8328_PCM_DIV_2 (4 << 6) +#define ES8328_PCM_DIV_4 (5 << 6) +#define ES8328_PCM_DIV_6 (6 << 6) +#define ES8328_PCM_DIV_8 (7 << 6) + +/* BCLK clock dividers */ +#define ES8328_BCLK_DIV_1 (0 << 7) +#define ES8328_BCLK_DIV_2 (1 << 7) +#define ES8328_BCLK_DIV_4 (2 << 7) +#define ES8328_BCLK_DIV_8 (3 << 7) + +/* VXCLK clock dividers */ +#define ES8328_VXCLK_DIV_1 (0 << 6) +#define ES8328_VXCLK_DIV_2 (1 << 6) +#define ES8328_VXCLK_DIV_4 (2 << 6) +#define ES8328_VXCLK_DIV_8 (3 << 6) +#define ES8328_VXCLK_DIV_16 (4 << 6) + +#define ES8328_DAI_HIFI 0 +#define ES8328_DAI_VOICE 1 + +#define ES8328_1536FS 1536 +#define ES8328_1024FS 1024 +#define ES8328_768FS 768 +#define ES8328_512FS 512 +#define ES8328_384FS 384 +#define ES8328_256FS 256 +#define ES8328_128FS 128 + +#endif -- GitLab From 7e7292dba2155c1433ce9f9a819f1acb9090747b Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 31 Jul 2014 10:43:37 +0800 Subject: [PATCH 0724/9167] ASoC: fsl: add imx-es8328 machine driver This adds an initial machine driver for the ES8328 audio codec on Freescale boards. The driver supports headphones and an audio regulator for an onboard speaker amp. Signed-off-by: Sean Cross Signed-off-by: Mark Brown --- .../bindings/sound/imx-audio-es8328.txt | 60 +++++ sound/soc/fsl/Kconfig | 14 ++ sound/soc/fsl/Makefile | 2 + sound/soc/fsl/imx-es8328.c | 232 ++++++++++++++++++ 4 files changed, 308 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/imx-audio-es8328.txt create mode 100644 sound/soc/fsl/imx-es8328.c diff --git a/Documentation/devicetree/bindings/sound/imx-audio-es8328.txt b/Documentation/devicetree/bindings/sound/imx-audio-es8328.txt new file mode 100644 index 000000000000..07b68ab206fb --- /dev/null +++ b/Documentation/devicetree/bindings/sound/imx-audio-es8328.txt @@ -0,0 +1,60 @@ +Freescale i.MX audio complex with ES8328 codec + +Required properties: +- compatible : "fsl,imx-audio-es8328" +- model : The user-visible name of this sound complex +- ssi-controller : The phandle of the i.MX SSI controller +- jack-gpio : Optional GPIO for headphone jack +- audio-amp-supply : Power regulator for speaker amps +- audio-codec : The phandle of the ES8328 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, ES8328 + pins, and the jacks on the board: + + Power supplies: + * audio-amp + + ES8328 pins: + * LOUT1 + * LOUT2 + * ROUT1 + * ROUT2 + * LINPUT1 + * LINPUT2 + * RINPUT1 + * RINPUT2 + * Mic PGA + + Board connectors: + * Headphone + * Speaker + * Mic Jack +- 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 (AUDMIX) + +Note: The AUDMUX port numbering should start at 1, which is consistent with +hardware manual. + +Example: + +sound { + compatible = "fsl,imx-audio-es8328"; + model = "imx-audio-es8328"; + ssi-controller = <&ssi1>; + audio-codec = <&codec>; + jack-gpio = <&gpio5 15 0>; + audio-amp-supply = <®_audio_amp>; + audio-routing = + "Speaker", "LOUT2", + "Speaker", "ROUT2", + "Speaker", "audio-amp", + "Headphone", "ROUT1", + "Headphone", "LOUT1", + "LINPUT1", "Mic Jack", + "RINPUT1", "Mic Jack", + "Mic Jack", "Mic Bias"; + mux-int-port = <1>; + mux-ext-port = <3>; +}; diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 2b99a9e86899..fa90340dc13a 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -257,6 +257,20 @@ config SND_SOC_IMX_WM8962 Say Y if you want to add support for SoC audio on an i.MX board with a wm8962 codec. +config SND_SOC_IMX_ES8328 + tristate "SoC Audio support for i.MX boards with the ES8328 codec" + depends on OF && (I2C || SPI) + select SND_SOC_ES8328_I2C if I2C + select SND_SOC_ES8328_SPI if SPI_MASTER + select SND_SOC_IMX_PCM_DMA + select SND_SOC_IMX_AUDMUX + select SND_SOC_FSL_SSI + select SND_SOC_FSL_UTILS + select SND_SOC_IMX_PCM_FIQ + help + Say Y if you want to add support for the ES8328 audio codec connected + via SSI/I2S over either SPI or I2C. + config SND_SOC_IMX_SGTL5000 tristate "SoC Audio support for i.MX boards with sgtl5000" depends on OF && I2C diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 8f6d84efa973..d28dc25c9375 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -52,6 +52,7 @@ snd-soc-eukrea-tlv320-objs := eukrea-tlv320.o snd-soc-phycore-ac97-objs := phycore-ac97.o snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o snd-soc-wm1133-ev1-objs := wm1133-ev1.o +snd-soc-imx-es8328-objs := imx-es8328.o snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o snd-soc-imx-wm8962-objs := imx-wm8962.o snd-soc-imx-spdif-objs := imx-spdif.o @@ -61,6 +62,7 @@ obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o +obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o diff --git a/sound/soc/fsl/imx-es8328.c b/sound/soc/fsl/imx-es8328.c new file mode 100644 index 000000000000..653e66d150c8 --- /dev/null +++ b/sound/soc/fsl/imx-es8328.c @@ -0,0 +1,232 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * Copyright 2012 Linaro Ltd. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "imx-audmux.h" + +#define DAI_NAME_SIZE 32 +#define MUX_PORT_MAX 7 + +struct imx_es8328_data { + struct device *dev; + struct snd_soc_dai_link dai; + struct snd_soc_card card; + char codec_dai_name[DAI_NAME_SIZE]; + char platform_name[DAI_NAME_SIZE]; + int jack_gpio; +}; + +static struct snd_soc_jack_gpio headset_jack_gpios[] = { + { + .gpio = -1, + .name = "headset-gpio", + .report = SND_JACK_HEADSET, + .invert = 0, + .debounce_time = 200, + }, +}; + +static struct snd_soc_jack headset_jack; + +static int imx_es8328_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + struct imx_es8328_data *data = container_of(rtd->card, + struct imx_es8328_data, card); + int ret = 0; + + /* Headphone jack detection */ + if (gpio_is_valid(data->jack_gpio)) { + ret = snd_soc_jack_new(rtd->codec, "Headphone", + SND_JACK_HEADPHONE | SND_JACK_BTN_0, + &headset_jack); + if (ret) + return ret; + + headset_jack_gpios[0].gpio = data->jack_gpio; + ret = snd_soc_jack_add_gpios(&headset_jack, + ARRAY_SIZE(headset_jack_gpios), + headset_jack_gpios); + } + + return ret; +} + +static const struct snd_soc_dapm_widget imx_es8328_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_REGULATOR_SUPPLY("audio-amp", 1, 0), +}; + +static int imx_es8328_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct device_node *ssi_np, *codec_np; + struct platform_device *ssi_pdev; + struct imx_es8328_data *data; + u32 int_port, ext_port; + int ret; + struct device *dev = &pdev->dev; + + ret = of_property_read_u32(np, "mux-int-port", &int_port); + if (ret) { + dev_err(dev, "mux-int-port missing or invalid\n"); + goto fail; + } + if (int_port > MUX_PORT_MAX || int_port == 0) { + dev_err(dev, "mux-int-port: hardware only has %d mux ports\n", + MUX_PORT_MAX); + goto fail; + } + + ret = of_property_read_u32(np, "mux-ext-port", &ext_port); + if (ret) { + dev_err(dev, "mux-ext-port missing or invalid\n"); + goto fail; + } + if (ext_port > MUX_PORT_MAX || ext_port == 0) { + dev_err(dev, "mux-ext-port: hardware only has %d mux ports\n", + MUX_PORT_MAX); + goto fail; + } + + /* + * The port numbering in the hardware manual starts at 1, while + * the audmux API expects it starts at 0. + */ + int_port--; + ext_port--; + ret = imx_audmux_v2_configure_port(int_port, + IMX_AUDMUX_V2_PTCR_SYN | + IMX_AUDMUX_V2_PTCR_TFSEL(ext_port) | + IMX_AUDMUX_V2_PTCR_TCSEL(ext_port) | + IMX_AUDMUX_V2_PTCR_TFSDIR | + IMX_AUDMUX_V2_PTCR_TCLKDIR, + IMX_AUDMUX_V2_PDCR_RXDSEL(ext_port)); + if (ret) { + dev_err(dev, "audmux internal port setup failed\n"); + return ret; + } + ret = imx_audmux_v2_configure_port(ext_port, + IMX_AUDMUX_V2_PTCR_SYN, + IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); + if (ret) { + dev_err(dev, "audmux external port setup failed\n"); + return ret; + } + + ssi_np = of_parse_phandle(pdev->dev.of_node, "ssi-controller", 0); + codec_np = of_parse_phandle(pdev->dev.of_node, "audio-codec", 0); + if (!ssi_np || !codec_np) { + dev_err(dev, "phandle missing or invalid\n"); + ret = -EINVAL; + goto fail; + } + + ssi_pdev = of_find_device_by_node(ssi_np); + if (!ssi_pdev) { + dev_err(dev, "failed to find SSI platform device\n"); + ret = -EINVAL; + goto fail; + } + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto fail; + } + + data->dev = dev; + + data->jack_gpio = of_get_named_gpio(pdev->dev.of_node, "jack-gpio", 0); + + data->dai.name = "hifi"; + data->dai.stream_name = "hifi"; + data->dai.codec_dai_name = "es8328-hifi-analog"; + data->dai.codec_of_node = codec_np; + data->dai.cpu_of_node = ssi_np; + data->dai.platform_of_node = ssi_np; + data->dai.init = &imx_es8328_dai_init; + data->dai.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM; + + data->card.dev = dev; + data->card.dapm_widgets = imx_es8328_dapm_widgets; + data->card.num_dapm_widgets = ARRAY_SIZE(imx_es8328_dapm_widgets); + ret = snd_soc_of_parse_card_name(&data->card, "model"); + if (ret) { + dev_err(dev, "Unable to parse card name\n"); + goto fail; + } + ret = snd_soc_of_parse_audio_routing(&data->card, "audio-routing"); + if (ret) { + dev_err(dev, "Unable to parse routing: %d\n", ret); + goto fail; + } + data->card.num_links = 1; + data->card.owner = THIS_MODULE; + data->card.dai_link = &data->dai; + + ret = snd_soc_register_card(&data->card); + if (ret) { + dev_err(dev, "Unable to register: %d\n", ret); + goto fail; + } + + platform_set_drvdata(pdev, data); +fail: + of_node_put(ssi_np); + of_node_put(codec_np); + + return ret; +} + +static int imx_es8328_remove(struct platform_device *pdev) +{ + struct imx_es8328_data *data = platform_get_drvdata(pdev); + + snd_soc_jack_free_gpios(&headset_jack, ARRAY_SIZE(headset_jack_gpios), + headset_jack_gpios); + + snd_soc_unregister_card(&data->card); + + return 0; +} + +static const struct of_device_id imx_es8328_dt_ids[] = { + { .compatible = "fsl,imx-audio-es8328", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_es8328_dt_ids); + +static struct platform_driver imx_es8328_driver = { + .driver = { + .name = "imx-es8328", + .of_match_table = imx_es8328_dt_ids, + }, + .probe = imx_es8328_probe, + .remove = imx_es8328_remove, +}; +module_platform_driver(imx_es8328_driver); + +MODULE_AUTHOR("Sean Cross "); +MODULE_DESCRIPTION("Kosagi i.MX6 ES8328 ASoC machine driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:imx-audio-es8328"); -- GitLab From afa93c9017fd48d4d5265854c75f5fcde0871548 Mon Sep 17 00:00:00 2001 From: "Chew, Chiau Ee" Date: Fri, 25 Jul 2014 01:10:54 +0800 Subject: [PATCH 0725/9167] spi/pxa2xx-pci: Add common clock framework support in PCI glue layer SPI PXA2XX core layer has dependency on common clock framework to obtain information on host supported clock rate. Thus, we setup the clock device in the PCI glue layer to enable PCI mode host pass in the clock rate information. Signed-off-by: Chew, Chiau Ee Acked-by: Kweh, Hock Leong Acked-by: Mika Westerberg Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 2 +- drivers/spi/spi-pxa2xx-pci.c | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 62e2242ad7e0..aa005cbf2e50 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -380,7 +380,7 @@ config SPI_PXA2XX additional documentation can be found a Documentation/spi/pxa2xx. config SPI_PXA2XX_PCI - def_tristate SPI_PXA2XX && PCI + def_tristate SPI_PXA2XX && PCI && COMMON_CLK config SPI_ROCKCHIP tristate "Rockchip SPI controller driver" diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index c1865c92ccb9..20ebbc764693 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include enum { PORT_CE4100, @@ -21,6 +23,7 @@ struct pxa_spi_info { int tx_chan_id; int rx_slave_id; int rx_chan_id; + unsigned long max_clk_rate; }; static struct pxa_spi_info spi_info_configs[] = { @@ -32,6 +35,7 @@ static struct pxa_spi_info spi_info_configs[] = { .tx_chan_id = -1, .rx_slave_id = -1, .rx_chan_id = -1, + .max_clk_rate = 3686400, }, [PORT_BYT] = { .type = LPSS_SSP, @@ -41,6 +45,7 @@ static struct pxa_spi_info spi_info_configs[] = { .tx_chan_id = 0, .rx_slave_id = 1, .rx_chan_id = 1, + .max_clk_rate = 50000000, }, }; @@ -53,6 +58,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, struct pxa2xx_spi_master spi_pdata; struct ssp_device *ssp; struct pxa_spi_info *c; + char buf[40]; ret = pcim_enable_device(dev); if (ret) @@ -84,6 +90,12 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn; ssp->type = c->type; + snprintf(buf, sizeof(buf), "pxa2xx-spi.%d", ssp->port_id); + ssp->clk = clk_register_fixed_rate(&dev->dev, buf , NULL, + CLK_IS_ROOT, c->max_clk_rate); + if (IS_ERR(ssp->clk)) + return PTR_ERR(ssp->clk); + memset(&pi, 0, sizeof(pi)); pi.parent = &dev->dev; pi.name = "pxa2xx-spi"; @@ -92,8 +104,10 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, pi.size_data = sizeof(spi_pdata); pdev = platform_device_register_full(&pi); - if (IS_ERR(pdev)) + if (IS_ERR(pdev)) { + clk_unregister(ssp->clk); return PTR_ERR(pdev); + } pci_set_drvdata(dev, pdev); @@ -103,8 +117,13 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev, static void pxa2xx_spi_pci_remove(struct pci_dev *dev) { struct platform_device *pdev = pci_get_drvdata(dev); + struct pxa2xx_spi_master *spi_pdata; + + spi_pdata = dev_get_platdata(&pdev->dev); platform_device_unregister(pdev); + clk_unregister(spi_pdata->ssp.clk); + pci_set_drvdata(dev, NULL); } static const struct pci_device_id pxa2xx_spi_pci_devices[] = { -- GitLab From 855675f6e6a65688a7f4cf45b9b5a98cf6c6f5c3 Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Mon, 4 Aug 2014 15:07:25 +0800 Subject: [PATCH 0726/9167] ASoC: fsl_sai: Set SYNC bit of TCR2 to Asynchronous Mode There is one design rule according to SAI's reference manual: If the transmitter bit clock and frame sync are to be used by both transmitter and receiver, the transmitter must be configured for asynchronous operation and the receiver for synchronous operation. And SYNC of TCR2 is a 2-width control bit: 00 Asynchronous mode. 01 Synchronous with receiver. 10 Synchronous with another SAI transmitter. 11 Synchronous with another SAI receiver. So the driver should have set SYNC bit of TCR2 to 0x0, and meanwhile set SYNC bit of RCR2 to 0x1 (Synchronous with transmitter). Signed-off-by: Nicolin Chen Signed-off-by: Mark Brown --- sound/soc/fsl/fsl_sai.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 4c9e71c2f52a..60fe7c77ba22 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -334,8 +334,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, * Rx sync with Tx clocks: Clear SYNC for Tx, set it for Rx. * Tx sync with Rx clocks: Clear SYNC for Rx, set it for Tx. */ - regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, - sai->synchronous[TX] ? FSL_SAI_CR2_SYNC : 0); + regmap_update_bits(sai->regmap, FSL_SAI_TCR2, FSL_SAI_CR2_SYNC, 0); regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, sai->synchronous[RX] ? FSL_SAI_CR2_SYNC : 0); -- GitLab From 39cf6d73dc1ed11c7d5d2c96a0ccbbb868a7f3ce Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2014 15:12:37 +0200 Subject: [PATCH 0727/9167] ARM: shmobile: r8a7790: Add CMT devices to DT Add the CMT0 and CMT1 counters to the r8a7790 device tree and make them disabled by default. Signed-off-by: Laurent Pinchart Tested-by: Simon Horman Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index d9ddecbb859c..7218bfff0bca 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -206,6 +206,38 @@ <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; }; + cmt0: timer@ffca0000 { + compatible = "renesas,cmt-48-gen2"; + reg = <0 0xffca0000 0 0x1004>; + interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, + <0 143 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp1_clks R8A7790_CLK_CMT0>; + clock-names = "fck"; + + renesas,channels-mask = <0x60>; + + status = "disabled"; + }; + + cmt1: timer@e6130000 { + compatible = "renesas,cmt-48-gen2"; + reg = <0 0xe6130000 0 0x1004>; + interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, + <0 121 IRQ_TYPE_LEVEL_HIGH>, + <0 122 IRQ_TYPE_LEVEL_HIGH>, + <0 123 IRQ_TYPE_LEVEL_HIGH>, + <0 124 IRQ_TYPE_LEVEL_HIGH>, + <0 125 IRQ_TYPE_LEVEL_HIGH>, + <0 126 IRQ_TYPE_LEVEL_HIGH>, + <0 127 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7790_CLK_CMT1>; + clock-names = "fck"; + + renesas,channels-mask = <0xff>; + + status = "disabled"; + }; + irqc0: interrupt-controller@e61c0000 { compatible = "renesas,irqc-r8a7790", "renesas,irqc"; #interrupt-cells = <2>; -- GitLab From ceaa18949a190cf335408751cac0de2a0de0b9e7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2014 15:12:38 +0200 Subject: [PATCH 0728/9167] ARM: shmobile: r8a7791: Add CMT devices to DT Add the CMT0 and CMT1 counters to the r8a7791 device tree and make them disabled by default. Signed-off-by: Laurent Pinchart Tested-by: Simon Horman Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 0d82a4b3c650..bdb9ac1509f8 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -189,6 +189,38 @@ <1 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; }; + cmt0: timer@ffca0000 { + compatible = "renesas,cmt-48-gen2"; + reg = <0 0xffca0000 0 0x1004>; + interrupts = <0 142 IRQ_TYPE_LEVEL_HIGH>, + <0 143 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp1_clks R8A7791_CLK_CMT0>; + clock-names = "fck"; + + renesas,channels-mask = <0x60>; + + status = "disabled"; + }; + + cmt1: timer@e6130000 { + compatible = "renesas,cmt-48-gen2"; + reg = <0 0xe6130000 0 0x1004>; + interrupts = <0 120 IRQ_TYPE_LEVEL_HIGH>, + <0 121 IRQ_TYPE_LEVEL_HIGH>, + <0 122 IRQ_TYPE_LEVEL_HIGH>, + <0 123 IRQ_TYPE_LEVEL_HIGH>, + <0 124 IRQ_TYPE_LEVEL_HIGH>, + <0 125 IRQ_TYPE_LEVEL_HIGH>, + <0 126 IRQ_TYPE_LEVEL_HIGH>, + <0 127 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp3_clks R8A7791_CLK_CMT1>; + clock-names = "fck"; + + renesas,channels-mask = <0xff>; + + status = "disabled"; + }; + irqc0: interrupt-controller@e61c0000 { compatible = "renesas,irqc-r8a7791", "renesas,irqc"; #interrupt-cells = <2>; -- GitLab From ef890ea26a37884a21f592c3feccadb019e8a11b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2014 15:12:39 +0200 Subject: [PATCH 0729/9167] ARM: shmobile: r8a7779: Add TMU devices to DT Add the TMU0, TMU1 and TMU2 counters to the r8a7779 device tree and make them disabled by default. Signed-off-by: Laurent Pinchart Tested-by: Simon Horman Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7779.dtsi | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi index 58d0d952d60e..463e3fd569b6 100644 --- a/arch/arm/boot/dts/r8a7779.dtsi +++ b/arch/arm/boot/dts/r8a7779.dtsi @@ -266,6 +266,48 @@ reg = <0xffc48000 0x38>; }; + tmu0: timer@ffd80000 { + compatible = "renesas,tmu"; + reg = <0xffd80000 0x30>; + interrupts = <0 32 IRQ_TYPE_LEVEL_HIGH>, + <0 33 IRQ_TYPE_LEVEL_HIGH>, + <0 34 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp0_clks R8A7779_CLK_TMU0>; + clock-names = "fck"; + + #renesas,channels = <3>; + + status = "disabled"; + }; + + tmu1: timer@ffd81000 { + compatible = "renesas,tmu"; + reg = <0xffd81000 0x30>; + interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>, + <0 37 IRQ_TYPE_LEVEL_HIGH>, + <0 38 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp0_clks R8A7779_CLK_TMU1>; + clock-names = "fck"; + + #renesas,channels = <3>; + + status = "disabled"; + }; + + tmu2: timer@ffd82000 { + compatible = "renesas,tmu"; + reg = <0xffd82000 0x30>; + interrupts = <0 40 IRQ_TYPE_LEVEL_HIGH>, + <0 41 IRQ_TYPE_LEVEL_HIGH>, + <0 42 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp0_clks R8A7779_CLK_TMU2>; + clock-names = "fck"; + + #renesas,channels = <3>; + + status = "disabled"; + }; + sata: sata@fc600000 { compatible = "renesas,rcar-sata"; reg = <0xfc600000 0x2000>; -- GitLab From 247fd5ec6e9a41f9299df27be82104efc56e622b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2014 15:12:41 +0200 Subject: [PATCH 0730/9167] ARM: shmobile: lager-reference: Enable CMT0 in device tree No more device needs to be added from platform code when booting the reference platform, remove the now empty r8a7790_add_dt_devices() function completely. Signed-off-by: Laurent Pinchart Tested-by: Simon Horman Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790-lager.dts | 4 ++++ arch/arm/mach-shmobile/board-lager-reference.c | 2 -- arch/arm/mach-shmobile/r8a7790.h | 1 - arch/arm/mach-shmobile/setup-r8a7790.c | 7 +------ 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 856b4236b674..7853c2c15ce6 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -252,6 +252,10 @@ }; }; +&cmt0 { + status = "ok"; +}; + &mmcif1 { pinctrl-0 = <&mmc1_pins>; pinctrl-names = "default"; diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index 41c808e56005..2a05c02bec39 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c @@ -92,7 +92,6 @@ static void __init lager_add_du_device(void) * devices until they get moved to DT. */ static const struct clk_name clk_names[] __initconst = { - { "cmt0", "fck", "sh-cmt-48-gen2.0" }, { "du0", "du.0", "rcar-du-r8a7790" }, { "du1", "du.1", "rcar-du-r8a7790" }, { "du2", "du.2", "rcar-du-r8a7790" }, @@ -103,7 +102,6 @@ static const struct clk_name clk_names[] __initconst = { static void __init lager_add_standard_devices(void) { shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); - r8a7790_add_dt_devices(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); lager_add_du_device(); diff --git a/arch/arm/mach-shmobile/r8a7790.h b/arch/arm/mach-shmobile/r8a7790.h index 459827f1369b..388f0514d931 100644 --- a/arch/arm/mach-shmobile/r8a7790.h +++ b/arch/arm/mach-shmobile/r8a7790.h @@ -27,7 +27,6 @@ enum { }; void r8a7790_add_standard_devices(void); -void r8a7790_add_dt_devices(void); void r8a7790_clock_init(void); void r8a7790_pinmux_init(void); void r8a7790_pm_init(void); diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 0c12b01bb9e3..877fdeb985d0 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -282,11 +282,6 @@ static struct resource cmt0_resources[] = { &cmt##idx##_platform_data, \ sizeof(struct sh_timer_config)) -void __init r8a7790_add_dt_devices(void) -{ - r8a7790_register_cmt(0); -} - void __init r8a7790_add_standard_devices(void) { r8a7790_register_scif(0); @@ -299,7 +294,7 @@ void __init r8a7790_add_standard_devices(void) r8a7790_register_scif(7); r8a7790_register_scif(8); r8a7790_register_scif(9); - r8a7790_add_dt_devices(); + r8a7790_register_cmt(0); r8a7790_register_irqc(0); r8a7790_register_thermal(); r8a7790_register_i2c(0); -- GitLab From 6a1d9460df90f96e31922ad5c891c5c54a4c7f4e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2014 15:12:42 +0200 Subject: [PATCH 0731/9167] ARM: shmobile: koelsch-reference: Enable CMT0 in device tree No more device needs to be added from platform code when booting the reference platform, remove the now empty r8a7791_add_dt_devices() function completely. Signed-off-by: Laurent Pinchart Tested-by: Simon Horman Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-koelsch.dts | 4 ++++ arch/arm/mach-shmobile/board-koelsch-reference.c | 2 -- arch/arm/mach-shmobile/r8a7791.h | 1 - arch/arm/mach-shmobile/setup-r8a7791.c | 7 +------ 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 23486c081a69..8f36d4f793a8 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -307,6 +307,10 @@ }; }; +&cmt0 { + status = "ok"; +}; + &sata0 { status = "okay"; }; diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c index 3ff88c138896..9db5e6774fb7 100644 --- a/arch/arm/mach-shmobile/board-koelsch-reference.c +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c @@ -88,7 +88,6 @@ static void __init koelsch_add_du_device(void) * devices until they get moved to DT. */ static const struct clk_name clk_names[] __initconst = { - { "cmt0", "fck", "sh-cmt-48-gen2.0" }, { "du0", "du.0", "rcar-du-r8a7791" }, { "du1", "du.1", "rcar-du-r8a7791" }, { "lvds0", "lvds.0", "rcar-du-r8a7791" }, @@ -97,7 +96,6 @@ static const struct clk_name clk_names[] __initconst = { static void __init koelsch_add_standard_devices(void) { shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); - r8a7791_add_dt_devices(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); koelsch_add_du_device(); diff --git a/arch/arm/mach-shmobile/r8a7791.h b/arch/arm/mach-shmobile/r8a7791.h index 86eae7bceb6f..c1bf7abefa5a 100644 --- a/arch/arm/mach-shmobile/r8a7791.h +++ b/arch/arm/mach-shmobile/r8a7791.h @@ -2,7 +2,6 @@ #define __ASM_R8A7791_H__ void r8a7791_add_standard_devices(void); -void r8a7791_add_dt_devices(void); void r8a7791_clock_init(void); void r8a7791_pinmux_init(void); void r8a7791_pm_init(void); diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c index d47d8b16a43f..35d78639244f 100644 --- a/arch/arm/mach-shmobile/setup-r8a7791.c +++ b/arch/arm/mach-shmobile/setup-r8a7791.c @@ -182,11 +182,6 @@ static const struct resource thermal_resources[] __initconst = { thermal_resources, \ ARRAY_SIZE(thermal_resources)) -void __init r8a7791_add_dt_devices(void) -{ - r8a7791_register_cmt(0); -} - void __init r8a7791_add_standard_devices(void) { r8a7791_register_scif(0); @@ -204,7 +199,7 @@ void __init r8a7791_add_standard_devices(void) r8a7791_register_scif(12); r8a7791_register_scif(13); r8a7791_register_scif(14); - r8a7791_add_dt_devices(); + r8a7791_register_cmt(0); r8a7791_register_irqc(0); r8a7791_register_thermal(); } -- GitLab From 5ecd7a5185008723056a4b70815aa017272ca751 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2014 15:12:43 +0200 Subject: [PATCH 0732/9167] ARM: shmobile: marzen-reference: Enable TMU0 in device tree No more device needs to be added from platform code when booting the reference platform, remove the now empty r8a7779_add_standard_devices_dt() function completely. Signed-off-by: Laurent Pinchart Tested-by: Simon Horman Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7779-marzen.dts | 4 ++++ arch/arm/mach-shmobile/board-marzen-reference.c | 10 ---------- arch/arm/mach-shmobile/r8a7779.h | 1 - arch/arm/mach-shmobile/setup-r8a7779.c | 17 +++++------------ 4 files changed, 9 insertions(+), 23 deletions(-) diff --git a/arch/arm/boot/dts/r8a7779-marzen.dts b/arch/arm/boot/dts/r8a7779-marzen.dts index 5745555df943..c160404e4d40 100644 --- a/arch/arm/boot/dts/r8a7779-marzen.dts +++ b/arch/arm/boot/dts/r8a7779-marzen.dts @@ -78,6 +78,10 @@ clock-frequency = <31250000>; }; +&tmu0 { + status = "okay"; +}; + &pfc { lan0_pins: lan0 { intc { diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c index 21b3e1ca2261..f6710033c429 100644 --- a/arch/arm/mach-shmobile/board-marzen-reference.c +++ b/arch/arm/mach-shmobile/board-marzen-reference.c @@ -37,18 +37,8 @@ static void __init marzen_init_timer(void) clocksource_of_init(); } -/* - * This is a really crude hack to provide clkdev support to platform - * devices until they get moved to DT. - */ -static const struct clk_name clk_names[] __initconst = { - { "tmu0", "fck", "sh-tmu.0" }, -}; - static void __init marzen_init(void) { - shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); - r8a7779_add_standard_devices_dt(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */ } diff --git a/arch/arm/mach-shmobile/r8a7779.h b/arch/arm/mach-shmobile/r8a7779.h index 5415c719dc19..19f97046dd70 100644 --- a/arch/arm/mach-shmobile/r8a7779.h +++ b/arch/arm/mach-shmobile/r8a7779.h @@ -17,7 +17,6 @@ extern void r8a7779_map_io(void); extern void r8a7779_earlytimer_init(void); extern void r8a7779_add_early_devices(void); extern void r8a7779_add_standard_devices(void); -extern void r8a7779_add_standard_devices_dt(void); extern void r8a7779_init_late(void); extern u32 r8a7779_read_mode_pins(void); extern void r8a7779_clock_init(void); diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 236c1befb9e3..11ceee607464 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -641,7 +641,7 @@ static void __init r8a7779_register_hpb_dmae(void) sizeof(dma_platform_data)); } -static struct platform_device *r8a7779_devices_dt[] __initdata = { +static struct platform_device *r8a7779_early_devices[] __initdata = { &tmu0_device, }; @@ -669,8 +669,8 @@ void __init r8a7779_add_standard_devices(void) r8a7779_init_pm_domains(); - platform_add_devices(r8a7779_devices_dt, - ARRAY_SIZE(r8a7779_devices_dt)); + platform_add_devices(r8a7779_early_devices, + ARRAY_SIZE(r8a7779_early_devices)); platform_add_devices(r8a7779_standard_devices, ARRAY_SIZE(r8a7779_standard_devices)); r8a7779_register_hpb_dmae(); @@ -678,8 +678,8 @@ void __init r8a7779_add_standard_devices(void) void __init r8a7779_add_early_devices(void) { - early_platform_add_devices(r8a7779_devices_dt, - ARRAY_SIZE(r8a7779_devices_dt)); + early_platform_add_devices(r8a7779_early_devices, + ARRAY_SIZE(r8a7779_early_devices)); /* Early serial console setup is not included here due to * memory map collisions. The SCIF serial ports in r8a7779 @@ -739,12 +739,6 @@ void __init r8a7779_init_irq_dt(void) __raw_writel(0x003fee3f, INT2SMSKCR4); } -void __init r8a7779_add_standard_devices_dt(void) -{ - platform_add_devices(r8a7779_devices_dt, - ARRAY_SIZE(r8a7779_devices_dt)); -} - #define MODEMR 0xffcc0020 u32 __init r8a7779_read_mode_pins(void) @@ -773,7 +767,6 @@ DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") .init_early = shmobile_init_delay, .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, - .init_machine = r8a7779_add_standard_devices_dt, .init_late = r8a7779_init_late, .dt_compat = r8a7779_compat_dt, MACHINE_END -- GitLab From 9162d39ccb9400bfaed85630cf517c85861faa6f Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2014 15:12:40 +0200 Subject: [PATCH 0733/9167] ARM: shmobile: r7s72100: Add MTU2 device to DT Add the MTU2 counter to the r7s72100 device tree and make it disabled by default. Signed-off-by: Laurent Pinchart Acked-by: Wolfram Sang [horms+renesas@verge.net.au correct irq number] Signed-off-by: Simon Horman --- arch/arm/boot/dts/r7s72100.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi index bdee22541189..1d28d01c163c 100644 --- a/arch/arm/boot/dts/r7s72100.dtsi +++ b/arch/arm/boot/dts/r7s72100.dtsi @@ -229,6 +229,16 @@ status = "disabled"; }; + mtu2: timer@fcff0000 { + compatible = "renesas,mtu2"; + reg = <0xfcff0000 0x400>; + interrupts = <0 107 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "tgi0a"; + clocks = <&mstp3_clks R7S72100_CLK_MTU2>; + clock-names = "fck"; + status = "disabled"; + }; + scif0: serial@e8007000 { compatible = "renesas,scif-r7s72100", "renesas,scif"; reg = <0xe8007000 64>; -- GitLab From 9dddfcfacaadb5491b62233b893b510fa00da4e0 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 9 Jul 2014 15:12:44 +0200 Subject: [PATCH 0734/9167] ARM: shmobile: genmai-reference: Enable MTU2 in device tree No more device needs to be added from platform code when booting the reference platform, move MTU2 registration from setup-r7s72100.c to board-genmai.c and remove the now empty r7s72100_add_dt_devices() function. As the genmai_add_standard_devices() function is now identical to the default init_machine implementation, remove it as well. Signed-off-by: Laurent Pinchart Acked-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm/boot/dts/r7s72100-genmai.dts | 4 ++++ .../mach-shmobile/board-genmai-reference.c | 20 ------------------ arch/arm/mach-shmobile/board-genmai.c | 14 ++++++++++++- arch/arm/mach-shmobile/r7s72100.h | 1 - arch/arm/mach-shmobile/setup-r7s72100.c | 21 ------------------- 5 files changed, 17 insertions(+), 43 deletions(-) diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts index 20705467f4c9..a3ed23c0a8f5 100644 --- a/arch/arm/boot/dts/r7s72100-genmai.dts +++ b/arch/arm/boot/dts/r7s72100-genmai.dts @@ -43,6 +43,10 @@ clock-frequency = <48000000>; }; +&mtu2 { + status = "ok"; +}; + &i2c2 { status = "okay"; clock-frequency = <400000>; diff --git a/arch/arm/mach-shmobile/board-genmai-reference.c b/arch/arm/mach-shmobile/board-genmai-reference.c index e5448f7b868a..bc52677986c3 100644 --- a/arch/arm/mach-shmobile/board-genmai-reference.c +++ b/arch/arm/mach-shmobile/board-genmai-reference.c @@ -19,29 +19,10 @@ */ #include -#include -#include #include -#include "clock.h" #include "common.h" -#include "r7s72100.h" - -/* - * This is a really crude hack to provide clkdev support to platform - * devices until they get moved to DT. - */ -static const struct clk_name clk_names[] = { - { "mtu2", "fck", "sh-mtu2" }, -}; - -static void __init genmai_add_standard_devices(void) -{ - shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), true); - r7s72100_add_dt_devices(); - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); -} static const char * const genmai_boards_compat_dt[] __initconst = { "renesas,genmai", @@ -50,6 +31,5 @@ static const char * const genmai_boards_compat_dt[] __initconst = { DT_MACHINE_START(GENMAI_DT, "genmai") .init_early = shmobile_init_delay, - .init_machine = genmai_add_standard_devices, .dt_compat = genmai_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-genmai.c b/arch/arm/mach-shmobile/board-genmai.c index 7bf2d8057535..ba545fc09649 100644 --- a/arch/arm/mach-shmobile/board-genmai.c +++ b/arch/arm/mach-shmobile/board-genmai.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -125,10 +126,21 @@ R7S72100_SCIF(7, 0xe800a800, gic_iid(249)); &scif##index##_platform_data, \ sizeof(scif##index##_platform_data)) +static struct resource mtu2_resources[] __initdata = { + DEFINE_RES_MEM(0xfcff0000, 0x400), + DEFINE_RES_IRQ_NAMED(gic_iid(139), "tgi0a"), +}; + +#define r7s72100_register_mtu2() \ + platform_device_register_resndata(&platform_bus, "sh-mtu2", \ + -1, mtu2_resources, \ + ARRAY_SIZE(mtu2_resources), \ + NULL, 0) + static void __init genmai_add_standard_devices(void) { r7s72100_clock_init(); - r7s72100_add_dt_devices(); + r7s72100_register_mtu2(); platform_device_register_full(ðer_info); diff --git a/arch/arm/mach-shmobile/r7s72100.h b/arch/arm/mach-shmobile/r7s72100.h index efb723c88dd0..321ae4e10128 100644 --- a/arch/arm/mach-shmobile/r7s72100.h +++ b/arch/arm/mach-shmobile/r7s72100.h @@ -1,7 +1,6 @@ #ifndef __ASM_R7S72100_H__ #define __ASM_R7S72100_H__ -void r7s72100_add_dt_devices(void); void r7s72100_clock_init(void); #endif /* __ASM_R7S72100_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c index f3b3b14ba972..d898cef24611 100644 --- a/arch/arm/mach-shmobile/setup-r7s72100.c +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -18,32 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include -#include -#include #include #include "common.h" -#include "irqs.h" -#include "r7s72100.h" - -static struct resource mtu2_resources[] __initdata = { - DEFINE_RES_MEM(0xfcff0000, 0x400), - DEFINE_RES_IRQ_NAMED(gic_iid(139), "tgi0a"), -}; - -#define r7s72100_register_mtu2() \ - platform_device_register_resndata(NULL, "sh-mtu2", \ - -1, mtu2_resources, \ - ARRAY_SIZE(mtu2_resources), \ - NULL, 0) - -void __init r7s72100_add_dt_devices(void) -{ - r7s72100_register_mtu2(); -} #ifdef CONFIG_USE_OF static const char *r7s72100_boards_compat_dt[] __initdata = { -- GitLab From 54a06dde40f6a01e323d49390d78b8c9f1dfacc0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 13 Aug 2014 13:45:00 +0200 Subject: [PATCH 0735/9167] ARM: shmobile: r8a7778: Add missing call to shmobile_init_late() Add the missing call to shmobile_init_late() to r8a7778_init_late(). This should make sure Suspend-to-RAM and CPUIdle are setup as expected on bockw. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7778.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index f00a488dcf43..383e43bf1cb6 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -520,6 +520,7 @@ void __init r8a7778_add_standard_devices(void) void __init r8a7778_init_late(void) { + shmobile_init_late(); platform_device_register_full(&ehci_info); platform_device_register_full(&ohci_info); } -- GitLab From 0f6442bef67d7f543d65d12e27006ceda8932b81 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Aug 2014 18:57:22 +0200 Subject: [PATCH 0736/9167] ARM: shmobile: shmobile_defconfig: Enable missing hardware support Based on the DTSes Notes: - MTD_SPI_NOR is a dependency for MTD_M25P80 since commit 03e296f613affcc2671c1e86d8c25ecad867204e ("mtd: m25p80: use the SPI nor framework") and commit e43b20619bdb6c851dd7b49cbd15e52875a785d4 ("mtd: spi-nor: shorten Kconfig naming"), - I2C_RIIC was enabled in the old genmai_defconfig. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/shmobile_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 3b136144cc83..0cd63f584665 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -49,6 +49,7 @@ CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_MTD=y CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y CONFIG_EEPROM_AT24=y CONFIG_BLK_DEV_SD=y CONFIG_ATA=y @@ -82,6 +83,7 @@ CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=20 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_I2C_GPIO=y +CONFIG_I2C_RIIC=y CONFIG_I2C_SH_MOBILE=y CONFIG_I2C_RCAR=y CONFIG_SPI=y -- GitLab From 2815d447f6538d11d0fbe88a2f3418905922ca0d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Aug 2014 18:57:23 +0200 Subject: [PATCH 0737/9167] ARM: shmobile: ape6evm_defconfig: Enable missing hardware support Based on the DTS Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/ape6evm_defconfig | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/arm/configs/ape6evm_defconfig b/arch/arm/configs/ape6evm_defconfig index bb396c0e5fda..b54b28fc5a70 100644 --- a/arch/arm/configs/ape6evm_defconfig +++ b/arch/arm/configs/ape6evm_defconfig @@ -12,7 +12,6 @@ CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y CONFIG_PERF_EVENTS=y CONFIG_SLAB=y -# CONFIG_BLOCK is not set CONFIG_ARCH_SHMOBILE_LEGACY=y CONFIG_ARCH_R8A73A4=y CONFIG_MACH_APE6EVM=y @@ -64,6 +63,8 @@ CONFIG_SERIAL_NONSTANDARD=y CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=12 CONFIG_SERIAL_SH_SCI_CONSOLE=y +CONFIG_I2C=y +CONFIG_I2C_SH_MOBILE=y CONFIG_GPIO_SH_PFC=y CONFIG_GPIOLIB=y # CONFIG_HWMON is not set @@ -72,11 +73,17 @@ CONFIG_RCAR_THERMAL=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_GPIO=y +CONFIG_REGULATOR_MAX8973=y # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set +CONFIG_MMC=y +CONFIG_MMC_SDHI=y +CONFIG_MMC_SH_MMCIF=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_GPIO=y +CONFIG_DMADEVICES=y +CONFIG_SH_DMAE=y # CONFIG_IOMMU_SUPPORT is not set # CONFIG_DNOTIFY is not set CONFIG_TMPFS=y -- GitLab From 4f0c320be6164ab39af42867aa1ccf69475850b7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Aug 2014 18:57:24 +0200 Subject: [PATCH 0738/9167] ARM: shmobile: bockw_defconfig: Enable missing hardware support Based on the DTS Notes: - MTD_SPI_NOR is a dependency for MTD_M25P80 since commit 03e296f613affcc2671c1e86d8c25ecad867204e ("mtd: m25p80: use the SPI nor framework") and commit e43b20619bdb6c851dd7b49cbd15e52875a785d4 ("mtd: spi-nor: shorten Kconfig naming"). Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/bockw_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/bockw_defconfig b/arch/arm/configs/bockw_defconfig index e816140d81c5..70b3f451f065 100644 --- a/arch/arm/configs/bockw_defconfig +++ b/arch/arm/configs/bockw_defconfig @@ -55,6 +55,7 @@ CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_NETDEVICES=y @@ -82,6 +83,7 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HWMON is not set CONFIG_I2C=y CONFIG_I2C_RCAR=y +CONFIG_GPIO_RCAR=y CONFIG_REGULATOR=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y -- GitLab From 1a194078571a0d060a230949cd1b4da259117ef0 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Aug 2014 18:57:25 +0200 Subject: [PATCH 0739/9167] ARM: shmobile: koelsch_defconfig: Enable missing hardware support Based on the DTS Notes: - MTD_SPI_NOR is a dependency for MTD_M25P80 since commit 03e296f613affcc2671c1e86d8c25ecad867204e ("mtd: m25p80: use the SPI nor framework") and commit e43b20619bdb6c851dd7b49cbd15e52875a785d4 ("mtd: spi-nor: shorten Kconfig naming"). Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/koelsch_defconfig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/configs/koelsch_defconfig b/arch/arm/configs/koelsch_defconfig index 86faab565a96..b33d19b7f134 100644 --- a/arch/arm/configs/koelsch_defconfig +++ b/arch/arm/configs/koelsch_defconfig @@ -15,6 +15,9 @@ CONFIG_MACH_KOELSCH=y CONFIG_CPU_BPREDICT_DISABLE=y CONFIG_PL310_ERRATA_588369=y CONFIG_ARM_ERRATA_754322=y +CONFIG_PCI=y +CONFIG_PCI_RCAR_GEN2=y +CONFIG_PCI_RCAR_GEN2_PCIE=y CONFIG_SMP=y CONFIG_SCHED_MC=y CONFIG_NR_CPUS=8 @@ -42,6 +45,8 @@ CONFIG_ATA=y CONFIG_SATA_RCAR=y CONFIG_MTD=y CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y +CONFIG_EEPROM_AT24=y CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_ARC is not set # CONFIG_NET_CADENCE is not set @@ -66,9 +71,12 @@ CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=20 CONFIG_SERIAL_SH_SCI_CONSOLE=y CONFIG_I2C=y +CONFIG_I2C_MUX=y +CONFIG_I2C_SH_MOBILE=y CONFIG_I2C_RCAR=y CONFIG_SPI=y CONFIG_SPI_RSPI=y +CONFIG_SPI_SH_MSIOF=y CONFIG_GPIOLIB=y CONFIG_GPIO_RCAR=y # CONFIG_HWMON is not set @@ -76,7 +84,16 @@ CONFIG_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_DA9210=y CONFIG_REGULATOR_GPIO=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_SOC_CAMERA=y +CONFIG_SOC_CAMERA_PLATFORM=y +CONFIG_VIDEO_RCAR_VIN=y +# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set +CONFIG_VIDEO_ADV7180=y # CONFIG_HID is not set # CONFIG_USB_SUPPORT is not set CONFIG_MMC=y -- GitLab From 489610f3324dc1f94c816f4053215d7540871875 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Aug 2014 18:57:26 +0200 Subject: [PATCH 0740/9167] ARM: shmobile: kzm9g_defconfig: Enable missing hardware support Based on the DTS Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/kzm9g_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig index bd097d455f87..8cb115d74fdf 100644 --- a/arch/arm/configs/kzm9g_defconfig +++ b/arch/arm/configs/kzm9g_defconfig @@ -119,6 +119,7 @@ CONFIG_MMC_SDHI=y CONFIG_MMC_SH_MMCIF=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_RS5C372=y CONFIG_DMADEVICES=y -- GitLab From 387ded8e60bcb6190492f90a3ef25e2bcb0a97a1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Aug 2014 18:57:27 +0200 Subject: [PATCH 0741/9167] ARM: shmobile: lager_defconfig: Enable missing hardware support Based on the DTS Notes: - MTD_SPI_NOR is a dependency for MTD_M25P80 since commit 03e296f613affcc2671c1e86d8c25ecad867204e ("mtd: m25p80: use the SPI nor framework") and commit e43b20619bdb6c851dd7b49cbd15e52875a785d4 ("mtd: spi-nor: shorten Kconfig naming"). Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/lager_defconfig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/configs/lager_defconfig b/arch/arm/configs/lager_defconfig index 58702440472a..929c571ea29b 100644 --- a/arch/arm/configs/lager_defconfig +++ b/arch/arm/configs/lager_defconfig @@ -22,6 +22,9 @@ CONFIG_ARM_ERRATA_458693=y CONFIG_ARM_ERRATA_460075=y CONFIG_ARM_ERRATA_743622=y CONFIG_ARM_ERRATA_754322=y +CONFIG_PCI=y +CONFIG_PCI_RCAR_GEN2=y +CONFIG_PCI_RCAR_GEN2_PCIE=y CONFIG_HAVE_ARM_ARCH_TIMER=y CONFIG_AEABI=y # CONFIG_OABI_COMPAT is not set @@ -53,6 +56,7 @@ CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_MTD=y CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y CONFIG_BLK_DEV_SD=y CONFIG_ATA=y CONFIG_SATA_RCAR=y @@ -85,11 +89,12 @@ CONFIG_SERIAL_SH_SCI=y CONFIG_SERIAL_SH_SCI_NR_UARTS=10 CONFIG_SERIAL_SH_SCI_CONSOLE=y # CONFIG_HW_RANDOM is not set -CONFIG_I2C=y CONFIG_I2C_GPIO=y +CONFIG_I2C_SH_MOBILE=y CONFIG_I2C_RCAR=y CONFIG_SPI=y CONFIG_SPI_RSPI=y +CONFIG_SPI_SH_MSIOF=y CONFIG_GPIO_SH_PFC=y CONFIG_GPIOLIB=y CONFIG_GPIO_RCAR=y @@ -98,6 +103,7 @@ CONFIG_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_DA9210=y CONFIG_REGULATOR_GPIO=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y -- GitLab From 6e3a4b191ee6db512c17197130b4e5170b3dabc3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 14 Aug 2014 18:57:28 +0200 Subject: [PATCH 0742/9167] ARM: shmobile: marzen_defconfig: Enable missing hardware support Based on the DTS Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/configs/marzen_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig index 92994f7f6fd8..ff91630d34e1 100644 --- a/arch/arm/configs/marzen_defconfig +++ b/arch/arm/configs/marzen_defconfig @@ -84,6 +84,7 @@ CONFIG_GPIO_RCAR=y CONFIG_THERMAL=y CONFIG_RCAR_THERMAL=y CONFIG_SSB=y +CONFIG_REGULATOR=y CONFIG_MEDIA_SUPPORT=y CONFIG_MEDIA_CAMERA_SUPPORT=y CONFIG_V4L_PLATFORM_DRIVERS=y -- GitLab From f7b98477f613a69b74ba4a715856630cc6508c0d Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 4 Aug 2014 15:51:48 +0900 Subject: [PATCH 0743/9167] ARM: shmobile: Remove genmai_defconfig from MAINTAINERS The genmai defconfig file has been removed by 3ed27bd90d6d0c8b ("ARM: shmobile: genmai: remove defconfig") so remove its entry in the MAINTAINERS accordingly. Reported-by: Joe Perches Signed-off-by: Simon Horman --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index aefa94841ff3..99b78075a50c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1355,7 +1355,6 @@ F: arch/arm/boot/dts/sh* F: arch/arm/configs/ape6evm_defconfig F: arch/arm/configs/armadillo800eva_defconfig F: arch/arm/configs/bockw_defconfig -F: arch/arm/configs/genmai_defconfig F: arch/arm/configs/koelsch_defconfig F: arch/arm/configs/kzm9g_defconfig F: arch/arm/configs/lager_defconfig -- GitLab From 0b8d1d579b4130f33a8776691453238839cb1973 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 2 Aug 2014 04:04:21 +0400 Subject: [PATCH 0744/9167] ARM: shmobile: r8a7791: add VIN DT support Define the generic R8A7791 parts of the VIN[0-2] device nodes. Add aliases for the VIN[0-2] device nodes. Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 0d82a4b3c650..0f2892140087 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -34,6 +34,9 @@ spi1 = &msiof0; spi2 = &msiof1; spi3 = &msiof2; + vin0 = &vin0; + vin1 = &vin1; + vin2 = &vin2; }; cpus { @@ -518,6 +521,30 @@ status = "disabled"; }; + vin0: video@e6ef0000 { + compatible = "renesas,vin-r8a7791"; + clocks = <&mstp8_clks R8A7791_CLK_VIN0>; + reg = <0 0xe6ef0000 0 0x1000>; + interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + vin1: video@e6ef1000 { + compatible = "renesas,vin-r8a7791"; + clocks = <&mstp8_clks R8A7791_CLK_VIN1>; + reg = <0 0xe6ef1000 0 0x1000>; + interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + vin2: video@e6ef2000 { + compatible = "renesas,vin-r8a7791"; + clocks = <&mstp8_clks R8A7791_CLK_VIN2>; + reg = <0 0xe6ef2000 0 0x1000>; + interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + clocks { #address-cells = <2>; #size-cells = <2>; -- GitLab From 8d62f4f75320db5e95d3610547a26e4487c30742 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 2 Aug 2014 04:05:54 +0400 Subject: [PATCH 0745/9167] ARM: shmobile: henninger: add VIN0/ADV7180 DT support Define the Henninger board dependent part of the VIN0 device node. Add the device node for Analog Devices ADV7180 video decoder to I2C2 bus. Add the necessary subnodes to interconnect VIN0 and ADV7180 devices. Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-henninger.dts | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791-henninger.dts b/arch/arm/boot/dts/r8a7791-henninger.dts index 3a2ef0a2a137..f1b56de10205 100644 --- a/arch/arm/boot/dts/r8a7791-henninger.dts +++ b/arch/arm/boot/dts/r8a7791-henninger.dts @@ -135,6 +135,11 @@ renesas,groups = "usb1"; renesas,function = "usb1"; }; + + vin0_pins: vin0 { + renesas,groups = "vin0_data8", "vin0_clk"; + renesas,function = "vin0"; + }; }; &scif0 { @@ -191,6 +196,19 @@ status = "okay"; clock-frequency = <400000>; + + composite-in@20 { + compatible = "adi,adv7180"; + reg = <0x20>; + remote = <&vin0>; + + port { + adv7180: endpoint { + bus-width = <8>; + remote-endpoint = <&vin0ep>; + }; + }; + }; }; &qspi { @@ -260,3 +278,20 @@ &pciec { status = "okay"; }; + +/* composite video input */ +&vin0 { + status = "ok"; + pinctrl-0 = <&vin0_pins>; + pinctrl-names = "default"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + vin0ep: endpoint { + remote-endpoint = <&adv7180>; + bus-width = <8>; + }; + }; +}; -- GitLab From 2cf088105db14c00ad69df09b9b4a37c2370ff44 Mon Sep 17 00:00:00 2001 From: "sergei.shtylyov@cogentembedded.com" Date: Wed, 6 Aug 2014 22:38:22 +0400 Subject: [PATCH 0746/9167] ARM: shmobile: koelsch: add VIN1/ADV7180 DT support Define the Koelsch board dependent part of the VIN1 device node. Add the device node for Analog Devices ADV7180 video decoder to I2C2 bus. Add the necessary subnodes to interconnect VIN1 and ADV7180 devices. Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791-koelsch.dts | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts index 23486c081a69..6be43da90526 100644 --- a/arch/arm/boot/dts/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/r8a7791-koelsch.dts @@ -289,6 +289,11 @@ renesas,groups = "usb1"; renesas,function = "usb1"; }; + + vin1_pins: vin1 { + renesas,groups = "vin1_data8", "vin1_clk"; + renesas,function = "vin1"; + }; }; ðer { @@ -412,6 +417,19 @@ status = "okay"; clock-frequency = <400000>; + composite-in@20 { + compatible = "adi,adv7180"; + reg = <0x20>; + remote = <&vin1>; + + port { + adv7180: endpoint { + bus-width = <8>; + remote-endpoint = <&vin1ep>; + }; + }; + }; + eeprom@50 { compatible = "renesas,24c02"; reg = <0x50>; @@ -459,3 +477,20 @@ &cpu0 { cpu0-supply = <&vdd_dvfs>; }; + +/* composite video input */ +&vin1 { + status = "ok"; + pinctrl-0 = <&vin1_pins>; + pinctrl-names = "default"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + vin1ep: endpoint { + remote-endpoint = <&adv7180>; + bus-width = <8>; + }; + }; +}; -- GitLab From c819acdab3bf02795db6d16a17426e21c99c3c28 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 19 Jul 2014 01:50:23 +0200 Subject: [PATCH 0747/9167] ARM: shmobile: r8a7790: Add DMAC clocks to DT Add the SYS-DMAC0 and SYS-DMAC1 clocks to the MSTP2 clock node. They will be used by the upcoming DMAC DT nodes. Signed-off-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index d9ddecbb859c..220662f38435 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -758,16 +758,19 @@ compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150138 0 4>, <0 0xe6150040 0 4>; clocks = <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, - <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>; + <&mp_clk>, <&mp_clk>, <&mp_clk>, <&mp_clk>, <&zs_clk>, + <&zs_clk>; #clock-cells = <1>; renesas,clock-indices = < R8A7790_CLK_SCIFA2 R8A7790_CLK_SCIFA1 R8A7790_CLK_SCIFA0 R8A7790_CLK_MSIOF2 R8A7790_CLK_SCIFB0 R8A7790_CLK_SCIFB1 R8A7790_CLK_MSIOF1 R8A7790_CLK_MSIOF3 R8A7790_CLK_SCIFB2 + R8A7790_CLK_SYS_DMAC1 R8A7790_CLK_SYS_DMAC0 >; clock-output-names = "scifa2", "scifa1", "scifa0", "msiof2", "scifb0", - "scifb1", "msiof1", "msiof3", "scifb2"; + "scifb1", "msiof1", "msiof3", "scifb2", + "sys-dmac1", "sys-dmac0"; }; mstp3_clks: mstp3_clks@e615013c { compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; -- GitLab From b9fea49c79f23212ff21ef2f305ea4ae865db860 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 19 Jul 2014 01:50:24 +0200 Subject: [PATCH 0748/9167] ARM: shmobile: r8a7790: Add DMAC devices to DT Instantiate the two system DMA controllers in the r8a7790 device tree. Signed-off-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 59 ++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 220662f38435..3707f0e56ce8 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -217,6 +217,65 @@ <0 3 IRQ_TYPE_LEVEL_HIGH>; }; + dmac0: dma-controller@e6700000 { + compatible = "renesas,rcar-dmac"; + reg = <0 0xe6700000 0 0x20000>; + interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH + 0 200 IRQ_TYPE_LEVEL_HIGH + 0 201 IRQ_TYPE_LEVEL_HIGH + 0 202 IRQ_TYPE_LEVEL_HIGH + 0 203 IRQ_TYPE_LEVEL_HIGH + 0 204 IRQ_TYPE_LEVEL_HIGH + 0 205 IRQ_TYPE_LEVEL_HIGH + 0 206 IRQ_TYPE_LEVEL_HIGH + 0 207 IRQ_TYPE_LEVEL_HIGH + 0 208 IRQ_TYPE_LEVEL_HIGH + 0 209 IRQ_TYPE_LEVEL_HIGH + 0 210 IRQ_TYPE_LEVEL_HIGH + 0 211 IRQ_TYPE_LEVEL_HIGH + 0 212 IRQ_TYPE_LEVEL_HIGH + 0 213 IRQ_TYPE_LEVEL_HIGH + 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14"; + clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC0>; + clock-names = "fck"; + #dma-cells = <1>; + dma-channels = <15>; + }; + + dmac1: dma-controller@e6720000 { + compatible = "renesas,rcar-dmac"; + reg = <0 0xe6720000 0 0x20000>; + interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH + 0 216 IRQ_TYPE_LEVEL_HIGH + 0 217 IRQ_TYPE_LEVEL_HIGH + 0 218 IRQ_TYPE_LEVEL_HIGH + 0 219 IRQ_TYPE_LEVEL_HIGH + 0 308 IRQ_TYPE_LEVEL_HIGH + 0 309 IRQ_TYPE_LEVEL_HIGH + 0 310 IRQ_TYPE_LEVEL_HIGH + 0 311 IRQ_TYPE_LEVEL_HIGH + 0 312 IRQ_TYPE_LEVEL_HIGH + 0 313 IRQ_TYPE_LEVEL_HIGH + 0 314 IRQ_TYPE_LEVEL_HIGH + 0 315 IRQ_TYPE_LEVEL_HIGH + 0 316 IRQ_TYPE_LEVEL_HIGH + 0 317 IRQ_TYPE_LEVEL_HIGH + 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14"; + clocks = <&mstp2_clks R8A7790_CLK_SYS_DMAC1>; + clock-names = "fck"; + #dma-cells = <1>; + dma-channels = <15>; + }; i2c0: i2c@e6508000 { #address-cells = <1>; #size-cells = <0>; -- GitLab From fde8feefc489652749920f18123ad9e48b427c5e Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 19 Jul 2014 01:50:25 +0200 Subject: [PATCH 0749/9167] ARM: shmobile: r8a7791: Add DMAC devices to DT Instantiate the two system DMA controllers in the r8a7791 device tree. Signed-off-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 60 ++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 0f2892140087..146ed647fb73 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -209,6 +209,66 @@ <0 17 IRQ_TYPE_LEVEL_HIGH>; }; + dmac0: dma-controller@e6700000 { + compatible = "renesas,rcar-dmac"; + reg = <0 0xe6700000 0 0x20000>; + interrupts = <0 197 IRQ_TYPE_LEVEL_HIGH + 0 200 IRQ_TYPE_LEVEL_HIGH + 0 201 IRQ_TYPE_LEVEL_HIGH + 0 202 IRQ_TYPE_LEVEL_HIGH + 0 203 IRQ_TYPE_LEVEL_HIGH + 0 204 IRQ_TYPE_LEVEL_HIGH + 0 205 IRQ_TYPE_LEVEL_HIGH + 0 206 IRQ_TYPE_LEVEL_HIGH + 0 207 IRQ_TYPE_LEVEL_HIGH + 0 208 IRQ_TYPE_LEVEL_HIGH + 0 209 IRQ_TYPE_LEVEL_HIGH + 0 210 IRQ_TYPE_LEVEL_HIGH + 0 211 IRQ_TYPE_LEVEL_HIGH + 0 212 IRQ_TYPE_LEVEL_HIGH + 0 213 IRQ_TYPE_LEVEL_HIGH + 0 214 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14"; + clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC0>; + clock-names = "fck"; + #dma-cells = <1>; + dma-channels = <15>; + }; + + dmac1: dma-controller@e6720000 { + compatible = "renesas,rcar-dmac"; + reg = <0 0xe6720000 0 0x20000>; + interrupts = <0 220 IRQ_TYPE_LEVEL_HIGH + 0 216 IRQ_TYPE_LEVEL_HIGH + 0 217 IRQ_TYPE_LEVEL_HIGH + 0 218 IRQ_TYPE_LEVEL_HIGH + 0 219 IRQ_TYPE_LEVEL_HIGH + 0 308 IRQ_TYPE_LEVEL_HIGH + 0 309 IRQ_TYPE_LEVEL_HIGH + 0 310 IRQ_TYPE_LEVEL_HIGH + 0 311 IRQ_TYPE_LEVEL_HIGH + 0 312 IRQ_TYPE_LEVEL_HIGH + 0 313 IRQ_TYPE_LEVEL_HIGH + 0 314 IRQ_TYPE_LEVEL_HIGH + 0 315 IRQ_TYPE_LEVEL_HIGH + 0 316 IRQ_TYPE_LEVEL_HIGH + 0 317 IRQ_TYPE_LEVEL_HIGH + 0 318 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", + "ch4", "ch5", "ch6", "ch7", + "ch8", "ch9", "ch10", "ch11", + "ch12", "ch13", "ch14"; + clocks = <&mstp2_clks R8A7791_CLK_SYS_DMAC1>; + clock-names = "fck"; + #dma-cells = <1>; + dma-channels = <15>; + }; + /* The memory map in the User's Manual maps the cores to bus numbers */ i2c0: i2c@e6508000 { #address-cells = <1>; -- GitLab From 591f2fa4eb0aae09cd76d276bb59e25824a7d408 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:06 +0200 Subject: [PATCH 0750/9167] ARM: shmobile: r8a7791 dtsi: Enable DMA for QSPI Add a DMA property to the QSPI node Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 146ed647fb73..ab55efdaa010 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -1012,6 +1012,8 @@ reg = <0 0xe6b10000 0 0x2c>; interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp9_clks R8A7791_CLK_QSPI_MOD>; + dmas = <&dmac0 0x17>, <&dmac0 0x18>; + dma-names = "tx", "rx"; num-cs = <1>; #address-cells = <1>; #size-cells = <0>; -- GitLab From a5ce27f5f3285520496af0fe5282395ac07c4138 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:07 +0200 Subject: [PATCH 0751/9167] ARM: shmobile: r8a7791 dtsi: Enable DMA for MSIOF Add register sets used for access by the DMA engine, and DMA properties to the MSIOF nodes. Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index ab55efdaa010..f26226e054b3 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -1022,9 +1022,11 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7791"; - reg = <0 0xe6e20000 0 0x0064>; + reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>; interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp0_clks R8A7791_CLK_MSIOF0>; + dmas = <&dmac0 0x51>, <&dmac0 0x52>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -1032,9 +1034,11 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-r8a7791"; - reg = <0 0xe6e10000 0 0x0064>; + reg = <0 0xe6e10000 0 0x0064>, <0 0xe7e10000 0 0x0064>; interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp2_clks R8A7791_CLK_MSIOF1>; + dmas = <&dmac0 0x55>, <&dmac0 0x56>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -1042,9 +1046,11 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-r8a7791"; - reg = <0 0xe6e00000 0 0x0064>; + reg = <0 0xe6e00000 0 0x0064>, <0 0xe7e00000 0 0x0064>; interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp2_clks R8A7791_CLK_MSIOF2>; + dmas = <&dmac0 0x41>, <&dmac0 0x42>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; -- GitLab From 37cf3d61a94790c6f12c6e6e7a28640b8531a8af Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:08 +0200 Subject: [PATCH 0752/9167] ARM: shmobile: r8a7790 dtsi: Enable DMA for QSPI Add a DMA property to the QSPI node Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 3707f0e56ce8..6dc328de4390 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -946,6 +946,8 @@ reg = <0 0xe6b10000 0 0x2c>; interrupts = <0 184 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp9_clks R8A7790_CLK_QSPI_MOD>; + dmas = <&dmac0 0x17>, <&dmac0 0x18>; + dma-names = "tx", "rx"; num-cs = <1>; #address-cells = <1>; #size-cells = <0>; -- GitLab From fbff66886b9c5f657b6649a264551ac572fae0b7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 6 Aug 2014 14:59:09 +0200 Subject: [PATCH 0753/9167] ARM: shmobile: r8a7790 dtsi: Enable DMA for MSIOF Add register sets used for access by the DMA engine, and DMA properties to the MSIOF nodes. Signed-off-by: Geert Uytterhoeven Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 6dc328de4390..60f8551d1945 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -956,9 +956,11 @@ msiof0: spi@e6e20000 { compatible = "renesas,msiof-r8a7790"; - reg = <0 0xe6e20000 0 0x0064>; + reg = <0 0xe6e20000 0 0x0064>, <0 0xe7e20000 0 0x0064>; interrupts = <0 156 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp0_clks R8A7790_CLK_MSIOF0>; + dmas = <&dmac0 0x51>, <&dmac0 0x52>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -966,9 +968,11 @@ msiof1: spi@e6e10000 { compatible = "renesas,msiof-r8a7790"; - reg = <0 0xe6e10000 0 0x0064>; + reg = <0 0xe6e10000 0 0x0064>, <0 0xe7e10000 0 0x0064>; interrupts = <0 157 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp2_clks R8A7790_CLK_MSIOF1>; + dmas = <&dmac0 0x55>, <&dmac0 0x56>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -976,9 +980,11 @@ msiof2: spi@e6e00000 { compatible = "renesas,msiof-r8a7790"; - reg = <0 0xe6e00000 0 0x0064>; + reg = <0 0xe6e00000 0 0x0064>, <0 0xe7e00000 0 0x0064>; interrupts = <0 158 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp2_clks R8A7790_CLK_MSIOF2>; + dmas = <&dmac0 0x41>, <&dmac0 0x42>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; @@ -986,9 +992,11 @@ msiof3: spi@e6c90000 { compatible = "renesas,msiof-r8a7790"; - reg = <0 0xe6c90000 0 0x0064>; + reg = <0 0xe6c90000 0 0x0064>, <0 0xe7c90000 0 0x0064>; interrupts = <0 159 IRQ_TYPE_LEVEL_HIGH>; clocks = <&mstp2_clks R8A7790_CLK_MSIOF3>; + dmas = <&dmac0 0x45>, <&dmac0 0x46>; + dma-names = "tx", "rx"; #address-cells = <1>; #size-cells = <0>; status = "disabled"; -- GitLab From 9f685bfc30edb4cba5d5ae142a9967cd0d74c40a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 13 Aug 2014 00:16:18 +0400 Subject: [PATCH 0754/9167] ARM: shmobile: r8a7790: add VIN device nodes Add device nodes for the four video input controllers on the R8A7790. Signed-off-by: Ben Dooks [Sergei: renamed VIN device nodes, edited changelog] Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 60f8551d1945..2278bd0968d1 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -33,6 +33,10 @@ spi2 = &msiof1; spi3 = &msiof2; spi4 = &msiof3; + vin0 = &vin0; + vin1 = &vin1; + vin2 = &vin2; + vin3 = &vin3; }; cpus { @@ -532,6 +536,38 @@ status = "disabled"; }; + vin0: video@e6ef0000 { + compatible = "renesas,vin-r8a7790"; + clocks = <&mstp8_clks R8A7790_CLK_VIN0>; + reg = <0 0xe6ef0000 0 0x1000>; + interrupts = <0 188 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + vin1: video@e6ef1000 { + compatible = "renesas,vin-r8a7790"; + clocks = <&mstp8_clks R8A7790_CLK_VIN1>; + reg = <0 0xe6ef1000 0 0x1000>; + interrupts = <0 189 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + vin2: video@e6ef2000 { + compatible = "renesas,vin-r8a7790"; + clocks = <&mstp8_clks R8A7790_CLK_VIN2>; + reg = <0 0xe6ef2000 0 0x1000>; + interrupts = <0 190 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + + vin3: video@e6ef3000 { + compatible = "renesas,vin-r8a7790"; + clocks = <&mstp8_clks R8A7790_CLK_VIN3>; + reg = <0 0xe6ef3000 0 0x1000>; + interrupts = <0 191 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; + }; + clocks { #address-cells = <2>; #size-cells = <2>; -- GitLab From d594c9775409a4276133db5e34dbd791329c5eae Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 13 Aug 2014 00:18:26 +0400 Subject: [PATCH 0755/9167] ARM: shmobile: lager: add VIN1/ADV7180 device nodes Add the Lager board specific device node part for VIN1 (composite video in); add the device node for Analog Devices ADV7180 video decoder to IIC2 bus. Add the necessary subnodes to interconnect VIN1 and ADV7180 devices. Signed-off-by: Ben Dooks [Sergei: rebased, edited changelog and summary] Signed-off-by: Sergei Shtylyov Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790-lager.dts | 36 +++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts index 856b4236b674..b5f56bcc8ae1 100644 --- a/arch/arm/boot/dts/r8a7790-lager.dts +++ b/arch/arm/boot/dts/r8a7790-lager.dts @@ -234,6 +234,11 @@ renesas,groups = "usb2"; renesas,function = "usb2"; }; + + vin1_pins: vin { + renesas,groups = "vin1_data8", "vin1_clk"; + renesas,function = "vin1"; + }; }; ðer { @@ -366,6 +371,19 @@ status = "ok"; pinctrl-0 = <&iic2_pins>; pinctrl-names = "default"; + + composite-in@20 { + compatible = "adi,adv7180"; + reg = <0x20>; + remote = <&vin1>; + + port { + adv7180: endpoint { + bus-width = <8>; + remote-endpoint = <&vin1ep0>; + }; + }; + }; }; &iic3 { @@ -401,3 +419,21 @@ pinctrl-0 = <&usb2_pins>; pinctrl-names = "default"; }; + +/* composite video input */ +&vin1 { + pinctrl-0 = <&vin1_pins>; + pinctrl-names = "default"; + + status = "ok"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + vin1ep0: endpoint { + remote-endpoint = <&adv7180>; + bus-width = <8>; + }; + }; +}; -- GitLab From 71d03dabd6d3141872e23effd00345afe2ea2dab Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Jul 2014 18:23:36 +0200 Subject: [PATCH 0756/9167] ARM: shmobile: r7s72100: genmai: Remove reference board file The genmai board now boots using the generic R7S72100 DT machine with the same feature set as the board file. Remove the board file. Signed-off-by: Laurent Pinchart Acked-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Makefile | 1 - .../mach-shmobile/board-genmai-reference.c | 35 ------------------- 2 files changed, 36 deletions(-) delete mode 100644 arch/arm/mach-shmobile/board-genmai-reference.c diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index fe3878a1a69a..a058ec346cd7 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -63,7 +63,6 @@ obj-$(CONFIG_ARCH_SH7372) += entry-intc.o # Board objects ifdef CONFIG_ARCH_SHMOBILE_MULTI -obj-$(CONFIG_MACH_GENMAI) += board-genmai-reference.o obj-$(CONFIG_MACH_KOELSCH) += board-koelsch-reference.o obj-$(CONFIG_MACH_LAGER) += board-lager-reference.o obj-$(CONFIG_MACH_MARZEN) += board-marzen-reference.o diff --git a/arch/arm/mach-shmobile/board-genmai-reference.c b/arch/arm/mach-shmobile/board-genmai-reference.c deleted file mode 100644 index bc52677986c3..000000000000 --- a/arch/arm/mach-shmobile/board-genmai-reference.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Genmai board support - * - * Copyright (C) 2013 Renesas Solutions Corp. - * Copyright (C) 2013 Magnus Damm - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include - -#include - -#include "common.h" - -static const char * const genmai_boards_compat_dt[] __initconst = { - "renesas,genmai", - NULL, -}; - -DT_MACHINE_START(GENMAI_DT, "genmai") - .init_early = shmobile_init_delay, - .dt_compat = genmai_boards_compat_dt, -MACHINE_END -- GitLab From 05104c266ae9a1673d92a068e2eeb0059db8c075 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Jul 2014 18:23:37 +0200 Subject: [PATCH 0757/9167] ARM: shmobile: r7s72100: genmai: Remove legacy board file The genmai board now boots using DT and multiplatform kernel with the same feature set as the legacy board. Remove the legacy board file and the board Kconfig option. Signed-off-by: Laurent Pinchart Acked-by: Wolfram Sang Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Kconfig | 9 -- arch/arm/mach-shmobile/Makefile | 1 - arch/arm/mach-shmobile/board-genmai.c | 173 -------------------------- 3 files changed, 183 deletions(-) delete mode 100644 arch/arm/mach-shmobile/board-genmai.c diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index e15dff790dbb..169bda468675 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -43,10 +43,6 @@ config ARCH_R8A7791 comment "Renesas ARM SoCs Board Type" -config MACH_GENMAI - bool "Genmai board" - depends on ARCH_R7S72100 - config MACH_KOELSCH bool "Koelsch board" depends on ARCH_R8A7791 @@ -232,11 +228,6 @@ config MACH_BOCKW_REFERENCE This is intended to aid developers -config MACH_GENMAI - bool "Genmai board" - depends on ARCH_R7S72100 - select USE_OF - config MACH_MARZEN bool "MARZEN board" depends on ARCH_R8A7779 diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index a058ec346cd7..be5fed20bf50 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -72,7 +72,6 @@ obj-$(CONFIG_MACH_APE6EVM_REFERENCE) += board-ape6evm-reference.o obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o obj-$(CONFIG_MACH_BOCKW) += board-bockw.o obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o -obj-$(CONFIG_MACH_GENMAI) += board-genmai.o obj-$(CONFIG_MACH_MARZEN) += board-marzen.o obj-$(CONFIG_MACH_LAGER) += board-lager.o obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o diff --git a/arch/arm/mach-shmobile/board-genmai.c b/arch/arm/mach-shmobile/board-genmai.c deleted file mode 100644 index ba545fc09649..000000000000 --- a/arch/arm/mach-shmobile/board-genmai.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Genmai board support - * - * Copyright (C) 2013-2014 Renesas Solutions Corp. - * Copyright (C) 2013 Magnus Damm - * Copyright (C) 2014 Cogent Embedded, 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. - * - * 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 -#include - -#include -#include - -#include "common.h" -#include "irqs.h" -#include "r7s72100.h" - -/* Ether */ -static const struct sh_eth_plat_data ether_pdata __initconst = { - .phy = 0x00, /* PD60610 */ - .edmac_endian = EDMAC_LITTLE_ENDIAN, - .phy_interface = PHY_INTERFACE_MODE_MII, - .no_ether_link = 1 -}; - -static const struct resource ether_resources[] __initconst = { - DEFINE_RES_MEM(0xe8203000, 0x800), - DEFINE_RES_MEM(0xe8204800, 0x200), - DEFINE_RES_IRQ(gic_iid(359)), -}; - -static const struct platform_device_info ether_info __initconst = { - .name = "r7s72100-ether", - .id = -1, - .res = ether_resources, - .num_res = ARRAY_SIZE(ether_resources), - .data = ðer_pdata, - .size_data = sizeof(ether_pdata), - .dma_mask = DMA_BIT_MASK(32), -}; - -/* RSPI */ -#define RSPI_RESOURCE(idx, baseaddr, irq) \ -static const struct resource rspi##idx##_resources[] __initconst = { \ - DEFINE_RES_MEM(baseaddr, 0x24), \ - DEFINE_RES_IRQ_NAMED(irq, "error"), \ - DEFINE_RES_IRQ_NAMED(irq + 1, "rx"), \ - DEFINE_RES_IRQ_NAMED(irq + 2, "tx"), \ -} - -RSPI_RESOURCE(0, 0xe800c800, gic_iid(270)); -RSPI_RESOURCE(1, 0xe800d000, gic_iid(273)); -RSPI_RESOURCE(2, 0xe800d800, gic_iid(276)); -RSPI_RESOURCE(3, 0xe800e000, gic_iid(279)); -RSPI_RESOURCE(4, 0xe800e800, gic_iid(282)); - -static const struct rspi_plat_data rspi_pdata __initconst = { - .num_chipselect = 1, -}; - -#define r7s72100_register_rspi(idx) \ - platform_device_register_resndata(NULL, "rspi-rz", idx, \ - rspi##idx##_resources, \ - ARRAY_SIZE(rspi##idx##_resources), \ - &rspi_pdata, sizeof(rspi_pdata)) - -static const struct spi_board_info spi_info[] __initconst = { - { - .modalias = "wm8978", - .max_speed_hz = 5000000, - .bus_num = 4, - .chip_select = 0, - }, -}; - -/* SCIF */ -#define R7S72100_SCIF(index, baseaddr, irq) \ -static const struct plat_sci_port scif##index##_platform_data = { \ - .type = PORT_SCIF, \ - .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, \ - .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ - .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \ - SCSCR_REIE, \ -}; \ - \ -static struct resource scif##index##_resources[] = { \ - DEFINE_RES_MEM(baseaddr, 0x100), \ - DEFINE_RES_IRQ(irq + 1), \ - DEFINE_RES_IRQ(irq + 2), \ - DEFINE_RES_IRQ(irq + 3), \ - DEFINE_RES_IRQ(irq), \ -} \ - -R7S72100_SCIF(0, 0xe8007000, gic_iid(221)); -R7S72100_SCIF(1, 0xe8007800, gic_iid(225)); -R7S72100_SCIF(2, 0xe8008000, gic_iid(229)); -R7S72100_SCIF(3, 0xe8008800, gic_iid(233)); -R7S72100_SCIF(4, 0xe8009000, gic_iid(237)); -R7S72100_SCIF(5, 0xe8009800, gic_iid(241)); -R7S72100_SCIF(6, 0xe800a000, gic_iid(245)); -R7S72100_SCIF(7, 0xe800a800, gic_iid(249)); - -#define r7s72100_register_scif(index) \ - platform_device_register_resndata(NULL, "sh-sci", index, \ - scif##index##_resources, \ - ARRAY_SIZE(scif##index##_resources), \ - &scif##index##_platform_data, \ - sizeof(scif##index##_platform_data)) - -static struct resource mtu2_resources[] __initdata = { - DEFINE_RES_MEM(0xfcff0000, 0x400), - DEFINE_RES_IRQ_NAMED(gic_iid(139), "tgi0a"), -}; - -#define r7s72100_register_mtu2() \ - platform_device_register_resndata(&platform_bus, "sh-mtu2", \ - -1, mtu2_resources, \ - ARRAY_SIZE(mtu2_resources), \ - NULL, 0) - -static void __init genmai_add_standard_devices(void) -{ - r7s72100_clock_init(); - r7s72100_register_mtu2(); - - platform_device_register_full(ðer_info); - - r7s72100_register_rspi(0); - r7s72100_register_rspi(1); - r7s72100_register_rspi(2); - r7s72100_register_rspi(3); - r7s72100_register_rspi(4); - spi_register_board_info(spi_info, ARRAY_SIZE(spi_info)); - - r7s72100_register_scif(0); - r7s72100_register_scif(1); - r7s72100_register_scif(2); - r7s72100_register_scif(3); - r7s72100_register_scif(4); - r7s72100_register_scif(5); - r7s72100_register_scif(6); - r7s72100_register_scif(7); -} - -static const char * const genmai_boards_compat_dt[] __initconst = { - "renesas,genmai", - NULL, -}; - -DT_MACHINE_START(GENMAI_DT, "genmai") - .init_early = shmobile_init_delay, - .init_machine = genmai_add_standard_devices, - .dt_compat = genmai_boards_compat_dt, -MACHINE_END -- GitLab From ad8c3af8b75ff26c5c887f2101da653bdcd53a38 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 2 Jul 2014 18:23:38 +0200 Subject: [PATCH 0758/9167] ARM: shmobile: r7s72100: Remove legacy board support There's no legacy board anymore, genmai now boots with multiplatform support only. Remove the leftovers. Makefile.boot portion pointed out by Paul Bolle. Signed-off-by: Laurent Pinchart Acked-by: Wolfram Sang Cc: Paul Bolle [horms+renesas@verge.net.au: squashed in patch containing Makefile.boot change] Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Kconfig | 8 - arch/arm/mach-shmobile/Makefile | 1 - arch/arm/mach-shmobile/Makefile.boot | 1 - arch/arm/mach-shmobile/clock-r7s72100.c | 231 ------------------------ arch/arm/mach-shmobile/r7s72100.h | 6 - arch/arm/mach-shmobile/setup-r7s72100.c | 2 - 6 files changed, 249 deletions(-) delete mode 100644 arch/arm/mach-shmobile/clock-r7s72100.c delete mode 100644 arch/arm/mach-shmobile/r7s72100.h diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 169bda468675..5814754c1240 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -145,14 +145,6 @@ config ARCH_R8A7791 select SYS_SUPPORTS_SH_CMT select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE -config ARCH_R7S72100 - bool "RZ/A1H (R7S72100)" - select ARCH_WANT_OPTIONAL_GPIOLIB - select ARM_GIC - select CPU_V7 - select SH_CLK_CPG - select SYS_SUPPORTS_SH_MTU2 - comment "Renesas ARM SoCs Board Type" config MACH_APE6EVM diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index be5fed20bf50..c7e2ad88baa9 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o -obj-$(CONFIG_ARCH_R7S72100) += clock-r7s72100.o endif # CPU reset vector handling objects diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot index ebf97d4bcfd8..a23e1555cca7 100644 --- a/arch/arm/mach-shmobile/Makefile.boot +++ b/arch/arm/mach-shmobile/Makefile.boot @@ -6,7 +6,6 @@ loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000 loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000 loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000 loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000 -loadaddr-$(CONFIG_MACH_GENMAI) += 0x08008000 loadaddr-$(CONFIG_MACH_KOELSCH) += 0x40008000 loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000 loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000 diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c deleted file mode 100644 index 3eb2ec401e0c..000000000000 --- a/arch/arm/mach-shmobile/clock-r7s72100.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * r7a72100 clock framework support - * - * Copyright (C) 2013 Renesas Solutions Corp. - * Copyright (C) 2012 Phil Edworthy - * Copyright (C) 2011 Magnus Damm - * - * 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 "common.h" -#include "r7s72100.h" - -/* Frequency Control Registers */ -#define FRQCR 0xfcfe0010 -#define FRQCR2 0xfcfe0014 -/* Standby Control Registers */ -#define STBCR3 0xfcfe0420 -#define STBCR4 0xfcfe0424 -#define STBCR7 0xfcfe0430 -#define STBCR9 0xfcfe0438 -#define STBCR10 0xfcfe043c - -#define PLL_RATE 30 - -static struct clk_mapping cpg_mapping = { - .phys = 0xfcfe0000, - .len = 0x1000, -}; - -/* Fixed 32 KHz root clock for RTC */ -static struct clk r_clk = { - .rate = 32768, -}; - -/* - * Default rate for the root input clock, reset this with clk_set_rate() - * from the platform code. - */ -static struct clk extal_clk = { - .rate = 13330000, - .mapping = &cpg_mapping, -}; - -static unsigned long pll_recalc(struct clk *clk) -{ - return clk->parent->rate * PLL_RATE; -} - -static struct sh_clk_ops pll_clk_ops = { - .recalc = pll_recalc, -}; - -static struct clk pll_clk = { - .ops = &pll_clk_ops, - .parent = &extal_clk, - .flags = CLK_ENABLE_ON_INIT, -}; - -static unsigned long bus_recalc(struct clk *clk) -{ - return clk->parent->rate / 3; -} - -static struct sh_clk_ops bus_clk_ops = { - .recalc = bus_recalc, -}; - -static struct clk bus_clk = { - .ops = &bus_clk_ops, - .parent = &pll_clk, - .flags = CLK_ENABLE_ON_INIT, -}; - -static unsigned long peripheral0_recalc(struct clk *clk) -{ - return clk->parent->rate / 12; -} - -static struct sh_clk_ops peripheral0_clk_ops = { - .recalc = peripheral0_recalc, -}; - -static struct clk peripheral0_clk = { - .ops = &peripheral0_clk_ops, - .parent = &pll_clk, - .flags = CLK_ENABLE_ON_INIT, -}; - -static unsigned long peripheral1_recalc(struct clk *clk) -{ - return clk->parent->rate / 6; -} - -static struct sh_clk_ops peripheral1_clk_ops = { - .recalc = peripheral1_recalc, -}; - -static struct clk peripheral1_clk = { - .ops = &peripheral1_clk_ops, - .parent = &pll_clk, - .flags = CLK_ENABLE_ON_INIT, -}; - -struct clk *main_clks[] = { - &r_clk, - &extal_clk, - &pll_clk, - &bus_clk, - &peripheral0_clk, - &peripheral1_clk, -}; - -static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */ -static int multipliers[] = { 1, 2, 1, 1 }; - -static struct clk_div_mult_table div4_div_mult_table = { - .divisors = div2, - .nr_divisors = ARRAY_SIZE(div2), - .multipliers = multipliers, - .nr_multipliers = ARRAY_SIZE(multipliers), -}; - -static struct clk_div4_table div4_table = { - .div_mult_table = &div4_div_mult_table, -}; - -enum { DIV4_I, - DIV4_NR }; - -#define DIV4(_reg, _bit, _mask, _flags) \ - SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) - -/* The mask field specifies the div2 entries that are valid */ -struct clk div4_clks[DIV4_NR] = { - [DIV4_I] = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT - | CLK_ENABLE_ON_INIT), -}; - -enum { - MSTP107, MSTP106, MSTP105, MSTP104, MSTP103, - MSTP97, MSTP96, MSTP95, MSTP94, - MSTP74, - MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40, - MSTP33, MSTP_NR -}; - -static struct clk mstp_clks[MSTP_NR] = { - [MSTP107] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 7, 0), /* RSPI0 */ - [MSTP106] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 6, 0), /* RSPI1 */ - [MSTP105] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 5, 0), /* RSPI2 */ - [MSTP104] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 4, 0), /* RSPI3 */ - [MSTP103] = SH_CLK_MSTP8(&peripheral1_clk, STBCR10, 3, 0), /* RSPI4 */ - [MSTP97] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 7, 0), /* RIIC0 */ - [MSTP96] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 6, 0), /* RIIC1 */ - [MSTP95] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 5, 0), /* RIIC2 */ - [MSTP94] = SH_CLK_MSTP8(&peripheral0_clk, STBCR9, 4, 0), /* RIIC3 */ - [MSTP74] = SH_CLK_MSTP8(&peripheral1_clk, STBCR7, 4, 0), /* Ether */ - [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */ - [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */ - [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */ - [MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */ - [MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */ - [MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */ - [MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */ - [MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */ - [MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */ -}; - -static struct clk_lookup lookups[] = { - /* main clocks */ - CLKDEV_CON_ID("rclk", &r_clk), - CLKDEV_CON_ID("extal", &extal_clk), - CLKDEV_CON_ID("pll_clk", &pll_clk), - CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk), - - /* DIV4 clocks */ - CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), - - /* MSTP clocks */ - CLKDEV_DEV_ID("rspi-rz.0", &mstp_clks[MSTP107]), - CLKDEV_DEV_ID("rspi-rz.1", &mstp_clks[MSTP106]), - CLKDEV_DEV_ID("rspi-rz.2", &mstp_clks[MSTP105]), - CLKDEV_DEV_ID("rspi-rz.3", &mstp_clks[MSTP104]), - CLKDEV_DEV_ID("rspi-rz.4", &mstp_clks[MSTP103]), - CLKDEV_DEV_ID("r7s72100-ether", &mstp_clks[MSTP74]), - - /* ICK */ - CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]), - CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]), - CLKDEV_ICK_ID("fck", "sh-mtu2", &mstp_clks[MSTP33]), -}; - -void __init r7s72100_clock_init(void) -{ - int k, ret = 0; - - for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) - ret = clk_register(main_clks[k]); - - clkdev_add_table(lookups, ARRAY_SIZE(lookups)); - - if (!ret) - ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); - - if (!ret) - ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); - - if (!ret) - shmobile_clk_init(); - else - panic("failed to setup rza1 clocks\n"); -} diff --git a/arch/arm/mach-shmobile/r7s72100.h b/arch/arm/mach-shmobile/r7s72100.h deleted file mode 100644 index 321ae4e10128..000000000000 --- a/arch/arm/mach-shmobile/r7s72100.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_R7S72100_H__ -#define __ASM_R7S72100_H__ - -void r7s72100_clock_init(void); - -#endif /* __ASM_R7S72100_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c index d898cef24611..111437df8eb6 100644 --- a/arch/arm/mach-shmobile/setup-r7s72100.c +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -24,7 +24,6 @@ #include "common.h" -#ifdef CONFIG_USE_OF static const char *r7s72100_boards_compat_dt[] __initdata = { "renesas,r7s72100", NULL, @@ -34,4 +33,3 @@ DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)") .init_early = shmobile_init_delay, .dt_compat = r7s72100_boards_compat_dt, MACHINE_END -#endif /* CONFIG_USE_OF */ -- GitLab From 3b1213f551145c124630fb592a8321724a40da32 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 30 Jul 2014 20:56:07 +0800 Subject: [PATCH 0759/9167] ARM: dts: sun8i: add rtc device node sun8i shares the same rtc hardware as sun6i. Now that we have a driver for it, add a device node to the DTSI for it so we can use it. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 54ac0787216a..62f002eb37b0 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -285,6 +285,12 @@ interrupts = <1 9 0xf04>; }; + rtc: rtc@01f00000 { + compatible = "allwinner,sun6i-a31-rtc"; + reg = <0x01f00000 0x54>; + interrupts = <0 40 4>, <0 41 4>; + }; + prcm@01f01400 { compatible = "allwinner,sun8i-a23-prcm"; reg = <0x01f01400 0x200>; -- GitLab From 5e7004351a8f144400873f0ad34690ec7cc97f01 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 30 Jul 2014 20:56:06 +0800 Subject: [PATCH 0760/9167] ARM: dts: sun6i: add rtc device node Now that we have a driver for sun6i's rtc hardware, add a device node for it so we can use it. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun6i-a31.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 44b07e512c24..8fdf90d52ab8 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -779,6 +779,12 @@ interrupts = <1 9 0xf04>; }; + rtc: rtc@01f00000 { + compatible = "allwinner,sun6i-a31-rtc"; + reg = <0x01f00000 0x54>; + interrupts = <0 40 4>, <0 41 4>; + }; + nmi_intc: interrupt-controller@01f00c0c { compatible = "allwinner,sun6i-a31-sc-nmi"; interrupt-controller; -- GitLab From 1324f53211398cd157edbedfe933fe21a9628b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Mon, 4 Aug 2014 17:09:57 -0300 Subject: [PATCH 0761/9167] ARM: sun4i: dt: Add node to represent the DMA controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Let's add a node to represent the A10 DMA controller on the device tree. Signed-off-by: Emilio López Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun4i-a10.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 459cb6377764..ce2fbb3c5a72 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -339,6 +339,14 @@ #size-cells = <1>; ranges; + dma: dma-controller@01c02000 { + compatible = "allwinner,sun4i-a10-dma"; + reg = <0x01c02000 0x1000>; + interrupts = <27>; + clocks = <&ahb_gates 6>; + #dma-cells = <2>; + }; + spi0: spi@01c05000 { compatible = "allwinner,sun4i-a10-spi"; reg = <0x01c05000 0x1000>; -- GitLab From 6a5775e482c4e6639090dd1a2c349d325da8732b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Mon, 4 Aug 2014 17:09:58 -0300 Subject: [PATCH 0762/9167] ARM: sun5i: dt: Add nodes to represent the DMA controllers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The A10S and A13 SoCs have sun4i-compatible DMA controllers. Let's add the corresponding nodes to represent them on the device tree. Signed-off-by: Emilio López Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun5i-a10s.dtsi | 8 ++++++++ arch/arm/boot/dts/sun5i-a13.dtsi | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 24b0ad3a7c07..aa6f1261ec90 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -300,6 +300,14 @@ #size-cells = <1>; ranges; + dma: dma-controller@01c02000 { + compatible = "allwinner,sun4i-a10-dma"; + reg = <0x01c02000 0x1000>; + interrupts = <27>; + clocks = <&ahb_gates 6>; + #dma-cells = <2>; + }; + spi0: spi@01c05000 { compatible = "allwinner,sun4i-a10-spi"; reg = <0x01c05000 0x1000>; diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index bf86e65dd167..cce04d16d7ea 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -298,6 +298,14 @@ #size-cells = <1>; ranges; + dma: dma-controller@01c02000 { + compatible = "allwinner,sun4i-a10-dma"; + reg = <0x01c02000 0x1000>; + interrupts = <27>; + clocks = <&ahb_gates 6>; + #dma-cells = <2>; + }; + spi0: spi@01c05000 { compatible = "allwinner,sun4i-a10-spi"; reg = <0x01c05000 0x1000>; -- GitLab From 316e0b0eebcfb030cdf265554fb34ef78380bf5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Mon, 4 Aug 2014 17:09:59 -0300 Subject: [PATCH 0763/9167] ARM: sun7i: dt: Add node to represent the DMA controller MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The A20 SoC has a sun4i-compatible DMA controller. Let's add a node to represent it on the device tree. Signed-off-by: Emilio López Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index 4011628c7381..c13b832871cd 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -423,6 +423,14 @@ interrupts = <0 0 4>; }; + dma: dma-controller@01c02000 { + compatible = "allwinner,sun4i-a10-dma"; + reg = <0x01c02000 0x1000>; + interrupts = <0 27 4>; + clocks = <&ahb_gates 6>; + #dma-cells = <2>; + }; + spi0: spi@01c05000 { compatible = "allwinner,sun4i-a10-spi"; reg = <0x01c05000 0x1000>; -- GitLab From 4192ff81174609e7d548e7a04d6fd940e860472e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Mon, 4 Aug 2014 17:10:00 -0300 Subject: [PATCH 0764/9167] ARM: sun4i: dt: enable DMA on SPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All of our SPI controllers support DMA transfers, so let's add the properties here so they can be used when it's best to do so. Signed-off-by: Emilio López Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun4i-a10.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index ce2fbb3c5a72..14cf43653341 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -353,6 +353,8 @@ interrupts = <10>; clocks = <&ahb_gates 20>, <&spi0_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 27>, <&dma 1 26>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -364,6 +366,8 @@ interrupts = <11>; clocks = <&ahb_gates 21>, <&spi1_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 9>, <&dma 1 8>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -459,6 +463,8 @@ interrupts = <12>; clocks = <&ahb_gates 22>, <&spi2_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 29>, <&dma 1 28>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -498,6 +504,8 @@ interrupts = <50>; clocks = <&ahb_gates 23>, <&spi3_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 31>, <&dma 1 30>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; -- GitLab From fed4c5c676f41359c7dbee635bd98e25e54c40f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Mon, 4 Aug 2014 17:10:01 -0300 Subject: [PATCH 0765/9167] ARM: sun5i: dt: enable DMA on SPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All of our SPI controllers support DMA transfers, so let's add the properties here so they can be used when it's best to do so. Signed-off-by: Emilio López Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun5i-a10s.dtsi | 6 ++++++ arch/arm/boot/dts/sun5i-a13.dtsi | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index aa6f1261ec90..02aa41f6fdc4 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -314,6 +314,8 @@ interrupts = <10>; clocks = <&ahb_gates 20>, <&spi0_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 27>, <&dma 1 26>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -325,6 +327,8 @@ interrupts = <11>; clocks = <&ahb_gates 21>, <&spi1_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 9>, <&dma 1 8>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -411,6 +415,8 @@ interrupts = <12>; clocks = <&ahb_gates 22>, <&spi2_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 29>, <&dma 1 28>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index cce04d16d7ea..d8f02ee1b4dc 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -312,6 +312,8 @@ interrupts = <10>; clocks = <&ahb_gates 20>, <&spi0_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 27>, <&dma 1 26>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -323,6 +325,8 @@ interrupts = <11>; clocks = <&ahb_gates 21>, <&spi1_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 9>, <&dma 1 8>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -384,6 +388,8 @@ interrupts = <12>; clocks = <&ahb_gates 22>, <&spi2_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 29>, <&dma 1 28>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; -- GitLab From ffec7210e11bb06c970c83ea0c3f2d7a1142458f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20L=C3=B3pez?= Date: Mon, 4 Aug 2014 17:10:02 -0300 Subject: [PATCH 0766/9167] ARM: sun7i: dt: enable DMA on SPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All of our SPI controllers support DMA transfers, so let's add the properties here so they can be used when it's best to do so. Signed-off-by: Emilio López Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun7i-a20.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index c13b832871cd..db22ef9cbed8 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -437,6 +437,8 @@ interrupts = <0 10 4>; clocks = <&ahb_gates 20>, <&spi0_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 27>, <&dma 1 26>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -448,6 +450,8 @@ interrupts = <0 11 4>; clocks = <&ahb_gates 21>, <&spi1_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 9>, <&dma 1 8>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -543,6 +547,8 @@ interrupts = <0 12 4>; clocks = <&ahb_gates 22>, <&spi2_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 29>, <&dma 1 28>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -582,6 +588,8 @@ interrupts = <0 50 4>; clocks = <&ahb_gates 23>, <&spi3_clk>; clock-names = "ahb", "mod"; + dmas = <&dma 1 31>, <&dma 1 30>; + dma-names = "rx", "tx"; status = "disabled"; #address-cells = <1>; #size-cells = <0>; -- GitLab From 6b2b16f5790e4187e1b38dfe495ae08eda235485 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:07 +0800 Subject: [PATCH 0767/9167] ARM: dts: sun8i: Add PIO controller node to the sun8i dtsi Now that we have a driver for the sun8i PIO controller, add the corresponding device node to the dtsi. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 62f002eb37b0..08184f694d4c 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -187,6 +187,20 @@ #size-cells = <1>; ranges; + pio: pinctrl@01c20800 { + compatible = "allwinner,sun8i-a23-pinctrl"; + reg = <0x01c20800 0x400>; + interrupts = <0 11 4>, + <0 15 4>, + <0 17 4>; + clocks = <&apb1_gates 5>; + gpio-controller; + interrupt-controller; + #address-cells = <1>; + #size-cells = <0>; + #gpio-cells = <3>; + }; + ahb1_rst: reset@01c202c0 { #reset-cells = <1>; compatible = "allwinner,sun6i-a31-clock-reset"; -- GitLab From b6a8711261b2979051832d1389d14c35dbf09dc6 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:08 +0800 Subject: [PATCH 0768/9167] ARM: dts: sun8i: Add R_PIO controller node to the dtsi Now that we have a driver for the R_PIO controller, add the corresponding device node to the dtsi. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 08184f694d4c..cb1fbfcd7f06 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -359,5 +359,18 @@ resets = <&apb0_rst 4>; status = "disabled"; }; + + r_pio: pinctrl@01f02c00 { + compatible = "allwinner,sun8i-a23-r-pinctrl"; + reg = <0x01f02c00 0x400>; + interrupts = <0 45 4>; + clocks = <&apb0_gates 0>; + resets = <&apb0_rst 0>; + gpio-controller; + interrupt-controller; + #address-cells = <1>; + #size-cells = <0>; + #gpio-cells = <3>; + }; }; }; -- GitLab From c4021571e35d10233d331773124568ef94cee66d Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:09 +0800 Subject: [PATCH 0769/9167] ARM: dts: sun8i: Add pinmux set for uart0 uart0 on sun8i is only muxed with mmc0, which makes it a poor choice for the console. However, some tablets only have pads for uart0 available on the circuit board. Here we add the uart0 pinmux set for people who need it. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index cb1fbfcd7f06..cbd481eff55d 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -199,6 +199,13 @@ #address-cells = <1>; #size-cells = <0>; #gpio-cells = <3>; + + uart0_pins_a: uart0@0 { + allwinner,pins = "PF2", "PF4"; + allwinner,function = "uart0"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; }; ahb1_rst: reset@01c202c0 { -- GitLab From 813097915853100d6cb0655c75f64e67a1ef57a8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:10 +0800 Subject: [PATCH 0770/9167] ARM: dts: sun8i: Add pin muxing option for R_UART R_UART is available on extra pads on certain tablets, which makes it ideal for use as a console. Here we add the pins for it. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index cbd481eff55d..32c195c49b83 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -378,6 +378,13 @@ #address-cells = <1>; #size-cells = <0>; #gpio-cells = <3>; + + r_uart_pins_a: r_uart@0 { + allwinner,pins = "PL2", "PL3"; + allwinner,function = "s_uart"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; }; }; }; -- GitLab From 1c602064e00a81b1600bed6b2fe17dffe80b01e0 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:11 +0800 Subject: [PATCH 0771/9167] ARM: dts: sun8i: ippo-q8h: Add pinctrl properties for R_UART Now that we have R_PIO controller support and the pinmux for R_UART, add the correct pinctrl properties to the R_UART node. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts index 34002e3eba9d..224f53ef8ebc 100644 --- a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts +++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts @@ -24,6 +24,8 @@ soc@01c00000 { r_uart: serial@01f02800 { + pinctrl-names = "default"; + pinctrl-0 = <&r_uart_pins_a>; status = "okay"; }; }; -- GitLab From 4b7ecb38d87045968f477a4a4e98b859cd66b9b4 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:12 +0800 Subject: [PATCH 0772/9167] ARM: dts: sun8i: Add mmc clocks to the dtsi The MMC module clocks on sun8i are the same as those found on previous Allwinner SoCs, module 0 clocks. This patch adds the clocks nodes to the dtsi with existing drivers. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 32c195c49b83..9bd5dcc1beb3 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -179,6 +179,30 @@ "apb2_uart1", "apb2_uart2", "apb2_uart3", "apb2_uart4"; }; + + mmc0_clk: clk@01c20088 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c20088 0x4>; + clocks = <&osc24M>, <&pll6>; + clock-output-names = "mmc0"; + }; + + mmc1_clk: clk@01c2008c { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c2008c 0x4>; + clocks = <&osc24M>, <&pll6>; + clock-output-names = "mmc1"; + }; + + mmc2_clk: clk@01c20090 { + #clock-cells = <0>; + compatible = "allwinner,sun4i-a10-mod0-clk"; + reg = <0x01c20090 0x4>; + clocks = <&osc24M>, <&pll6>; + clock-output-names = "mmc2"; + }; }; soc@01c00000 { -- GitLab From cdb6fd6798339efd6e1cb768d9d504929342b91b Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:13 +0800 Subject: [PATCH 0773/9167] ARM: dts: sun8i: Add pin-muxing info for the mmc controllers This adds pin-muxing info for the mmc controller / port combinations which are known to be used on actual boards. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 9bd5dcc1beb3..342b52aab344 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -230,6 +230,20 @@ allwinner,drive = <0>; allwinner,pull = <0>; }; + + mmc0_pins_a: mmc0@0 { + allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; + allwinner,function = "mmc0"; + allwinner,drive = <2>; + allwinner,pull = <0>; + }; + + mmc1_pins_a: mmc1@0 { + allwinner,pins = "PG0","PG1","PG2","PG3","PG4","PG5"; + allwinner,function = "mmc1"; + allwinner,drive = <2>; + allwinner,pull = <0>; + }; }; ahb1_rst: reset@01c202c0 { -- GitLab From eacda1f11fcb8e38cdc9954c1f9cce295315bcab Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:14 +0800 Subject: [PATCH 0774/9167] ARM: dts: sun8i: Add mmc controller nodes Add nodes for the 3 mmc controllers found on A23 SoCs to the sun8i DTSI. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 342b52aab344..284522e1a591 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -211,6 +211,39 @@ #size-cells = <1>; ranges; + mmc0: mmc@01c0f000 { + compatible = "allwinner,sun5i-a13-mmc"; + reg = <0x01c0f000 0x1000>; + clocks = <&ahb1_gates 8>, <&mmc0_clk>; + clock-names = "ahb", "mmc"; + resets = <&ahb1_rst 8>; + reset-names = "ahb"; + interrupts = <0 60 4>; + status = "disabled"; + }; + + mmc1: mmc@01c10000 { + compatible = "allwinner,sun5i-a13-mmc"; + reg = <0x01c10000 0x1000>; + clocks = <&ahb1_gates 9>, <&mmc1_clk>; + clock-names = "ahb", "mmc"; + resets = <&ahb1_rst 9>; + reset-names = "ahb"; + interrupts = <0 61 4>; + status = "disabled"; + }; + + mmc2: mmc@01c11000 { + compatible = "allwinner,sun5i-a13-mmc"; + reg = <0x01c11000 0x1000>; + clocks = <&ahb1_gates 10>, <&mmc2_clk>; + clock-names = "ahb", "mmc"; + resets = <&ahb1_rst 10>; + reset-names = "ahb"; + interrupts = <0 62 4>; + status = "disabled"; + }; + pio: pinctrl@01c20800 { compatible = "allwinner,sun8i-a23-pinctrl"; reg = <0x01c20800 0x400>; -- GitLab From cd78d3f2d716c291481206d4f87f1eeb20278f24 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:15 +0800 Subject: [PATCH 0775/9167] ARM: dts: sun8i: Enable mmc controller on ippo-q8h-v5 The card detect pin setting was taken from the original fex file, and is confirmed to work. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts index 224f53ef8ebc..ef1e4f3aaf39 100644 --- a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts +++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts @@ -13,6 +13,7 @@ /dts-v1/; /include/ "sun8i-a23.dtsi" +/include/ "sunxi-common-regulators.dtsi" / { model = "Ippo Q8H Dual Core Tablet (v5)"; @@ -23,6 +24,25 @@ }; soc@01c00000 { + mmc0: mmc@01c0f000 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_q8h>; + vmmc-supply = <®_vcc3v0>; + bus-width = <4>; + cd-gpios = <&pio 1 4 0>; /* PB4 */ + cd-inverted; + status = "okay"; + }; + + pinctrl@01c20800 { + mmc0_cd_pin_q8h: mmc0_cd_pin@0 { + allwinner,pins = "PB4"; + allwinner,function = "gpio_in"; + allwinner,drive = <0>; + allwinner,pull = <1>; + }; + }; + r_uart: serial@01f02800 { pinctrl-names = "default"; pinctrl-0 = <&r_uart_pins_a>; -- GitLab From 1890f518d9dd62f02c23046890ce5c288906a045 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 17 Aug 2014 11:52:16 +0800 Subject: [PATCH 0776/9167] ARM: dts: sun8i: Add pin-muxing info for the i2c controllers This adds pin-muxing info for the i2c controller / port combinations which are known to be used on actual boards. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 284522e1a591..9386d1f565b9 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -277,6 +277,27 @@ allwinner,drive = <2>; allwinner,pull = <0>; }; + + i2c0_pins_a: i2c0@0 { + allwinner,pins = "PH2", "PH3"; + allwinner,function = "i2c0"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + i2c1_pins_a: i2c1@0 { + allwinner,pins = "PH4", "PH5"; + allwinner,function = "i2c1"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + i2c2_pins_a: i2c2@0 { + allwinner,pins = "PE12", "PE13"; + allwinner,function = "i2c2"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; }; ahb1_rst: reset@01c202c0 { -- GitLab From 8a36eaa2ff4a9452a78d799503b920b4e1a0ec31 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 17 Aug 2014 12:03:05 +0200 Subject: [PATCH 0777/9167] ASoC: dmic: Add to SND_SOC_ALL_CODECS Improve build coverage of the dmic driver. Signed-off-by: Lars-Peter Clausen 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 8838838e25ed..e514e98e48c4 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -56,6 +56,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_DA7213 if I2C select SND_SOC_DA732X if I2C select SND_SOC_DA9055 if I2C + select SND_SOC_DMIC select SND_SOC_BT_SCO select SND_SOC_ISABELLE if I2C select SND_SOC_JZ4740_CODEC -- GitLab From 9ba1e456e1fa3729fc6be73403a7b2083f9590eb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sun, 17 Aug 2014 12:08:57 +0200 Subject: [PATCH 0778/9167] regmap: Add explicit dependencies to catch "select" misuse Add explicit dependencies for the various regmap modules, so Kconfig will print a warning message when another module selects a regmap module without fulfilling its dependencies. Without this, it's much more difficult to find out which module did the offending select. Signed-off-by: Geert Uytterhoeven Signed-off-by: Mark Brown --- drivers/base/regmap/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/base/regmap/Kconfig b/drivers/base/regmap/Kconfig index 4251570610c9..8a3f51f7b1b9 100644 --- a/drivers/base/regmap/Kconfig +++ b/drivers/base/regmap/Kconfig @@ -11,12 +11,15 @@ config REGMAP config REGMAP_I2C tristate + depends on I2C config REGMAP_SPI tristate + depends on SPI config REGMAP_SPMI tristate + depends on SPMI config REGMAP_MMIO tristate -- GitLab From 1d3e6a6985c14f0510ebbd81fb9e8c02b24f8791 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 17 Aug 2014 18:34:48 +0800 Subject: [PATCH 0779/9167] regulator: da9211: Check return value of devm_kzalloc() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/da9211-regulator.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index ccc2e362d751..a26f1d283c57 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -343,6 +343,8 @@ static int da9211_i2c_probe(struct i2c_client *i2c, unsigned int data; chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL); + if (!chip) + return -ENOMEM; chip->dev = &i2c->dev; chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config); -- GitLab From 371e07ec837464375fe4d7ef3bd13e13cdfbb458 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 17 Aug 2014 16:18:17 +0200 Subject: [PATCH 0780/9167] ASoC: edma-pcm: Include edma-pcm.h edma_pcm_platform_register() is declared in edma-pcm.h and defined in edma-pcm.c. To make sure that the function signature matches for both edma-pcm.c should include edma-pcm.h Fixes the following sparse warning: sound/soc/davinci/edma-pcm.c:48:5: warning: symbol 'edma_pcm_platform_register' was not declared. Should it be static? Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/davinci/edma-pcm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/davinci/edma-pcm.c b/sound/soc/davinci/edma-pcm.c index 605e643133db..59e588abe54b 100644 --- a/sound/soc/davinci/edma-pcm.c +++ b/sound/soc/davinci/edma-pcm.c @@ -25,6 +25,8 @@ #include #include +#include "edma-pcm.h" + static const struct snd_pcm_hardware edma_pcm_hardware = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | -- GitLab From d80a12f92466d0bc4fd244c9052a8a88518c868e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 17 Aug 2014 16:18:18 +0200 Subject: [PATCH 0781/9167] ASoC: odrodix2_max98090: Make non exported symbols static odroidx2_drvdata and odroidu3_drvdata are not used outside this module so make them static (and also const while we are at it). Fixes the following warnings from sparse: sound/soc/samsung/odroidx2_max98090.c:69:26: warning: symbol 'odroidx2_drvdata' was not declared. Should it be static? sound/soc/samsung/odroidx2_max98090.c:74:26: warning: symbol 'odroidu3_drvdata' was not declared. Should it be static? Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/odroidx2_max98090.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/odroidx2_max98090.c b/sound/soc/samsung/odroidx2_max98090.c index 278edf9e2a87..3c8f60423e82 100644 --- a/sound/soc/samsung/odroidx2_max98090.c +++ b/sound/soc/samsung/odroidx2_max98090.c @@ -66,12 +66,12 @@ static struct snd_soc_card odroidx2 = { .late_probe = odroidx2_late_probe, }; -struct odroidx2_drv_data odroidx2_drvdata = { +static const struct odroidx2_drv_data odroidx2_drvdata = { .dapm_widgets = odroidx2_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(odroidx2_dapm_widgets), }; -struct odroidx2_drv_data odroidu3_drvdata = { +static const struct odroidx2_drv_data odroidu3_drvdata = { .dapm_widgets = odroidu3_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(odroidu3_dapm_widgets), }; -- GitLab From 6c7d1dfca999f58c65ed7b10c2f0945dd92db103 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 17 Aug 2014 16:18:20 +0200 Subject: [PATCH 0782/9167] ASoC: sh: Fix dma direction type dmaengine_prep_slave_single() expects a enum dma_transfer_direction and not a enum dma_data_direction. Since the integer representations of both DMA_TO_DEVICE and DMA_MEM_TO_DEV aswell as DMA_FROM_DEVICE and DMA_DEV_TO_MEM have the same value the code worked fine even though it was using the wrong type. Fixes the following warnings from sparse: sound/soc/sh/fsi.c:1307:42: warning: mixing different enum types sound/soc/sh/fsi.c:1307:42: int enum dma_data_direction versus sound/soc/sh/fsi.c:1307:42: int enum dma_transfer_direction Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index c76344350e44..66fddec9543d 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1297,9 +1297,14 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io) struct snd_pcm_substream *substream = io->substream; struct dma_async_tx_descriptor *desc; int is_play = fsi_stream_is_play(fsi, io); - enum dma_data_direction dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; + enum dma_transfer_direction dir; int ret = -EIO; + if (is_play) + dir = DMA_MEM_TO_DEV; + else + dir = DMA_DEV_TO_MEM; + desc = dmaengine_prep_dma_cyclic(io->chan, substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), -- GitLab From e8a70c25b809367fc314743e1ba1dbf0159398a7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 17 Aug 2014 16:18:21 +0200 Subject: [PATCH 0783/9167] ASoC: samsung idma: Add proper annotation for casting iomem pointers It is not always possible to interchange iomem pointers with normal pointers, which why we have annotations for iomem pointers and warn when casting them to a normal pointer or vice versa. In this case the casting is fine and unfortunately necessary so add the proper annotations to tell code checkers that it is intentional. This silences the following warnings from sparse: sound/soc/samsung/idma.c:354:20: warning: incorrect type in argument 1 (different address spaces) expected void volatile [noderef] *addr got unsigned char *area sound/soc/samsung/idma.c:372:22: warning: cast removes address space of expression Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/samsung/idma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index db6cefa18017..0e8dd985fcb3 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -351,7 +351,7 @@ static void idma_free(struct snd_pcm *pcm) if (!buf->area) return; - iounmap(buf->area); + iounmap((void __iomem *)buf->area); buf->area = NULL; buf->addr = 0; @@ -369,7 +369,7 @@ static int preallocate_idma_buffer(struct snd_pcm *pcm, int stream) buf->dev.type = SNDRV_DMA_TYPE_CONTINUOUS; buf->addr = idma.lp_tx_addr; buf->bytes = idma_hardware.buffer_bytes_max; - buf->area = (unsigned char *)ioremap(buf->addr, buf->bytes); + buf->area = (unsigned char * __force)ioremap(buf->addr, buf->bytes); return 0; } -- GitLab From 6391fffb7b6099fae0e869229279d147c47f617a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 17 Aug 2014 16:18:22 +0200 Subject: [PATCH 0784/9167] ASoC: ab8500-codec: Drop bank prefix from AB8500_GPIO_DIR4_REG register define The AB8500_GPIO_DIR4_REG register define has the bank for the register in the upper 8 bits and the register itself in the lower 8 bits. When passing it to abx500_{set,get}_register_interruptible() the upper bits get truncated which generates the following warning from sparse: sound/soc/codecs/ab8500-codec.c:1972:53: warning: cast truncates bits from constant value (1013 becomes 13) sound/soc/codecs/ab8500-codec.c:1980:53: warning: cast truncates bits from constant value (1013 becomes 13) The bank is passed separately to abx500_{set,get}_register_interruptible() so the code works fine as it is. Given that all users of AB8500_GPIO_DIR4_REG always truncate the upper 8 bits just remove them from the define. Also remove the unnecessary casts to u8. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/ab8500-codec.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 1fb4402bf72d..62cf231f34cb 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c @@ -56,8 +56,7 @@ #define GPIO31_DIR_OUTPUT 0x40 /* Macrocell register definitions */ -#define AB8500_CTRL3_REG 0x0200 -#define AB8500_GPIO_DIR4_REG 0x1013 +#define AB8500_GPIO_DIR4_REG 0x13 /* Bank AB8500_MISC */ /* Nr of FIR/IIR-coeff banks in ANC-block */ #define AB8500_NR_OF_ANC_COEFF_BANKS 2 @@ -1968,16 +1967,16 @@ static int ab8500_audio_setup_mics(struct snd_soc_codec *codec, dev_dbg(codec->dev, "%s: Enter.\n", __func__); /* Set DMic-clocks to outputs */ - status = abx500_get_register_interruptible(codec->dev, (u8)AB8500_MISC, - (u8)AB8500_GPIO_DIR4_REG, + status = abx500_get_register_interruptible(codec->dev, AB8500_MISC, + AB8500_GPIO_DIR4_REG, &value8); if (status < 0) return status; value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT | GPIO31_DIR_OUTPUT; status = abx500_set_register_interruptible(codec->dev, - (u8)AB8500_MISC, - (u8)AB8500_GPIO_DIR4_REG, + AB8500_MISC, + AB8500_GPIO_DIR4_REG, value); if (status < 0) return status; -- GitLab From 9e5b208dc9b2460f83f218ef6a6a1b1309fcd6b0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 3 Aug 2014 13:03:06 -0400 Subject: [PATCH 0785/9167] SUNRPC: Do not override wspace tests in svc_handle_xprt We already determined that there was enough wspace when we called svc_xprt_enqueue. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 6666c6745858..08e48cecfdcc 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -744,7 +744,7 @@ static int svc_handle_xprt(struct svc_rqst *rqstp, struct svc_xprt *xprt) svc_add_new_temp_xprt(serv, newxpt); else module_put(xprt->xpt_class->xcl_owner); - } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) { + } else { /* XPT_DATA|XPT_DEFERRED case: */ dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", rqstp, rqstp->rq_pool->sp_id, xprt, -- GitLab From d6a7ce424f9e32b6a5589f6bb96e0d1381479d48 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 3 Aug 2014 13:03:07 -0400 Subject: [PATCH 0786/9167] lockd: Ensure that lockd_start_svc sets the server rq_task... Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/lockd/svc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 8f27c93f8d2e..b416b3355807 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -313,6 +313,8 @@ static int lockd_start_svc(struct svc_serv *serv) "lockd_up: kthread_run failed, error=%d\n", error); goto out_task; } + nlmsvc_rqst->rq_task = nlmsvc_task; + dprintk("lockd_up: service started\n"); return 0; -- GitLab From 887999774aeca9375b3831dbe58bab02df7b327f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 3 Aug 2014 13:03:08 -0400 Subject: [PATCH 0787/9167] nfs: Ensure that nfs_callback_start_svc sets the server rq_task... Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfs/callback.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 54de482143cc..e3dd1cd175d9 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -244,6 +244,7 @@ static int nfs_callback_start_svc(int minorversion, struct rpc_xprt *xprt, cb_info->task = NULL; return ret; } + rqstp->rq_task = cb_info->task; dprintk("nfs_callback_up: service started\n"); return 0; } -- GitLab From 106f359cf4d613ebf54cb9f29721bb956fc3460e Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 3 Aug 2014 13:03:09 -0400 Subject: [PATCH 0788/9167] SUNRPC: Do not grab pool->sp_lock unnecessarily in svc_get_next_xprt Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 08e48cecfdcc..08e49d1e17b3 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -651,8 +651,8 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) } else { if (pool->sp_task_pending) { pool->sp_task_pending = 0; - spin_unlock_bh(&pool->sp_lock); - return ERR_PTR(-EAGAIN); + xprt = ERR_PTR(-EAGAIN); + goto out; } /* No data pending. Go to sleep */ svc_thread_enqueue(pool, rqstp); @@ -672,8 +672,8 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) */ if (kthread_should_stop()) { set_current_state(TASK_RUNNING); - spin_unlock_bh(&pool->sp_lock); - return ERR_PTR(-EINTR); + xprt = ERR_PTR(-EINTR); + goto out; } add_wait_queue(&rqstp->rq_wait, &wait); @@ -683,8 +683,12 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) try_to_freeze(); - spin_lock_bh(&pool->sp_lock); remove_wait_queue(&rqstp->rq_wait, &wait); + xprt = rqstp->rq_xprt; + if (xprt != NULL) + return xprt; + + spin_lock_bh(&pool->sp_lock); if (!time_left) pool->sp_stats.threads_timedout++; @@ -699,6 +703,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) return ERR_PTR(-EAGAIN); } } +out: spin_unlock_bh(&pool->sp_lock); return xprt; } -- GitLab From 983c684466e02b21f83c025ea539deee6c0aeac0 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 3 Aug 2014 13:03:10 -0400 Subject: [PATCH 0789/9167] SUNRPC: get rid of the request wait queue We're always _only_ waking up tasks from within the sp_threads list, so we know that they are enqueued and alive. The rq_wait waitqueue is just a distraction with extra atomic semantics. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svc.h | 1 - net/sunrpc/svc.c | 2 -- net/sunrpc/svc_xprt.c | 32 +++++++++++++++++--------------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index cf61ecd148e0..21678464883a 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -280,7 +280,6 @@ struct svc_rqst { bool rq_splice_ok; /* turned off in gss privacy * to prevent encrypting page * cache pages */ - wait_queue_head_t rq_wait; /* synchronization */ struct task_struct *rq_task; /* service thread */ }; diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 1db5007ddbce..ca8a7958f4e6 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -612,8 +612,6 @@ svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool, int node) if (!rqstp) goto out_enomem; - init_waitqueue_head(&rqstp->rq_wait); - serv->sv_nrthreads++; spin_lock_bh(&pool->sp_lock); pool->sp_nrthreads++; diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 08e49d1e17b3..faaf2b46273b 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -348,8 +348,6 @@ static void svc_xprt_do_enqueue(struct svc_xprt *xprt) cpu = get_cpu(); pool = svc_pool_for_cpu(xprt->xpt_server, cpu); - put_cpu(); - spin_lock_bh(&pool->sp_lock); if (!list_empty(&pool->sp_threads) && @@ -382,10 +380,15 @@ static void svc_xprt_do_enqueue(struct svc_xprt *xprt) printk(KERN_ERR "svc_xprt_enqueue: server %p, rq_xprt=%p!\n", rqstp, rqstp->rq_xprt); - rqstp->rq_xprt = xprt; + /* Note the order of the following 3 lines: + * We want to assign xprt to rqstp->rq_xprt only _after_ + * we've woken up the process, so that we don't race with + * the lockless check in svc_get_next_xprt(). + */ svc_xprt_get(xprt); + wake_up_process(rqstp->rq_task); + rqstp->rq_xprt = xprt; pool->sp_stats.threads_woken++; - wake_up(&rqstp->rq_wait); } else { dprintk("svc: transport %p put into queue\n", xprt); list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); @@ -394,6 +397,7 @@ static void svc_xprt_do_enqueue(struct svc_xprt *xprt) out_unlock: spin_unlock_bh(&pool->sp_lock); + put_cpu(); } /* @@ -509,7 +513,7 @@ void svc_wake_up(struct svc_serv *serv) svc_thread_dequeue(pool, rqstp); rqstp->rq_xprt = NULL; */ - wake_up(&rqstp->rq_wait); + wake_up_process(rqstp->rq_task); } else pool->sp_task_pending = 1; spin_unlock_bh(&pool->sp_lock); @@ -628,7 +632,6 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) { struct svc_xprt *xprt; struct svc_pool *pool = rqstp->rq_pool; - DECLARE_WAITQUEUE(wait, current); long time_left; /* Normally we will wait up to 5 seconds for any required @@ -654,15 +657,15 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) xprt = ERR_PTR(-EAGAIN); goto out; } - /* No data pending. Go to sleep */ - svc_thread_enqueue(pool, rqstp); - /* * We have to be able to interrupt this wait * to bring down the daemons ... */ set_current_state(TASK_INTERRUPTIBLE); + /* No data pending. Go to sleep */ + svc_thread_enqueue(pool, rqstp); + /* * checking kthread_should_stop() here allows us to avoid * locking and signalling when stopping kthreads that call @@ -676,14 +679,13 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) goto out; } - add_wait_queue(&rqstp->rq_wait, &wait); spin_unlock_bh(&pool->sp_lock); time_left = schedule_timeout(timeout); + __set_current_state(TASK_RUNNING); try_to_freeze(); - remove_wait_queue(&rqstp->rq_wait, &wait); xprt = rqstp->rq_xprt; if (xprt != NULL) return xprt; @@ -786,10 +788,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) printk(KERN_ERR "svc_recv: service %p, transport not NULL!\n", rqstp); - if (waitqueue_active(&rqstp->rq_wait)) - printk(KERN_ERR - "svc_recv: service %p, wait queue active!\n", - rqstp); + + /* Make sure the task pointer is set! */ + if (WARN_ON_ONCE(!rqstp->rq_task)) + rqstp->rq_task = current_task; err = svc_alloc_arg(rqstp); if (err) -- GitLab From a4aa8054a60c545f100826271ac9f04c34bf828d Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 3 Aug 2014 13:03:11 -0400 Subject: [PATCH 0790/9167] SUNRPC: Fix broken kthread_should_stop test in svc_get_next_xprt We should definitely not be exiting svc_get_next_xprt() with the thread enqueued. Fix this by ensuring that we fall through to the dequeue. Also move the test itself outside the spin lock protected section. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index faaf2b46273b..5eb6f32df3e5 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -632,7 +632,7 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) { struct svc_xprt *xprt; struct svc_pool *pool = rqstp->rq_pool; - long time_left; + long time_left = 0; /* Normally we will wait up to 5 seconds for any required * cache information to be provided. @@ -665,30 +665,19 @@ static struct svc_xprt *svc_get_next_xprt(struct svc_rqst *rqstp, long timeout) /* No data pending. Go to sleep */ svc_thread_enqueue(pool, rqstp); - - /* - * checking kthread_should_stop() here allows us to avoid - * locking and signalling when stopping kthreads that call - * svc_recv. If the thread has already been woken up, then - * we can exit here without sleeping. If not, then it - * it'll be woken up quickly during the schedule_timeout - */ - if (kthread_should_stop()) { - set_current_state(TASK_RUNNING); - xprt = ERR_PTR(-EINTR); - goto out; - } - spin_unlock_bh(&pool->sp_lock); - time_left = schedule_timeout(timeout); - __set_current_state(TASK_RUNNING); + if (!(signalled() || kthread_should_stop())) { + time_left = schedule_timeout(timeout); + __set_current_state(TASK_RUNNING); - try_to_freeze(); + try_to_freeze(); - xprt = rqstp->rq_xprt; - if (xprt != NULL) - return xprt; + xprt = rqstp->rq_xprt; + if (xprt != NULL) + return xprt; + } else + __set_current_state(TASK_RUNNING); spin_lock_bh(&pool->sp_lock); if (!time_left) -- GitLab From 0c0746d03eac70e12bcb39e7f1c7f0a1dd31123c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 3 Aug 2014 13:03:12 -0400 Subject: [PATCH 0791/9167] SUNRPC: More optimisations of svc_xprt_enqueue() Just move the transport locking out of the spin lock protected area altogether. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 5eb6f32df3e5..c0db66d81e34 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -346,18 +346,6 @@ static void svc_xprt_do_enqueue(struct svc_xprt *xprt) if (!svc_xprt_has_something_to_do(xprt)) return; - cpu = get_cpu(); - pool = svc_pool_for_cpu(xprt->xpt_server, cpu); - spin_lock_bh(&pool->sp_lock); - - if (!list_empty(&pool->sp_threads) && - !list_empty(&pool->sp_sockets)) - printk(KERN_ERR - "svc_xprt_enqueue: " - "threads and transports both waiting??\n"); - - pool->sp_stats.packets++; - /* Mark transport as busy. It will remain in this state until * the provider calls svc_xprt_received. We update XPT_BUSY * atomically because it also guards against trying to enqueue @@ -366,9 +354,15 @@ static void svc_xprt_do_enqueue(struct svc_xprt *xprt) if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) { /* Don't enqueue transport while already enqueued */ dprintk("svc: transport %p busy, not enqueued\n", xprt); - goto out_unlock; + return; } + cpu = get_cpu(); + pool = svc_pool_for_cpu(xprt->xpt_server, cpu); + spin_lock_bh(&pool->sp_lock); + + pool->sp_stats.packets++; + if (!list_empty(&pool->sp_threads)) { rqstp = list_entry(pool->sp_threads.next, struct svc_rqst, @@ -395,7 +389,6 @@ static void svc_xprt_do_enqueue(struct svc_xprt *xprt) pool->sp_stats.sockets_queued++; } -out_unlock: spin_unlock_bh(&pool->sp_lock); put_cpu(); } -- GitLab From f8d1ff47b6858c1a26a658060c18a778696636db Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 3 Aug 2014 13:03:13 -0400 Subject: [PATCH 0792/9167] SUNRPC: Optimise away svc_recv_available We really do not want to do ioctls in the server's fast path. Instead, let's use the fact that we managed to read a full record as the indicator that we should try to read the socket again. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- net/sunrpc/svcsock.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index c24a8ff33f8f..0e8b667337a2 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -311,19 +311,6 @@ static int svc_one_sock_name(struct svc_sock *svsk, char *buf, int remaining) return len; } -/* - * Check input queue length - */ -static int svc_recv_available(struct svc_sock *svsk) -{ - struct socket *sock = svsk->sk_sock; - int avail, err; - - err = kernel_sock_ioctl(sock, TIOCINQ, (unsigned long) &avail); - - return (err >= 0)? avail : err; -} - /* * Generic recvfrom routine. */ @@ -339,8 +326,14 @@ static int svc_recvfrom(struct svc_rqst *rqstp, struct kvec *iov, int nr, rqstp->rq_xprt_hlen = 0; + clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); len = kernel_recvmsg(svsk->sk_sock, &msg, iov, nr, buflen, msg.msg_flags); + /* If we read a full record, then assume there may be more + * data to read (stream based sockets only!) + */ + if (len == buflen) + set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); dprintk("svc: socket %p recvfrom(%p, %Zu) = %d\n", svsk, iov[0].iov_base, iov[0].iov_len, len); @@ -980,8 +973,6 @@ static int svc_tcp_recv_record(struct svc_sock *svsk, struct svc_rqst *rqstp) unsigned int want; int len; - clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); - if (svsk->sk_tcplen < sizeof(rpc_fraghdr)) { struct kvec iov; @@ -1073,8 +1064,6 @@ static int copy_pages_to_kvecs(struct kvec *vec, struct page **pages, int len) static void svc_tcp_fragment_received(struct svc_sock *svsk) { /* If we have more data, signal svc_xprt_enqueue() to try again */ - if (svc_recv_available(svsk) > sizeof(rpc_fraghdr)) - set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); dprintk("svc: TCP %s record (%d bytes)\n", svc_sock_final_rec(svsk) ? "final" : "nonfinal", svc_sock_reclen(svsk)); -- GitLab From 7142b98d9fd7cec4e5218869ec547f30068c8daf Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 6 Aug 2014 13:44:20 -0400 Subject: [PATCH 0793/9167] nfsd: Clean up drc cache in preparation for global spinlock elimination Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfsd/nfscache.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index ff9567633245..c74bcd628c4f 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -27,7 +27,11 @@ */ #define TARGET_BUCKET_SIZE 64 -static struct hlist_head * cache_hash; +struct nfsd_drc_bucket { + struct hlist_head cache_hash; +}; + +static struct nfsd_drc_bucket *drc_hashtbl; static struct list_head lru_head; static struct kmem_cache *drc_slab; @@ -116,6 +120,12 @@ nfsd_hashsize(unsigned int limit) return roundup_pow_of_two(limit / TARGET_BUCKET_SIZE); } +static u32 +nfsd_cache_hash(__be32 xid) +{ + return hash_32(be32_to_cpu(xid), maskbits); +} + static struct svc_cacherep * nfsd_reply_cache_alloc(void) { @@ -170,8 +180,8 @@ int nfsd_reply_cache_init(void) if (!drc_slab) goto out_nomem; - cache_hash = kcalloc(hashsize, sizeof(struct hlist_head), GFP_KERNEL); - if (!cache_hash) + drc_hashtbl = kcalloc(hashsize, sizeof(*drc_hashtbl), GFP_KERNEL); + if (!drc_hashtbl) goto out_nomem; return 0; @@ -193,8 +203,8 @@ void nfsd_reply_cache_shutdown(void) nfsd_reply_cache_free_locked(rp); } - kfree (cache_hash); - cache_hash = NULL; + kfree (drc_hashtbl); + drc_hashtbl = NULL; if (drc_slab) { kmem_cache_destroy(drc_slab); @@ -218,15 +228,10 @@ lru_put_end(struct svc_cacherep *rp) * Move a cache entry from one hash list to another */ static void -hash_refile(struct svc_cacherep *rp) +hash_refile(struct nfsd_drc_bucket *b, struct svc_cacherep *rp) { hlist_del_init(&rp->c_hash); - /* - * No point in byte swapping c_xid since we're just using it to pick - * a hash bucket. - */ - hlist_add_head(&rp->c_hash, cache_hash + - hash_32((__force u32)rp->c_xid, maskbits)); + hlist_add_head(&rp->c_hash, &b->cache_hash); } /* @@ -355,17 +360,13 @@ nfsd_cache_match(struct svc_rqst *rqstp, __wsum csum, struct svc_cacherep *rp) * NULL on failure. */ static struct svc_cacherep * -nfsd_cache_search(struct svc_rqst *rqstp, __wsum csum) +nfsd_cache_search(struct nfsd_drc_bucket *b, struct svc_rqst *rqstp, + __wsum csum) { struct svc_cacherep *rp, *ret = NULL; - struct hlist_head *rh; + struct hlist_head *rh = &b->cache_hash; unsigned int entries = 0; - /* - * No point in byte swapping rq_xid since we're just using it to pick - * a hash bucket. - */ - rh = &cache_hash[hash_32((__force u32)rqstp->rq_xid, maskbits)]; hlist_for_each_entry(rp, rh, c_hash) { ++entries; if (nfsd_cache_match(rqstp, csum, rp)) { @@ -403,6 +404,8 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) vers = rqstp->rq_vers, proc = rqstp->rq_proc; __wsum csum; + u32 hash = nfsd_cache_hash(xid); + struct nfsd_drc_bucket *b = &drc_hashtbl[hash]; unsigned long age; int type = rqstp->rq_cachetype; int rtn = RC_DOIT; @@ -429,7 +432,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) /* go ahead and prune the cache */ prune_cache_entries(); - found = nfsd_cache_search(rqstp, csum); + found = nfsd_cache_search(b, rqstp, csum); if (found) { if (likely(rp)) nfsd_reply_cache_free_locked(rp); @@ -454,7 +457,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) rp->c_len = rqstp->rq_arg.len; rp->c_csum = csum; - hash_refile(rp); + hash_refile(b, rp); lru_put_end(rp); /* release any buffer */ -- GitLab From bedd4b61a46d0398192a08fbe6821d1ac65aba84 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 6 Aug 2014 13:44:21 -0400 Subject: [PATCH 0794/9167] nfsd: convert the lru list into a per-bucket thing Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfsd/nfscache.c | 73 +++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index c74bcd628c4f..c01f44eb7fe4 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -29,10 +29,10 @@ struct nfsd_drc_bucket { struct hlist_head cache_hash; + struct list_head lru_head; }; static struct nfsd_drc_bucket *drc_hashtbl; -static struct list_head lru_head; static struct kmem_cache *drc_slab; /* max number of entries allowed in the cache */ @@ -40,6 +40,7 @@ static unsigned int max_drc_entries; /* number of significant bits in the hash value */ static unsigned int maskbits; +static unsigned int drc_hashsize; /* * Stats and other tracking of on the duplicate reply cache. All of these and @@ -167,8 +168,8 @@ nfsd_reply_cache_free(struct svc_cacherep *rp) int nfsd_reply_cache_init(void) { unsigned int hashsize; + unsigned int i; - INIT_LIST_HEAD(&lru_head); max_drc_entries = nfsd_cache_size_limit(); num_drc_entries = 0; hashsize = nfsd_hashsize(max_drc_entries); @@ -183,6 +184,9 @@ int nfsd_reply_cache_init(void) drc_hashtbl = kcalloc(hashsize, sizeof(*drc_hashtbl), GFP_KERNEL); if (!drc_hashtbl) goto out_nomem; + for (i = 0; i < hashsize; i++) + INIT_LIST_HEAD(&drc_hashtbl[i].lru_head); + drc_hashsize = hashsize; return 0; out_nomem: @@ -194,17 +198,22 @@ int nfsd_reply_cache_init(void) void nfsd_reply_cache_shutdown(void) { struct svc_cacherep *rp; + unsigned int i; unregister_shrinker(&nfsd_reply_cache_shrinker); cancel_delayed_work_sync(&cache_cleaner); - while (!list_empty(&lru_head)) { - rp = list_entry(lru_head.next, struct svc_cacherep, c_lru); - nfsd_reply_cache_free_locked(rp); + for (i = 0; i < drc_hashsize; i++) { + struct list_head *head = &drc_hashtbl[i].lru_head; + while (!list_empty(head)) { + rp = list_first_entry(head, struct svc_cacherep, c_lru); + nfsd_reply_cache_free_locked(rp); + } } kfree (drc_hashtbl); drc_hashtbl = NULL; + drc_hashsize = 0; if (drc_slab) { kmem_cache_destroy(drc_slab); @@ -217,10 +226,10 @@ void nfsd_reply_cache_shutdown(void) * not already scheduled. */ static void -lru_put_end(struct svc_cacherep *rp) +lru_put_end(struct nfsd_drc_bucket *b, struct svc_cacherep *rp) { rp->c_timestamp = jiffies; - list_move_tail(&rp->c_lru, &lru_head); + list_move_tail(&rp->c_lru, &b->lru_head); schedule_delayed_work(&cache_cleaner, RC_EXPIRE); } @@ -234,17 +243,13 @@ hash_refile(struct nfsd_drc_bucket *b, struct svc_cacherep *rp) hlist_add_head(&rp->c_hash, &b->cache_hash); } -/* - * Walk the LRU list and prune off entries that are older than RC_EXPIRE. - * Also prune the oldest ones when the total exceeds the max number of entries. - */ static long -prune_cache_entries(void) +prune_bucket(struct nfsd_drc_bucket *b) { struct svc_cacherep *rp, *tmp; long freed = 0; - list_for_each_entry_safe(rp, tmp, &lru_head, c_lru) { + list_for_each_entry_safe(rp, tmp, &b->lru_head, c_lru) { /* * Don't free entries attached to calls that are still * in-progress, but do keep scanning the list. @@ -257,16 +262,33 @@ prune_cache_entries(void) nfsd_reply_cache_free_locked(rp); freed++; } + return freed; +} + +/* + * Walk the LRU list and prune off entries that are older than RC_EXPIRE. + * Also prune the oldest ones when the total exceeds the max number of entries. + */ +static long +prune_cache_entries(void) +{ + unsigned int i; + long freed = 0; + bool cancel = true; + + for (i = 0; i < drc_hashsize; i++) { + struct nfsd_drc_bucket *b = &drc_hashtbl[i]; + + freed += prune_bucket(b); + if (!list_empty(&b->lru_head)) + cancel = false; + } /* - * Conditionally rearm the job. If we cleaned out the list, then - * cancel any pending run (since there won't be any work to do). - * Otherwise, we rearm the job or modify the existing one to run in - * RC_EXPIRE since we just ran the pruner. + * Conditionally rearm the job to run in RC_EXPIRE since we just + * ran the pruner. */ - if (list_empty(&lru_head)) - cancel_delayed_work(&cache_cleaner); - else + if (!cancel) mod_delayed_work(system_wq, &cache_cleaner, RC_EXPIRE); return freed; } @@ -458,7 +480,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) rp->c_csum = csum; hash_refile(b, rp); - lru_put_end(rp); + lru_put_end(b, rp); /* release any buffer */ if (rp->c_type == RC_REPLBUFF) { @@ -475,7 +497,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) nfsdstats.rchits++; /* We found a matching entry which is either in progress or done. */ age = jiffies - rp->c_timestamp; - lru_put_end(rp); + lru_put_end(b, rp); rtn = RC_DROPIT; /* Request being processed or excessive rexmits */ @@ -530,12 +552,17 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) { struct svc_cacherep *rp = rqstp->rq_cacherep; struct kvec *resv = &rqstp->rq_res.head[0], *cachv; + u32 hash; + struct nfsd_drc_bucket *b; int len; size_t bufsize = 0; if (!rp) return; + hash = nfsd_cache_hash(rp->c_xid); + b = &drc_hashtbl[hash]; + len = resv->iov_len - ((char*)statp - (char*)resv->iov_base); len >>= 2; @@ -568,7 +595,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) } spin_lock(&cache_lock); drc_mem_usage += bufsize; - lru_put_end(rp); + lru_put_end(b, rp); rp->c_secure = rqstp->rq_secure; rp->c_type = cachetype; rp->c_state = RC_DONE; -- GitLab From 11acf6ef3b58abd1c5eb94eaa38ed3b9dbc387f7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 6 Aug 2014 13:44:22 -0400 Subject: [PATCH 0795/9167] nfsd: Remove the cache_hash list Now that the lru list is per-bucket, we don't need a second list for searches. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfsd/cache.h | 1 - fs/nfsd/nfscache.c | 19 ++----------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h index b582f9ab6b2a..dd96a3830004 100644 --- a/fs/nfsd/cache.h +++ b/fs/nfsd/cache.h @@ -18,7 +18,6 @@ * is much larger than a sockaddr_in6. */ struct svc_cacherep { - struct hlist_node c_hash; struct list_head c_lru; unsigned char c_state, /* unused, inprog, done */ diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index c01f44eb7fe4..8abec475f80f 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -28,7 +28,6 @@ #define TARGET_BUCKET_SIZE 64 struct nfsd_drc_bucket { - struct hlist_head cache_hash; struct list_head lru_head; }; @@ -137,7 +136,6 @@ nfsd_reply_cache_alloc(void) rp->c_state = RC_UNUSED; rp->c_type = RC_NOCACHE; INIT_LIST_HEAD(&rp->c_lru); - INIT_HLIST_NODE(&rp->c_hash); } return rp; } @@ -149,8 +147,6 @@ nfsd_reply_cache_free_locked(struct svc_cacherep *rp) drc_mem_usage -= rp->c_replvec.iov_len; kfree(rp->c_replvec.iov_base); } - if (!hlist_unhashed(&rp->c_hash)) - hlist_del(&rp->c_hash); list_del(&rp->c_lru); --num_drc_entries; drc_mem_usage -= sizeof(*rp); @@ -233,16 +229,6 @@ lru_put_end(struct nfsd_drc_bucket *b, struct svc_cacherep *rp) schedule_delayed_work(&cache_cleaner, RC_EXPIRE); } -/* - * Move a cache entry from one hash list to another - */ -static void -hash_refile(struct nfsd_drc_bucket *b, struct svc_cacherep *rp) -{ - hlist_del_init(&rp->c_hash); - hlist_add_head(&rp->c_hash, &b->cache_hash); -} - static long prune_bucket(struct nfsd_drc_bucket *b) { @@ -386,10 +372,10 @@ nfsd_cache_search(struct nfsd_drc_bucket *b, struct svc_rqst *rqstp, __wsum csum) { struct svc_cacherep *rp, *ret = NULL; - struct hlist_head *rh = &b->cache_hash; + struct list_head *rh = &b->lru_head; unsigned int entries = 0; - hlist_for_each_entry(rp, rh, c_hash) { + list_for_each_entry(rp, rh, c_lru) { ++entries; if (nfsd_cache_match(rqstp, csum, rp)) { ret = rp; @@ -479,7 +465,6 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) rp->c_len = rqstp->rq_arg.len; rp->c_csum = csum; - hash_refile(b, rp); lru_put_end(b, rp); /* release any buffer */ -- GitLab From 31e60f52224197dc989a82237905dfe643183f7c Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 6 Aug 2014 13:44:23 -0400 Subject: [PATCH 0796/9167] nfsd: convert num_drc_entries to an atomic_t ...so we can remove the spinlocking around it. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfsd/nfscache.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 8abec475f80f..dc909091349b 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -47,7 +47,7 @@ static unsigned int drc_hashsize; */ /* total number of entries */ -static unsigned int num_drc_entries; +static atomic_t num_drc_entries; /* cache misses due only to checksum comparison failures */ static unsigned int payload_misses; @@ -148,7 +148,7 @@ nfsd_reply_cache_free_locked(struct svc_cacherep *rp) kfree(rp->c_replvec.iov_base); } list_del(&rp->c_lru); - --num_drc_entries; + atomic_dec(&num_drc_entries); drc_mem_usage -= sizeof(*rp); kmem_cache_free(drc_slab, rp); } @@ -167,7 +167,7 @@ int nfsd_reply_cache_init(void) unsigned int i; max_drc_entries = nfsd_cache_size_limit(); - num_drc_entries = 0; + atomic_set(&num_drc_entries, 0); hashsize = nfsd_hashsize(max_drc_entries); maskbits = ilog2(hashsize); @@ -242,7 +242,7 @@ prune_bucket(struct nfsd_drc_bucket *b) */ if (rp->c_state == RC_INPROG) continue; - if (num_drc_entries <= max_drc_entries && + if (atomic_read(&num_drc_entries) <= max_drc_entries && time_before(jiffies, rp->c_timestamp + RC_EXPIRE)) break; nfsd_reply_cache_free_locked(rp); @@ -290,13 +290,7 @@ cache_cleaner_func(struct work_struct *unused) static unsigned long nfsd_reply_cache_count(struct shrinker *shrink, struct shrink_control *sc) { - unsigned long num; - - spin_lock(&cache_lock); - num = num_drc_entries; - spin_unlock(&cache_lock); - - return num; + return atomic_read(&num_drc_entries); } static unsigned long @@ -386,11 +380,12 @@ nfsd_cache_search(struct nfsd_drc_bucket *b, struct svc_rqst *rqstp, /* tally hash chain length stats */ if (entries > longest_chain) { longest_chain = entries; - longest_chain_cachesize = num_drc_entries; + longest_chain_cachesize = atomic_read(&num_drc_entries); } else if (entries == longest_chain) { /* prefer to keep the smallest cachesize possible here */ - longest_chain_cachesize = min(longest_chain_cachesize, - num_drc_entries); + longest_chain_cachesize = min_t(unsigned int, + longest_chain_cachesize, + atomic_read(&num_drc_entries)); } return ret; @@ -433,7 +428,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) rp = nfsd_reply_cache_alloc(); spin_lock(&cache_lock); if (likely(rp)) { - ++num_drc_entries; + atomic_inc(&num_drc_entries); drc_mem_usage += sizeof(*rp); } @@ -617,7 +612,8 @@ static int nfsd_reply_cache_stats_show(struct seq_file *m, void *v) { spin_lock(&cache_lock); seq_printf(m, "max entries: %u\n", max_drc_entries); - seq_printf(m, "num entries: %u\n", num_drc_entries); + seq_printf(m, "num entries: %u\n", + atomic_read(&num_drc_entries)); seq_printf(m, "hash buckets: %u\n", 1 << maskbits); seq_printf(m, "mem usage: %u\n", drc_mem_usage); seq_printf(m, "cache hits: %u\n", nfsdstats.rchits); -- GitLab From 89a26b3d295d35fefcc994cb0cf3817d0ff432d5 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 6 Aug 2014 13:44:24 -0400 Subject: [PATCH 0797/9167] nfsd: split DRC global spinlock into per-bucket locks Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfsd/nfscache.c | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index dc909091349b..74603654b7f9 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -29,6 +29,7 @@ struct nfsd_drc_bucket { struct list_head lru_head; + spinlock_t cache_lock; }; static struct nfsd_drc_bucket *drc_hashtbl; @@ -79,7 +80,6 @@ static struct shrinker nfsd_reply_cache_shrinker = { * A cache entry is "single use" if c_state == RC_INPROG * Otherwise, it when accessing _prev or _next, the lock must be held. */ -static DEFINE_SPINLOCK(cache_lock); static DECLARE_DELAYED_WORK(cache_cleaner, cache_cleaner_func); /* @@ -154,11 +154,11 @@ nfsd_reply_cache_free_locked(struct svc_cacherep *rp) } static void -nfsd_reply_cache_free(struct svc_cacherep *rp) +nfsd_reply_cache_free(struct nfsd_drc_bucket *b, struct svc_cacherep *rp) { - spin_lock(&cache_lock); + spin_lock(&b->cache_lock); nfsd_reply_cache_free_locked(rp); - spin_unlock(&cache_lock); + spin_unlock(&b->cache_lock); } int nfsd_reply_cache_init(void) @@ -180,8 +180,10 @@ int nfsd_reply_cache_init(void) drc_hashtbl = kcalloc(hashsize, sizeof(*drc_hashtbl), GFP_KERNEL); if (!drc_hashtbl) goto out_nomem; - for (i = 0; i < hashsize; i++) + for (i = 0; i < hashsize; i++) { INIT_LIST_HEAD(&drc_hashtbl[i].lru_head); + spin_lock_init(&drc_hashtbl[i].cache_lock); + } drc_hashsize = hashsize; return 0; @@ -265,9 +267,13 @@ prune_cache_entries(void) for (i = 0; i < drc_hashsize; i++) { struct nfsd_drc_bucket *b = &drc_hashtbl[i]; + if (list_empty(&b->lru_head)) + continue; + spin_lock(&b->cache_lock); freed += prune_bucket(b); if (!list_empty(&b->lru_head)) cancel = false; + spin_unlock(&b->cache_lock); } /* @@ -282,9 +288,7 @@ prune_cache_entries(void) static void cache_cleaner_func(struct work_struct *unused) { - spin_lock(&cache_lock); prune_cache_entries(); - spin_unlock(&cache_lock); } static unsigned long @@ -296,12 +300,7 @@ nfsd_reply_cache_count(struct shrinker *shrink, struct shrink_control *sc) static unsigned long nfsd_reply_cache_scan(struct shrinker *shrink, struct shrink_control *sc) { - unsigned long freed; - - spin_lock(&cache_lock); - freed = prune_cache_entries(); - spin_unlock(&cache_lock); - return freed; + return prune_cache_entries(); } /* * Walk an xdr_buf and get a CRC for at most the first RC_CSUMLEN bytes @@ -426,14 +425,14 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) * preallocate an entry. */ rp = nfsd_reply_cache_alloc(); - spin_lock(&cache_lock); + spin_lock(&b->cache_lock); if (likely(rp)) { atomic_inc(&num_drc_entries); drc_mem_usage += sizeof(*rp); } /* go ahead and prune the cache */ - prune_cache_entries(); + prune_bucket(b); found = nfsd_cache_search(b, rqstp, csum); if (found) { @@ -470,7 +469,7 @@ nfsd_cache_lookup(struct svc_rqst *rqstp) } rp->c_type = RC_NOCACHE; out: - spin_unlock(&cache_lock); + spin_unlock(&b->cache_lock); return rtn; found_entry: @@ -548,7 +547,7 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) /* Don't cache excessive amounts of data and XDR failures */ if (!statp || len > (256 >> 2)) { - nfsd_reply_cache_free(rp); + nfsd_reply_cache_free(b, rp); return; } @@ -563,23 +562,23 @@ nfsd_cache_update(struct svc_rqst *rqstp, int cachetype, __be32 *statp) bufsize = len << 2; cachv->iov_base = kmalloc(bufsize, GFP_KERNEL); if (!cachv->iov_base) { - nfsd_reply_cache_free(rp); + nfsd_reply_cache_free(b, rp); return; } cachv->iov_len = bufsize; memcpy(cachv->iov_base, statp, bufsize); break; case RC_NOCACHE: - nfsd_reply_cache_free(rp); + nfsd_reply_cache_free(b, rp); return; } - spin_lock(&cache_lock); + spin_lock(&b->cache_lock); drc_mem_usage += bufsize; lru_put_end(b, rp); rp->c_secure = rqstp->rq_secure; rp->c_type = cachetype; rp->c_state = RC_DONE; - spin_unlock(&cache_lock); + spin_unlock(&b->cache_lock); return; } @@ -610,7 +609,6 @@ nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *data) */ static int nfsd_reply_cache_stats_show(struct seq_file *m, void *v) { - spin_lock(&cache_lock); seq_printf(m, "max entries: %u\n", max_drc_entries); seq_printf(m, "num entries: %u\n", atomic_read(&num_drc_entries)); @@ -622,7 +620,6 @@ static int nfsd_reply_cache_stats_show(struct seq_file *m, void *v) seq_printf(m, "payload misses: %u\n", payload_misses); seq_printf(m, "longest chain len: %u\n", longest_chain); seq_printf(m, "cachesize at longest: %u\n", longest_chain_cachesize); - spin_unlock(&cache_lock); return 0; } -- GitLab From ef9b16dc6de692865e898a35e750119b5b9c82c5 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 6 Aug 2014 13:44:25 -0400 Subject: [PATCH 0798/9167] nfsd: Reorder nfsd_cache_match to check more powerful discriminators first We would normally expect the xid and the checksum to be the best discriminators. Check them before looking at the procedure number, etc. Signed-off-by: Trond Myklebust Signed-off-by: J. Bruce Fields --- fs/nfsd/nfscache.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 74603654b7f9..122f69185ef5 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c @@ -338,20 +338,24 @@ nfsd_cache_csum(struct svc_rqst *rqstp) static bool nfsd_cache_match(struct svc_rqst *rqstp, __wsum csum, struct svc_cacherep *rp) { - /* Check RPC header info first */ - if (rqstp->rq_xid != rp->c_xid || rqstp->rq_proc != rp->c_proc || - rqstp->rq_prot != rp->c_prot || rqstp->rq_vers != rp->c_vers || - rqstp->rq_arg.len != rp->c_len || - !rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) || - rpc_get_port(svc_addr(rqstp)) != rpc_get_port((struct sockaddr *)&rp->c_addr)) + /* Check RPC XID first */ + if (rqstp->rq_xid != rp->c_xid) return false; - /* compare checksum of NFS data */ if (csum != rp->c_csum) { ++payload_misses; return false; } + /* Other discriminators */ + if (rqstp->rq_proc != rp->c_proc || + rqstp->rq_prot != rp->c_prot || + rqstp->rq_vers != rp->c_vers || + rqstp->rq_arg.len != rp->c_len || + !rpc_cmp_addr(svc_addr(rqstp), (struct sockaddr *)&rp->c_addr) || + rpc_get_port(svc_addr(rqstp)) != rpc_get_port((struct sockaddr *)&rp->c_addr)) + return false; + return true; } -- GitLab From 6bcc034eac79873468cdfd1ccea9f25ee67c4500 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Sat, 9 Aug 2014 10:22:40 -0400 Subject: [PATCH 0799/9167] nfsd: protect lease-related nfs4_file fields with fi_lock Currently these fields are protected with the state_lock, but that doesn't really make a lot of sense. These fields are "private" to the nfs4_file, and can be protected with the more granular fi_lock. The fi_lock is already held when setting these fields. Make the code hold the fp->fi_lock when clearing the lease-related fields in the nfs4_file, and no longer require that the state_lock be held when calling into this function. To prevent lock inversion with the i_lock, we also move the vfs_setlease and fput calls outside of the fi_lock. This also sets us up for allowing vfs_setlease calls to block in the future. Finally, remove a redundant NULL pointer check. unhash_delegation_locked locks the fp->fi_lock prior to that check, so fp in that function must never be NULL. Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2e80a59e7e91..309ec3b1090a 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -673,15 +673,20 @@ nfs4_put_stid(struct nfs4_stid *s) static void nfs4_put_deleg_lease(struct nfs4_file *fp) { - lockdep_assert_held(&state_lock); + struct file *filp = NULL; + struct file_lock *fl; - if (!fp->fi_lease) - return; - if (atomic_dec_and_test(&fp->fi_delegees)) { - vfs_setlease(fp->fi_deleg_file, F_UNLCK, &fp->fi_lease); + spin_lock(&fp->fi_lock); + if (fp->fi_lease && atomic_dec_and_test(&fp->fi_delegees)) { + swap(filp, fp->fi_deleg_file); + fl = fp->fi_lease; fp->fi_lease = NULL; - fput(fp->fi_deleg_file); - fp->fi_deleg_file = NULL; + } + spin_unlock(&fp->fi_lock); + + if (filp) { + vfs_setlease(filp, F_UNLCK, &fl); + fput(filp); } } @@ -717,8 +722,7 @@ unhash_delegation_locked(struct nfs4_delegation *dp) list_del_init(&dp->dl_recall_lru); list_del_init(&dp->dl_perfile); spin_unlock(&fp->fi_lock); - if (fp) - nfs4_put_deleg_lease(fp); + nfs4_put_deleg_lease(fp); } static void destroy_delegation(struct nfs4_delegation *dp) -- GitLab From afbda402a02bde74f350ff98243265dfd3108fb3 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Sat, 9 Aug 2014 10:22:41 -0400 Subject: [PATCH 0800/9167] nfsd: call nfs4_put_deleg_lease outside of state_lock Currently, we hold the state_lock when releasing the lease. That's potentially problematic in the future if we allow for setlease methods that can sleep. Move the nfs4_put_deleg_lease call out of the delegation unhashing routine (which was always a bit goofy anyway), and into the unlocked sections of the callers of unhash_delegation_locked. Signed-off-by: Jeff Layton Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 309ec3b1090a..4356d32479b2 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -722,7 +722,6 @@ unhash_delegation_locked(struct nfs4_delegation *dp) list_del_init(&dp->dl_recall_lru); list_del_init(&dp->dl_perfile); spin_unlock(&fp->fi_lock); - nfs4_put_deleg_lease(fp); } static void destroy_delegation(struct nfs4_delegation *dp) @@ -730,6 +729,7 @@ static void destroy_delegation(struct nfs4_delegation *dp) spin_lock(&state_lock); unhash_delegation_locked(dp); spin_unlock(&state_lock); + nfs4_put_deleg_lease(dp->dl_stid.sc_file); nfs4_put_stid(&dp->dl_stid); } @@ -739,6 +739,8 @@ static void revoke_delegation(struct nfs4_delegation *dp) WARN_ON(!list_empty(&dp->dl_recall_lru)); + nfs4_put_deleg_lease(dp->dl_stid.sc_file); + if (clp->cl_minorversion == 0) nfs4_put_stid(&dp->dl_stid); else { @@ -1639,6 +1641,7 @@ __destroy_client(struct nfs4_client *clp) while (!list_empty(&reaplist)) { dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru); list_del_init(&dp->dl_recall_lru); + nfs4_put_deleg_lease(dp->dl_stid.sc_file); nfs4_put_stid(&dp->dl_stid); } while (!list_empty(&clp->cl_revoked)) { @@ -6406,6 +6409,7 @@ nfs4_state_shutdown_net(struct net *net) list_for_each_safe(pos, next, &reaplist) { dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru); list_del_init(&dp->dl_recall_lru); + nfs4_put_deleg_lease(dp->dl_stid.sc_file); nfs4_put_stid(&dp->dl_stid); } -- GitLab From 63bab0651be0ba857200219a08644e6a99f448b6 Mon Sep 17 00:00:00 2001 From: Ross Lagerwall Date: Sat, 9 Aug 2014 14:44:00 +0100 Subject: [PATCH 0801/9167] nfsd3: Check write permission after checking existence When creating a file that already exists in a read-only directory with O_EXCL, the NFSv3 server returns EACCES rather than EEXIST (which local files and the NFSv4 server return). Fix this by checking the MAY_CREATE permission only if the file does not exist. Since this already happens in do_nfsd_create, the check in nfsd3_proc_create can simply be removed. Signed-off-by: Ross Lagerwall Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs3proc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index fa2525b2e9d7..fc51f7f6b36d 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -223,11 +223,6 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, newfhp = fh_init(&resp->fh, NFS3_FHSIZE); attr = &argp->attrs; - /* Get the directory inode */ - nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, NFSD_MAY_CREATE); - if (nfserr) - RETURN_STATUS(nfserr); - /* Unfudge the mode bits */ attr->ia_mode &= ~S_IFMT; if (!(attr->ia_valid & ATTR_MODE)) { -- GitLab From 1383bf37ce2554d7632f21ee03f3ea815edaf933 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 11 Aug 2014 16:41:05 -0400 Subject: [PATCH 0802/9167] nfsd4: remove obsolete comment We do what Neil suggests now. Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f9821ce6658a..8112ce8f4b23 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -31,13 +31,6 @@ * 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. - * - * TODO: Neil Brown made the following observation: We currently - * initially reserve NFSD_BUFSIZE space on the transmit queue and - * never release any of that until the request is complete. - * It would be good to calculate a new maximum response size while - * decoding the COMPOUND, and call svc_reserve with this number - * at the end of nfs4svc_decode_compoundargs. */ #include -- GitLab From f7b43d0c992c3ec3e8d9285c3fb5e1e0eb0d031a Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 12 Aug 2014 11:41:40 -0400 Subject: [PATCH 0803/9167] nfsd4: reserve adequate space for LOCK op As of 8c7424cff6 "nfsd4: don't try to encode conflicting owner if low on space", we permit the server to process a LOCK operation even if there might not be space to return the conflicting lockowner, because we've made returning the conflicting lockowner optional. However, the rpc server still wants to know the most we might possibly return, so we need to take into account the possible conflicting lockowner in the svc_reserve_space() call here. Symptoms were log messages like "RPC request reserved 88 but used 108". Fixes: 8c7424cff6 "nfsd4: don't try to encode conflicting owner if low on space" Reported-by: Kinglong Mee Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8112ce8f4b23..e771a1a7c6f1 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1663,6 +1663,14 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp) readbytes += nfsd4_max_reply(argp->rqstp, op); } else max_reply += nfsd4_max_reply(argp->rqstp, op); + /* + * OP_LOCK may return a conflicting lock. (Special case + * because it will just skip encoding this if it runs + * out of xdr buffer space, and it is the only operation + * that behaves this way.) + */ + if (op->opnum == OP_LOCK) + max_reply += NFS4_OPAQUE_LIMIT; if (op->status) { argp->opcnt = i+1; -- GitLab From 6b2eb32e697d151ebaf52f9b0304d16f63a27b43 Mon Sep 17 00:00:00 2001 From: Nathaniel Clark Date: Fri, 15 Aug 2014 12:48:06 -0400 Subject: [PATCH 0804/9167] staging/lustre/llite: check for integer overflow in hsm user request Check to make sure total size of request does not overflow when calculated. Return -1 from hur_len() if it does overflow. Signed-off-by: Nathaniel Clark Reviewed-on: http://review.whamcloud.com/10615 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4984 Reviewed-by: Andreas Dilger Reviewed-by: John L. Hammond Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/include/lustre/lustre_user.h | 23 +++++++++++++++---- drivers/staging/lustre/lustre/llite/dir.c | 4 +++- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h index a69b27a78042..4c1b3cba77ba 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_user.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_user.h @@ -997,12 +997,25 @@ static inline void *hur_data(struct hsm_user_request *hur) return &(hur->hur_user_item[hur->hur_request.hr_itemcount]); } -/** Compute the current length of the provided hsm_user_request. */ -static inline int hur_len(struct hsm_user_request *hur) +/** + * Compute the current length of the provided hsm_user_request. This returns -1 + * instead of an errno because ssize_t is defined to be only [ -1, SSIZE_MAX ] + * + * return -1 on bounds check error. + */ +static inline ssize_t hur_len(struct hsm_user_request *hur) { - return offsetof(struct hsm_user_request, - hur_user_item[hur->hur_request.hr_itemcount]) + - hur->hur_request.hr_data_len; + __u64 size; + + /* can't overflow a __u64 since hr_itemcount is only __u32 */ + size = offsetof(struct hsm_user_request, hur_user_item[0]) + + (__u64)hur->hur_request.hr_itemcount * + sizeof(hur->hur_user_item[0]) + hur->hur_request.hr_data_len; + + if (size != (ssize_t)size) + return -1; + + return size; } /****** HSM RPCs to copytool *****/ diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index efa2faf080d7..de5892c5e7d6 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -1787,7 +1787,7 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return ll_fid2path(inode, (void *)arg); case LL_IOC_HSM_REQUEST: { struct hsm_user_request *hur; - int totalsize; + ssize_t totalsize; OBD_ALLOC_PTR(hur); if (hur == NULL) @@ -1802,6 +1802,8 @@ static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) /* Compute the whole struct size */ totalsize = hur_len(hur); OBD_FREE_PTR(hur); + if (totalsize < 0) + return -E2BIG; /* Final size will be more than double totalsize */ if (totalsize >= MDS_MAXREQSIZE / 3) -- GitLab From 7591805af511b7f71fec87c69a539d1d0cfb93a1 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Fri, 15 Aug 2014 12:48:07 -0400 Subject: [PATCH 0805/9167] staging/lustre/mdc: cleanup intent if mdc_finish_enqueue() fails In mdc_enqueue() clear the lock handle, lock mode, and request stored in the lookup intent if mdc_finish_enqueue() fails. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/10963 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5289 Reviewed-by: Lai Siyao Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index c64a38eaee3e..d02bf313d591 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -944,7 +944,12 @@ int mdc_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, memset(lockh, 0, sizeof(*lockh)); } ptlrpc_req_finished(req); + + it->d.lustre.it_lock_handle = 0; + it->d.lustre.it_lock_mode = 0; + it->d.lustre.it_data = NULL; } + return rc; } -- GitLab From 6aa5107281ea065b9a7818a1c640e022d41a421b Mon Sep 17 00:00:00 2001 From: Paul Cassella Date: Fri, 15 Aug 2014 12:48:08 -0400 Subject: [PATCH 0806/9167] staging/lustre/llite: Make sure ft_flags is valid In ll_fault0, the 'fault' struct is mostly cleared before the call to cl_io_loop, but ft_flags is not reset. It is ordinarily set by the call to filemap_fault in vvp_io_kernel_fault, but if Lustre returns before calling filemap_fault, it still has the old value of ft_flags. ll_fault0 will then consume the ft_flags field. If it has the VM_FAULT_RETRY bit set, it will be used as ll_fault0() and ll_fault()'s return value. This is a problem when VM_FAULT_RETRY is in ft_flags: When fault/filemap_fault return with that flag set, they have already released the mmap semaphore, and do_page_fault does not need to release it. Incorrectly returning this flag from ll_fault means mmap_sem is not upped in the kernel's do_page_fault(). In addition to clearing ft_flags, this patch does not use it unless it is valid. It's potentially misleading to return ft_flags in "fault_ret" if ft_flags has not been set by filemap_fault. This adds clarity, but does not change the current behavior: When not valid, ft_flags is replaced by fault_ret, which is zero, as is ft_flags when not set by filemap_fault. Signed-off-by: Patrick Farrell Reviewed-on: http://review.whamcloud.com/10956 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5291 Reviewed-by: Bobi Jam Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/llite_internal.h | 4 ++++ drivers/staging/lustre/lustre/llite/llite_mmap.c | 8 +++++++- drivers/staging/lustre/lustre/llite/vvp_io.c | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 634ffa645e06..684405e26b58 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -894,6 +894,10 @@ struct vvp_io { * fault API used bitflags for return code. */ unsigned int ft_flags; + /** + * check that flags are from filemap_fault + */ + bool ft_flags_valid; } fault; } fault; } u; diff --git a/drivers/staging/lustre/lustre/llite/llite_mmap.c b/drivers/staging/lustre/lustre/llite/llite_mmap.c index 7dae610f5c86..59166481e1a2 100644 --- a/drivers/staging/lustre/lustre/llite/llite_mmap.c +++ b/drivers/staging/lustre/lustre/llite/llite_mmap.c @@ -310,10 +310,16 @@ static int ll_fault0(struct vm_area_struct *vma, struct vm_fault *vmf) vio->u.fault.ft_vma = vma; vio->u.fault.ft_vmpage = NULL; vio->u.fault.fault.ft_vmf = vmf; + vio->u.fault.fault.ft_flags = 0; + vio->u.fault.fault.ft_flags_valid = 0; result = cl_io_loop(env, io); - fault_ret = vio->u.fault.fault.ft_flags; + /* ft_flags are only valid if we reached + * the call to filemap_fault */ + if (vio->u.fault.fault.ft_flags_valid) + fault_ret = vio->u.fault.fault.ft_flags; + vmpage = vio->u.fault.ft_vmpage; if (result != 0 && vmpage != NULL) { page_cache_release(vmpage); diff --git a/drivers/staging/lustre/lustre/llite/vvp_io.c b/drivers/staging/lustre/lustre/llite/vvp_io.c index a4117d6a3866..fd248745cbff 100644 --- a/drivers/staging/lustre/lustre/llite/vvp_io.c +++ b/drivers/staging/lustre/lustre/llite/vvp_io.c @@ -615,6 +615,7 @@ static int vvp_io_kernel_fault(struct vvp_fault_io *cfio) struct vm_fault *vmf = cfio->fault.ft_vmf; cfio->fault.ft_flags = filemap_fault(cfio->ft_vma, vmf); + cfio->fault.ft_flags_valid = 1; if (vmf->page) { CDEBUG(D_PAGE, -- GitLab From f261f48a39dd3349e5980cdc40604d78ea587ffc Mon Sep 17 00:00:00 2001 From: Fan Yong Date: Fri, 15 Aug 2014 12:48:09 -0400 Subject: [PATCH 0807/9167] staging/lustre/ldlm: drop redundant ibits lock interoperability check In very old release (older than Lustre-1.8), if the client talks with the server that does not support ibits lock, then the client needs to convert it as plain lock. Such interoperability check and convertion is out of date for a long time. Drop it. Signed-off-by: Fan Yong Reviewed-on: http://review.whamcloud.com/11004 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4971 Reviewed-by: Andreas Dilger Reviewed-by: wangdi Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../lustre/lustre/include/obd_support.h | 1 + .../staging/lustre/lustre/ldlm/ldlm_lock.c | 50 +++---------------- .../staging/lustre/lustre/ldlm/ldlm_request.c | 15 +----- drivers/staging/lustre/lustre/ptlrpc/import.c | 15 ++++-- 4 files changed, 19 insertions(+), 62 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd_support.h b/drivers/staging/lustre/lustre/include/obd_support.h index 92c89925ff67..874606a45cc1 100644 --- a/drivers/staging/lustre/lustre/include/obd_support.h +++ b/drivers/staging/lustre/lustre/include/obd_support.h @@ -402,6 +402,7 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, #define OBD_FAIL_TGT_LAST_REPLAY 0x710 #define OBD_FAIL_TGT_CLIENT_ADD 0x711 #define OBD_FAIL_TGT_RCVG_FLAG 0x712 +#define OBD_FAIL_TGT_DELAY_CONDITIONAL 0x713 #define OBD_FAIL_MDC_REVALIDATE_PAUSE 0x800 #define OBD_FAIL_MDC_ENQUEUE_PAUSE 0x801 diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c index d022666fb705..3143222d162f 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_lock.c @@ -613,50 +613,12 @@ EXPORT_SYMBOL(__ldlm_handle2lock); */ void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc) { - struct obd_export *exp = lock->l_export ?: lock->l_conn_export; - - /* INODEBITS_INTEROP: If the other side does not support - * inodebits, reply with a plain lock descriptor. */ - if ((lock->l_resource->lr_type == LDLM_IBITS) && - (exp && !(exp_connect_flags(exp) & OBD_CONNECT_IBITS))) { - /* Make sure all the right bits are set in this lock we - are going to pass to client */ - LASSERTF(lock->l_policy_data.l_inodebits.bits == - (MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE | - MDS_INODELOCK_LAYOUT), - "Inappropriate inode lock bits during conversion %llu\n", - lock->l_policy_data.l_inodebits.bits); - - ldlm_res2desc(lock->l_resource, &desc->l_resource); - desc->l_resource.lr_type = LDLM_PLAIN; - - /* Convert "new" lock mode to something old client can - understand */ - if ((lock->l_req_mode == LCK_CR) || - (lock->l_req_mode == LCK_CW)) - desc->l_req_mode = LCK_PR; - else - desc->l_req_mode = lock->l_req_mode; - if ((lock->l_granted_mode == LCK_CR) || - (lock->l_granted_mode == LCK_CW)) { - desc->l_granted_mode = LCK_PR; - } else { - /* We never grant PW/EX locks to clients */ - LASSERT((lock->l_granted_mode != LCK_PW) && - (lock->l_granted_mode != LCK_EX)); - desc->l_granted_mode = lock->l_granted_mode; - } - - /* We do not copy policy here, because there is no - policy for plain locks */ - } else { - ldlm_res2desc(lock->l_resource, &desc->l_resource); - desc->l_req_mode = lock->l_req_mode; - desc->l_granted_mode = lock->l_granted_mode; - ldlm_convert_policy_to_wire(lock->l_resource->lr_type, - &lock->l_policy_data, - &desc->l_policy_data); - } + ldlm_res2desc(lock->l_resource, &desc->l_resource); + desc->l_req_mode = lock->l_req_mode; + desc->l_granted_mode = lock->l_granted_mode; + ldlm_convert_policy_to_wire(lock->l_resource->lr_type, + &lock->l_policy_data, + &desc->l_policy_data); } EXPORT_SYMBOL(ldlm_lock2desc); diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c index 8867dc175325..37b86082eb73 100644 --- a/drivers/staging/lustre/lustre/ldlm/ldlm_request.c +++ b/drivers/staging/lustre/lustre/ldlm/ldlm_request.c @@ -876,21 +876,8 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp, /* for the local lock, add the reference */ ldlm_lock_addref_internal(lock, einfo->ei_mode); ldlm_lock2handle(lock, lockh); - if (policy != NULL) { - /* INODEBITS_INTEROP: If the server does not support - * inodebits, we will request a plain lock in the - * descriptor (ldlm_lock2desc() below) but use an - * inodebits lock internally with both bits set. - */ - if (einfo->ei_type == LDLM_IBITS && - !(exp_connect_flags(exp) & - OBD_CONNECT_IBITS)) - lock->l_policy_data.l_inodebits.bits = - MDS_INODELOCK_LOOKUP | - MDS_INODELOCK_UPDATE; - else + if (policy != NULL) lock->l_policy_data = *policy; - } if (einfo->ei_type == LDLM_EXTENT) lock->l_req_extent = policy->l_extent; diff --git a/drivers/staging/lustre/lustre/ptlrpc/import.c b/drivers/staging/lustre/lustre/ptlrpc/import.c index f522fc5d3a93..771b213b17ae 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/import.c +++ b/drivers/staging/lustre/lustre/ptlrpc/import.c @@ -1024,10 +1024,17 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, spin_unlock(&imp->imp_lock); - if (!ocd->ocd_ibits_known && - ocd->ocd_connect_flags & OBD_CONNECT_IBITS) - CERROR("Inodebits aware server returned zero compatible" - " bits?\n"); + 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", + imp->imp_obd->obd_name, + imp->imp_connection->c_remote_uuid.uuid, + imp->imp_connect_flags_orig, + ocd->ocd_connect_flags); + GOTO(out, rc = -EPROTO); + } if ((ocd->ocd_connect_flags & OBD_CONNECT_VERSION) && (ocd->ocd_version > LUSTRE_VERSION_CODE + -- GitLab From f7acd3376387dbf55f76cc77e7dbc870c2719aff Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Fri, 15 Aug 2014 12:48:10 -0400 Subject: [PATCH 0808/9167] staging/lustre/clio: reorder initialization in cl_req_alloc() In cl_req_alloc() ensure that the list heads crq_pages and crq_layers have been initialized before passing the request to cl_req_completion(). This fixes an oops in the error path. Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/11009 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5290 Reviewed-by: Bobi Jam Reviewed-by: Jinshan Xiong Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/obdclass/cl_io.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 6870ee823736..4265821b8e09 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -1452,12 +1452,13 @@ struct cl_req *cl_req_alloc(const struct lu_env *env, struct cl_page *page, if (req != NULL) { int result; + req->crq_type = crt; + INIT_LIST_HEAD(&req->crq_pages); + INIT_LIST_HEAD(&req->crq_layers); + OBD_ALLOC(req->crq_o, nr_objects * sizeof(req->crq_o[0])); if (req->crq_o != NULL) { req->crq_nrobjs = nr_objects; - req->crq_type = crt; - INIT_LIST_HEAD(&req->crq_pages); - INIT_LIST_HEAD(&req->crq_layers); result = cl_req_init(env, req, page); } else result = -ENOMEM; -- GitLab From b6ee56fe2afe10cf855de8d11b6097fa82c26163 Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Fri, 15 Aug 2014 12:48:11 -0400 Subject: [PATCH 0809/9167] staging/lustre/llite: hold inode mutex around ll_setattr_raw() ll_setattr_raw() expects to be called with the inode mutex held so do when calling it from ll_hsm_import(). Signed-off-by: John L. Hammond Reviewed-on: http://review.whamcloud.com/11349 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5456 Reviewed-by: Jinshan Xiong Reviewed-by: Faccini Bruno Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index fd1b75a3a569..084fb9206fd5 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -2116,10 +2116,14 @@ static int ll_hsm_import(struct inode *inode, struct file *file, ATTR_MTIME | ATTR_MTIME_SET | ATTR_ATIME | ATTR_ATIME_SET; + mutex_lock(&inode->i_mutex); + rc = ll_setattr_raw(file->f_dentry, attr, true); if (rc == -ENODATA) rc = 0; + mutex_unlock(&inode->i_mutex); + out: if (hss != NULL) OBD_FREE_PTR(hss); -- GitLab From 2b358b4ea5b2912726d872611089e790a8388b62 Mon Sep 17 00:00:00 2001 From: Frank Zago Date: Fri, 15 Aug 2014 12:48:12 -0400 Subject: [PATCH 0810/9167] staging/lustre/llite: optimize ll_fid2path() The only parameter from userspace that matters is the length of the buffer. We don't need to allocate then import the whole structure. By importing only that length, we can save a memory allocation. Add sparse annotations to that function. Signed-off-by: frank zago Reviewed-on: http://review.whamcloud.com/11167 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5389 Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 34 +++++++++---------- .../lustre/lustre/llite/llite_internal.h | 2 +- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 084fb9206fd5..d3874e1afba8 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1702,37 +1702,35 @@ static int ll_do_fiemap(struct inode *inode, struct ll_user_fiemap *fiemap, return rc; } -int ll_fid2path(struct inode *inode, void *arg) +int ll_fid2path(struct inode *inode, void __user *arg) { - struct obd_export *exp = ll_i2mdexp(inode); - struct getinfo_fid2path *gfout, *gfin; - int outsize, rc; + struct obd_export *exp = ll_i2mdexp(inode); + const struct getinfo_fid2path __user *gfin = arg; + struct getinfo_fid2path *gfout; + u32 pathlen; + size_t outsize; + int rc; if (!capable(CFS_CAP_DAC_READ_SEARCH) && !(ll_i2sbi(inode)->ll_flags & LL_SBI_USER_FID2PATH)) return -EPERM; - /* Need to get the buflen */ - OBD_ALLOC_PTR(gfin); - if (gfin == NULL) - return -ENOMEM; - if (copy_from_user(gfin, arg, sizeof(*gfin))) { - OBD_FREE_PTR(gfin); + /* Only need to get the buflen */ + if (get_user(pathlen, &gfin->gf_pathlen)) return -EFAULT; - } - outsize = sizeof(*gfout) + gfin->gf_pathlen; + outsize = sizeof(*gfout) + pathlen; + OBD_ALLOC(gfout, outsize); - if (gfout == NULL) { - OBD_FREE_PTR(gfin); + if (gfout == NULL) return -ENOMEM; - } - memcpy(gfout, gfin, sizeof(*gfout)); - OBD_FREE_PTR(gfin); + + if (copy_from_user(gfout, arg, sizeof(*gfout))) + GOTO(gf_free, rc = -EFAULT); /* Call mdc_iocontrol */ rc = obd_iocontrol(OBD_IOC_FID2PATH, exp, outsize, gfout, NULL); - if (rc) + if (rc != 0) GOTO(gf_free, rc); if (copy_to_user(arg, gfout, outsize)) diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index 684405e26b58..b42d87971f5e 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -775,7 +775,7 @@ int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp, int *lmm_size, struct ptlrpc_request **request); int ll_fsync(struct file *file, loff_t start, loff_t end, int data); int ll_merge_lvb(const struct lu_env *env, struct inode *inode); -int ll_fid2path(struct inode *inode, void *arg); +int ll_fid2path(struct inode *inode, void __user *arg); int ll_data_version(struct inode *inode, __u64 *data_version, int extent_lock); int ll_hsm_release(struct inode *inode); -- GitLab From c7b09efacf54210be511450768c0ee98071feb7f Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Fri, 15 Aug 2014 12:48:13 -0400 Subject: [PATCH 0811/9167] staging/lustre/llite: Fix integer overflow in ll_fid2path Reported by Dan Carpenter outsize = sizeof(*gfout) + gfin->gf_pathlen; Where outsize is int and gf_pathlen is u32 from userspace can lead to integer overflowwhere outsize is some small number less than sizeof(*gfout) Add a check for pathlen to be of sensical size. Signed-off-by: Oleg Drokin Reviewed-on: http://review.whamcloud.com/11412 Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5476 Reviewed-by: Dmitry Eremin Reviewed-by: John L. Hammond Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/llite/file.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index d3874e1afba8..4a33638bef25 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1719,6 +1719,9 @@ int ll_fid2path(struct inode *inode, void __user *arg) if (get_user(pathlen, &gfin->gf_pathlen)) return -EFAULT; + if (pathlen > PATH_MAX) + return -EINVAL; + outsize = sizeof(*gfout) + pathlen; OBD_ALLOC(gfout, outsize); -- GitLab From 48caf5a060491edb2e1793539dad72e70c54c869 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 17 Aug 2014 09:17:04 -0700 Subject: [PATCH 0812/9167] staging: vt6655: Convert DBG_PRT to pr_ DBG_PRT uses are unnecessarily complex. Convert DBG_PRT msglevel to pr_. This changes the KERN_ type of several uses. It also enables dynamic_debug for the pr_debug conversions. This patch can be a prelude to converting these pr_ uses to dev_ as appropriate. Other changes: Realign arguments of these conversions. Remove now unused static int msglevel declarations. Remove now unused DBG_PRT #define. Compile tested only. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6655/80211mgr.c | 33 ++-- drivers/staging/vt6655/baseband.c | 62 +++---- drivers/staging/vt6655/bssdb.c | 57 ++++--- drivers/staging/vt6655/card.c | 30 ++-- drivers/staging/vt6655/channel.c | 7 +- drivers/staging/vt6655/datarate.c | 11 +- drivers/staging/vt6655/device.h | 6 - drivers/staging/vt6655/device_main.c | 231 ++++++++++++++------------- drivers/staging/vt6655/dpc.c | 129 ++++++++------- drivers/staging/vt6655/hostap.c | 107 ++++++------- drivers/staging/vt6655/ioctl.c | 82 +++++----- drivers/staging/vt6655/iwctl.c | 102 ++++++------ drivers/staging/vt6655/key.c | 122 +++++++------- drivers/staging/vt6655/mac.c | 65 ++++---- drivers/staging/vt6655/mib.c | 54 +++++-- drivers/staging/vt6655/power.c | 10 +- drivers/staging/vt6655/rxtx.c | 87 +++++----- drivers/staging/vt6655/wcmd.c | 84 +++++----- drivers/staging/vt6655/wmgr.c | 204 +++++++++++------------ drivers/staging/vt6655/wpa.c | 28 ++-- drivers/staging/vt6655/wpa2.c | 20 +-- drivers/staging/vt6655/wpactl.c | 70 ++++---- drivers/staging/vt6655/wroute.c | 12 +- 23 files changed, 840 insertions(+), 773 deletions(-) diff --git a/drivers/staging/vt6655/80211mgr.c b/drivers/staging/vt6655/80211mgr.c index 2c1fd82e8e85..7d2c6472ec9a 100644 --- a/drivers/staging/vt6655/80211mgr.c +++ b/drivers/staging/vt6655/80211mgr.c @@ -63,10 +63,6 @@ /*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ - -static int msglevel = MSG_LEVEL_INFO; -/* static int msglevel =MSG_LEVEL_DEBUG; */ /*--------------------- Static Functions --------------------------*/ /*--------------------- Export Variables --------------------------*/ @@ -218,9 +214,8 @@ vMgrDecodeBeacon( break; default: - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "Unrecognized EID=%dd in beacon decode.\n", - pItem->byElementID); + pr_debug("Unrecognized EID=%dd in beacon decode\n", + pItem->byElementID); break; } @@ -406,9 +401,8 @@ vMgrDecodeAssocRequest( break; default: - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "Unrecognized EID=%dd in assocreq decode.\n", - pItem->byElementID); + pr_debug("Unrecognized EID=%dd in assocreq decode\n", + pItem->byElementID); break; } pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); @@ -489,9 +483,7 @@ vMgrDecodeAssocResponse( if ((((unsigned char *)pItem) < (pFrame->pBuf + pFrame->len)) && (pItem->byElementID == WLAN_EID_EXTSUPP_RATES)) { pFrame->pExtSuppRates = (PWLAN_IE_SUPP_RATES)pItem; - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "pFrame->pExtSuppRates=[%p].\n", - pItem); + pr_debug("pFrame->pExtSuppRates=[%p]\n", pItem); } else { pFrame->pExtSuppRates = NULL; } @@ -594,9 +586,8 @@ vMgrDecodeReassocRequest( (PWLAN_IE_SUPP_RATES)pItem; break; default: - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "Unrecognized EID=%dd in reassocreq decode.\n", - pItem->byElementID); + pr_debug("Unrecognized EID=%dd in reassocreq decode\n", + pItem->byElementID); break; } pItem = (PWLAN_IE)(((unsigned char *)pItem) + 2 + pItem->len); @@ -666,9 +657,8 @@ vMgrDecodeProbeRequest( break; default: - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "Bad EID=%dd in probereq\n", - pItem->byElementID); + pr_debug("Bad EID=%dd in probereq\n", + pItem->byElementID); break; } @@ -819,9 +809,8 @@ vMgrDecodeProbeResponse( break; default: - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "Bad EID=%dd in proberesp\n", - pItem->byElementID); + pr_debug("Bad EID=%dd in proberesp\n", + pItem->byElementID); break; } diff --git a/drivers/staging/vt6655/baseband.c b/drivers/staging/vt6655/baseband.c index 3d76ed5ad5f1..c1025ff542ed 100644 --- a/drivers/staging/vt6655/baseband.c +++ b/drivers/staging/vt6655/baseband.c @@ -56,10 +56,6 @@ #include "srom.h" #include "rf.h" -/*--------------------- Static Definitions -------------------------*/ -/* static int msglevel =MSG_LEVEL_DEBUG; */ -static int msglevel = MSG_LEVEL_INFO; - /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ @@ -2009,7 +2005,7 @@ bool BBbReadEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned ch if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x30); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x30)\n"); + pr_debug(" DBG_PORT80(0x30)\n"); return false; } return true; @@ -2050,7 +2046,7 @@ bool BBbWriteEmbedded(void __iomem *dwIoBase, unsigned char byBBAddr, unsigned c if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x31); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x31)\n"); + pr_debug(" DBG_PORT80(0x31)\n"); return false; } return true; @@ -2725,18 +2721,22 @@ void BBvAntennaDiversity(struct vnt_private *pDevice, if (pDevice->byAntennaState == 0) { if (pDevice->uDiversityCnt > pDevice->ulDiversityNValue) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ulDiversityNValue=[%d],54M-[%d]\n", - (int)pDevice->ulDiversityNValue, (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate]); + pr_debug("ulDiversityNValue=[%d],54M-[%d]\n", + (int)pDevice->ulDiversityNValue, + (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate]); if (pDevice->uNumSQ3[pDevice->wAntDiversityMaxRate] < pDevice->uDiversityCnt/2) { pDevice->ulRatio_State0 = s_ulGetRatio(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SQ3_State0, rate = [%08x]\n", (int)pDevice->ulRatio_State0); + pr_debug("SQ3_State0, rate = [%08x]\n", + (int)pDevice->ulRatio_State0); if (pDevice->byTMax == 0) return; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1.[%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); + pr_debug("1.[%08x], uNumSQ3[%d]=%d, %d\n", + (int)pDevice->ulRatio_State0, + (int)pDevice->wAntDiversityMaxRate, + (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], + (int)pDevice->uDiversityCnt); s_vChangeAntenna(pDevice); pDevice->byAntennaState = 1; @@ -2758,14 +2758,17 @@ void BBvAntennaDiversity(struct vnt_private *pDevice, del_timer(&pDevice->TimerSQ3Tmax1); pDevice->ulRatio_State1 = s_ulGetRatio(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n", - (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1); + pr_debug("RX:SQ3_State1, rate0 = %08x,rate1 = %08x\n", + (int)pDevice->ulRatio_State0, + (int)pDevice->ulRatio_State1); if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, - (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); + pr_debug("2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", + (int)pDevice->ulRatio_State0, + (int)pDevice->ulRatio_State1, + (int)pDevice->wAntDiversityMaxRate, + (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], + (int)pDevice->uDiversityCnt); s_vChangeAntenna(pDevice); pDevice->TimerSQ3Tmax3.expires = RUN_AT(pDevice->byTMax3 * HZ); @@ -2800,10 +2803,12 @@ TimerSQ3CallBack( { struct vnt_private *pDevice = hDeviceContext; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TimerSQ3CallBack..."); + pr_debug("TimerSQ3CallBack...\n"); spin_lock_irq(&pDevice->lock); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "3.[%08x][%08x], %d\n", (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, (int)pDevice->uDiversityCnt); + pr_debug("3.[%08x][%08x], %d\n", + (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, + (int)pDevice->uDiversityCnt); s_vChangeAntenna(pDevice); pDevice->byAntennaState = 0; @@ -2842,7 +2847,7 @@ TimerState1CallBack( { struct vnt_private *pDevice = hDeviceContext; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TimerState1CallBack..."); + pr_debug("TimerState1CallBack...\n"); spin_lock_irq(&pDevice->lock); if (pDevice->uDiversityCnt < pDevice->ulDiversityMValue/100) { @@ -2853,14 +2858,17 @@ TimerState1CallBack( add_timer(&pDevice->TimerSQ3Tmax2); } else { pDevice->ulRatio_State1 = s_ulGetRatio(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SQ3_State1, rate0 = %08x,rate1 = %08x\n", - (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1); + pr_debug("SQ3_State1, rate0 = %08x,rate1 = %08x\n", + (int)pDevice->ulRatio_State0, + (int)pDevice->ulRatio_State1); if (pDevice->ulRatio_State1 < pDevice->ulRatio_State0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", - (int)pDevice->ulRatio_State0, (int)pDevice->ulRatio_State1, - (int)pDevice->wAntDiversityMaxRate, - (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], (int)pDevice->uDiversityCnt); + pr_debug("2.[%08x][%08x], uNumSQ3[%d]=%d, %d\n", + (int)pDevice->ulRatio_State0, + (int)pDevice->ulRatio_State1, + (int)pDevice->wAntDiversityMaxRate, + (int)pDevice->uNumSQ3[(int)pDevice->wAntDiversityMaxRate], + (int)pDevice->uDiversityCnt); s_vChangeAntenna(pDevice); diff --git a/drivers/staging/vt6655/bssdb.c b/drivers/staging/vt6655/bssdb.c index bb59b989def0..996d3302ce3d 100644 --- a/drivers/staging/vt6655/bssdb.c +++ b/drivers/staging/vt6655/bssdb.c @@ -63,8 +63,6 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - 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}, @@ -127,8 +125,7 @@ BSSpSearchBSSList( unsigned int ii = 0; if (pbyDesireBSSID != NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID); + pr_debug("BSSpSearchBSSList BSSID[%pM]\n", pbyDesireBSSID); if ((!is_broadcast_ether_addr(pbyDesireBSSID)) && (memcmp(pbyDesireBSSID, ZeroBSSID, 6) != 0)) pbyBSSID = pbyDesireBSSID; @@ -194,7 +191,9 @@ BSSpSearchBSSList( ((pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) ) { /* Type not match skip this BSS */ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSS type mismatch.... Config[%d] BSS[0x%04x]\n", pMgmt->eConfigMode, pCurrBSS->wCapInfo); + pr_debug("BSS type mismatch.... Config[%d] BSS[0x%04x]\n", + pMgmt->eConfigMode, + pCurrBSS->wCapInfo); continue; } @@ -202,7 +201,9 @@ BSSpSearchBSSList( 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 */ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Physical type mismatch.... ePhyType[%d] BSS[%d]\n", ePhyType, pCurrBSS->eNetworkTypeInUse); + pr_debug("Physical type mismatch.... ePhyType[%d] BSS[%d]\n", + ePhyType, + pCurrBSS->eNetworkTypeInUse); continue; } } @@ -350,7 +351,7 @@ BSSbInsertToBSSList( } if (ii == MAX_BSS_NUM) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get free KnowBSS node failed.\n"); + pr_debug("Get free KnowBSS node failed\n"); return false; } /* save the BSS info */ @@ -375,7 +376,8 @@ BSSbInsertToBSSList( if (pExtSuppRates->len > WLAN_RATES_MAXLEN) pExtSuppRates->len = WLAN_RATES_MAXLEN; memcpy(pBSSList->abyExtSuppRates, pExtSuppRates, pExtSuppRates->len + WLAN_IEHDR_LEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSbInsertToBSSList: pExtSuppRates->len = %d\n", pExtSuppRates->len); + pr_debug("BSSbInsertToBSSList: pExtSuppRates->len = %d\n", + pExtSuppRates->len); } else { memset(pBSSList->abyExtSuppRates, 0, WLAN_IEHDR_LEN + WLAN_RATES_MAXLEN + 1); @@ -740,7 +742,7 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) /* if not found replace uInActiveCount is largest one */ if (ii == (MAX_NODE_NUM + 1)) { *puNodeIndex = SelectIndex; - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Replace inactive node = %d\n", 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) @@ -757,7 +759,7 @@ BSSvCreateOneNode(void *hDeviceContext, unsigned int *puNodeIndex) skb_queue_head_init(&pMgmt->sNodeDBTable[*puNodeIndex].sTxPSQueue); pMgmt->sNodeDBTable[*puNodeIndex].byAuthSequence = 0; pMgmt->sNodeDBTable[*puNodeIndex].wEnQueueCnt = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create node index = %d\n", ii); + pr_debug("Create node index = %d\n", ii); return; }; @@ -842,7 +844,8 @@ BSSvUpdateAPNode( netdev_dbg(pDevice->dev, "BSSvUpdateAPNode:MaxSuppRate is %d\n", pMgmt->sNodeDBTable[0].wMaxSuppRate); /* auto rate fallback function initiation */ - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->sNodeDBTable[0].wTxDataRate = %d\n", pMgmt->sNodeDBTable[0].wTxDataRate); + pr_debug("pMgmt->sNodeDBTable[0].wTxDataRate = %d\n", + pMgmt->sNodeDBTable[0].wTxDataRate); }; /*+ @@ -959,8 +962,8 @@ BSSvSecondCallBack( if (ii > 0) { if (pMgmt->sNodeDBTable[ii].uInActiveCount > MAX_INACTIVE_COUNT) { BSSvRemoveOneNode(pDevice, ii); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "Inactive timeout [%d] sec, STA index = [%d] remove\n", MAX_INACTIVE_COUNT, ii); + pr_debug("Inactive timeout [%d] sec, STA index = [%d] remove\n", + MAX_INACTIVE_COUNT, ii); continue; } @@ -1010,11 +1013,13 @@ BSSvSecondCallBack( /* check if pending PS queue */ if (pMgmt->sNodeDBTable[ii].wEnQueueCnt != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index= %d, Queue = %d pending\n", - ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); + pr_debug("Index= %d, Queue = %d pending\n", + ii, + pMgmt->sNodeDBTable[ii].wEnQueueCnt); if ((ii > 0) && (pMgmt->sNodeDBTable[ii].wEnQueueCnt > 15)) { BSSvRemoveOneNode(pDevice, ii); - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Pending many queues PS STA Index = %d remove\n", ii); + pr_info("Pending many queues PS STA Index = %d remove\n", + ii); continue; } } @@ -1098,7 +1103,8 @@ BSSvSecondCallBack( netif_stop_queue(pDevice->dev); pDevice->bLinkPass = false; pDevice->bRoaming = true; - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost AP beacon [%d] sec, disconnected !\n", pMgmt->sNodeDBTable[0].uInActiveCount); + 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; @@ -1143,7 +1149,7 @@ BSSvSecondCallBack( if (pDevice->bWPADEVUp) pDevice->eEncryptionStatus = pDevice->eOldEncryptionStatus; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Roaming ...\n"); + pr_debug("Roaming ...\n"); BSSvClearBSSList((void *)pDevice, pDevice->bLinkPass); pMgmt->eScanType = WMAC_SCAN_ACTIVE; bScheduleCommand((void *)pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID); @@ -1159,7 +1165,7 @@ BSSvSecondCallBack( if (pDevice->uAutoReConnectTime < 10) { pDevice->uAutoReConnectTime++; } else { - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Adhoc re-scanning ...\n"); + 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); @@ -1170,7 +1176,8 @@ BSSvSecondCallBack( if (pDevice->bUpdateBBVGA) s_vCheckPreEDThreshold((void *)pDevice); if (pMgmt->sNodeDBTable[0].uInActiveCount >= ADHOC_LOST_BEACON_COUNT) { - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Lost other STA beacon [%d] sec, started !\n", pMgmt->sNodeDBTable[0].uInActiveCount); + 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); @@ -1229,7 +1236,8 @@ BSSvUpdateNodeTxCounter( /* Only Unicast using support rates */ if (pTxBufHead->wFIFOCtl & FIFOCTL_NEEDACK) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wRate %04X, byTsr0 %02X, byTsr1 %02X\n", wRate, byTsr0, byTsr1); + 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) { @@ -1370,7 +1378,7 @@ BSSvClearNodeDBTable( /* check if sTxPSQueue has been initial */ if (pMgmt->sNodeDBTable[ii].sTxPSQueue.next != NULL) { while ((skb = skb_dequeue(&pMgmt->sNodeDBTable[ii].sTxPSQueue)) != NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS skb != NULL %d\n", ii); + pr_debug("PS skb != NULL %d\n", ii); dev_kfree_skb(skb); } } @@ -1412,7 +1420,10 @@ void s_vCheckSensitivity( if (uNumofdBm > 0) { LocalldBmAverage = LocalldBmAverage/uNumofdBm; for (ii = 0; ii < BB_VGA_LEVEL; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LocalldBmAverage:%ld, %ld %02x\n", LocalldBmAverage, pDevice->ldBmThreshold[ii], pDevice->abyBBVGA[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; diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 633585fd4a96..9807374b33f4 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -59,8 +59,6 @@ /*--------------------- Static Definitions -------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - #define C_SIFS_A 16 // micro sec. #define C_SIFS_BG 10 @@ -747,14 +745,14 @@ bool CARDbSetBSSID(struct vnt_private *pDevice, MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_BSSID); pDevice->bBSSIDFilter = false; pDevice->byRxMode &= ~RCR_BSSID; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode); + 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; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: rx_mode = %x\n", pDevice->byRxMode); + pr_debug("wmgr: rx_mode = %x\n", pDevice->byRxMode); } // Adopt BSS state in Adapter Device Object pDevice->eOPMode = eOPMode; @@ -838,7 +836,7 @@ CARDbPowerDown( } MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n"); + pr_debug("Go to Doze ZZZZZZZZZZZZZZZ\n"); return true; } @@ -975,17 +973,18 @@ CARDbAdd_PMKID_Candidate( struct pmkid_candidate *pCandidateList; unsigned int ii = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); + pr_debug("bAdd_PMKID_Candidate START: (%d)\n", + (int)pDevice->gsPMKIDCandidate.NumCandidates); if (pDevice->gsPMKIDCandidate.NumCandidates >= MAX_PMKIDLIST) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 3\n"); + pr_debug("vFlush_PMKID_Candidate: 3\n"); memset(&pDevice->gsPMKIDCandidate, 0, sizeof(SPMKIDCandidateEvent)); } for (ii = 0; ii < 6; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02X ", *(pbyBSSID + ii)); + pr_debug("%02X ", *(pbyBSSID + ii)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + pr_debug("\n"); // Update Old Candidate for (ii = 0; ii < pDevice->gsPMKIDCandidate.NumCandidates; ii++) { @@ -1009,7 +1008,8 @@ CARDbAdd_PMKID_Candidate( memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); pDevice->gsPMKIDCandidate.NumCandidates++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); + pr_debug("NumCandidates:%d\n", + (int)pDevice->gsPMKIDCandidate.NumCandidates); return true; } @@ -1559,22 +1559,22 @@ static unsigned short CARDwGetOFDMControlRate(struct vnt_private *pDevice, { unsigned int ui = (unsigned int) wRateIdx; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BASIC RATE: %X\n", pDevice->wBasicRate); + pr_debug("BASIC RATE: %X\n", pDevice->wBasicRate); if (!CARDbIsOFDMinBasicRate((void *)pDevice)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); + pr_debug("CARDwGetOFDMControlRate:(NO OFDM) %d\n", wRateIdx); if (wRateIdx > RATE_24M) wRateIdx = RATE_24M; return wRateIdx; } while (ui > RATE_11M) { if (pDevice->wBasicRate & ((unsigned short)1 << ui)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate : %d\n", ui); + pr_debug("CARDwGetOFDMControlRate : %d\n", ui); return (unsigned short)ui; } ui--; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CARDwGetOFDMControlRate: 6M\n"); + pr_debug("CARDwGetOFDMControlRate: 6M\n"); return (unsigned short)RATE_24M; } @@ -2017,5 +2017,5 @@ void CARDvUpdateNextTBTT(void __iomem *dwIoBase, u64 qwTSF, unsigned short wBeac VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT, (u32)qwTSF); VNSvOutPortD(dwIoBase + MAC_REG_NEXTTBTT + 4, (u32)(qwTSF >> 32)); MACvRegBitsOn(dwIoBase, MAC_REG_TFTCTL, TFTCTL_TBTTSYNCEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Card:Update Next TBTT[%8llx]\n", qwTSF); + pr_debug("Card:Update Next TBTT[%8llx]\n", qwTSF); } diff --git a/drivers/staging/vt6655/channel.c b/drivers/staging/vt6655/channel.c index 753d523800c3..4ce964ba14b7 100644 --- a/drivers/staging/vt6655/channel.c +++ b/drivers/staging/vt6655/channel.c @@ -30,8 +30,6 @@ #define CARD_MAX_CHANNEL_TBL 56 -static int msglevel = MSG_LEVEL_INFO; - /*--------------------- Static Variables --------------------------*/ static SChannelTblElement sChannelTbl[CARD_MAX_CHANNEL_TBL + 1] = @@ -480,7 +478,10 @@ void init_channel_table(void *pDeviceHandler) } } - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Zone=[%d][%c][%c]!!\n", pDevice->byZoneType, ChannelRuleTab[pDevice->byZoneType].chCountryCode[0], ChannelRuleTab[pDevice->byZoneType].chCountryCode[1]); + 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) diff --git a/drivers/staging/vt6655/datarate.c b/drivers/staging/vt6655/datarate.c index d489fe4a4ecb..52907a4fae9d 100644 --- a/drivers/staging/vt6655/datarate.c +++ b/drivers/staging/vt6655/datarate.c @@ -49,7 +49,6 @@ extern unsigned short TxRate_iwconfig; /* 2008-5-8 by chester */ /*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; static const unsigned char acbyIERate[MAX_RATE] = { 0x02, 0x04, 0x0B, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C }; @@ -208,7 +207,7 @@ RATEvParseMaxRate( *pwSuppRate = 0; uRateLen = pItemRates->len; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate Len: %d\n", uRateLen); + pr_debug("ParseMaxRate Len: %d\n", uRateLen); if (pDevice->eCurrentPHYType != PHY_TYPE_11B) { if (uRateLen > WLAN_RATES_MAXLEN) uRateLen = WLAN_RATES_MAXLEN; @@ -222,7 +221,8 @@ RATEvParseMaxRate( if (WLAN_MGMT_IS_BASICRATE(byRate) && bUpdateBasicRate) { /* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */ CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); + pr_debug("ParseMaxRate AddBasicRate: %d\n", + wGetRateIdx(byRate)); } byRate = (unsigned char)(pItemRates->abyRates[ii]&0x7F); if (byHighSuppRate == 0) @@ -244,7 +244,8 @@ RATEvParseMaxRate( if (WLAN_MGMT_IS_BASICRATE(pItemExtRates->abyRates[ii])) { /* Add to basic rate set, update pDevice->byTopCCKBasicRate and pDevice->byTopOFDMBasicRate */ CARDbAddBasicRate((void *)pDevice, wGetRateIdx(byRate)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ParseMaxRate AddBasicRate: %d\n", wGetRateIdx(byRate)); + pr_debug("ParseMaxRate AddBasicRate: %d\n", + wGetRateIdx(byRate)); } byRate = (unsigned char)(pItemExtRates->abyRates[ii]&0x7F); if (byHighSuppRate == 0) @@ -268,7 +269,7 @@ RATEvParseMaxRate( if (wOldBasicRate != pDevice->wBasicRate) CARDvSetRSPINF((void *)pDevice, pDevice->eCurrentPHYType); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Exit ParseMaxRate\n"); + pr_debug("Exit ParseMaxRate\n"); } /*+ diff --git a/drivers/staging/vt6655/device.h b/drivers/staging/vt6655/device.h index e1a322fa9c02..e4c52925a112 100644 --- a/drivers/staging/vt6655/device.h +++ b/drivers/staging/vt6655/device.h @@ -148,12 +148,6 @@ /*--------------------- Export Types ------------------------------*/ -#define DBG_PRT(l, p, args...) \ -do { \ - if (l <= msglevel) \ - printk(p, ##args); \ -} while (0) - #define PRINT_K(p, args...) \ do { \ if (PRIVATE_Message) \ diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index beab35d8a4cb..a44233c2dd29 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -89,8 +89,6 @@ #include /*--------------------- Static Definitions -------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - // // Define module options // @@ -400,18 +398,19 @@ device_set_options(struct vnt_private *pDevice) pDevice->wCTSDuration = 0; pDevice->byPreambleType = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uChannel= %d\n", (int)pDevice->uChannel); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byOpMode= %d\n", (int)pDevice->byOpMode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ePSMode= %d\n", (int)pDevice->ePSMode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " wRTSThreshold= %d\n", (int)pDevice->wRTSThreshold); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortRetryLimit= %d\n", (int)pDevice->byShortRetryLimit); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byLongRetryLimit= %d\n", (int)pDevice->byLongRetryLimit); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byPreambleType= %d\n", (int)pDevice->byPreambleType); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byShortPreamble= %d\n", (int)pDevice->byShortPreamble); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " uConnectionRate= %d\n", (int)pDevice->uConnectionRate); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " byBBType= %d\n", (int)pDevice->byBBType); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->b11hEnable= %d\n", (int)pDevice->b11hEnable); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pDevice->bDiversityRegCtlON= %d\n", (int)pDevice->bDiversityRegCtlON); + 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); + pr_debug(" byPreambleType= %d\n", (int)pDevice->byPreambleType); + pr_debug(" byShortPreamble= %d\n", (int)pDevice->byShortPreamble); + pr_debug(" uConnectionRate= %d\n", (int)pDevice->uConnectionRate); + pr_debug(" byBBType= %d\n", (int)pDevice->byBBType); + pr_debug(" pDevice->b11hEnable= %d\n", (int)pDevice->b11hEnable); + pr_debug(" pDevice->bDiversityRegCtlON= %d\n", + (int)pDevice->bDiversityRegCtlON); } static void s_vCompleteCurrentMeasure(struct vnt_private *pDevice, @@ -565,10 +564,10 @@ static void device_init_registers(struct vnt_private *pDevice) } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO - "bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n", - pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue, - (int)pDevice->ulDiversityMValue, pDevice->byTMax, pDevice->byTMax2); + pr_debug("bDiversityEnable=[%d],NValue=[%d],MValue=[%d],TMax=[%d],TMax2=[%d]\n", + pDevice->bDiversityEnable, (int)pDevice->ulDiversityNValue, + (int)pDevice->ulDiversityMValue, pDevice->byTMax, + pDevice->byTMax2); /* zonetype initial */ pDevice->byOriginalZonetype = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; @@ -581,7 +580,7 @@ static void device_init_registers(struct vnt_private *pDevice) pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0; pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0B; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :USA\n"); + pr_debug("Init Zone Type :USA\n"); } else if ((zonetype == 1) && (pDevice->abyEEPROM[EEP_OFS_ZONETYPE] != 0x01)) { /* for Japan */ @@ -593,7 +592,7 @@ static void device_init_registers(struct vnt_private *pDevice) pDevice->abyEEPROM[EEP_OFS_ZONETYPE] = 0x02; pDevice->abyEEPROM[EEP_OFS_MAXCHANNEL] = 0x0D; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Init Zone Type :Europe\n"); + 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", @@ -616,12 +615,12 @@ static void device_init_registers(struct vnt_private *pDevice) pDevice->byRevId = 0x80; pDevice->byRFType &= RF_MASK; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRFType = %x\n", pDevice->byRFType); + pr_debug("pDevice->byRFType = %x\n", pDevice->byRFType); if (!pDevice->bZoneRegExist) pDevice->byZoneType = pDevice->abyEEPROM[EEP_OFS_ZONETYPE]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byZoneType = %x\n", pDevice->byZoneType); + pr_debug("pDevice->byZoneType = %x\n", pDevice->byZoneType); /* Init RF module */ RFbInit(pDevice); @@ -744,8 +743,7 @@ static void device_init_registers(struct vnt_private *pDevice) /* get Permanent network address */ SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Network address = %pM\n", - pDevice->abyCurrentNetAddr); + pr_debug("Network address = %pM\n", pDevice->abyCurrentNetAddr); /* reset Tx pointer */ CARDvSafeResetRx(pDevice); @@ -985,12 +983,10 @@ static void device_print_info(struct vnt_private *pDevice) { struct net_device *dev = pDevice->dev; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: %s\n", dev->name, get_chip_name(pDevice->chip_id)); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: MAC=%pM", dev->name, dev->dev_addr); - - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IO=0x%lx Mem=0x%lx ", - (unsigned long)pDevice->ioaddr, (unsigned long)pDevice->PortOffset); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO " IRQ=%d\n", pDevice->dev->irq); + 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); } static void vt6655_init_info(struct pci_dev *pcid, @@ -1094,7 +1090,7 @@ static void device_free_info(struct vnt_private *pDevice) else ptr->prev->next = ptr->next; } else { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "info struct not found\n"); + pr_err("info struct not found\n"); return; } #ifdef HOSTAP @@ -1125,7 +1121,8 @@ static bool device_init_rings(struct vnt_private *pDevice) pDevice->sOpts.nTxDescs[1] * sizeof(STxDesc), &pDevice->pool_dma); if (vir_pool == NULL) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s : allocate desc dma memory failed\n", pDevice->dev->name); + pr_err("%s : allocate desc dma memory failed\n", + pDevice->dev->name); return false; } @@ -1144,7 +1141,8 @@ static bool device_init_rings(struct vnt_private *pDevice) CB_MAX_BUF_SIZE, &pDevice->tx_bufs_dma0); if (pDevice->tx0_bufs == NULL) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: allocate buf dma memory failed\n", pDevice->dev->name); + pr_err("%s: allocate buf dma memory failed\n", + pDevice->dev->name); pci_free_consistent(pDevice->pcid, pDevice->sOpts.nRxDescs0 * sizeof(SRxDesc) + pDevice->sOpts.nRxDescs1 * sizeof(SRxDesc) + @@ -1222,8 +1220,8 @@ static void device_init_rd0_ring(struct vnt_private *pDevice) pDesc->pRDInfo = alloc_rd_info(); ASSERT(pDesc->pRDInfo); if (!device_alloc_rx_buf(pDevice, pDesc)) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc rx bufs\n", + pDevice->dev->name); } pDesc->next = &(pDevice->aRD0Ring[(i+1) % pDevice->sOpts.nRxDescs0]); pDesc->pRDInfo->curr_desc = cpu_to_le32(curr); @@ -1247,8 +1245,8 @@ static void device_init_rd1_ring(struct vnt_private *pDevice) pDesc->pRDInfo = alloc_rd_info(); ASSERT(pDesc->pRDInfo); if (!device_alloc_rx_buf(pDevice, pDesc)) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc rx bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc rx bufs\n", + pDevice->dev->name); } pDesc->next = &(pDevice->aRD1Ring[(i+1) % pDevice->sOpts.nRxDescs1]); pDesc->pRDInfo->curr_desc = cpu_to_le32(curr); @@ -1269,8 +1267,8 @@ static void device_init_defrag_cb(struct vnt_private *pDevice) for (i = 0; i < CB_MAX_RX_FRAG; i++) { pDeF = &(pDevice->sRxDFCB[i]); if (!device_alloc_frag_buf(pDevice, pDeF)) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc frag bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc frag bufs\n", + pDevice->dev->name); } } pDevice->cbDFCB = CB_MAX_RX_FRAG; @@ -1428,8 +1426,8 @@ static int device_rx_srv(struct vnt_private *pDevice, unsigned int uIdx) break; if (device_receive_frame(pDevice, pRD)) { if (!device_alloc_rx_buf(pDevice, pRD)) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR - "%s: can not allocate rx buf\n", pDevice->dev->name); + pr_err("%s: can not allocate rx buf\n", + pDevice->dev->name); break; } } @@ -1520,8 +1518,9 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) if (!(byTsr1 & TSR1_TERR)) { if (byTsr0 != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X].\n", - (int)uIdx, byTsr1, byTsr0); + pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n", + (int)uIdx, byTsr1, + byTsr0); } if ((pTxBufHead->wFragCtl & FRAGCTL_ENDFRAG) != FRAGCTL_NONFRAG) pDevice->s802_11Counter.TransmittedFragmentCount++; @@ -1529,8 +1528,8 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) pStats->tx_packets++; pStats->tx_bytes += pTD->pTDInfo->skb->len; } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] dropped & tsr1[%02X] tsr0[%02X].\n", - (int)uIdx, byTsr1, byTsr0); + pr_debug(" Tx[%d] dropped & tsr1[%02X] tsr0[%02X]\n", + (int)uIdx, byTsr1, byTsr0); pStats->tx_errors++; pStats->tx_dropped++; } @@ -1538,7 +1537,7 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) { if (pDevice->bEnableHostapd) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx call back netif..\n"); + pr_debug("tx call back netif..\n"); skb = pTD->pTDInfo->skb; skb->dev = pDevice->apdev; skb_reset_mac_header(skb); @@ -1550,8 +1549,8 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) if (byTsr1 & TSR1_TERR) { if ((pTD->pTDInfo->byFlags & TD_FLAGS_PRIV_SKB) != 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Tx[%d] fail has error. tsr1[%02X] tsr0[%02X].\n", - (int)uIdx, byTsr1, byTsr0); + pr_debug(" Tx[%d] fail has error. tsr1[%02X] tsr0[%02X]\n", + (int)uIdx, byTsr1, byTsr0); } @@ -1569,8 +1568,9 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; pTD->pTDInfo->byFlags &= ~(TD_FLAGS_NETIF_SKB); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "tx_srv:tx fail re-queue sta index= %d, QueCnt= %d\n" - , (int)uNodeIndex, pMgmt->sNodeDBTable[uNodeIndex].wEnQueueCnt); + 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--; } @@ -1587,7 +1587,8 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) if (AVAIL_TD(pDevice, uIdx) < RESERV_AC0DMA) { bFull = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " AC0DMA is Full = %d\n", pDevice->iTDUsed[uIdx]); + pr_debug(" AC0DMA is Full = %d\n", + pDevice->iTDUsed[uIdx]); } if (netif_queue_stopped(pDevice->dev) && !bFull) netif_wake_queue(pDevice->dev); @@ -1602,9 +1603,7 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx) static void device_error(struct vnt_private *pDevice, unsigned short status) { if (status & ISR_FETALERR) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR - "%s: Hardware fatal error.\n", - pDevice->dev->name); + pr_err("%s: Hardware fatal error\n", pDevice->dev->name); netif_stop_queue(pDevice->dev); del_timer(&pDevice->sTimerCommand); del_timer(&(pDevice->pMgmt->sTimerSecondCallback)); @@ -1658,7 +1657,7 @@ static int device_open(struct net_device *dev) wpa_Result.authenticated = false; pDevice->fWPA_Authened = false; #endif - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device init rd0 ring\n"); + pr_debug("call device init rd0 ring\n"); device_init_rd0_ring(pDevice); device_init_rd1_ring(pDevice); device_init_defrag_cb(pDevice); @@ -1671,7 +1670,7 @@ static int device_open(struct net_device *dev) vMgrObjectInit(pDevice); vMgrTimerInit(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call device_init_registers\n"); + pr_debug("call device_init_registers\n"); device_init_registers(pDevice); MACvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); @@ -1702,7 +1701,7 @@ static int device_open(struct net_device *dev) pDevice->eEncryptionStatus = Ndis802_11Encryption1Enabled; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "call MACvIntEnable\n"); + pr_debug("call MACvIntEnable\n"); MACvIntEnable(pDevice->PortOffset, IMR_MASK_VALUE); if (pDevice->pMgmt->eConfigMode == WMAC_CONFIG_AP) { @@ -1713,7 +1712,7 @@ static int device_open(struct net_device *dev) } pDevice->flags |= DEVICE_FLAGS_OPENED; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_open success..\n"); + pr_debug("device_open success..\n"); return 0; } @@ -1759,7 +1758,7 @@ static int device_close(struct net_device *dev) //2008-0714-01by chester device_release_WPADEV(pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_close..\n"); + pr_debug("device_close..\n"); return 0; } @@ -1769,11 +1768,11 @@ static int device_dma0_tx_80211(struct sk_buff *skb, struct net_device *dev) unsigned char *pbMPDU; unsigned int cbMPDULen = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211\n"); + pr_debug("device_dma0_tx_80211\n"); spin_lock_irq(&pDevice->lock); if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_tx_80211, td0 <=0\n"); + pr_debug("device_dma0_tx_80211, td0 <=0\n"); dev_kfree_skb_irq(skb); spin_unlock_irq(&pDevice->lock); return 0; @@ -1816,14 +1815,14 @@ bool device_dma0_xmit(struct vnt_private *pDevice, if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) { dev_kfree_skb_irq(skb); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, td0 <=0\n"); + 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); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "device_dma0_xmit, assocCount = 0\n"); + pr_debug("device_dma0_xmit, assocCount = 0\n"); return false; } } @@ -1869,7 +1868,7 @@ bool device_dma0_xmit(struct vnt_private *pDevice, else pDevice->byPreambleType = PREAMBLE_LONG; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dma0: pDevice->wCurrentRate = %d\n", pDevice->wCurrentRate); + pr_debug("dma0: pDevice->wCurrentRate = %d\n", pDevice->wCurrentRate); if (pDevice->wCurrentRate <= RATE_11M) { byPktType = PK_TYPE_11B; @@ -1994,8 +1993,9 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { // set tx map wAID = pMgmt->sNodeDBTable[uNodeIndex].wAID; pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set:pMgmt->abyPSTxMap[%d]= %d\n", - (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]); + pr_debug("Set:pMgmt->abyPSTxMap[%d]= %d\n", + (wAID >> 3), + pMgmt->abyPSTxMap[wAID >> 3]); spin_unlock_irq(&pDevice->lock); return 0; } @@ -2011,7 +2011,7 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { } if (!bNodeExist) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Unknown STA not found in node DB\n"); + pr_debug("Unknown STA not found in node DB\n"); dev_kfree_skb_irq(skb); spin_unlock_irq(&pDevice->lock); return 0; @@ -2040,19 +2040,19 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { // get group key if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { bTKIP_UseGTK = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n"); + pr_debug("Get GTK\n"); break; } } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get PTK.\n"); + 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 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS Serach Key:\n"); + pr_debug("IBSS Serach Key:\n"); for (ii = 0; ii < 6; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "%x\n", *(pbyBSSID+ii)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "\n"); + pr_debug("%x\n", *(pbyBSSID+ii)); + pr_debug("\n"); // get pairwise key if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == true) @@ -2063,18 +2063,20 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { pTransmitKey = NULL; if (pDevice->pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); + pr_debug("IBSS and KEY is NULL. [%d]\n", + pDevice->pMgmt->eCurrMode); else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "NOT IBSS and KEY is NULL. [%d]\n", pDevice->pMgmt->eCurrMode); + pr_debug("NOT IBSS and KEY is NULL. [%d]\n", + pDevice->pMgmt->eCurrMode); } else { bTKIP_UseGTK = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n"); + pr_debug("Get GTK\n"); } } while (false); } if (pDevice->bEnableHostWEP) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "acdma0: STA index %d\n", uNodeIndex); + pr_debug("acdma0: STA index %d\n", uNodeIndex); if (pDevice->bEncryptionEnable) { pTransmitKey = &STempKey; pTransmitKey->byCipherSuite = pMgmt->sNodeDBTable[uNodeIndex].byCipherSuite; @@ -2092,7 +2094,8 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { uMACfragNum = cbGetFragCount(pDevice, pTransmitKey, cbFrameBodySize, &pDevice->sTxEthHeader); if (uMACfragNum > AVAIL_TD(pDevice, TYPE_AC0DMA)) { - DBG_PRT(MSG_LEVEL_ERR, KERN_DEBUG "uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", uMACfragNum); + pr_debug("uMACfragNum > AVAIL_TD(TYPE_AC0DMA) = %d\n", + uMACfragNum); dev_kfree_skb_irq(skb); spin_unlock_irq(&pDevice->lock); return 0; @@ -2170,18 +2173,21 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { } if (bNeedEncryption) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); + pr_debug("ntohs Pkt Type=%04x\n", + ntohs(pDevice->sTxEthHeader.wType)); if ((pDevice->sTxEthHeader.wType) == TYPE_PKT_802_1x) { bNeedEncryption = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); + 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) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Don't Find TX KEY\n"); + pr_debug("Don't Find TX KEY\n"); } else { if (bTKIP_UseGTK) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "error: KEY is GTK!!~~\n"); + pr_debug("error: KEY is GTK!!~~\n"); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); + pr_debug("Find PTK [%lX]\n", + pTransmitKey->dwKeyIndex); bNeedEncryption = true; } } @@ -2195,13 +2201,14 @@ static int device_xmit(struct sk_buff *skb, struct net_device *dev) { if (pDevice->bEnableHostWEP) { if ((uNodeIndex != 0) && (pMgmt->sNodeDBTable[uNodeIndex].dwKeyIndex & PAIRWISE_KEY)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Find PTK [%lX]\n", pTransmitKey->dwKeyIndex); + pr_debug("Find PTK [%lX]\n", + pTransmitKey->dwKeyIndex); bNeedEncryption = true; } } } else { if (pTransmitKey == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return no tx key\n"); + pr_debug("return no tx key\n"); dev_kfree_skb_irq(skb); spin_unlock_irq(&pDevice->lock); return 0; @@ -2305,7 +2312,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) return IRQ_RETVAL(handled); if (pDevice->dwIsr == 0xffffffff) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwIsr = 0xffff\n"); + pr_debug("dwIsr = 0xffff\n"); return IRQ_RETVAL(handled); } @@ -2332,7 +2339,7 @@ static irqreturn_t device_intr(int irq, void *dev_instance) MACvWriteISR(pDevice->PortOffset, pDevice->dwIsr); if (pDevice->dwIsr & ISR_FETALERR) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " ISR_FETALERR\n"); + pr_debug(" ISR_FETALERR\n"); VNSvOutPortB(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, 0); VNSvOutPortW(pDevice->PortOffset + MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPECTI); device_error(pDevice, pDevice->dwIsr); @@ -2442,12 +2449,18 @@ static irqreturn_t device_intr(int irq, void *dev_instance) if (pDevice->uBBVGADiffCount == 1) { // first VGA diff gain BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", - (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount); + pr_debug("First RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", + (int)ldBm, + pDevice->byBBVGANew, + pDevice->byBBVGACurrent, + (int)pDevice->uBBVGADiffCount); } if (pDevice->uBBVGADiffCount >= BB_VGA_CHANGE_THRESHOLD) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", - (int)ldBm, pDevice->byBBVGANew, pDevice->byBBVGACurrent, (int)pDevice->uBBVGADiffCount); + pr_debug("RSSI[%d] NewGain[%d] OldGain[%d] Count[%d]\n", + (int)ldBm, + pDevice->byBBVGANew, + pDevice->byBBVGACurrent, + (int)pDevice->uBBVGADiffCount); BBvSetVGAGainOffset(pDevice, pDevice->byBBVGANew); } } else { @@ -2638,7 +2651,7 @@ static void device_set_multi(struct net_device *dev) { VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ - DBG_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name); + 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) @@ -2670,7 +2683,7 @@ static void device_set_multi(struct net_device *dev) { } VNSvOutPortB(pDevice->PortOffset + MAC_REG_RCR, pDevice->byRxMode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pDevice->byRxMode = %x\n", pDevice->byRxMode); + pr_debug("pDevice->byRxMode = %x\n", pDevice->byRxMode); } static struct net_device_stats *device_get_stats(struct net_device *dev) @@ -2760,13 +2773,13 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) // Set desired station name case SIOCSIWNICKN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWNICKN\n"); + pr_debug(" SIOCSIWNICKN\n"); rc = -EOPNOTSUPP; break; // Get current station name case SIOCGIWNICKN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWNICKN\n"); + pr_debug(" SIOCGIWNICKN\n"); rc = -EOPNOTSUPP; break; @@ -2863,12 +2876,12 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) // Get the current Tx-Power case SIOCGIWTXPOW: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWTXPOW\n"); + pr_debug(" SIOCGIWTXPOW\n"); rc = -EOPNOTSUPP; break; case SIOCSIWTXPOW: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWTXPOW\n"); + pr_debug(" SIOCSIWTXPOW\n"); rc = -EOPNOTSUPP; break; @@ -2911,7 +2924,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; case SIOCSIWSENS: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSENS\n"); + pr_debug(" SIOCSIWSENS\n"); rc = -EOPNOTSUPP; break; @@ -2935,50 +2948,50 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) // Set the spy list case SIOCSIWSPY: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSPY\n"); + pr_debug(" SIOCSIWSPY\n"); rc = -EOPNOTSUPP; break; // Get the spy list case SIOCGIWSPY: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSPY\n"); + pr_debug(" SIOCGIWSPY\n"); rc = -EOPNOTSUPP; break; #endif // WIRELESS_SPY case SIOCGIWPRIV: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPRIV\n"); + pr_debug(" SIOCGIWPRIV\n"); rc = -EOPNOTSUPP; break; //2008-0409-07, by Einsn Liu #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT case SIOCSIWAUTH: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n"); + pr_debug(" SIOCSIWAUTH\n"); rc = iwctl_siwauth(dev, NULL, &(wrq->u.param), NULL); break; case SIOCGIWAUTH: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAUTH\n"); + pr_debug(" SIOCGIWAUTH\n"); rc = iwctl_giwauth(dev, NULL, &(wrq->u.param), NULL); break; case SIOCSIWGENIE: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWGENIE\n"); + pr_debug(" SIOCSIWGENIE\n"); rc = iwctl_siwgenie(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); break; case SIOCGIWGENIE: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWGENIE\n"); + 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]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODEEXT\n"); + 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)) { @@ -2998,12 +3011,12 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) break; case SIOCGIWENCODEEXT: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODEEXT\n"); + pr_debug(" SIOCGIWENCODEEXT\n"); rc = iwctl_giwencodeext(dev, NULL, &(wrq->u.encoding), NULL); break; case SIOCSIWMLME: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMLME\n"); + pr_debug(" SIOCSIWMLME\n"); rc = iwctl_siwmlme(dev, NULL, &(wrq->u.data), wrq->u.data.pointer); break; @@ -3061,7 +3074,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) default: rc = -EOPNOTSUPP; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Ioctl command not support..%x\n", cmd); + pr_debug("Ioctl command not support..%x\n", cmd); } @@ -3072,7 +3085,7 @@ static int device_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) bScheduleCommand((void *)pDevice, WLAN_CMD_RUN_AP, NULL); spin_unlock_irq(&pDevice->lock); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Commit the settings\n"); + pr_debug("Commit the settings\n"); spin_lock_irq(&pDevice->lock); pDevice->bLinkPass = false; memset(pMgmt->abyCurrBSSID, 0, 6); diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index d26ca96d2da4..7589cb4805f9 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -61,8 +61,6 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - static const unsigned char acbyRxRate[MAX_RATE] = {2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108}; @@ -325,7 +323,7 @@ device_receive_frame( // Min (ACK): 10HD +4CRC + 2Padding + 4Len + 8TSF + 4RSR if ((FrameSize > 2364) || (FrameSize <= 32)) { // Frame Size error drop this packet. - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 1\n"); + pr_debug("---------- WRONG Length 1\n"); return false; } @@ -343,7 +341,7 @@ device_receive_frame( if ((FrameSize > 2346)|(FrameSize < 14)) { // Max: 2312Payload + 30HD +4CRC // Min: 14 bytes ACK - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "---------- WRONG Length 2\n"); + pr_debug("---------- WRONG Length 2\n"); return false; } //PLICE_DEBUG-> @@ -421,7 +419,7 @@ device_receive_frame( if (IS_FC_WEP(pbyFrame)) { bool bRxDecryOK = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx WEP pkt\n"); + pr_debug("rx WEP pkt\n"); bIsWEP = true; if ((pDevice->bEnableHostWEP) && (iSANodeIndex >= 0)) { pKey = &STempKey; @@ -459,7 +457,7 @@ device_receive_frame( if (bRxDecryOK) { if ((*pbyNewRsr & NEWRSR_DECRYPTOK) == 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV Fail\n"); + pr_debug("ICV Fail\n"); if ((pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || (pDevice->pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) || @@ -473,7 +471,7 @@ device_receive_frame( return false; } } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP Func Fail\n"); + pr_debug("WEP Func Fail\n"); return false; } if ((pKey != NULL) && (pKey->byCipherSuite == KEY_CTL_CCMP)) @@ -554,8 +552,8 @@ device_receive_frame( if (!(*pbyRsr & RSR_BSSIDOK)) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc more frag bufs\n", + pDevice->dev->name); } } return false; @@ -565,8 +563,8 @@ device_receive_frame( if (!pDevice->bLinkPass || !(*pbyRsr & RSR_BSSIDOK)) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc more frag bufs\n", + pDevice->dev->name); } } return false; @@ -642,7 +640,7 @@ device_receive_frame( wEtherType = (skb->data[cbIVOffset + 4 + 24 + 6] << 8) | skb->data[cbIVOffset + 4 + 24 + 6 + 1]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wEtherType = %04x\n", wEtherType); + pr_debug("wEtherType = %04x\n", wEtherType); if (wEtherType == ETH_P_PAE) { skb->dev = pDevice->apdev; @@ -717,13 +715,13 @@ device_receive_frame( if ((le32_to_cpu(*pdwMIC_L) != dwLocalMIC_L) || (le32_to_cpu(*pdwMIC_R) != dwLocalMIC_R) || pDevice->bRxMICFail) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC comparison is fail!\n"); + 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])) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc more frag bufs\n", + pDevice->dev->name); } } //2008-0409-07, by Einsn Liu @@ -804,7 +802,7 @@ device_receive_frame( if ((wRxTSC15_0 < wLocalTSC15_0) && (dwRxTSC47_16 <= dwLocalTSC47_16) && !((dwRxTSC47_16 == 0) && (dwLocalTSC47_16 == 0xFFFFFFFF))) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC is illegal~~!\n "); + pr_debug("TSC is illegal~~!\n "); if (pKey->byCipherSuite == KEY_CTL_TKIP) pDevice->s802_11Counter.TKIPReplays++; else @@ -812,8 +810,8 @@ device_receive_frame( if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc more frag bufs\n", + pDevice->dev->name); } } return false; @@ -840,8 +838,8 @@ device_receive_frame( )) { if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc more frag bufs\n", + pDevice->dev->name); } } return false; @@ -862,8 +860,8 @@ device_receive_frame( if (bDeFragRx) { if (!device_alloc_frag_buf(pDevice, &pDevice->sRxDFCB[pDevice->uCurrentDFCBIdx])) { - DBG_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: can not alloc more frag bufs\n", - pDevice->dev->name); + pr_err("%s: can not alloc more frag bufs\n", + pDevice->dev->name); } return false; } @@ -897,7 +895,7 @@ static bool s_bAPModeRxCtl( (WLAN_MGMT_REASON_CLASS2_NONAUTH), &Status ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n"); + pr_debug("dpc: send vMgrDeAuthenBeginSta 1\n"); return true; } if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) { @@ -909,7 +907,7 @@ static bool s_bAPModeRxCtl( (WLAN_MGMT_REASON_CLASS3_NONASSOC), &Status ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n"); + pr_debug("dpc: send vMgrDisassocBeginSta 2\n"); return true; } @@ -918,7 +916,7 @@ static bool s_bAPModeRxCtl( if (IS_CTL_PSPOLL(pbyFrame)) { pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 1\n"); + pr_debug("dpc: WLAN_CMD_RX_PSPOLL 1\n"); } else { // check Data PS state // if PW bit off, send out all PS bufferring packets. @@ -926,7 +924,7 @@ static bool s_bAPModeRxCtl( pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 2\n"); + pr_debug("dpc: WLAN_CMD_RX_PSPOLL 2\n"); } } } else { @@ -940,7 +938,7 @@ static bool s_bAPModeRxCtl( pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable = false; pMgmt->sNodeDBTable[iSANodeIndex].bRxPSPoll = true; bScheduleCommand((void *)pDevice, WLAN_CMD_RX_PSPOLL, NULL); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: WLAN_CMD_RX_PSPOLL 3\n"); + pr_debug("dpc: WLAN_CMD_RX_PSPOLL 3\n"); } } @@ -952,16 +950,18 @@ static bool s_bAPModeRxCtl( (WLAN_MGMT_REASON_CLASS2_NONAUTH), &Status ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%pM\n", - p802_11Header->abyAddr3); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%pM\n", - p802_11Header->abyAddr2); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%pM\n", - p802_11Header->abyAddr1); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl); + 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)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode); + pr_debug("dpc:pDevice->byRxMode = %x\n", + pDevice->byRxMode); return true; } } @@ -999,7 +999,7 @@ static bool s_bHandleRxEncryption( } byKeyIdx = (*(pbyIV+3) & 0xc0); byKeyIdx >>= 6; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\nKeyIdx: %d\n", byKeyIdx); + pr_debug("\nKeyIdx: %d\n", byKeyIdx); if ((pMgmt->eAuthenMode == WMAC_AUTH_WPA) || (pMgmt->eAuthenMode == WMAC_AUTH_WPAPSK) || @@ -1009,14 +1009,14 @@ static bool s_bHandleRxEncryption( if (((*pbyRsr & (RSR_ADDRBROAD | RSR_ADDRMULTI)) == 0) && (pDevice->pMgmt->byCSSPK != KEY_CTL_NONE)) { // unicast pkt use pairwise key - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unicast pkt\n"); + 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; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "unicast pkt: %d, %p\n", byDecMode, pKey); + pr_debug("unicast pkt: %d, %p\n", byDecMode, pKey); } else { // use group key KeybGetKey(&(pDevice->sKey), pDevice->abyBSSID, byKeyIdx, &pKey); @@ -1024,7 +1024,8 @@ static bool s_bHandleRxEncryption( byDecMode = KEY_CTL_TKIP; else if (pDevice->pMgmt->byCSSGK == KEY_CTL_CCMP) byDecMode = KEY_CTL_CCMP; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group pkt: %d, %d, %p\n", byKeyIdx, byDecMode, pKey); + pr_debug("group pkt: %d, %d, %p\n", + byKeyIdx, byDecMode, pKey); } } // our WEP only support Default Key @@ -1038,10 +1039,11 @@ static bool s_bHandleRxEncryption( } *pKeyOut = pKey; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); + pr_debug("AES:%d %d %d\n", + pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); if (pKey == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey == NULL\n"); + pr_debug("pKey == NULL\n"); return false; } @@ -1074,13 +1076,13 @@ static bool s_bHandleRxEncryption( 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)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ExtIV: %lx\n", *pdwRxTSC47_16); + 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); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC0_15: %x\n", *pwRxTSC15_0); + pr_debug("TSC0_15: %x\n", *pwRxTSC15_0); if ((byDecMode == KEY_CTL_TKIP) && (pDevice->byLocalID <= REV_ID_VT3253_A1)) { @@ -1093,10 +1095,10 @@ static bool s_bHandleRxEncryption( rc4_encrypt(&pDevice->SBox, pbyIV+8, pbyIV+8, PayloadLen); if (ETHbIsBufferCrc32Ok(pbyIV+8, PayloadLen)) { *pbyNewRsr |= NEWRSR_DECRYPTOK; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV OK!\n"); + pr_debug("ICV OK!\n"); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV FAIL!!!\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PayloadLen = %d\n", PayloadLen); + pr_debug("ICV FAIL!!!\n"); + pr_debug("PayloadLen = %d\n", PayloadLen); } } }// end of TKIP/AES @@ -1136,21 +1138,22 @@ static bool s_bHostWepRxEncryption( } byKeyIdx = (*(pbyIV+3) & 0xc0); byKeyIdx >>= 6; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\nKeyIdx: %d\n", byKeyIdx); + 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; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AES:%d %d %d\n", pDevice->pMgmt->byCSSPK, pDevice->pMgmt->byCSSGK, byDecMode); + 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 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byDecMode == KEY_CTL_WEP\n"); + pr_debug("byDecMode == KEY_CTL_WEP\n"); if ((pDevice->byLocalID <= REV_ID_VT3253_A1) || (((PSKeyTable)(pKey->pvKeyTable))->bSoftWEP == true) || @@ -1176,31 +1179,32 @@ static bool s_bHostWepRxEncryption( 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)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ExtIV: %lx\n", *pdwRxTSC47_16); + 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); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "TSC0_15: %x\n", *pwRxTSC15_0); + 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 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_TKIP\n"); + 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; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV OK!\n"); + pr_debug("ICV OK!\n"); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ICV FAIL!!!\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PayloadLen = %d\n", PayloadLen); + pr_debug("ICV FAIL!!!\n"); + pr_debug("PayloadLen = %d\n", + PayloadLen); } } } @@ -1209,12 +1213,12 @@ static bool s_bHostWepRxEncryption( if (!bOnFly) { // Software CCMP // NotOnFly - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "soft KEY_CTL_CCMP\n"); + pr_debug("soft KEY_CTL_CCMP\n"); if (AESbGenCCMP(pKey->abyKey, pbyFrame, FrameSize)) { *pbyNewRsr |= NEWRSR_DECRYPTOK; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CCMP MIC compare OK!\n"); + pr_debug("CCMP MIC compare OK!\n"); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "CCMP MIC fail!\n"); + pr_debug("CCMP MIC fail!\n"); } } } @@ -1252,7 +1256,7 @@ static bool s_bAPModeRxData( // if any node in PS mode, buffer packet until DTIM. if (skbcpy == NULL) { - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "relay multicast no skb available\n"); + pr_info("relay multicast no skb available\n"); } else { skbcpy->dev = pDevice->dev; skbcpy->len = FrameSize; @@ -1280,8 +1284,9 @@ static bool s_bAPModeRxData( pMgmt->sNodeDBTable[iDANodeIndex].wEnQueueCnt++; wAID = pMgmt->sNodeDBTable[iDANodeIndex].wAID; pMgmt->abyPSTxMap[wAID >> 3] |= byMask[wAID & 7]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n", - iDANodeIndex, (wAID >> 3), pMgmt->abyPSTxMap[wAID >> 3]); + pr_debug("relay: index= %d, pMgmt->abyPSTxMap[%d]= %d\n", + iDANodeIndex, (wAID >> 3), + pMgmt->abyPSTxMap[wAID >> 3]); return true; } else { bRelayOnly = true; diff --git a/drivers/staging/vt6655/hostap.c b/drivers/staging/vt6655/hostap.c index c10a1b56ebb8..0dd87d481280 100644 --- a/drivers/staging/vt6655/hostap.c +++ b/drivers/staging/vt6655/hostap.c @@ -47,9 +47,6 @@ /*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - /*--------------------- Static Functions --------------------------*/ /*--------------------- Export Variables --------------------------*/ @@ -77,7 +74,7 @@ static int hostap_enable_hostapd(struct vnt_private *pDevice, int rtnl_locked) .ndo_start_xmit = pDevice->tx_80211, }; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Enabling hostapd mode\n", dev->name); + pr_debug("%s: Enabling hostapd mode\n", dev->name); pDevice->apdev = alloc_etherdev(sizeof(*apdev_priv)); if (pDevice->apdev == NULL) @@ -101,15 +98,15 @@ static int hostap_enable_hostapd(struct vnt_private *pDevice, int rtnl_locked) else ret = register_netdev(pDevice->apdev); if (ret) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdevice(AP) failed!\n", - dev->name); + pr_debug("%s: register_netdevice(AP) failed!\n", + dev->name); free_netdev(pDevice->apdev); pDevice->apdev = NULL; return -1; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdevice %s for AP management\n", - dev->name, pDevice->apdev->name); + pr_debug("%s: Registered netdevice %s for AP management\n", + dev->name, pDevice->apdev->name); KeyvInitTable(&pDevice->sKey, pDevice->PortOffset); @@ -132,15 +129,15 @@ static int hostap_enable_hostapd(struct vnt_private *pDevice, int rtnl_locked) static int hostap_disable_hostapd(struct vnt_private *pDevice, int rtnl_locked) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: disabling hostapd mode\n", pDevice->dev->name); + 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); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", - pDevice->dev->name, pDevice->apdev->name); + pr_debug("%s: Netdevice %s unregistered\n", + pDevice->dev->name, pDevice->apdev->name); } if (pDevice->apdev) free_netdev(pDevice->apdev); @@ -257,17 +254,10 @@ static int hostap_add_sta(struct vnt_private *pDevice, pMgmt->sNodeDBTable[uNodeIndex].ulLastRxJiffer = jiffies; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Add STA AID= %d\n", pMgmt->sNodeDBTable[uNodeIndex].wAID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", - param->sta_addr[0], - param->sta_addr[1], - param->sta_addr[2], - param->sta_addr[3], - param->sta_addr[4], - param->sta_addr[5] - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Max Support rate = %d\n", - pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); + 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; } @@ -324,8 +314,8 @@ static int hostap_set_flags_sta(struct vnt_private *pDevice, 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; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " dwFlags = %x\n", - (unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); + pr_debug(" dwFlags = %x\n", + (unsigned int)pMgmt->sNodeDBTable[uNodeIndex].dwFlags); } else { return -ENOENT; } @@ -358,18 +348,18 @@ static int hostap_set_generic_element(struct vnt_private *pDevice, pMgmt->wWPAIELen = param->u.generic_elem.len; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen); + pr_debug("pMgmt->wWPAIELen = %d\n", pMgmt->wWPAIELen); // disable wpa if (pMgmt->wWPAIELen == 0) { pMgmt->eAuthenMode = WMAC_AUTH_OPEN; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " No WPAIE, Disable WPA\n"); + 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; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set WPAIE enable WPA\n"); + pr_debug("Set WPAIE enable WPA\n"); } else return -EINVAL; } @@ -432,7 +422,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice, if ((param->u.crypt.idx > 3) || (param->u.crypt.key_len > MAX_KEY_LEN)) { param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n"); + pr_debug(" HOSTAP_CRYPT_ERR_KEY_SET_FAILED\n"); return -EINVAL; } @@ -444,12 +434,12 @@ static int hostap_set_encryption(struct vnt_private *pDevice, } else { if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); + pr_debug(" HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); return -EINVAL; } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: sta_index %d\n", iNodeIndex); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " hostap_set_encryption: alg %d\n", param->u.crypt.alg); + 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) { @@ -457,7 +447,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice, param->sta_addr, pMgmt->sNodeDBTable[iNodeIndex].dwKeyIndex, pDevice->PortOffset)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybRemoveKey fail\n"); + pr_debug("KeybRemoveKey fail\n"); } pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; } @@ -588,7 +578,7 @@ static int hostap_set_encryption(struct vnt_private *pDevice, // Key Table Full pMgmt->sNodeDBTable[iNodeIndex].bOnFly = false; bKeyTableFull = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Key Table Full\n"); + pr_debug(" Key Table Full\n"); } } @@ -602,16 +592,15 @@ static int hostap_set_encryption(struct vnt_private *pDevice, MACvSetDefaultKeyCtl(pDevice->PortOffset, wKeyCtl, MAX_KEY_TABLE-1, pDevice->byLocalID); } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set key sta_index= %d\n", iNodeIndex); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " tx_index=%d len=%d\n", param->u.crypt.idx, - param->u.crypt.key_len); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 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] -); + 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; @@ -651,11 +640,11 @@ static int hostap_get_encryption(struct vnt_private *pDevice, } else { if (BSSDBbIsSTAInNodeDB(pMgmt, param->sta_addr, &iNodeIndex) == false) { param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); + pr_debug("hostap_get_encryption: HOSTAP_CRYPT_ERR_UNKNOWN_ADDR\n"); return -EINVAL; } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "hostap_get_encryption: %d\n", iNodeIndex); + 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); @@ -697,67 +686,67 @@ int vt6655_hostap_ioctl(struct vnt_private *pDevice, struct iw_point *p) switch (param->cmd) { case VIAWGET_HOSTAPD_SET_ENCRYPTION: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ENCRYPTION\n"); + 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: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_ENCRYPTION\n"); + 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: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR\n"); + pr_debug("VIAWGET_HOSTAPD_SET_ASSOC_AP_ADDR\n"); ret = -EOPNOTSUPP; goto out; case VIAWGET_HOSTAPD_FLUSH: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_FLUSH\n"); + 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: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_ADD_STA\n"); + 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: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_REMOVE_STA\n"); + 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: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_GET_INFO_STA\n"); + 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: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_FLAGS_STA\n"); + pr_debug("VIAWGET_HOSTAPD_SET_FLAGS_STA\n"); ret = hostap_set_flags_sta(pDevice, param); break; case VIAWGET_HOSTAPD_MLME: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_MLME\n"); + pr_debug("VIAWGET_HOSTAPD_MLME\n"); ret = -EOPNOTSUPP; goto out; case VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT\n"); + pr_debug("VIAWGET_HOSTAPD_SET_GENERIC_ELEMENT\n"); ret = hostap_set_generic_element(pDevice, param); break; case VIAWGET_HOSTAPD_SCAN_REQ: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_SCAN_REQ\n"); + pr_debug("VIAWGET_HOSTAPD_SCAN_REQ\n"); ret = -EOPNOTSUPP; goto out; case VIAWGET_HOSTAPD_STA_CLEAR_STATS: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_HOSTAPD_STA_CLEAR_STATS\n"); + pr_debug("VIAWGET_HOSTAPD_STA_CLEAR_STATS\n"); ret = -EOPNOTSUPP; goto out; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vt6655_hostap_ioctl: unknown cmd=%d\n", - (int)param->cmd); + pr_debug("vt6655_hostap_ioctl: unknown cmd=%d\n", + (int)param->cmd); ret = -EOPNOTSUPP; goto out; } diff --git a/drivers/staging/vt6655/ioctl.c b/drivers/staging/vt6655/ioctl.c index 306a7db937f7..970e80d92fb9 100644 --- a/drivers/staging/vt6655/ioctl.c +++ b/drivers/staging/vt6655/ioctl.c @@ -38,8 +38,6 @@ #include "wpactl.h" #include "rf.h" -static int msglevel = MSG_LEVEL_INFO; - #ifdef WPA_SM_Transtatus SWPAResult wpa_Result; #endif @@ -74,7 +72,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) switch (pReq->wCmdCode) { case WLAN_CMD_BSS_SCAN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_BSS_SCAN..begin\n"); + pr_debug("WLAN_CMD_BSS_SCAN..begin\n"); if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) { result = -EFAULT; break; @@ -175,27 +173,27 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) memcpy(pMgmt->abyDesireSSID, pItemSSID, pItemSSID->len + WLAN_IEHDR_LEN); if (sJoinCmd.wBSSType == ADHOC) { pMgmt->eConfigMode = WMAC_CONFIG_IBSS_STA; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to adhoc mode\n"); + pr_debug("ioct set to adhoc mode\n"); } else { pMgmt->eConfigMode = WMAC_CONFIG_ESS_STA; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to STA mode\n"); + pr_debug("ioct set to STA mode\n"); } if (sJoinCmd.bPSEnable == true) { pDevice->ePSMode = WMAC_POWER_FAST; pMgmt->wListenInterval = 2; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving On\n"); + pr_debug("Power Saving On\n"); } else { pDevice->ePSMode = WMAC_POWER_CAM; pMgmt->wListenInterval = 1; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Power Saving Off\n"); + pr_debug("Power Saving Off\n"); } if (sJoinCmd.bShareKeyAuth == true) { pMgmt->bShareKeyAlgorithm = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key\n"); + pr_debug("Share Key\n"); } else { pMgmt->bShareKeyAlgorithm = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System\n"); + pr_debug("Open System\n"); } pDevice->uChannel = sJoinCmd.uChannel; netif_stop_queue(pDevice->dev); @@ -207,7 +205,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) break; case WLAN_CMD_SET_WEP: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WEP Key.\n"); + pr_debug("WLAN_CMD_SET_WEP Key\n"); memset(&sWEPCmd, 0, sizeof(SCmdSetWEP)); if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) { result = -EFAULT; @@ -217,7 +215,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) pDevice->bEncryptionEnable = false; pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled; MACvDisableDefaultKey(pDevice->PortOffset); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WEP function disable.\n"); + pr_debug("WEP function disable\n"); break; } @@ -247,7 +245,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) case WLAN_CMD_GET_LINK: { SCmdLinkStatus sLinkStatus; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_GET_LINK status.\n"); + pr_debug("WLAN_CMD_GET_LINK status\n"); memset(&sLinkStatus, 0, sizeof(sLinkStatus)); @@ -268,7 +266,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) memcpy(sLinkStatus.abySSID, pItemSSID->abySSID, pItemSSID->len); memcpy(sLinkStatus.abyBSSID, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); sLinkStatus.uLinkRate = pMgmt->sNodeDBTable[0].wTxDataRate; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Link Success!\n"); + pr_debug(" Link Success!\n"); } else { sLinkStatus.bLink = false; sLinkStatus.uLinkRate = 0; @@ -364,7 +362,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) break; case WLAN_CMD_STOP_MAC: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_STOP_MAC\n"); + pr_debug("WLAN_CMD_STOP_MAC\n"); netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); @@ -383,7 +381,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) break; case WLAN_CMD_START_MAC: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_START_MAC\n"); + pr_debug("WLAN_CMD_START_MAC\n"); if (pDevice->bMACSuspend == true) { if (pDevice->bRadioOff == true) @@ -396,7 +394,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) break; case WLAN_CMD_SET_HOSTAPD: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD\n"); + pr_debug("WLAN_CMD_SET_HOSTAPD\n"); if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { result = -EFAULT; @@ -404,23 +402,23 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) } if (sValue.dwValue == 1) { if (vt6655_hostap_set_hostapd(pDevice, 1, 1) == 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n"); + pr_debug("Enable HOSTAP\n"); } else { result = -EFAULT; break; } } else { vt6655_hostap_set_hostapd(pDevice, 0, 1); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HOSTAP\n"); + pr_debug("Disable HOSTAP\n"); } break; case WLAN_CMD_SET_HOSTAPD_STA: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOSTAPD_STA\n"); + pr_debug("WLAN_CMD_SET_HOSTAPD_STA\n"); break; case WLAN_CMD_SET_802_1X: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_802_1X\n"); + pr_debug("WLAN_CMD_SET_802_1X\n"); if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { result = -EFAULT; break; @@ -428,15 +426,15 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) if (sValue.dwValue == 1) { pDevice->bEnable8021x = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable 802.1x\n"); + pr_debug("Enable 802.1x\n"); } else { pDevice->bEnable8021x = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable 802.1x\n"); + pr_debug("Disable 802.1x\n"); } break; case WLAN_CMD_SET_HOST_WEP: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_HOST_WEP\n"); + pr_debug("WLAN_CMD_SET_HOST_WEP\n"); if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { result = -EFAULT; break; @@ -444,32 +442,32 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) if (sValue.dwValue == 1) { pDevice->bEnableHostWEP = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HostWEP\n"); + pr_debug("Enable HostWEP\n"); } else { pDevice->bEnableHostWEP = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable HostWEP\n"); + pr_debug("Disable HostWEP\n"); } break; case WLAN_CMD_SET_WPA: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_SET_WPA\n"); + pr_debug("WLAN_CMD_SET_WPA\n"); if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) { result = -EFAULT; break; } if (sValue.dwValue == 1) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n"); + pr_debug("up wpadev\n"); eth_hw_addr_inherit(pDevice->wpadev, pDevice->dev); pDevice->bWPADEVUp = true; } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "close wpadev\n"); + pr_debug("close wpadev\n"); pDevice->bWPADEVUp = false; } break; case WLAN_CMD_AP_START: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WLAN_CMD_AP_START\n"); + pr_debug("WLAN_CMD_AP_START\n"); if (pDevice->bRadioOff == true) { CARDbRadioPowerOn(pDevice); vMgrTimerInit(pDevice); @@ -483,9 +481,9 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) if (sStartAPCmd.wBSSType == AP) { pMgmt->eConfigMode = WMAC_CONFIG_AP; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct set to AP mode\n"); + pr_debug("ioct set to AP mode\n"); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ioct BSS type not set to AP mode\n"); + pr_debug("ioct BSS type not set to AP mode\n"); result = -EFAULT; break; } @@ -513,10 +511,10 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) if (sStartAPCmd.bShareKeyAuth == true) { pMgmt->bShareKeyAlgorithm = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Share Key\n"); + pr_debug("Share Key\n"); } else { pMgmt->bShareKeyAlgorithm = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Open System\n"); + pr_debug("Open System\n"); } memcpy(pMgmt->abyIBSSSuppRates, abySuppRates, 6); @@ -540,8 +538,8 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) pMgmt->abyIBSSSuppRates[3] |= BIT7; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Support Rate= %*ph\n", - 4, pMgmt->abyIBSSSuppRates + 2); + pr_debug("Support Rate= %*ph\n", + 4, pMgmt->abyIBSSSuppRates + 2); netif_stop_queue(pDevice->dev); spin_lock_irq(&pDevice->lock); @@ -597,12 +595,12 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) pNodeList->sNodeList[jj].byKeyIndex = pNode->byKeyIndex; pNodeList->sNodeList[jj].wWepKeyLength = pNode->uWepKeyLength; memcpy(&(pNodeList->sNodeList[jj].abyWepKey[0]), &(pNode->abyWepKey[0]), WEP_KEYMAXLEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "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]); + 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; @@ -653,7 +651,7 @@ int private_ioctl(struct vnt_private *pDevice, struct ifreq *rq) #endif default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Private command not support..\n"); + pr_debug("Private command not support..\n"); } return result; diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 0c73064a147d..6a6bdd31cfd7 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -66,9 +66,6 @@ static const long frequency_list[] = { }; /*--------------------- Static Classes ----------------------------*/ - -static int msglevel = MSG_LEVEL_INFO; - /*--------------------- Static Variables --------------------------*/ /*--------------------- Static Functions --------------------------*/ @@ -108,7 +105,7 @@ static int iwctl_commit(struct net_device *dev, void *wrq, char *extra) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWCOMMIT\n"); + pr_debug(" SIOCSIWCOMMIT\n"); return 0; } @@ -140,7 +137,7 @@ static int iwctl_siwscan(struct net_device *dev, unsigned char abyScanSSID[WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1]; PWLAN_IE_SSID pItemSSID = NULL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWSCAN\n"); + pr_debug(" SIOCSIWSCAN\n"); if (pDevice->byReAssocCount > 0) { //reject scan when re-associating! //send scan event to wpa_Supplicant @@ -210,7 +207,7 @@ static int iwctl_giwscan(struct net_device *dev, long ldBm; char buf[MAX_WPA_IE_LEN * 2 + 30]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSCAN\n"); + pr_debug(" SIOCGIWSCAN\n"); if (pMgmt->eScanState == WMAC_IS_SCANNING) { // In scanning.. @@ -353,7 +350,7 @@ int iwctl_siwfreq(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFREQ\n"); + pr_debug(" SIOCSIWFREQ\n"); // If setting by frequency, convert to a channel if ((wrq->e == 1) && @@ -374,11 +371,12 @@ int iwctl_siwfreq(struct net_device *dev, int channel = wrq->m; if ((channel < 1) || (channel > 14)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: New channel value of %d is invalid!\n", dev->name, wrq->m); + pr_debug("%s: New channel value of %d is invalid!\n", + dev->name, wrq->m); rc = -EINVAL; } else { // Yes ! We can set it !!! - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set to channel = %d\n", channel); + pr_debug(" Set to channel = %d\n", channel); pDevice->uChannel = channel; //2007-0207-04, by EinsnLiu //Make change effect at once @@ -401,7 +399,7 @@ int iwctl_giwfreq(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFREQ\n"); + pr_debug(" SIOCGIWFREQ\n"); #ifdef WEXT_USECHANNELS wrq->m = (int)pMgmt->uCurrChannel; @@ -433,10 +431,10 @@ int iwctl_siwmode(struct net_device *dev, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWMODE\n"); + pr_debug(" SIOCSIWMODE\n"); if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP && pDevice->bEnableHostapd) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Can't set operation mode, hostapd is running\n"); + pr_debug("Can't set operation mode, hostapd is running\n"); return rc; } @@ -448,7 +446,7 @@ int iwctl_siwmode(struct net_device *dev, pDevice->bCommit = true; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to ad-hoc\n"); + pr_debug("set mode to ad-hoc\n"); break; case IW_MODE_AUTO: case IW_MODE_INFRA: @@ -458,7 +456,7 @@ int iwctl_siwmode(struct net_device *dev, pDevice->bCommit = true; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to infrastructure\n"); + pr_debug("set mode to infrastructure\n"); break; case IW_MODE_MASTER: @@ -472,7 +470,7 @@ int iwctl_siwmode(struct net_device *dev, pDevice->bCommit = true; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set mode to Access Point\n"); + pr_debug("set mode to Access Point\n"); break; case IW_MODE_REPEAT: @@ -498,7 +496,7 @@ int iwctl_giwmode(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWMODE\n"); + pr_debug(" SIOCGIWMODE\n"); // If not managed, assume it's ad-hoc switch (pMgmt->eConfigMode) { case WMAC_CONFIG_ESS_STA: @@ -533,7 +531,7 @@ int iwctl_giwrange(struct net_device *dev, int i, k; unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRANGE\n"); + pr_debug(" SIOCGIWRANGE\n"); if (wrq->pointer) { wrq->length = sizeof(struct iw_range); memset(range, 0, sizeof(struct iw_range)); @@ -640,7 +638,7 @@ int iwctl_siwap(struct net_device *dev, int rc = 0; unsigned char ZeroBSSID[WLAN_BSSID_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAP\n"); + pr_debug(" SIOCSIWAP\n"); if (pMgmt->eScanState == WMAC_IS_SCANNING) { // In scanning.. pr_debug("SIOCSIWAP(??)-->In scanning..\n"); @@ -697,7 +695,7 @@ int iwctl_giwap(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAP\n"); + pr_debug(" SIOCGIWAP\n"); memcpy(wrq->sa_data, pMgmt->abyCurrBSSID, 6); //2008-0410, by Einsn Liu @@ -731,7 +729,7 @@ int iwctl_giwaplist(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWAPLIST\n"); + pr_debug(" SIOCGIWAPLIST\n"); if (!capable(CAP_NET_ADMIN)) { rc = -EPERM; @@ -800,7 +798,7 @@ int iwctl_siwessid(struct net_device *dev, //2008-0409-05, by Einsn Liu unsigned char len; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWESSID\n"); + pr_debug(" SIOCSIWESSID\n"); pDevice->fWPA_Authened = false; if (pMgmt->eScanState == WMAC_IS_SCANNING) { // In scanning.. @@ -885,7 +883,7 @@ int iwctl_siwessid(struct net_device *dev, } #endif - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "set essid = %s\n", pItemSSID->abySSID); + pr_debug("set essid = %s\n", pItemSSID->abySSID); } if (pDevice->flags & DEVICE_FLAGS_OPENED) @@ -907,7 +905,7 @@ int iwctl_giwessid(struct net_device *dev, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); PWLAN_IE_SSID pItemSSID; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWESSID\n"); + pr_debug(" SIOCGIWESSID\n"); // Note : if wrq->u.data.flags != 0, we should // get the relevant SSID from the SSID list... @@ -939,7 +937,7 @@ int iwctl_siwrate(struct net_device *dev, int i; unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRATE\n"); + pr_debug(" SIOCSIWRATE\n"); if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { rc = -EINVAL; return rc; @@ -993,7 +991,8 @@ int iwctl_siwrate(struct net_device *dev, pDevice->uConnectionRate = 3; } else { pDevice->uConnectionRate = brate; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fixed to Rate %d\n", pDevice->uConnectionRate); + pr_debug("Fixed to Rate %d\n", + pDevice->uConnectionRate); } } else { @@ -1019,7 +1018,7 @@ int iwctl_giwrate(struct net_device *dev, //Mark the unnecessary sentences. // PSMgmtObject pMgmt = &(pDevice->sMgmtObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRATE\n"); + pr_debug(" SIOCGIWRATE\n"); { unsigned char abySupportedRates[13] = {0x02, 0x04, 0x0B, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x90}; int brate = 0; @@ -1062,7 +1061,7 @@ int iwctl_siwrts(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRTS\n"); + pr_debug(" SIOCSIWRTS\n"); { int rthr = wrq->value; @@ -1090,7 +1089,7 @@ int iwctl_giwrts(struct net_device *dev, { struct vnt_private *pDevice = netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRTS\n"); + pr_debug(" SIOCGIWRTS\n"); wrq->value = pDevice->wRTSThreshold; wrq->disabled = (wrq->value >= 2312); wrq->fixed = 1; @@ -1111,7 +1110,7 @@ int iwctl_siwfrag(struct net_device *dev, int rc = 0; int fthr = wrq->value; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWFRAG\n"); + pr_debug(" SIOCSIWFRAG\n"); if (wrq->disabled) fthr = 2312; @@ -1136,7 +1135,7 @@ int iwctl_giwfrag(struct net_device *dev, { struct vnt_private *pDevice = netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWFRAG\n"); + pr_debug(" SIOCGIWFRAG\n"); wrq->value = pDevice->wFragmentationThreshold; wrq->disabled = (wrq->value >= 2312); wrq->fixed = 1; @@ -1155,7 +1154,7 @@ int iwctl_siwretry(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWRETRY\n"); + pr_debug(" SIOCSIWRETRY\n"); if (wrq->disabled) { rc = -EINVAL; @@ -1189,7 +1188,7 @@ int iwctl_giwretry(struct net_device *dev, { struct vnt_private *pDevice = netdev_priv(dev); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWRETRY\n"); + pr_debug(" SIOCGIWRETRY\n"); wrq->disabled = 0; // Can't be disabled // Note : by default, display the min retry number @@ -1234,7 +1233,7 @@ int iwctl_siwencode(struct net_device *dev, PSKeyTable pkeytab; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWENCODE\n"); + pr_debug(" SIOCSIWENCODE\n"); if ((wrq->flags & IW_ENCODE_DISABLED) == 0) { //Not disable encryption @@ -1262,11 +1261,12 @@ int iwctl_siwencode(struct net_device *dev, if (wrq->length > 0) {//have key if (wrq->length == WLAN_WEP232_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 232 bit wep key\n"); + pr_debug("Set 232 bit wep key\n"); } else if (wrq->length == WLAN_WEP104_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 104 bit wep key\n"); + pr_debug("Set 104 bit wep key\n"); } else if (wrq->length == WLAN_WEP40_KEYLEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Set 40 bit wep key, index= %d\n", (int)dwKeyIndex); + pr_debug("Set 40 bit wep key, index= %d\n", + (int)dwKeyIndex); } else {//no support length rc = -EINVAL; return rc; @@ -1274,9 +1274,9 @@ int iwctl_siwencode(struct net_device *dev, memset(pDevice->abyKey, 0, WLAN_WEP232_KEYLEN); memcpy(pDevice->abyKey, extra, wrq->length); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "abyKey: "); + pr_debug("abyKey: "); for (ii = 0; ii < wrq->length; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pDevice->abyKey[ii]); + pr_debug("%02x ", pDevice->abyKey[ii]); if (pDevice->flags & DEVICE_FLAGS_OPENED) { spin_lock_irq(&pDevice->lock); @@ -1304,10 +1304,10 @@ int iwctl_siwencode(struct net_device *dev, rc = -EINVAL; return rc; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Just set Default key Index:\n"); + pr_debug("Just set Default key Index:\n"); pkeytab = &(pDevice->sKey.KeyTable[MAX_KEY_TABLE - 1]); if (pkeytab->GroupKey[(unsigned char)dwKeyIndex].uKeyLength == 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Default key len is 0\n"); + pr_debug("Default key len is 0\n"); rc = -EINVAL; return rc; } @@ -1317,7 +1317,7 @@ int iwctl_siwencode(struct net_device *dev, } } else {//disable the key - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disable WEP function\n"); + pr_debug("Disable WEP function\n"); if (pDevice->bEncryptionEnable == false) return 0; pMgmt->bShareKeyAlgorithm = false; @@ -1333,11 +1333,11 @@ int iwctl_siwencode(struct net_device *dev, //End Modify,Einsn if (wrq->flags & IW_ENCODE_RESTRICTED) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & ShareKey System\n"); + pr_debug("Enable WEP & ShareKey System\n"); pMgmt->bShareKeyAlgorithm = true; } if (wrq->flags & IW_ENCODE_OPEN) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable WEP & Open System\n"); + pr_debug("Enable WEP & Open System\n"); pMgmt->bShareKeyAlgorithm = false; } return rc; @@ -1355,7 +1355,7 @@ int iwctl_giwencode(struct net_device *dev, unsigned int index = (unsigned int)(wrq->flags & IW_ENCODE_INDEX); PSKeyItem pKey = NULL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWENCODE\n"); + pr_debug(" SIOCGIWENCODE\n"); if (index > WLAN_WEP_NKEYS) return -EINVAL; @@ -1414,7 +1414,7 @@ int iwctl_siwpower(struct net_device *dev, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int rc = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER\n"); + pr_debug(" SIOCSIWPOWER\n"); if (!(pDevice->flags & DEVICE_FLAGS_OPENED)) { rc = -EINVAL; @@ -1436,14 +1436,14 @@ int iwctl_siwpower(struct net_device *dev, } switch (wrq->flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_UNICAST_R\n"); + pr_debug(" SIOCSIWPOWER: IW_POWER_UNICAST_R\n"); rc = -EINVAL; break; case IW_POWER_ALL_R: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ALL_R\n"); + pr_debug(" SIOCSIWPOWER: IW_POWER_ALL_R\n"); rc = -EINVAL; case IW_POWER_ON: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWPOWER: IW_POWER_ON\n"); + pr_debug(" SIOCSIWPOWER: IW_POWER_ON\n"); break; default: rc = -EINVAL; @@ -1464,7 +1464,7 @@ int iwctl_giwpower(struct net_device *dev, PSMgmtObject pMgmt = &(pDevice->sMgmtObj); int mode = pDevice->ePSMode; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWPOWER\n"); + pr_debug(" SIOCGIWPOWER\n"); wrq->disabled = (mode == WMAC_POWER_CAM); if (wrq->disabled) @@ -1493,7 +1493,7 @@ int iwctl_giwsens(struct net_device *dev, struct vnt_private *pDevice = netdev_priv(dev); long ldBm; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCGIWSENS\n"); + pr_debug(" SIOCGIWSENS\n"); if (pDevice->bLinkPass == true) { RFvRSSITodBm(pDevice, (unsigned char)(pDevice->uCurrRSSI), &ldBm); wrq->value = ldBm; @@ -1520,7 +1520,7 @@ int iwctl_siwauth(struct net_device *dev, static int wpa_version = 0; //must be static to save the last value,einsn liu static int pairwise = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " SIOCSIWAUTH\n"); + pr_debug(" SIOCSIWAUTH\n"); switch (wrq->flags & IW_AUTH_INDEX) { case IW_AUTH_WPA_VERSION: wpa_version = wrq->value; diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 19037908097d..211afae306c7 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -44,8 +44,6 @@ /*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ /*--------------------- Export Variables --------------------------*/ @@ -134,7 +132,7 @@ bool KeybGetKey( { int i; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetKey()\n"); + pr_debug("KeybGetKey()\n"); *pKey = NULL; for (i = 0; i < MAX_KEY_TABLE; i++) { @@ -196,7 +194,7 @@ bool KeybSetKey( PSKeyItem pKey; unsigned int uKeyIdx; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetKey: %lX\n", dwKeyIndex); + pr_debug("Enter KeybSetKey: %lX\n", dwKeyIndex); j = (MAX_KEY_TABLE-1); for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { @@ -221,7 +219,8 @@ bool KeybSetKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); + 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); @@ -252,17 +251,17 @@ bool KeybSetKey( pKey->dwTSC47_16 = 0; pKey->wTSC15_0 = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R):\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: "); + pr_debug("KeybSetKey(R):\n"); + pr_debug("pKey->bKeyValid: %d\n ", pKey->bKeyValid); + pr_debug("pKey->abyKey: "); for (ii = 0; ii < pKey->uKeyLength; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]); + pr_debug("%02x ", pKey->abyKey[ii]); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + pr_debug("\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); + 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; } @@ -284,7 +283,8 @@ bool KeybSetKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[j].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(N)[%lX]: %d\n", pTable->KeyTable[j].dwGTKeyIndex, j); + 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); @@ -315,18 +315,18 @@ bool KeybSetKey( pKey->dwTSC47_16 = 0; pKey->wTSC15_0 = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(N):\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: "); + 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++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]); + pr_debug("%02x ", pKey->abyKey[ii]); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + pr_debug("\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n ", pKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n ", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n ", pKey->dwKeyIndex); + 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; } @@ -511,48 +511,51 @@ bool KeybGetTransmitKey( if (pTable->KeyTable[i].PairwiseKey.bKeyValid) { *pKey = &(pTable->KeyTable[i].PairwiseKey); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PAIRWISE_KEY: KeyTable.abyBSSID: "); + pr_debug("KeybGetTransmitKey:"); + pr_debug("PAIRWISE_KEY: KeyTable.abyBSSID: "); for (ii = 0; ii < 6; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x ", pTable->KeyTable[i].abyBSSID[ii]); + pr_debug("%x ", + pTable->KeyTable[i].abyBSSID[ii]); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + pr_debug("\n"); return true; } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PairwiseKey.bKeyValid == false\n"); + pr_debug("PairwiseKey.bKeyValid == false\n"); return false; } } // End of Type == PAIRWISE else { if (pTable->KeyTable[i].dwGTKeyIndex == 0) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ERROR: dwGTKeyIndex == 0 !!!\n"); + 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)]); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybGetTransmitKey:"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP_KEY: KeyTable.abyBSSID\n"); + pr_debug("KeybGetTransmitKey:"); + pr_debug("GROUP_KEY: KeyTable.abyBSSID\n"); for (ii = 0; ii < 6; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x ", pTable->KeyTable[i].abyBSSID[ii]); + pr_debug("%x ", + pTable->KeyTable[i].abyBSSID[ii]); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dwGTKeyIndex: %lX\n", pTable->KeyTable[i].dwGTKeyIndex); + pr_debug("\n"); + pr_debug("dwGTKeyIndex: %lX\n", + pTable->KeyTable[i].dwGTKeyIndex); return true; } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GroupKey.bKeyValid == false\n"); + pr_debug("GroupKey.bKeyValid == false\n"); return false; } } // End of Type = GROUP } // BSSID match } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ERROR: NO Match BSSID !!! "); + pr_debug("ERROR: NO Match BSSID !!! "); for (ii = 0; ii < 6; ii++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", *(pbyBSSID+ii)); + pr_debug("%02x ", *(pbyBSSID+ii)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + pr_debug("\n"); return false; } @@ -617,7 +620,8 @@ bool KeybSetDefaultKey( PSKeyItem pKey; unsigned int uKeyIdx; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetDefaultKey: %1x, %d\n", (int)dwKeyIndex, (int)uKeyLength); + pr_debug("Enter KeybSetDefaultKey: %1x, %d\n", + (int)dwKeyIndex, (int)uKeyLength); if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key return false; @@ -636,7 +640,9 @@ bool KeybSetDefaultKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[MAX_KEY_TABLE-1].dwGTKeyIndex, MAX_KEY_TABLE-1); + 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 @@ -676,18 +682,18 @@ bool KeybSetDefaultKey( pKey->dwTSC47_16 = 0; pKey->wTSC15_0 = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R):\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n", pKey->bKeyValid); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n", (int)pKey->uKeyLength); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey:\n"); + 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++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%x", pKey->abyKey[ii]); + pr_debug("%x", pKey->abyKey[ii]); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + pr_debug("\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwTSC47_16: %lx\n", pKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->wTSC15_0: %x\n", pKey->wTSC15_0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->dwKeyIndex: %lx\n", pKey->dwKeyIndex); + 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; } @@ -724,7 +730,7 @@ bool KeybSetAllGroupKey( PSKeyItem pKey; unsigned int uKeyIdx; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); + pr_debug("Enter KeybSetAllGroupKey: %lX\n", dwKeyIndex); if ((dwKeyIndex & PAIRWISE_KEY) != 0) // Pairwise key return false; @@ -739,7 +745,8 @@ bool KeybSetAllGroupKey( if ((dwKeyIndex & TRANSMIT_KEY) != 0) { // Group transmit key pTable->KeyTable[i].dwGTKeyIndex = dwKeyIndex; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Group transmit key(R)[%lX]: %d\n", pTable->KeyTable[i].dwGTKeyIndex, i); + pr_debug("Group transmit key(R)[%lX]: %d\n", + pTable->KeyTable[i].dwGTKeyIndex, i); } pTable->KeyTable[i].wKeyCtl &= 0xFF0F; // clear group key control filed @@ -771,14 +778,15 @@ bool KeybSetAllGroupKey( pKey->dwTSC47_16 = 0; pKey->wTSC15_0 = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KeybSetKey(R):\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->bKeyValid: %d\n ", pKey->bKeyValid); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->uKeyLength: %d\n ", (int)pKey->uKeyLength); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pKey->abyKey: "); + 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++) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%02x ", pKey->abyKey[ii]); + pr_debug("%02x ", pKey->abyKey[ii]); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "\n"); + pr_debug("\n"); } // (pTable->KeyTable[i].bInUse == true) } diff --git a/drivers/staging/vt6655/mac.c b/drivers/staging/vt6655/mac.c index 9bbc873de702..e3b0b7f7ca85 100644 --- a/drivers/staging/vt6655/mac.c +++ b/drivers/staging/vt6655/mac.c @@ -73,8 +73,6 @@ #include "mac.h" unsigned short TxRate_iwconfig;//2008-5-8 by chester -/*--------------------- Static Definitions -------------------------*/ -static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ @@ -837,7 +835,7 @@ bool MACbSafeRxOff(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x10); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x10)\n"); + pr_debug(" DBG_PORT80(0x10)\n"); return false; } for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { @@ -847,7 +845,7 @@ bool MACbSafeRxOff(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x11); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x11)\n"); + pr_debug(" DBG_PORT80(0x11)\n"); return false; } @@ -861,7 +859,7 @@ bool MACbSafeRxOff(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x12); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x12)\n"); + pr_debug(" DBG_PORT80(0x12)\n"); return false; } return true; @@ -899,7 +897,7 @@ bool MACbSafeTxOff(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x20); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x20)\n"); + pr_debug(" DBG_PORT80(0x20)\n"); return false; } for (ww = 0; ww < W_MAX_TIMEOUT; ww++) { @@ -909,7 +907,7 @@ bool MACbSafeTxOff(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x21); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x21)\n"); + pr_debug(" DBG_PORT80(0x21)\n"); return false; } @@ -924,7 +922,7 @@ bool MACbSafeTxOff(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x24); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x24)\n"); + pr_debug(" DBG_PORT80(0x24)\n"); return false; } return true; @@ -949,13 +947,13 @@ bool MACbSafeStop(void __iomem *dwIoBase) if (!MACbSafeRxOff(dwIoBase)) { DBG_PORT80(0xA1); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeRxOff == false)\n"); + pr_debug(" MACbSafeRxOff == false)\n"); MACbSafeSoftwareReset(dwIoBase); return false; } if (!MACbSafeTxOff(dwIoBase)) { DBG_PORT80(0xA2); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " MACbSafeTxOff == false)\n"); + pr_debug(" MACbSafeTxOff == false)\n"); MACbSafeSoftwareReset(dwIoBase); return false; } @@ -1172,7 +1170,7 @@ void MACvSetCurrAC0DescAddrEx(void __iomem *dwIoBase, unsigned long dwCurrDescAd } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x26); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x26)\n"); + pr_debug(" DBG_PORT80(0x26)\n"); } VNSvOutPortD(dwIoBase + MAC_REG_AC0DMAPTR, dwCurrDescAddr); if (byOrgDMACtl & DMACTL_RUN) @@ -1295,7 +1293,7 @@ bool MACbTxDMAOff(void __iomem *dwIoBase, unsigned int idx) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x29); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x29)\n"); + pr_debug(" DBG_PORT80(0x29)\n"); return false; } return true; @@ -1319,7 +1317,7 @@ void MACvClearBusSusInd(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x33); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); + pr_debug(" DBG_PORT80(0x33)\n"); } } @@ -1341,7 +1339,7 @@ void MACvEnableBusSusEn(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x34); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x34)\n"); + pr_debug(" DBG_PORT80(0x34)\n"); } } @@ -1364,7 +1362,7 @@ bool MACbFlushSYNCFifo(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x35); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); + pr_debug(" DBG_PORT80(0x33)\n"); } return true; } @@ -1388,7 +1386,7 @@ bool MACbPSWakeup(void __iomem *dwIoBase) } if (ww == W_MAX_TIMEOUT) { DBG_PORT80(0x36); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " DBG_PORT80(0x33)\n"); + pr_debug(" DBG_PORT80(0x33)\n"); return false; } return true; @@ -1419,7 +1417,7 @@ void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned in if (byLocalID <= 1) return; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n"); + pr_debug("MACvSetKeyEntry\n"); wOffset = MISCFIFO_KEYETRY0; wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); @@ -1427,7 +1425,8 @@ void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned in dwData |= wKeyCtl; dwData <<= 16; dwData |= MAKEWORD(*(pbyAddr+4), *(pbyAddr+5)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %X, KeyCtl:%X\n", wOffset, dwData, wKeyCtl); + pr_debug("1. wOffset: %d, Data: %X, KeyCtl:%X\n", + wOffset, dwData, wKeyCtl); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); @@ -1442,7 +1441,7 @@ void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned in dwData |= *(pbyAddr+1); dwData <<= 8; dwData |= *(pbyAddr+0); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2. wOffset: %d, Data: %X\n", wOffset, dwData); + pr_debug("2. wOffset: %d, Data: %X\n", wOffset, dwData); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); @@ -1452,7 +1451,8 @@ void MACvSetKeyEntry(void __iomem *dwIoBase, unsigned short wKeyCtl, unsigned in wOffset += (uKeyIdx * 4); for (ii = 0; ii < 4; ii++) { // always push 128 bits - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "3.(%d) wOffset: %d, Data: %X\n", ii, wOffset+ii, *pdwKey); + pr_debug("3.(%d) wOffset: %d, Data: %X\n", + ii, wOffset+ii, *pdwKey); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); @@ -1510,7 +1510,7 @@ void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, if (byLocalID <= 1) return; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultKeyEntry\n"); + pr_debug("MACvSetDefaultKeyEntry\n"); wOffset = MISCFIFO_KEYETRY0; wOffset += (10 * MISCFIFO_KEYENTRYSIZE); @@ -1519,7 +1519,8 @@ void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, wOffset += (uKeyIdx * 4); // always push 128 bits for (ii = 0; ii < 3; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); + pr_debug("(%d) wOffset: %d, Data: %lX\n", + ii, wOffset+ii, *pdwKey); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); @@ -1531,7 +1532,7 @@ void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+3); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End. wOffset: %d, Data: %lX\n", wOffset+3, dwData); + pr_debug("End. wOffset: %d, Data: %lX\n", wOffset+3, dwData); } /* @@ -1564,7 +1565,7 @@ void MACvSetDefaultKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); + pr_debug("MACvEnableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); } */ @@ -1595,7 +1596,8 @@ void MACvDisableDefaultKey(void __iomem *dwIoBase) VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", wOffset, dwData); + pr_debug("MACvDisableDefaultKey: wOffset: %d, Data: %lX\n", + wOffset, dwData); } /* @@ -1622,7 +1624,7 @@ void MACvSetDefaultTKIPKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, if (byLocalID <= 1) return; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetDefaultTKIPKeyEntry\n"); + pr_debug("MACvSetDefaultTKIPKeyEntry\n"); wOffset = MISCFIFO_KEYETRY0; // Kyle test : change offset from 10 -> 0 wOffset += (10 * MISCFIFO_KEYENTRYSIZE); @@ -1640,10 +1642,12 @@ void MACvSetDefaultTKIPKeyEntry(void __iomem *dwIoBase, unsigned int uKeyLen, wOffset++; wOffset += (uKeyIdx * 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, idx:%d\n", wOffset, *pdwKey, uKeyIdx); + pr_debug("1. wOffset: %d, Data: %lX, idx:%d\n", + wOffset, *pdwKey, uKeyIdx); // always push 128 bits for (ii = 0; ii < 4; ii++) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "2.(%d) wOffset: %d, Data: %lX\n", ii, wOffset+ii, *pdwKey); + pr_debug("2.(%d) wOffset: %d, Data: %lX\n", + ii, wOffset+ii, *pdwKey); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset+ii); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, *pdwKey++); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFCTL, MISCFFCTL_WRITE); @@ -1673,7 +1677,7 @@ void MACvSetDefaultKeyCtl(void __iomem *dwIoBase, unsigned short wKeyCtl, unsign if (byLocalID <= 1) return; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MACvSetKeyEntry\n"); + pr_debug("MACvSetKeyEntry\n"); wOffset = MISCFIFO_KEYETRY0; wOffset += (uEntryIdx * MISCFIFO_KEYENTRYSIZE); @@ -1681,7 +1685,8 @@ void MACvSetDefaultKeyCtl(void __iomem *dwIoBase, unsigned short wKeyCtl, unsign dwData |= wKeyCtl; dwData <<= 16; dwData |= 0xffff; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "1. wOffset: %d, Data: %lX, KeyCtl:%X\n", wOffset, dwData, wKeyCtl); + pr_debug("1. wOffset: %d, Data: %lX, KeyCtl:%X\n", + wOffset, dwData, wKeyCtl); VNSvOutPortW(dwIoBase + MAC_REG_MISCFFNDEX, wOffset); VNSvOutPortD(dwIoBase + MAC_REG_MISCFFDATA, dwData); diff --git a/drivers/staging/vt6655/mib.c b/drivers/staging/vt6655/mib.c index 36895970a892..111c01877086 100644 --- a/drivers/staging/vt6655/mib.c +++ b/drivers/staging/vt6655/mib.c @@ -44,8 +44,6 @@ #include "wctl.h" #include "baseband.h" -/*--------------------- Static Definitions -------------------------*/ -static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ @@ -190,75 +188,101 @@ void STAvUpdateRDStatCounter(PSStatCounter pStatistic, if (byRSR & RSR_CRCOK) pStatistic->CustomStat.ullRsr11MCRCOk++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "11M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr11M, (int)pStatistic->CustomStat.ullRsr11MCRCOk, byRSR); + 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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 5M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr5M, (int)pStatistic->CustomStat.ullRsr5MCRCOk, byRSR); + 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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 2M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr2M, (int)pStatistic->CustomStat.ullRsr2MCRCOk, byRSR); + 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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 1M: ALL[%d], OK[%d]:[%02x]\n", (int)pStatistic->CustomStat.ullRsr1M, (int)pStatistic->CustomStat.ullRsr1MCRCOk, byRSR); + 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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 6M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr6M, (int)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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " 9M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr9M, (int)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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "12M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr12M, (int)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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "18M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr18M, (int)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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "24M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr24M, (int)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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "36M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr36M, (int)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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "48M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr48M, (int)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++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "54M: ALL[%d], OK[%d]\n", (int)pStatistic->CustomStat.ullRsr54M, (int)pStatistic->CustomStat.ullRsr54MCRCOk); + pr_debug("54M: ALL[%d], OK[%d]\n", + (int)pStatistic->CustomStat.ullRsr54M, + (int)pStatistic->CustomStat.ullRsr54MCRCOk); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Unknown: Total[%d], CRCOK[%d]\n", (int)pStatistic->dwRsrRxPacket+1, (int)pStatistic->dwRsrCRCOk); + pr_debug("Unknown: Total[%d], CRCOK[%d]\n", + (int)pStatistic->dwRsrRxPacket+1, + (int)pStatistic->dwRsrCRCOk); } if (byRSR & RSR_BSSIDOK) diff --git a/drivers/staging/vt6655/power.c b/drivers/staging/vt6655/power.c index de23f2d98e3d..93681b338c1b 100644 --- a/drivers/staging/vt6655/power.c +++ b/drivers/staging/vt6655/power.c @@ -50,8 +50,6 @@ /*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ /*--------------------- Export Variables --------------------------*/ @@ -113,7 +111,7 @@ PSvEnablePowerSaving( PSbSendNullPacket(pDevice); pDevice->bPWBitOn = true; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "PS:Power Saving Mode Enable...\n"); + pr_debug("PS:Power Saving Mode Enable...\n"); } /*+ @@ -210,7 +208,7 @@ PSbConsiderPowerDown( // no Tx, no Rx isr, now go to Doze MACvRegBitsOn(pDevice->PortOffset, MAC_REG_PSCTL, PSCTL_GO2DOZE); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Go to Doze ZZZZZZZZZZZZZZZ\n"); + pr_debug("Go to Doze ZZZZZZZZZZZZZZZ\n"); return true; } @@ -249,7 +247,7 @@ PSvSendPSPOLL( pTxPacket->cbPayloadLen = 0; // send the frame if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send PS-Poll packet failed..\n"); + pr_debug("Send PS-Poll packet failed..\n"); } /*+ @@ -314,7 +312,7 @@ PSbSendNullPacket( pTxPacket->cbPayloadLen = 0; // send the frame if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); + pr_debug("Send Null Packet failed !\n"); return false; } diff --git a/drivers/staging/vt6655/rxtx.c b/drivers/staging/vt6655/rxtx.c index b6253581eec4..869555a99b8c 100644 --- a/drivers/staging/vt6655/rxtx.c +++ b/drivers/staging/vt6655/rxtx.c @@ -68,8 +68,6 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - #define PLICE_DEBUG /*--------------------- Static Functions --------------------------*/ @@ -248,7 +246,7 @@ s_vFillTxKey( *(pbyIVHead+3) = (unsigned char)(((byKeyIndex << 6) & 0xc0) | 0x20); // 0x20 is ExtIV // Append IV&ExtIV after Mac Header *pdwExtIV = cpu_to_le32(pTransmitKey->dwTSC47_16); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); + pr_debug("vFillTxKey()---- pdwExtIV: %lx\n", *pdwExtIV); } else if (pTransmitKey->byCipherSuite == KEY_CTL_CCMP) { pTransmitKey->wTSC15_0++; @@ -1422,7 +1420,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, MIC_vAppend((unsigned char *)&(psEthHeader->abyDstAddr[0]), 12); dwMIC_Priority = 0; MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC KEY: %X, %X\n", dwMICKey0, dwMICKey1); + pr_debug("MIC KEY: %X, %X\n", dwMICKey0, dwMICKey1); } /////////////////////////////////////////////////////////////////// @@ -1452,7 +1450,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, //========================= // Start Fragmentation //========================= - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Start Fragmentation...\n"); + pr_debug("Start Fragmentation...\n"); wFragType = FRAGCTL_STAFRAG; //Fill FIFO,RrvTime,RTS,and CTS @@ -1505,7 +1503,8 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, uTotalCopyLength += cbFragPayloadSize - cb802_1_H_len; if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Start MIC: %d\n", cbFragPayloadSize); + pr_debug("Start MIC: %d\n", + cbFragPayloadSize); MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFragPayloadSize); } @@ -1540,7 +1539,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, //========================= // Last Fragmentation //========================= - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last Fragmentation...\n"); + pr_debug("Last Fragmentation...\n"); wFragType = FRAGCTL_ENDFRAG; @@ -1590,8 +1589,10 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, } if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, cbLastFragPayloadSize, uTmpLen); + pr_debug("LAST: uMICFragLen:%d, cbLastFragPayloadSize:%d, uTmpLen:%d\n", + uMICFragLen, + cbLastFragPayloadSize, + uTmpLen); if (bMIC2Frag == false) { if (uTmpLen != 0) @@ -1599,22 +1600,23 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, pdwMIC_L = (u32 *)(pbyBuffer + uLength + uTmpLen); pdwMIC_R = (u32 *)(pbyBuffer + uLength + uTmpLen + 4); MIC_vGetMIC(pdwMIC_L, pdwMIC_R); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Last MIC:%X, %X\n", *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)); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen >= 4: %X, %d\n", - *(unsigned char *)((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); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "LAST: uMICFragLen < 4: %X, %d\n", - *(unsigned char *)((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)); } } MIC_vUnInit(); @@ -1655,7 +1657,7 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, //========================= // Middle Fragmentation //========================= - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Middle Fragmentation...\n"); + pr_debug("Middle Fragmentation...\n"); wFragType = FRAGCTL_MIDFRAG; @@ -1715,12 +1717,17 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, dwSafeMIC_L = *pdwMIC_L; dwSafeMIC_R = *pdwMIC_R; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIDDLE: uMICFragLen:%d, cbFragPayloadSize:%d, uTmpLen:%d\n", - uMICFragLen, cbFragPayloadSize, uTmpLen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Fill MIC in Middle frag [%d]\n", uMICFragLen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get MIC:%X, %X\n", *pdwMIC_L, *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); } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Middle frag len: %d\n", uTmpLen); + pr_debug("Middle frag len: %d\n", + uTmpLen); } else { ASSERT(uTmpLen == (cbFragPayloadSize)); @@ -1814,7 +1821,8 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, ); if ((bNeedEncrypt == true) && (pTransmitKey != NULL) && (pTransmitKey->byCipherSuite == KEY_CTL_TKIP)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Length:%d, %d\n", cbFrameBodySize - cb802_1_H_len, uLength); + pr_debug("Length:%d, %d\n", + cbFrameBodySize - cb802_1_H_len, uLength); MIC_vAppend((pbyBuffer + uLength - cb802_1_H_len), cbFrameBodySize); @@ -1830,9 +1838,10 @@ s_cbFillTxBufHead(struct vnt_private *pDevice, unsigned char byPktType, pDevice->bTxMICFail = false; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "uLength: %d, %d\n", uLength, cbFrameBodySize); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderLength, uPadding, cbIVlen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R); + 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); } @@ -2258,11 +2267,11 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, PAIRWISE_KEY, &pTransmitKey) == false) { // get group key if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == true) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get GTK.\n"); + pr_debug("Get GTK\n"); break; } } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get PTK.\n"); + pr_debug("Get PTK\n"); break; } } @@ -2270,9 +2279,10 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) pbyBSSID = pDevice->abyBroadcastAddr; if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { pTransmitKey = NULL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "KEY is NULL. OP Mode[%d]\n", pDevice->eOPMode); + pr_debug("KEY is NULL. OP Mode[%d]\n", + pDevice->eOPMode); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Get GTK.\n"); + pr_debug("Get GTK\n"); } } while (false); //Fill TXKEY @@ -2327,7 +2337,7 @@ CMD_STATUS csMgmt_xmit(struct vnt_private *pDevice, PSTxMgmtPacket pPacket) pDevice->iTDUsed[TYPE_TXDMA0]++; if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n"); + pr_debug(" available td0 <= 1\n"); pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; @@ -2579,7 +2589,8 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vDMA0_tx_80211: p80211Header->sA3.wFrameCtl = %x\n", p80211Header->sA3.wFrameCtl); + 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 @@ -2766,7 +2777,8 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, MIC_vAppend((unsigned char *)&(sEthHeader.abyDstAddr[0]), 12); dwMIC_Priority = 0; MIC_vAppend((unsigned char *)&dwMIC_Priority, 4); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "DMA0_tx_8021:MIC KEY: %X, %X\n", dwMICKey0, dwMICKey1); + pr_debug("DMA0_tx_8021:MIC KEY: %X, %X\n", + dwMICKey0, dwMICKey1); uLength = cbHeaderSize + cbMacHdLen + uPadding + cbIVlen; @@ -2784,9 +2796,10 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, pDevice->bTxMICFail = false; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "uLength: %d, %d\n", uLength, cbFrameBodySize); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "cbReqCount:%d, %d, %d, %d\n", cbReqCount, cbHeaderSize, uPadding, cbIVlen); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "MIC:%x, %x\n", *pdwMIC_L, *pdwMIC_R); + 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); } @@ -2844,7 +2857,7 @@ void vDMA0_tx_80211(struct vnt_private *pDevice, struct sk_buff *skb, pDevice->iTDUsed[TYPE_TXDMA0]++; if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 1) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " available td0 <= 1\n"); + pr_debug(" available td0 <= 1\n"); pDevice->apCurrTD[TYPE_TXDMA0] = pFrstTD->next; diff --git a/drivers/staging/vt6655/wcmd.c b/drivers/staging/vt6655/wcmd.c index 0045f7f7995d..7565073122de 100644 --- a/drivers/staging/vt6655/wcmd.c +++ b/drivers/staging/vt6655/wcmd.c @@ -58,8 +58,6 @@ /*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ static @@ -216,9 +214,9 @@ s_vProbeChannel( if (pTxPacket != NULL) { for (ii = 0; ii < 2; ii++) { if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request sending fail..\n"); + pr_debug("Probe request sending fail..\n"); else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request is sending..\n"); + pr_debug("Probe request is sending..\n"); } } } @@ -335,7 +333,7 @@ vCommandTimer( return; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_SCAN_START\n"); + 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) { @@ -355,7 +353,8 @@ vCommandTimer( // Set Baseband's sensitivity back. // Set channel back set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", 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, OP_MODE_ADHOC); else @@ -367,7 +366,8 @@ vCommandTimer( } else { //2008-8-4 by chester if (!is_channel_valid(pMgmt->uScanChannel)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Invalid channel pMgmt->uScanChannel = %d\n", pMgmt->uScanChannel); + pr_debug("Invalid channel pMgmt->uScanChannel = %d\n", + pMgmt->uScanChannel); s_bCommandComplete(pDevice); spin_unlock_irq(&pDevice->lock); return; @@ -387,9 +387,11 @@ vCommandTimer( vAdHocBeaconStop(pDevice); if (set_channel(pMgmt->pAdapter, pMgmt->uScanChannel)) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SCAN Channel: %d\n", pMgmt->uScanChannel); + pr_debug("SCAN Channel: %d\n", + pMgmt->uScanChannel); else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SET SCAN Channel Fail: %d\n", pMgmt->uScanChannel); + pr_debug("SET SCAN Channel Fail: %d\n", + pMgmt->uScanChannel); CARDbSetBSSID(pMgmt->pAdapter, pMgmt->abyCurrBSSID, OP_MODE_UNKNOWN); pMgmt->uScanChannel++; @@ -422,7 +424,8 @@ vCommandTimer( // Set Baseband's sensitivity back. // Set channel back set_channel(pMgmt->pAdapter, pMgmt->uCurrChannel); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Scanning, set back to channel: [%d]\n", 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, OP_MODE_ADHOC); else @@ -451,7 +454,7 @@ vCommandTimer( spin_unlock_irq(&pDevice->lock); return; } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Disassociation Packet..\n"); + pr_debug("Send Disassociation Packet..\n"); // reason = 8 : disassoc because sta has left vMgrDisassocBeginSta((void *)pDevice, pMgmt, pMgmt->abyCurrBSSID, (8), &Status); pDevice->bLinkPass = false; @@ -470,7 +473,7 @@ vCommandTimer( spin_unlock_irq(&pDevice->lock); return; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " CARDbRadioPowerOff\n"); + pr_debug(" CARDbRadioPowerOff\n"); //2008-09-02 by chester s_bCommandComplete(pDevice); break; @@ -496,15 +499,16 @@ vCommandTimer( pr_debug("chester-abyDesireSSID=%s\n", ((PWLAN_IE_SSID)pMgmt->abyDesireSSID)->abySSID); pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; pItemSSIDCurr = (PWLAN_IE_SSID)pMgmt->abyCurrSSID; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: desire ssid = %s\n", pItemSSID->abySSID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); + pr_debug(" cmd: desire ssid = %s\n", pItemSSID->abySSID); + pr_debug(" cmd: curr ssid = %s\n", pItemSSIDCurr->abySSID); if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Cmd pMgmt->eCurrState == WMAC_STATE_ASSOC\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pItemSSID->len =%d\n", pItemSSID->len); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " pItemSSIDCurr->len = %d\n", pItemSSIDCurr->len); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " desire ssid = %s\n", pItemSSID->abySSID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " curr ssid = %s\n", pItemSSIDCurr->abySSID); + 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) || @@ -541,7 +545,7 @@ vCommandTimer( pDevice->eCommandState = WLAN_AUTHENTICATE_WAIT; vCommandTimerWait((void *)pDevice, AUTHENTICATE_TIMEOUT); spin_unlock_irq(&pDevice->lock); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); + pr_debug(" Set eCommandState = WLAN_AUTHENTICATE_WAIT\n"); return; } } @@ -560,7 +564,7 @@ vCommandTimer( // start own IBSS vMgrCreateOwnIBSS((void *)pDevice, &Status); if (Status != CMD_STATUS_SUCCESS) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail !\n"); + pr_debug(" WLAN_CMD_IBSS_CREATE fail !\n"); BSSvAddMulticastNode(pDevice); } @@ -572,7 +576,7 @@ vCommandTimer( // start own IBSS vMgrCreateOwnIBSS((void *)pDevice, &Status); if (Status != CMD_STATUS_SUCCESS) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail !\n"); + pr_debug(" WLAN_CMD_IBSS_CREATE fail !\n"); BSSvAddMulticastNode(pDevice); if (netif_queue_stopped(pDevice->dev)) @@ -580,7 +584,7 @@ vCommandTimer( pDevice->bLinkPass = true; } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Disconnect SSID none\n"); + pr_debug("Disconnect SSID none\n"); #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT { union iwreq_data wrqu; @@ -598,15 +602,15 @@ vCommandTimer( break; case WLAN_AUTHENTICATE_WAIT: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_AUTHENTICATE_WAIT\n"); + pr_debug("eCommandState == WLAN_AUTHENTICATE_WAIT\n"); if (pMgmt->eCurrState == WMAC_STATE_AUTH) { // Call mgr to begin the association pDevice->byLinkWaitCount = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCurrState == WMAC_STATE_AUTH\n"); + pr_debug("eCurrState == WMAC_STATE_AUTH\n"); vMgrAssocBeginSta((void *)pDevice, pMgmt, &Status); if (Status == CMD_STATUS_SUCCESS) { pDevice->byLinkWaitCount = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState = WLAN_ASSOCIATE_WAIT\n"); + pr_debug("eCommandState = WLAN_ASSOCIATE_WAIT\n"); pDevice->eCommandState = WLAN_ASSOCIATE_WAIT; vCommandTimerWait((void *)pDevice, ASSOCIATE_TIMEOUT); spin_unlock_irq(&pDevice->lock); @@ -629,7 +633,7 @@ vCommandTimer( case WLAN_ASSOCIATE_WAIT: if (pMgmt->eCurrState == WMAC_STATE_ASSOC) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCurrState == WMAC_STATE_ASSOC\n"); + pr_debug("eCurrState == WMAC_STATE_ASSOC\n"); if (pDevice->ePSMode != WMAC_POWER_CAM) PSvEnablePowerSaving((void *)pDevice, pMgmt->wListenInterval); @@ -675,7 +679,7 @@ vCommandTimer( break; case WLAN_CMD_AP_MODE_START: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_AP_MODE_START\n"); + pr_debug("eCommandState == WLAN_CMD_AP_MODE_START\n"); if (pMgmt->eConfigMode == WMAC_CONFIG_AP) { del_timer(&pMgmt->sTimerSecondCallback); @@ -692,12 +696,12 @@ vCommandTimer( vMgrCreateOwnIBSS((void *)pDevice, &Status); if (Status != CMD_STATUS_SUCCESS) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail !\n"); + pr_debug(" vMgrCreateOwnIBSS fail !\n"); // alway turn off unicast bit MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST); pDevice->byRxMode &= ~RCR_UNICAST; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wcmd: rx_mode = %x\n", pDevice->byRxMode); + pr_debug("wcmd: rx_mode = %x\n", pDevice->byRxMode); BSSvAddMulticastNode(pDevice); if (netif_queue_stopped(pDevice->dev)) netif_wake_queue(pDevice->dev); @@ -719,7 +723,7 @@ vCommandTimer( pDevice->bMoreData = true; } if (!device_dma0_xmit(pDevice, skb, 0)) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Multicast ps tx fail\n"); + pr_debug("Multicast ps tx fail\n"); pMgmt->sNodeDBTable[0].wEnQueueCnt--; } @@ -729,8 +733,9 @@ vCommandTimer( for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) { if (pMgmt->sNodeDBTable[ii].bActive && pMgmt->sNodeDBTable[ii].bRxPSPoll) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d Enqueu Cnt= %d\n", - ii, pMgmt->sNodeDBTable[ii].wEnQueueCnt); + 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 @@ -741,7 +746,7 @@ vCommandTimer( pDevice->bMoreData = true; } if (!device_dma0_xmit(pDevice, skb, ii)) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "sta ps tx fail\n"); + pr_debug("sta ps tx fail\n"); pMgmt->sNodeDBTable[ii].wEnQueueCnt--; // check if sta ps enabled, and wait next pspoll. @@ -753,7 +758,8 @@ vCommandTimer( // clear tx map pMgmt->abyPSTxMap[pMgmt->sNodeDBTable[ii].wAID >> 3] &= ~byMask[pMgmt->sNodeDBTable[ii].wAID & 7]; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Index=%d PS queue clear\n", ii); + pr_debug("Index=%d PS queue clear\n", + ii); } pMgmt->sNodeDBTable[ii].bRxPSPoll = false; } @@ -763,7 +769,7 @@ vCommandTimer( break; case WLAN_CMD_RADIO_START: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState == WLAN_CMD_RADIO_START\n"); + pr_debug("eCommandState == WLAN_CMD_RADIO_START\n"); if (pDevice->bRadioCmd) CARDbRadioPowerOn(pDevice); else @@ -786,7 +792,7 @@ vCommandTimer( } pDevice->byBBVGACurrent = pDevice->byBBVGANew; BBvSetVGAGainOffset(pDevice, pDevice->byBBVGACurrent); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent); + pr_debug("SetVGAGainOffset %02X\n", pDevice->byBBVGACurrent); s_bCommandComplete(pDevice); break; @@ -824,7 +830,7 @@ s_bCommandComplete( pDevice->bCmdRunning = true; switch (pDevice->eCommand) { case WLAN_CMD_BSSID_SCAN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_BSSID_SCAN\n"); + pr_debug("eCommandState= WLAN_CMD_BSSID_SCAN\n"); pDevice->eCommandState = WLAN_CMD_SCAN_START; pMgmt->uScanChannel = 0; if (pSSID->len != 0) @@ -839,7 +845,7 @@ s_bCommandComplete( pSSID->len = WLAN_SSID_MAXLEN; if (pSSID->len != 0) memcpy(pDevice->pMgmt->abyDesireSSID, pSSID, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "eCommandState= WLAN_CMD_SSID_START\n"); + pr_debug("eCommandState= WLAN_CMD_SSID_START\n"); break; case WLAN_CMD_DISASSOCIATE: pDevice->eCommandState = WLAN_CMD_DISASSOCIATE_START; diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index d696f5bf76d1..c998a16ebd1d 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -86,9 +86,6 @@ /*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - /*--------------------- Static Functions --------------------------*/ //2008-8-4 by chester static bool ChannelExceedZoneType( @@ -551,9 +548,9 @@ vMgrReAssocBeginSta( /* send the frame */ *pStatus = csMgmt_xmit(pDevice, pTxPacket); if (*pStatus != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx failed.\n"); + pr_debug("Mgt:Reassociation tx failed\n"); else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Reassociation tx sending.\n"); + pr_debug("Mgt:Reassociation tx sending\n"); } } @@ -718,8 +715,8 @@ s_vMgrRxAssocRequest( if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) pDevice->bBarkerPreambleMd = true; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Associate AID= %d\n", wAssocAID); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", + 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], @@ -727,7 +724,7 @@ s_vMgrRxAssocRequest( sFrame.pHdr->sA3.abyAddr2[4], sFrame.pHdr->sA3.abyAddr2[5] ); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d\n", + pr_info("Max Support rate = %d\n", pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); } else { /* TODO: received STA under state1 handle */ @@ -753,9 +750,9 @@ s_vMgrRxAssocRequest( /* send the frame */ Status = csMgmt_xmit(pDevice, pTxPacket); if (Status != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx failed\n"); + pr_debug("Mgt:Assoc response tx failed\n"); else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Assoc response tx sending..\n"); + pr_debug("Mgt:Assoc response tx sending..\n"); } } @@ -867,8 +864,8 @@ s_vMgrRxReAssocRequest( if (!pMgmt->sNodeDBTable[uNodeIndex].bShortPreamble) pDevice->bBarkerPreambleMd = true; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Rx ReAssociate AID= %d\n", wAssocAID); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "MAC=%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", + 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], @@ -876,7 +873,7 @@ s_vMgrRxReAssocRequest( sFrame.pHdr->sA3.abyAddr2[4], sFrame.pHdr->sA3.abyAddr2[5] ); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d\n", + pr_info("Max Support rate = %d\n", pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); } @@ -901,9 +898,9 @@ s_vMgrRxReAssocRequest( Status = csMgmt_xmit(pDevice, pTxPacket); if (Status != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx failed\n"); + pr_debug("Mgt:ReAssoc response tx failed\n"); else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:ReAssoc response tx sending..\n"); + pr_debug("Mgt:ReAssoc response tx sending..\n"); } } @@ -961,13 +958,14 @@ s_vMgrRxAssocResponse( // set AID pMgmt->wCurrAID = cpu_to_le16((*(sFrame.pwAid))); if ((pMgmt->wCurrAID >> 14) != (BIT0 | BIT1)) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n"); + pr_debug("AID from AP, has two msb clear\n"); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14 | BIT15)); + 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; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Link with AP(SSID): %s\n", pItemSSID->abySSID); + pr_info("Link with AP(SSID): %s\n", pItemSSID->abySSID); pDevice->bLinkPass = true; pDevice->uBBVGADiffCount = 0; if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) { @@ -1206,8 +1204,8 @@ s_vMgrRxAuthentication( s_vMgrRxAuthenSequence_4(pDevice, pMgmt, &sFrame); break; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Auth Sequence error, seq = %d\n", - cpu_to_le16((*(sFrame.pwAuthSequence)))); + pr_debug("Auth Sequence error, seq = %d\n", + cpu_to_le16((*(sFrame.pwAuthSequence)))); break; } } @@ -1306,9 +1304,9 @@ s_vMgrRxAuthenSequence_1( if (pDevice->bEnableHostapd) return; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx..\n"); + pr_debug("Mgt:Authreq_reply sequence_1 tx..\n"); if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_1 tx failed.\n"); + pr_debug("Mgt:Authreq_reply sequence_1 tx failed\n"); } /*+ @@ -1337,11 +1335,11 @@ s_vMgrRxAuthenSequence_2( switch (cpu_to_le16((*(pFrame->pwAuthAlgorithm)))) { case WLAN_AUTH_ALG_OPENSYSTEM: if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Successful.\n"); + pr_info("802.11 Authen (OPEN) Successful\n"); pMgmt->eCurrState = WMAC_STATE_AUTH; timer_expire(pDevice->sTimerCommand, 0); } else { - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (OPEN) Failed.\n"); + pr_info("802.11 Authen (OPEN) Failed\n"); s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); pMgmt->eCurrState = WMAC_STATE_IDLE; } @@ -1381,16 +1379,17 @@ s_vMgrRxAuthenSequence_2( pTxPacket->cbPayloadLen = sFrame.len - WLAN_HDR_ADDR3_LEN; // send the frame if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx failed.\n"); + pr_debug("Mgt:Auth_reply sequence_2 tx failed\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Auth_reply sequence_2 tx ...\n"); + pr_debug("Mgt:Auth_reply sequence_2 tx ...\n"); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:rx Auth_reply sequence_2 status error ...\n"); + pr_debug("Mgt:rx Auth_reply sequence_2 status error ...\n"); s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); } break; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", cpu_to_le16((*(pFrame->pwAuthAlgorithm)))); + pr_debug("Mgt: rx auth.seq = 2 unknown AuthAlgorithm=%d\n", + cpu_to_le16((*(pFrame->pwAuthAlgorithm)))); break; } } @@ -1444,7 +1443,7 @@ s_vMgrRxAuthenSequence_3( pMgmt->sNodeDBTable[uNodeIndex].byAuthSequence = 0; } uStatusCode = WLAN_MGMT_STATUS_SUCCESS; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Challenge text check ok..\n"); + pr_debug("Challenge text check ok..\n"); reply: // send auth reply @@ -1477,7 +1476,7 @@ s_vMgrRxAuthenSequence_3( return; if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Authreq_reply sequence_4 tx failed.\n"); + pr_debug("Mgt:Authreq_reply sequence_4 tx failed\n"); } /*+ @@ -1499,11 +1498,11 @@ s_vMgrRxAuthenSequence_4( ) { if (cpu_to_le16((*(pFrame->pwStatus))) == WLAN_MGMT_STATUS_SUCCESS) { - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Successful.\n"); + pr_info("802.11 Authen (SHAREDKEY) Successful\n"); pMgmt->eCurrState = WMAC_STATE_AUTH; timer_expire(pDevice->sTimerCommand, 0); } else{ - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "802.11 Authen (SHAREDKEY) Failed.\n"); + pr_info("802.11 Authen (SHAREDKEY) Failed\n"); s_vMgrLogStatus(pMgmt, cpu_to_le16((*(pFrame->pwStatus)))); pMgmt->eCurrState = WMAC_STATE_IDLE; } @@ -1540,13 +1539,14 @@ s_vMgrRxDisassociation( if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) BSSvRemoveOneNode(pDevice, uNodeIndex); else - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx disassoc, sta not found\n"); + 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); - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP disassociated me, reason=%d.\n", cpu_to_le16(*(sFrame.pwReason))); + 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)) { @@ -1611,13 +1611,14 @@ s_vMgrRxDeauthentication( if (BSSDBbIsSTAInNodeDB(pMgmt, pRxPacket->p80211Header->sA3.abyAddr2, &uNodeIndex)) BSSvRemoveOneNode(pDevice, uNodeIndex); else - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Rx deauth, sta not found\n"); + 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); - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP deauthed me, reason=%d.\n", cpu_to_le16((*(sFrame.pwReason)))); + 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)) { @@ -1755,7 +1756,7 @@ s_vMgrRxBeacon( (sFrame.pwCapInfo == NULL) || (sFrame.pSSID == NULL) || (sFrame.pSuppRates == NULL)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n"); + pr_debug("Rx beacon frame error\n"); return; } @@ -1790,7 +1791,7 @@ s_vMgrRxBeacon( pBSSList = BSSpAddrIsInBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, sFrame.pSSID); if (pBSSList == NULL) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon/insert: RxChannel = : %d\n", byCurrChannel); + pr_debug("Beacon/insert: RxChannel = : %d\n", byCurrChannel); BSSbInsertToBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, *sFrame.pqwTimestamp, @@ -1964,7 +1965,7 @@ s_vMgrRxBeacon( } } -// DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Beacon 2\n"); +// pr_debug("Beacon 2\n"); // check if CF field exists if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) { if (sFrame.pCFParms->wCFPDurRemaining > 0) { @@ -2030,14 +2031,14 @@ s_vMgrRxBeacon( } else { pMgmt->bInTIMWake = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Not In TIM..\n"); + pr_debug("BCN: Not In TIM..\n"); if (!pDevice->bPWBitOn) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Send Null Packet\n"); + pr_debug("BCN: Send Null Packet\n"); if (PSbSendNullPacket(pDevice)) pDevice->bPWBitOn = true; } if (PSbConsiderPowerDown(pDevice, false, false)) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n"); + pr_debug("BCN: Power down now...\n"); } } @@ -2105,7 +2106,7 @@ s_vMgrRxBeacon( // if other stations joined, indicate connection to upper layer.. if (pMgmt->eCurrState == WMAC_STATE_STARTED) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Current IBSS State: [Started]........to: [Jointed]\n"); + pr_debug("Current IBSS State: [Started]........to: [Jointed]\n"); pMgmt->eCurrState = WMAC_STATE_JOINTED; pDevice->bLinkPass = true; if (netif_queue_stopped(pDevice->dev)) @@ -2131,7 +2132,7 @@ s_vMgrRxBeacon( (PWLAN_IE_SUPP_RATES)pMgmt->abyCurrSuppRates, WLAN_RATES_MAXLEN_11B); // set HW beacon interval and re-synchronizing.... - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rejoining to Other Adhoc group with same SSID........\n"); + 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); @@ -2191,7 +2192,7 @@ vMgrCreateOwnIBSS( unsigned char abyOFDM_RATE[] = {0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6C}; unsigned short wSuppRate; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Create Basic Service Set .......\n"); + pr_debug("Create Basic Service Set .......\n"); if (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA) { if ((pMgmt->eAuthenMode == WMAC_AUTH_WPANONE) && @@ -2300,7 +2301,7 @@ vMgrCreateOwnIBSS( if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { // AP mode BSSID = MAC addr memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "AP beacon created BSSID:%pM\n", + pr_info("AP beacon created BSSID:%pM\n", pMgmt->abyCurrBSSID); } @@ -2321,7 +2322,7 @@ vMgrCreateOwnIBSS( pMgmt->abyCurrBSSID[0] &= ~IEEE_ADDR_GROUP; pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Adhoc beacon created bssid:%pM\n", + pr_info("Adhoc beacon created bssid:%pM\n", pMgmt->abyCurrBSSID); } @@ -2435,7 +2436,7 @@ vMgrJoinBSSBegin( if (ii == MAX_BSS_NUM) { *pStatus = CMD_STATUS_RESOURCES; - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n"); + pr_info("BSS finding:BSS list is empty\n"); return; } @@ -2450,11 +2451,12 @@ vMgrJoinBSSBegin( if (pCurr == NULL) { *pStatus = CMD_STATUS_RESOURCES; pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID; - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID); + pr_info("Scanning [%s] not found, disconnected !\n", + pItemSSID->abySSID); return; } - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n"); + 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 @@ -2532,10 +2534,11 @@ vMgrJoinBSSBegin( if (pMgmt->eAuthenMode == WMAC_AUTH_WPA2) { bool bResult = bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate: 1(%d)\n", bResult); + pr_debug("bAdd_PMKID_Candidate: 1(%d)\n", + bResult); if (!bResult) { vFlush_PMKID_Candidate((void *)pDevice); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "vFlush_PMKID_Candidate: 4\n"); + pr_debug("vFlush_PMKID_Candidate: 4\n"); bAdd_PMKID_Candidate((void *)pDevice, pMgmt->abyCurrBSSID, &pCurr->sRSNCapObj); } } @@ -2543,9 +2546,9 @@ vMgrJoinBSSBegin( // Preamble type auto-switch: if AP can receive short-preamble cap, // we can turn on too. - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join ESS\n"); + pr_debug("Join ESS\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "End of Join AP -- A/B/G Action\n"); + pr_debug("End of Join AP -- A/B/G Action\n"); } else { pMgmt->eCurrState = WMAC_STATE_IDLE; } @@ -2603,8 +2606,8 @@ vMgrJoinBSSBegin( pMgmt->eCurrState = WMAC_STATE_STARTED; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Join IBSS ok:%pM\n", - pMgmt->abyCurrBSSID); + 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. @@ -2651,7 +2654,7 @@ s_vMgrSynchBSS( pDevice->eEncryptionStatus, &(pMgmt->byCSSPK), &(pMgmt->byCSSGK))) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "s_bCipherMatch Fail .......\n"); + pr_debug("s_bCipherMatch Fail .......\n"); return; } @@ -2689,8 +2692,7 @@ s_vMgrSynchBSS( MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = " - "%pM\n", pMgmt->abyCurrBSSID); + pr_debug("Sync:set CurrBSSID address = %pM\n", pMgmt->abyCurrBSSID); if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) { if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) || @@ -2745,19 +2747,20 @@ s_vMgrSynchBSS( pCurr->sERP.byERP, pMgmt->abyCurrSuppRates, pMgmt->abyCurrExtSuppRates)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType); + pr_debug("<----s_bSynchBSS Set Phy Mode Fail [%d]\n", ePhyType); return; } // set channel and clear NAV if (!set_channel(pMgmt->pAdapter, pCurr->uChannel)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "<----s_bSynchBSS Set Channel [%d]\n", 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; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:Set to channel = [%d]\n", (int)pCurr->uChannel); + pr_debug("Sync:Set to channel = [%d]\n", (int)pCurr->uChannel); *pStatus = CMD_STATUS_SUCCESS; @@ -3954,13 +3957,14 @@ s_vMgrRxProbeResponse( (sFrame.pwCapInfo == NULL) || (sFrame.pSSID == NULL) || (sFrame.pSuppRates == NULL)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p]\n", pRxPacket->p80211Header); + pr_debug("Probe resp:Fail addr:[%p]\n", + pRxPacket->p80211Header); DBG_PORT80(0xCC); return; } if (sFrame.pSSID->len == 0) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0\n"); + pr_debug("Rx Probe resp: SSID len = 0\n"); if (sFrame.pDSParms != NULL) { if (byCurrChannel > CB_MAX_CHANNEL_24G) { @@ -4014,7 +4018,8 @@ s_vMgrRxProbeResponse( (void *)pRxPacket ); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp/insert: RxChannel = : %d\n", byCurrChannel); + pr_debug("Probe resp/insert: RxChannel = : %d\n", + byCurrChannel); BSSbInsertToBSSList((void *)pDevice, sFrame.pHdr->sA3.abyAddr3, *sFrame.pqwTimestamp, @@ -4103,7 +4108,7 @@ s_vMgrRxProbeRequest( /* send the frame */ Status = csMgmt_xmit(pDevice, pTxPacket); if (Status != CMD_STATUS_PENDING) - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Mgt:Probe response tx failed\n"); + pr_debug("Mgt:Probe response tx failed\n"); } } } @@ -4143,7 +4148,7 @@ vMgrRxManagePacket( switch (WLAN_GET_FC_FSTYPE((pRxPacket->p80211Header->sA3.wFrameCtl))) { case WLAN_FSTYPE_ASSOCREQ: // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocreq\n"); + pr_debug("rx assocreq\n"); if (eNodeState < NODE_AUTH) { // send deauth notification // reason = (6) class 2 received from nonauth sta @@ -4153,7 +4158,7 @@ vMgrRxManagePacket( (6), &Status ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 1\n"); + pr_debug("wmgr: send vMgrDeAuthenBeginSta 1\n"); } else { s_vMgrRxAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); } @@ -4161,14 +4166,14 @@ vMgrRxManagePacket( case WLAN_FSTYPE_ASSOCRESP: // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp1\n"); + pr_debug("rx assocresp1\n"); s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, false); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx assocresp2\n"); + pr_debug("rx assocresp2\n"); break; case WLAN_FSTYPE_REASSOCREQ: // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocreq\n"); + pr_debug("rx reassocreq\n"); // Todo: reassoc if (eNodeState < NODE_AUTH) { // send deauth notification @@ -4179,7 +4184,7 @@ vMgrRxManagePacket( (6), &Status ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 2\n"); + pr_debug("wmgr: send vMgrDeAuthenBeginSta 2\n"); } s_vMgrRxReAssocRequest(pDevice, pMgmt, pRxPacket, uNodeIndex); @@ -4187,7 +4192,7 @@ vMgrRxManagePacket( case WLAN_FSTYPE_REASSOCRESP: // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx reassocresp\n"); + pr_debug("rx reassocresp\n"); s_vMgrRxAssocResponse(pDevice, pMgmt, pRxPacket, true); break; @@ -4198,7 +4203,7 @@ vMgrRxManagePacket( case WLAN_FSTYPE_PROBERESP: // Frame Clase = 0 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx proberesp\n"); + pr_debug("rx proberesp\n"); s_vMgrRxProbeResponse(pDevice, pMgmt, pRxPacket); break; @@ -4213,12 +4218,12 @@ vMgrRxManagePacket( case WLAN_FSTYPE_ATIM: // Frame Clase = 1 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx atim\n"); + pr_debug("rx atim\n"); break; case WLAN_FSTYPE_DISASSOC: // Frame Clase = 2 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx disassoc\n"); + pr_debug("rx disassoc\n"); if (eNodeState < NODE_AUTH) { // send deauth notification // reason = (6) class 2 received from nonauth sta @@ -4228,25 +4233,25 @@ vMgrRxManagePacket( (6), &Status ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wmgr: send vMgrDeAuthenBeginSta 3\n"); + pr_debug("wmgr: send vMgrDeAuthenBeginSta 3\n"); } s_vMgrRxDisassociation(pDevice, pMgmt, pRxPacket); break; case WLAN_FSTYPE_AUTHEN: // Frame Clase = 1 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx authen\n"); + pr_debug("rx authen\n"); s_vMgrRxAuthentication(pDevice, pMgmt, pRxPacket); break; case WLAN_FSTYPE_DEAUTHEN: // Frame Clase = 1 - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx deauthen\n"); + pr_debug("rx deauthen\n"); s_vMgrRxDeauthentication(pDevice, pMgmt, pRxPacket); break; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx unknown mgmt\n"); + pr_debug("rx unknown mgmt\n"); } } @@ -4319,46 +4324,46 @@ s_vMgrLogStatus( { switch (wStatus) { case WLAN_MGMT_STATUS_UNSPEC_FAILURE: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Unspecified error.\n"); + pr_info("Status code == Unspecified error\n"); break; case WLAN_MGMT_STATUS_CAPS_UNSUPPORTED: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Can't support all requested capabilities.\n"); + pr_info("Status code == Can't support all requested capabilities\n"); break; case WLAN_MGMT_STATUS_REASSOC_NO_ASSOC: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Reassoc denied, can't confirm original Association.\n"); + pr_info("Status code == Reassoc denied, can't confirm original Association\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, undefine in spec\n"); + pr_info("Status code == Assoc denied, undefine in spec\n"); break; case WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Peer doesn't support authen algorithm.\n"); + pr_info("Status code == Peer doesn't support authen algorithm\n"); break; case WLAN_MGMT_STATUS_RX_AUTH_NOSEQ: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen frame received out of sequence.\n"); + pr_info("Status code == Authen frame received out of sequence\n"); break; case WLAN_MGMT_STATUS_CHALLENGE_FAIL: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, challenge failure.\n"); + pr_info("Status code == Authen rejected, challenge failure\n"); break; case WLAN_MGMT_STATUS_AUTH_TIMEOUT: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Authen rejected, timeout waiting for next frame.\n"); + pr_info("Status code == Authen rejected, timeout waiting for next frame\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, AP too busy.\n"); + pr_info("Status code == Assoc denied, AP too busy\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_RATES: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we haven't enough basic rates.\n"); + pr_info("Status code == Assoc denied, we haven't enough basic rates\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_SHORTPREAMBLE: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support short preamble.\n"); + pr_info("Status code == Assoc denied, we do not support short preamble\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_PBCC: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support PBCC.\n"); + pr_info("Status code == Assoc denied, we do not support PBCC\n"); break; case WLAN_MGMT_STATUS_ASSOC_DENIED_AGILITY: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Status code == Assoc denied, we do not support channel agility.\n"); + pr_info("Status code == Assoc denied, we do not support channel agility\n"); break; default: - DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Unknown status code %d.\n", wStatus); + pr_info("Unknown status code %d\n", wStatus); break; } } @@ -4390,7 +4395,8 @@ bAdd_PMKID_Candidate( struct pmkid_candidate *pCandidateList; unsigned int ii = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "bAdd_PMKID_Candidate START: (%d)\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); + pr_debug("bAdd_PMKID_Candidate START: (%d)\n", + (int)pDevice->gsPMKIDCandidate.NumCandidates); if ((pDevice == NULL) || (pbyBSSID == NULL) || (psRSNCapObj == NULL)) return false; @@ -4420,7 +4426,8 @@ bAdd_PMKID_Candidate( memcpy(pCandidateList->BSSID, pbyBSSID, ETH_ALEN); pDevice->gsPMKIDCandidate.NumCandidates++; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "NumCandidates:%d\n", (int)pDevice->gsPMKIDCandidate.NumCandidates); + pr_debug("NumCandidates:%d\n", + (int)pDevice->gsPMKIDCandidate.NumCandidates); return true; } @@ -4537,8 +4544,9 @@ s_bCipherMatch( } } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%d, %d, %d, %d, EncStatus:%d\n", - byMulticastCipher, byCipherMask, pBSSNode->bWPAValid, pBSSNode->bWPA2Valid, EncStatus); + 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) { diff --git a/drivers/staging/vt6655/wpa.c b/drivers/staging/vt6655/wpa.c index 7b1bab91a9cf..5d4eca8512af 100644 --- a/drivers/staging/vt6655/wpa.c +++ b/drivers/staging/vt6655/wpa.c @@ -43,8 +43,6 @@ #include "80211mgr.h" /*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - 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 }; @@ -115,13 +113,13 @@ WPA_ParseRSN( WPA_ClearRSN(pBSSList); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WPA_ParseRSN: [%d]\n", pRSN->len); + 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)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Legal RSN\n"); + 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) @@ -139,13 +137,14 @@ WPA_ParseRSN( // any vendor checks here pBSSList->byGKType = WPA_NONE; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "byGKType: %x\n", pBSSList->byGKType); + pr_debug("byGKType: %x\n", pBSSList->byGKType); } if (pRSN->len >= 12) { //oui1(4)+ver(2)+GKS(4)+PKSCnt(2) j = 0; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wPKCount: %d, sizeof(pBSSList->abyPKType): %zu\n", pRSN->wPKCount, sizeof(pBSSList->abyPKType)); + 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)) @@ -163,19 +162,20 @@ WPA_ParseRSN( break; } pBSSList->wPKCount = (unsigned short)j; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wPKCount: %d\n", pBSSList->wPKCount); + pr_debug("wPKCount: %d\n", pBSSList->wPKCount); } m = pRSN->wPKCount; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "m: %d\n", m); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "14+m*4: %d\n", 14+m*4); + 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; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wAuthCount: %d, sizeof(pBSSList->abyAuthType): %zu\n", - pIE_RSN_Auth->wAuthCount, sizeof(pBSSList->abyAuthType)); + 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)) @@ -191,14 +191,14 @@ WPA_ParseRSN( } if (j > 0) pBSSList->wAuthCount = (unsigned short)j; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wAuthCount: %d\n", pBSSList->wAuthCount); + pr_debug("wAuthCount: %d\n", pBSSList->wAuthCount); } if (pIE_RSN_Auth != NULL) { n = pIE_RSN_Auth->wAuthCount; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "n: %d\n", n); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "14+4+(m+n)*4: %d\n", 14+4+(m+n)*4); + 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; diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 4e1b63be380f..bb335ef51172 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -35,8 +35,6 @@ #include "device.h" #include "wmgr.h" -/*--------------------- Static Definitions -------------------------*/ -static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ @@ -116,7 +114,7 @@ WPA2vParseRSN( unsigned char *pbyOUI; bool bUseGK = false; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "WPA2_ParseRSN: [%d]\n", pRSN->len); + pr_debug("WPA2_ParseRSN: [%d]\n", pRSN->len); WPA2_ClearRSN(pBSSNode); @@ -135,7 +133,7 @@ WPA2vParseRSN( // information element header makes sense if ((pRSN->byElementID == WLAN_EID_RSN) && (pRSN->wVersion == 1)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Legal 802.11i RSN\n"); + pr_debug("Legal 802.11i RSN\n"); pbyOUI = &(pRSN->abyRSN[0]); if (!memcmp(pbyOUI, abyOUIWEP40, 4)) @@ -153,7 +151,7 @@ WPA2vParseRSN( // any vendor checks here pBSSNode->byCSSGK = WLAN_11i_CSS_UNKNOWN; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "802.11i CSS: %X\n", pBSSNode->byCSSGK); + pr_debug("802.11i CSS: %X\n", pBSSNode->byCSSGK); if (pRSN->len == 6) { pBSSNode->bWPA2Valid = true; @@ -186,7 +184,8 @@ WPA2vParseRSN( pBSSNode->abyCSSPK[j++] = WLAN_11i_CSS_UNKNOWN; } pbyOUI += 4; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "abyCSSPK[%d]: %X\n", j-1, pBSSNode->abyCSSPK[j-1]); + pr_debug("abyCSSPK[%d]: %X\n", + j-1, pBSSNode->abyCSSPK[j-1]); } else break; } //for @@ -206,7 +205,7 @@ WPA2vParseRSN( return; } pBSSNode->wCSSPKCount = (unsigned short)j; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wCSSPKCount: %d\n", pBSSNode->wCSSPKCount); + pr_debug("wCSSPKCount: %d\n", pBSSNode->wCSSPKCount); } m = *((unsigned short *)&(pRSN->abyRSN[4])); @@ -224,12 +223,15 @@ WPA2vParseRSN( else // any vendor checks here pBSSNode->abyAKMSSAuthType[j++] = WLAN_11i_AKMSS_UNKNOWN; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "abyAKMSSAuthType[%d]: %X\n", j-1, pBSSNode->abyAKMSSAuthType[j-1]); + pr_debug("abyAKMSSAuthType[%d]: %X\n", + j-1, + pBSSNode->abyAKMSSAuthType[j-1]); } else break; } pBSSNode->wAKMSSAuthCount = (unsigned short)j; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount); + 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) diff --git a/drivers/staging/vt6655/wpactl.c b/drivers/staging/vt6655/wpactl.c index 5a1bfe9f31fa..37d98f717dc3 100644 --- a/drivers/staging/vt6655/wpactl.c +++ b/drivers/staging/vt6655/wpactl.c @@ -50,9 +50,6 @@ static const int frequency_list[] = { }; /*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; - /*--------------------- Static Functions --------------------------*/ /*--------------------- Export Variables --------------------------*/ @@ -103,8 +100,7 @@ static int wpa_init_wpadev(struct vnt_private *pDevice) pDevice->wpadev->mem_end = dev->mem_end; ret = register_netdev(pDevice->wpadev); if (ret) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: register_netdev(WPA) failed!\n", - dev->name); + pr_debug("%s: register_netdev(WPA) failed!\n", dev->name); free_netdev(pDevice->wpadev); return -1; } @@ -115,8 +111,8 @@ static int wpa_init_wpadev(struct vnt_private *pDevice) return -ENOMEM; } - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Registered netdev %s for WPA management\n", - dev->name, pDevice->wpadev->name); + pr_debug("%s: Registered netdev %s for WPA management\n", + dev->name, pDevice->wpadev->name); return 0; } @@ -142,8 +138,8 @@ static int wpa_release_wpadev(struct vnt_private *pDevice) } if (pDevice->wpadev) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "%s: Netdevice %s unregistered\n", - pDevice->dev->name, pDevice->wpadev->name); + pr_debug("%s: Netdevice %s unregistered\n", + pDevice->dev->name, pDevice->wpadev->name); unregister_netdev(pDevice->wpadev); free_netdev(pDevice->wpadev); pDevice->wpadev = NULL; @@ -206,7 +202,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx, param->u.wpa_key.seq_len > MAX_KEY_LEN) return -EINVAL; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "param->u.wpa_key.alg_name = %d\n", param->u.wpa_key.alg_name); + 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; @@ -284,7 +280,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx, } if (param->u.wpa_key.key_index >= MAX_GROUP_KEY) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return dwKeyIndex > 3\n"); + pr_debug("return dwKeyIndex > 3\n"); return -EINVAL; } @@ -323,7 +319,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx, if ((byKeyDecMode == KEY_CTL_TKIP) && (param->u.wpa_key.key_len != MAX_KEY_LEN)) { // TKIP Key must be 256 bits - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "return- TKIP Key must be 256 bits!\n"); + pr_debug("return- TKIP Key must be 256 bits!\n"); return -EINVAL; } // Check AES key length @@ -336,7 +332,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx, // 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. - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Groupe Key Assign.\n"); + pr_debug("Groupe Key Assign\n"); if (KeybSetAllGroupKey(&(pDevice->sKey), dwKeyIndex, @@ -354,18 +350,18 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx, byKeyDecMode, pDevice->PortOffset, pDevice->byLocalID)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "GROUP Key Assign.\n"); + pr_debug("GROUP Key Assign\n"); } else { return -EINVAL; } } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Assign.\n"); + pr_debug("Pairwise Key Assign\n"); // BSSID not 0xffffffffffff // Pairwise Key can't be WEP if (byKeyDecMode == KEY_CTL_WEP) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key can't be WEP\n"); + pr_debug("Pairwise Key can't be WEP\n"); return -EINVAL; } @@ -382,7 +378,7 @@ int wpa_set_keys(struct vnt_private *pDevice, void *ctx, byKeyDecMode, pDevice->PortOffset, pDevice->byLocalID)) { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Pairwise Key Set\n"); + pr_debug("Pairwise Key Set\n"); } else { // Key Table Full @@ -640,7 +636,7 @@ static int wpa_get_scan(struct vnt_private *pDevice, ret = -EFAULT; param->u.scan_results.scan_count = count; - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count); + pr_debug(" param->u.scan_results.scan_count = %d\n", count); kfree(pBuf); return ret; @@ -670,12 +666,14 @@ static int wpa_set_associate(struct vnt_private *pDevice, bool bWepEnabled = false; // set key type & algorithm - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "pairwise_suite = %d\n", param->u.wpa_associate.pairwise_suite); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "group_suite = %d\n", param->u.wpa_associate.group_suite); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "key_mgmt_suite = %d\n", param->u.wpa_associate.key_mgmt_suite); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "auth_alg = %d\n", param->u.wpa_associate.auth_alg); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "mode = %d\n", param->u.wpa_associate.mode); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ie_len = %d\n", param->u.wpa_associate.wpa_ie_len); + 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) @@ -826,60 +824,60 @@ int wpa_ioctl(struct vnt_private *pDevice, struct iw_point *p) switch (param->cmd) { case VIAWGET_SET_WPA: ret = wpa_set_wpa(pDevice, param); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_WPA\n"); + pr_debug("VIAWGET_SET_WPA\n"); break; case VIAWGET_SET_KEY: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_KEY\n"); + 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: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_SCAN\n"); + pr_debug("VIAWGET_SET_SCAN\n"); ret = wpa_set_scan(pDevice, param); break; case VIAWGET_GET_SCAN: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SCAN\n"); + pr_debug("VIAWGET_GET_SCAN\n"); ret = wpa_get_scan(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_GET_SSID: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_SSID\n"); + pr_debug("VIAWGET_GET_SSID\n"); ret = wpa_get_ssid(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_GET_BSSID: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_GET_BSSID\n"); + pr_debug("VIAWGET_GET_BSSID\n"); ret = wpa_get_bssid(pDevice, param); wpa_ioctl = 1; break; case VIAWGET_SET_ASSOCIATE: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_ASSOCIATE\n"); + pr_debug("VIAWGET_SET_ASSOCIATE\n"); ret = wpa_set_associate(pDevice, param); break; case VIAWGET_SET_DISASSOCIATE: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DISASSOCIATE\n"); + pr_debug("VIAWGET_SET_DISASSOCIATE\n"); ret = wpa_set_disassociate(pDevice, param); break; case VIAWGET_SET_DROP_UNENCRYPT: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DROP_UNENCRYPT\n"); + pr_debug("VIAWGET_SET_DROP_UNENCRYPT\n"); break; case VIAWGET_SET_DEAUTHENTICATE: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "VIAWGET_SET_DEAUTHENTICATE\n"); + pr_debug("VIAWGET_SET_DEAUTHENTICATE\n"); break; default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "wpa_ioctl: unknown cmd=%d\n", - param->cmd); + pr_debug("wpa_ioctl: unknown cmd=%d\n", + param->cmd); ret = -EOPNOTSUPP; goto out; } diff --git a/drivers/staging/vt6655/wroute.c b/drivers/staging/vt6655/wroute.c index 44ce6e274957..d1171fa3446e 100644 --- a/drivers/staging/vt6655/wroute.c +++ b/drivers/staging/vt6655/wroute.c @@ -42,8 +42,6 @@ /*--------------------- Static Classes ----------------------------*/ -/*--------------------- Static Variables --------------------------*/ -static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ /*--------------------- Export Variables --------------------------*/ @@ -78,8 +76,7 @@ bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, unsigned char *pbyBSSID; if (AVAIL_TD(pDevice, TYPE_AC0DMA) <= 0) { - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_INFO "Relay can't allocate TD1..\n"); + pr_debug("Relay can't allocate TD1..\n"); return false; } @@ -102,11 +99,10 @@ bool ROUTEbRelay(struct vnt_private *pDevice, unsigned char *pbySkbData, if (KeybGetTransmitKey(&(pDevice->sKey), pbyBSSID, GROUP_KEY, &pTransmitKey) == false) { pTransmitKey = NULL; - DBG_PRT(MSG_LEVEL_DEBUG, - KERN_DEBUG "KEY is NULL. [%d]\n", - pDevice->pMgmt->eCurrMode); + pr_debug("KEY is NULL. [%d]\n", + pDevice->pMgmt->eCurrMode); } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_DEBUG "Get GTK.\n"); + pr_debug("Get GTK\n"); } } -- GitLab From 114acca8ef16f21c5d50f16d154d05ffddb20049 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Fri, 15 Aug 2014 12:55:55 -0400 Subject: [PATCH 0813/9167] staging/lustre: get rid of seqno_t and mdsno_t typedefs seqno_t is u64 and mdsno_t is u32 so just use them as such. Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/fid/fid_request.c | 6 +++--- drivers/staging/lustre/lustre/fld/fld_cache.c | 16 ++++++++-------- drivers/staging/lustre/lustre/fld/fld_internal.h | 2 +- drivers/staging/lustre/lustre/fld/fld_request.c | 9 ++++----- .../lustre/lustre/include/lustre/lustre_idl.h | 2 -- .../staging/lustre/lustre/include/lustre_fid.h | 2 +- .../staging/lustre/lustre/include/lustre_fld.h | 5 ++--- .../staging/lustre/lustre/include/md_object.h | 2 +- drivers/staging/lustre/lustre/include/obd.h | 2 +- drivers/staging/lustre/lustre/lmv/lmv_fld.c | 2 +- drivers/staging/lustre/lustre/lmv/lmv_internal.h | 10 ++++------ drivers/staging/lustre/lustre/lmv/lmv_obd.c | 8 +++----- 12 files changed, 29 insertions(+), 37 deletions(-) diff --git a/drivers/staging/lustre/lustre/fid/fid_request.c b/drivers/staging/lustre/lustre/fid/fid_request.c index 992d07591b08..46c11ca85a69 100644 --- a/drivers/staging/lustre/lustre/fid/fid_request.c +++ b/drivers/staging/lustre/lustre/fid/fid_request.c @@ -187,7 +187,7 @@ static int seq_client_alloc_meta(const struct lu_env *env, /* Allocate new sequence for client. */ static int seq_client_alloc_seq(const struct lu_env *env, - struct lu_client_seq *seq, seqno_t *seqnr) + struct lu_client_seq *seq, u64 *seqnr) { int rc; @@ -249,7 +249,7 @@ static void seq_fid_alloc_fini(struct lu_client_seq *seq) * Allocate the whole seq to the caller. **/ int seq_client_get_seq(const struct lu_env *env, - struct lu_client_seq *seq, seqno_t *seqnr) + struct lu_client_seq *seq, u64 *seqnr) { wait_queue_t link; int rc; @@ -313,7 +313,7 @@ int seq_client_alloc_fid(const struct lu_env *env, seq->lcs_fid.f_oid = seq->lcs_width; while (1) { - seqno_t seqnr; + u64 seqnr; if (!fid_is_zero(&seq->lcs_fid) && fid_oid(&seq->lcs_fid) < seq->lcs_width) { diff --git a/drivers/staging/lustre/lustre/fld/fld_cache.c b/drivers/staging/lustre/lustre/fld/fld_cache.c index 759a233a7028..f5a340af499e 100644 --- a/drivers/staging/lustre/lustre/fld/fld_cache.c +++ b/drivers/staging/lustre/lustre/fld/fld_cache.c @@ -263,8 +263,8 @@ void fld_cache_punch_hole(struct fld_cache *cache, struct fld_cache_entry *f_new) { const struct lu_seq_range *range = &f_new->fce_range; - const seqno_t new_start = range->lsr_start; - const seqno_t new_end = range->lsr_end; + const u64 new_start = range->lsr_start; + const u64 new_end = range->lsr_end; struct fld_cache_entry *fldt; OBD_ALLOC_GFP(fldt, sizeof(*fldt), GFP_ATOMIC); @@ -302,9 +302,9 @@ static void fld_cache_overlap_handle(struct fld_cache *cache, struct fld_cache_entry *f_new) { const struct lu_seq_range *range = &f_new->fce_range; - const seqno_t new_start = range->lsr_start; - const seqno_t new_end = range->lsr_end; - const mdsno_t mdt = range->lsr_index; + const u64 new_start = range->lsr_start; + const u64 new_end = range->lsr_end; + const u32 mdt = range->lsr_index; /* this is overlap case, these case are checking overlapping with * prev range only. fixup will handle overlapping with next range. */ @@ -386,8 +386,8 @@ int fld_cache_insert_nolock(struct fld_cache *cache, struct fld_cache_entry *n; struct list_head *head; struct list_head *prev = NULL; - const seqno_t new_start = f_new->fce_range.lsr_start; - const seqno_t new_end = f_new->fce_range.lsr_end; + const u64 new_start = f_new->fce_range.lsr_start; + const u64 new_end = f_new->fce_range.lsr_end; __u32 new_flags = f_new->fce_range.lsr_flags; /* @@ -516,7 +516,7 @@ struct fld_cache_entry * lookup \a seq sequence for range in fld cache. */ int fld_cache_lookup(struct fld_cache *cache, - const seqno_t seq, struct lu_seq_range *range) + const u64 seq, struct lu_seq_range *range) { struct fld_cache_entry *flde; struct fld_cache_entry *prev = NULL; diff --git a/drivers/staging/lustre/lustre/fld/fld_internal.h b/drivers/staging/lustre/lustre/fld/fld_internal.h index 5da0c1da0d39..8806b6096953 100644 --- a/drivers/staging/lustre/lustre/fld/fld_internal.h +++ b/drivers/staging/lustre/lustre/fld/fld_internal.h @@ -167,7 +167,7 @@ void fld_cache_delete(struct fld_cache *cache, void fld_cache_delete_nolock(struct fld_cache *cache, const struct lu_seq_range *range); int fld_cache_lookup(struct fld_cache *cache, - const seqno_t seq, struct lu_seq_range *range); + const u64 seq, struct lu_seq_range *range); struct fld_cache_entry* fld_cache_entry_lookup(struct fld_cache *cache, struct lu_seq_range *range); diff --git a/drivers/staging/lustre/lustre/fld/fld_request.c b/drivers/staging/lustre/lustre/fld/fld_request.c index 8e512f9c3db0..4539a0284a78 100644 --- a/drivers/staging/lustre/lustre/fld/fld_request.c +++ b/drivers/staging/lustre/lustre/fld/fld_request.c @@ -110,15 +110,14 @@ static void fld_exit_request(struct client_obd *cli) client_obd_list_unlock(&cli->cl_loi_list_lock); } -static int fld_rrb_hash(struct lu_client_fld *fld, - seqno_t seq) +static int fld_rrb_hash(struct lu_client_fld *fld, u64 seq) { LASSERT(fld->lcf_count > 0); return do_div(seq, fld->lcf_count); } static struct lu_fld_target * -fld_rrb_scan(struct lu_client_fld *fld, seqno_t seq) +fld_rrb_scan(struct lu_client_fld *fld, u64 seq) { struct lu_fld_target *target; int hash; @@ -173,7 +172,7 @@ struct lu_fld_hash fld_hash[] = { }; static struct lu_fld_target * -fld_client_get_target(struct lu_client_fld *fld, seqno_t seq) +fld_client_get_target(struct lu_client_fld *fld, u64 seq) { struct lu_fld_target *target; @@ -453,7 +452,7 @@ int fld_client_rpc(struct obd_export *exp, return rc; } -int fld_client_lookup(struct lu_client_fld *fld, seqno_t seq, mdsno_t *mds, +int fld_client_lookup(struct lu_client_fld *fld, u64 seq, u32 *mds, __u32 flags, const struct lu_env *env) { struct lu_seq_range res = { 0 }; diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index 757146273724..186f5e3e95ca 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -165,8 +165,6 @@ #define LUSTRE_LOG_VERSION 0x00050000 #define LUSTRE_MGS_VERSION 0x00060000 -typedef __u32 mdsno_t; -typedef __u64 seqno_t; typedef __u64 obd_id; typedef __u64 obd_seq; typedef __s64 obd_time; diff --git a/drivers/staging/lustre/lustre/include/lustre_fid.h b/drivers/staging/lustre/lustre/include/lustre_fid.h index ffb00f171240..2d6fbb4b1b39 100644 --- a/drivers/staging/lustre/lustre/include/lustre_fid.h +++ b/drivers/staging/lustre/lustre/include/lustre_fid.h @@ -469,7 +469,7 @@ void seq_client_flush(struct lu_client_seq *seq); int seq_client_alloc_fid(const struct lu_env *env, struct lu_client_seq *seq, struct lu_fid *fid); int seq_client_get_seq(const struct lu_env *env, struct lu_client_seq *seq, - seqno_t *seqnr); + u64 *seqnr); int seq_site_fini(const struct lu_env *env, struct seq_server_site *ss); /* Fids common stuff */ int fid_is_local(const struct lu_env *env, diff --git a/drivers/staging/lustre/lustre/include/lustre_fld.h b/drivers/staging/lustre/lustre/include/lustre_fld.h index ce6330f9bb50..64c504849a22 100644 --- a/drivers/staging/lustre/lustre/include/lustre_fld.h +++ b/drivers/staging/lustre/lustre/include/lustre_fld.h @@ -137,15 +137,14 @@ void fld_client_fini(struct lu_client_fld *fld); void fld_client_flush(struct lu_client_fld *fld); -int fld_client_lookup(struct lu_client_fld *fld, seqno_t seq, mdsno_t *mds, +int fld_client_lookup(struct lu_client_fld *fld, u64 seq, u32 *mds, __u32 flags, const struct lu_env *env); int fld_client_create(struct lu_client_fld *fld, struct lu_seq_range *range, const struct lu_env *env); -int fld_client_delete(struct lu_client_fld *fld, - seqno_t seq, +int fld_client_delete(struct lu_client_fld *fld, u64 seq, const struct lu_env *env); int fld_client_add_target(struct lu_client_fld *fld, diff --git a/drivers/staging/lustre/lustre/include/md_object.h b/drivers/staging/lustre/lustre/include/md_object.h index 2e5d55030a63..bd5f6186bf31 100644 --- a/drivers/staging/lustre/lustre/include/md_object.h +++ b/drivers/staging/lustre/lustre/include/md_object.h @@ -451,7 +451,7 @@ struct seq_server_site { /** * mds number of this site. */ - mdsno_t ss_node_id; + u32 ss_node_id; /** * Fid location database */ diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 489bdd399627..b4721367c17f 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -1057,7 +1057,7 @@ struct md_op_data { struct lu_fid op_fid2; /* operation fid2 (usually child) */ struct lu_fid op_fid3; /* 2 extra fids to find conflicting */ struct lu_fid op_fid4; /* to the operation locks. */ - mdsno_t op_mds; /* what mds server open will go to */ + u32 op_mds; /* what mds server open will go to */ struct lustre_handle op_handle; obd_time op_mod_time; const char *op_name; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_fld.c b/drivers/staging/lustre/lustre/lmv/lmv_fld.c index 8289bcc5f8e1..e8421f04beda 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_fld.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_fld.c @@ -53,7 +53,7 @@ int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, - mdsno_t *mds) + u32 *mds) { int rc; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_internal.h b/drivers/staging/lustre/lustre/lmv/lmv_internal.h index eb18a5900e13..80e6604f420d 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_internal.h +++ b/drivers/staging/lustre/lustre/lmv/lmv_internal.h @@ -70,10 +70,8 @@ int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, int lmv_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *, void *, int); -int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, - mdsno_t *mds); -int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, - mdsno_t mds); +int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid, u32 *mds); +int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds); int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid, struct md_op_data *op_data); @@ -111,7 +109,7 @@ static inline int lmv_get_easize(struct lmv_obd *lmv) } static inline struct lmv_tgt_desc * -lmv_get_target(struct lmv_obd *lmv, mdsno_t mds) +lmv_get_target(struct lmv_obd *lmv, u32 mds) { int count = lmv->desc.ld_tgt_count; int i; @@ -130,7 +128,7 @@ lmv_get_target(struct lmv_obd *lmv, mdsno_t mds) static inline struct lmv_tgt_desc * lmv_find_target(struct lmv_obd *lmv, const struct lu_fid *fid) { - mdsno_t mds = 0; + u32 mds = 0; int rc; if (lmv->desc.ld_tgt_count > 1) { diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index a66b3e000d57..0b1e4a1364d3 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -1201,8 +1201,7 @@ static int lmv_choose_mds(struct lmv_obd *lmv, struct md_op_data *op_data, * This is _inode_ placement policy function (not name). */ static int lmv_placement_policy(struct obd_device *obd, - struct md_op_data *op_data, - mdsno_t *mds) + struct md_op_data *op_data, u32 *mds) { struct lmv_obd *lmv = &obd->u.lmv; @@ -1241,8 +1240,7 @@ static int lmv_placement_policy(struct obd_device *obd, return 0; } -int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, - mdsno_t mds) +int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid, u32 mds) { struct lmv_tgt_desc *tgt; int rc; @@ -1279,7 +1277,7 @@ int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid, { struct obd_device *obd = class_exp2obd(exp); struct lmv_obd *lmv = &obd->u.lmv; - mdsno_t mds = 0; + u32 mds = 0; int rc; LASSERT(op_data != NULL); -- GitLab From 21aef7d9d654416b8167ad8047a628d3968a97da Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Fri, 15 Aug 2014 12:55:56 -0400 Subject: [PATCH 0814/9167] staging/lustre: get rid of obd_* typedefs We have a bunch of typedefs for common things that made no sense and hid the actual type from plain view. Replace them with proper uXX or sXX types. Exception is in lustre_idl.h where they are replaced with __uXX and __sXX to be able to be included in userspace Signed-off-by: Oleg Drokin Signed-off-by: Greg Kroah-Hartman --- .../staging/lustre/lustre/include/cl_object.h | 4 +- .../staging/lustre/lustre/include/lclient.h | 2 +- .../lustre/lustre/include/linux/obd_class.h | 6 +- .../staging/lustre/lustre/include/lu_object.h | 6 +- .../lustre/lustre/include/lustre/lustre_idl.h | 122 ++++++++---------- .../lustre/lustre/include/lustre_lib.h | 8 +- .../lustre/lustre/include/lustre_lite.h | 2 +- drivers/staging/lustre/lustre/include/obd.h | 48 ++++--- .../staging/lustre/lustre/include/obd_cksum.h | 6 +- .../staging/lustre/lustre/include/obd_class.h | 24 ++-- .../staging/lustre/lustre/include/obd_ost.h | 2 +- .../lustre/lustre/lclient/lcommon_cl.c | 4 +- drivers/staging/lustre/lustre/llite/file.c | 7 +- .../lustre/lustre/llite/llite_internal.h | 4 +- .../staging/lustre/lustre/llite/llite_lib.c | 2 +- .../lustre/lustre/llite/llite_rmtacl.c | 2 +- drivers/staging/lustre/lustre/llite/lloop.c | 2 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 8 +- .../lustre/lustre/lov/lov_cl_internal.h | 4 +- drivers/staging/lustre/lustre/lov/lov_ea.c | 8 +- .../staging/lustre/lustre/lov/lov_internal.h | 28 ++-- drivers/staging/lustre/lustre/lov/lov_io.c | 8 +- drivers/staging/lustre/lustre/lov/lov_lock.c | 24 ++-- drivers/staging/lustre/lustre/lov/lov_merge.c | 14 +- drivers/staging/lustre/lustre/lov/lov_obd.c | 44 +++---- .../staging/lustre/lustre/lov/lov_offset.c | 29 ++--- drivers/staging/lustre/lustre/lov/lov_pack.c | 4 +- drivers/staging/lustre/lustre/lov/lov_page.c | 2 +- .../staging/lustre/lustre/lov/lov_request.c | 18 +-- .../staging/lustre/lustre/lov/lovsub_dev.c | 2 +- .../staging/lustre/lustre/mdc/mdc_internal.h | 2 +- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 2 +- .../staging/lustre/lustre/mdc/mdc_request.c | 14 +- .../staging/lustre/lustre/mgc/mgc_request.c | 4 +- .../staging/lustre/lustre/obdclass/cl_io.c | 2 +- .../lustre/lustre/obdclass/linux/linux-obdo.c | 8 +- .../lustre/lustre/obdclass/local_storage.c | 2 +- drivers/staging/lustre/lustre/obdclass/obdo.c | 12 +- drivers/staging/lustre/lustre/obdecho/echo.c | 21 +-- .../lustre/lustre/obdecho/echo_client.c | 58 ++++----- drivers/staging/lustre/lustre/osc/lproc_osc.c | 2 +- drivers/staging/lustre/lustre/osc/osc_cache.c | 2 +- .../lustre/lustre/osc/osc_cl_internal.h | 2 +- .../staging/lustre/lustre/osc/osc_internal.h | 6 +- drivers/staging/lustre/lustre/osc/osc_io.c | 2 +- drivers/staging/lustre/lustre/osc/osc_quota.c | 8 +- .../staging/lustre/lustre/osc/osc_request.c | 46 +++---- drivers/staging/lustre/lustre/ptlrpc/layout.c | 4 +- .../lustre/lustre/ptlrpc/pack_generic.c | 6 +- 49 files changed, 315 insertions(+), 332 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/cl_object.h b/drivers/staging/lustre/lustre/include/cl_object.h index e51cd690f907..41858e43d732 100644 --- a/drivers/staging/lustre/lustre/include/cl_object.h +++ b/drivers/staging/lustre/lustre/include/cl_object.h @@ -2508,7 +2508,7 @@ struct cl_req_operations { void (*cro_attr_set)(const struct lu_env *env, const struct cl_req_slice *slice, const struct cl_object *obj, - struct cl_req_attr *attr, obd_valid flags); + struct cl_req_attr *attr, u64 flags); /** * Called top-to-bottom from cl_req_completion() to notify layers that * transfer completed. Has to free all state allocated by @@ -3182,7 +3182,7 @@ void cl_req_page_add (const struct lu_env *env, struct cl_req *req, void cl_req_page_done (const struct lu_env *env, struct cl_page *page); int cl_req_prep (const struct lu_env *env, struct cl_req *req); void cl_req_attr_set (const struct lu_env *env, struct cl_req *req, - struct cl_req_attr *attr, obd_valid flags); + struct cl_req_attr *attr, u64 flags); void cl_req_completion(const struct lu_env *env, struct cl_req *req, int ioret); /** \defgroup cl_sync_io cl_sync_io diff --git a/drivers/staging/lustre/lustre/include/lclient.h b/drivers/staging/lustre/lustre/include/lclient.h index 386a36c00f57..fa45c94b814a 100644 --- a/drivers/staging/lustre/lustre/include/lclient.h +++ b/drivers/staging/lustre/lustre/include/lclient.h @@ -350,7 +350,7 @@ void ccc_req_completion(const struct lu_env *env, const struct cl_req_slice *slice, int ioret); void ccc_req_attr_set(const struct lu_env *env,const struct cl_req_slice *slice, const struct cl_object *obj, - struct cl_req_attr *oa, obd_valid flags); + struct cl_req_attr *oa, u64 flags); struct lu_device *ccc2lu_dev (struct ccc_device *vdv); struct lu_object *ccc2lu (struct ccc_object *vob); diff --git a/drivers/staging/lustre/lustre/include/linux/obd_class.h b/drivers/staging/lustre/lustre/include/linux/obd_class.h index 021ead6639fc..99c5bd1fd0ae 100644 --- a/drivers/staging/lustre/lustre/include/linux/obd_class.h +++ b/drivers/staging/lustre/lustre/include/linux/obd_class.h @@ -49,9 +49,9 @@ /* obdo.c */ void obdo_from_la(struct obdo *dst, struct lu_attr *la, __u64 valid); -void la_from_obdo(struct lu_attr *la, struct obdo *dst, obd_flag valid); -void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid); -void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid); +void la_from_obdo(struct lu_attr *la, struct obdo *dst, u32 valid); +void obdo_refresh_inode(struct inode *dst, struct obdo *src, u32 valid); +void obdo_to_inode(struct inode *dst, struct obdo *src, u32 valid); #define ll_inode_flags(inode) (inode->i_flags) diff --git a/drivers/staging/lustre/lustre/include/lu_object.h b/drivers/staging/lustre/lustre/include/lu_object.h index d5c368bab5bd..a6ce42a93d43 100644 --- a/drivers/staging/lustre/lustre/include/lu_object.h +++ b/drivers/staging/lustre/lustre/include/lu_object.h @@ -404,11 +404,11 @@ struct lu_attr { /** size in bytes */ __u64 la_size; /** modification time in seconds since Epoch */ - obd_time la_mtime; + s64 la_mtime; /** access time in seconds since Epoch */ - obd_time la_atime; + s64 la_atime; /** change time in seconds since Epoch */ - obd_time la_ctime; + s64 la_ctime; /** 512-byte blocks allocated to object */ __u64 la_blocks; /** permission bits and file type */ diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index 186f5e3e95ca..570f54f794f2 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -165,20 +165,6 @@ #define LUSTRE_LOG_VERSION 0x00050000 #define LUSTRE_MGS_VERSION 0x00060000 -typedef __u64 obd_id; -typedef __u64 obd_seq; -typedef __s64 obd_time; -typedef __u64 obd_size; -typedef __u64 obd_off; -typedef __u64 obd_blocks; -typedef __u64 obd_valid; -typedef __u32 obd_blksize; -typedef __u32 obd_mode; -typedef __u32 obd_uid; -typedef __u32 obd_gid; -typedef __u32 obd_flag; -typedef __u32 obd_count; - /** * Describes a range of sequence, lsr_start is included but lsr_end is * not in the range. @@ -411,7 +397,7 @@ static inline void fid_zero(struct lu_fid *fid) memset(fid, 0, sizeof(*fid)); } -static inline obd_id fid_ver_oid(const struct lu_fid *fid) +static inline __u64 fid_ver_oid(const struct lu_fid *fid) { return ((__u64)fid_ver(fid) << 32 | fid_oid(fid)); } @@ -475,7 +461,7 @@ enum dot_lustre_oid { FID_OID_DOT_LUSTRE_OBF = 2UL, }; -static inline int fid_seq_is_mdt0(obd_seq seq) +static inline int fid_seq_is_mdt0(__u64 seq) { return (seq == FID_SEQ_OST_MDT0); } @@ -485,7 +471,7 @@ static inline int fid_seq_is_mdt(const __u64 seq) return seq == FID_SEQ_OST_MDT0 || seq >= FID_SEQ_NORMAL; }; -static inline int fid_seq_is_echo(obd_seq seq) +static inline int fid_seq_is_echo(__u64 seq) { return (seq == FID_SEQ_ECHO); } @@ -495,7 +481,7 @@ static inline int fid_is_echo(const struct lu_fid *fid) return fid_seq_is_echo(fid_seq(fid)); } -static inline int fid_seq_is_llog(obd_seq seq) +static inline int fid_seq_is_llog(__u64 seq) { return (seq == FID_SEQ_LLOG); } @@ -595,13 +581,13 @@ static inline int fid_is_norm(const struct lu_fid *fid) } /* convert an OST objid into an IDIF FID SEQ number */ -static inline obd_seq fid_idif_seq(obd_id id, __u32 ost_idx) +static inline __u64 fid_idif_seq(__u64 id, __u32 ost_idx) { return FID_SEQ_IDIF | (ost_idx << 16) | ((id >> 32) & 0xffff); } /* convert a packed IDIF FID into an OST objid */ -static inline obd_id fid_idif_id(obd_seq seq, __u32 oid, __u32 ver) +static inline __u64 fid_idif_id(__u64 seq, __u32 oid, __u32 ver) { return ((__u64)ver << 48) | ((seq & 0xffff) << 32) | oid; } @@ -613,7 +599,7 @@ static inline __u32 fid_idif_ost_idx(const struct lu_fid *fid) } /* extract OST sequence (group) from a wire ost_id (id/seq) pair */ -static inline obd_seq ostid_seq(const struct ost_id *ostid) +static inline __u64 ostid_seq(const struct ost_id *ostid) { if (fid_seq_is_mdt0(ostid->oi.oi_seq)) return FID_SEQ_OST_MDT0; @@ -628,7 +614,7 @@ static inline obd_seq ostid_seq(const struct ost_id *ostid) } /* extract OST objid from a wire ost_id (id/seq) pair */ -static inline obd_id ostid_id(const struct ost_id *ostid) +static inline __u64 ostid_id(const struct ost_id *ostid) { if (fid_seq_is_mdt0(ostid_seq(ostid))) return ostid->oi.oi_id & IDIF_OID_MASK; @@ -1855,9 +1841,9 @@ extern void lustre_swab_niobuf_remote (struct niobuf_remote *nbr); struct ost_lvb_v1 { __u64 lvb_size; - obd_time lvb_mtime; - obd_time lvb_atime; - obd_time lvb_ctime; + __s64 lvb_mtime; + __s64 lvb_atime; + __s64 lvb_ctime; __u64 lvb_blocks; }; @@ -1865,9 +1851,9 @@ extern void lustre_swab_ost_lvb_v1(struct ost_lvb_v1 *lvb); struct ost_lvb { __u64 lvb_size; - obd_time lvb_mtime; - obd_time lvb_atime; - obd_time lvb_ctime; + __s64 lvb_mtime; + __s64 lvb_atime; + __s64 lvb_ctime; __u64 lvb_blocks; __u32 lvb_mtime_ns; __u32 lvb_atime_ns; @@ -2248,9 +2234,9 @@ struct mdt_body { struct lustre_handle handle; __u64 valid; __u64 size; /* Offset, in the case of MDS_READPAGE */ - obd_time mtime; - obd_time atime; - obd_time ctime; + __s64 mtime; + __s64 atime; + __s64 ctime; __u64 blocks; /* XID, in the case of MDS_READPAGE */ __u64 ioepoch; __u64 t_state; /* transient file state defined in @@ -2333,9 +2319,9 @@ struct mdt_rec_setattr { __u32 sa_gid; __u64 sa_size; __u64 sa_blocks; - obd_time sa_mtime; - obd_time sa_atime; - obd_time sa_ctime; + __s64 sa_mtime; + __s64 sa_atime; + __s64 sa_ctime; __u32 sa_attr_flags; __u32 sa_mode; __u32 sa_bias; /* some operation flags */ @@ -2464,7 +2450,7 @@ struct mdt_rec_create { struct lu_fid cr_fid1; struct lu_fid cr_fid2; struct lustre_handle cr_old_handle; /* handle in case of open replay */ - obd_time cr_time; + __s64 cr_time; __u64 cr_rdev; __u64 cr_ioepoch; __u64 cr_padding_1; /* rr_blocks */ @@ -2504,7 +2490,7 @@ struct mdt_rec_link { __u32 lk_suppgid2_h; struct lu_fid lk_fid1; struct lu_fid lk_fid2; - obd_time lk_time; + __s64 lk_time; __u64 lk_padding_1; /* rr_atime */ __u64 lk_padding_2; /* rr_ctime */ __u64 lk_padding_3; /* rr_size */ @@ -2531,7 +2517,7 @@ struct mdt_rec_unlink { __u32 ul_suppgid2_h; struct lu_fid ul_fid1; struct lu_fid ul_fid2; - obd_time ul_time; + __s64 ul_time; __u64 ul_padding_2; /* rr_atime */ __u64 ul_padding_3; /* rr_ctime */ __u64 ul_padding_4; /* rr_size */ @@ -2558,7 +2544,7 @@ struct mdt_rec_rename { __u32 rn_suppgid2_h; struct lu_fid rn_fid1; struct lu_fid rn_fid2; - obd_time rn_time; + __s64 rn_time; __u64 rn_padding_1; /* rr_atime */ __u64 rn_padding_2; /* rr_ctime */ __u64 rn_padding_3; /* rr_size */ @@ -2588,7 +2574,7 @@ struct mdt_rec_setxattr { __u32 sx_padding_2; __u32 sx_padding_3; __u64 sx_valid; - obd_time sx_time; + __s64 sx_time; __u64 sx_padding_5; /* rr_ctime */ __u64 sx_padding_6; /* rr_size */ __u64 sx_padding_7; /* rr_blocks */ @@ -2621,9 +2607,9 @@ struct mdt_rec_reint { __u32 rr_suppgid2_h; struct lu_fid rr_fid1; struct lu_fid rr_fid2; - obd_time rr_mtime; - obd_time rr_atime; - obd_time rr_ctime; + __s64 rr_mtime; + __s64 rr_atime; + __s64 rr_ctime; __u64 rr_size; __u64 rr_blocks; __u32 rr_bias; @@ -2977,8 +2963,8 @@ struct cfg_marker { __u32 cm_flags; __u32 cm_vers; /* lustre release version number */ __u32 cm_padding; /* 64 bit align */ - obd_time cm_createtime; /*when this record was first created */ - obd_time cm_canceltime; /*when this record is no longer valid*/ + __s64 cm_createtime; /*when this record was first created */ + __s64 cm_canceltime; /*when this record is no longer valid*/ char cm_tgtname[MTI_NAME_MAXLEN]; char cm_comment[MTI_NAME_MAXLEN]; }; @@ -3082,16 +3068,16 @@ struct llog_logid_rec { struct llog_unlink_rec { struct llog_rec_hdr lur_hdr; - obd_id lur_oid; - obd_count lur_oseq; - obd_count lur_count; + __u64 lur_oid; + __u32 lur_oseq; + __u32 lur_count; struct llog_rec_tail lur_tail; } __attribute__((packed)); struct llog_unlink64_rec { struct llog_rec_hdr lur_hdr; struct lu_fid lur_fid; - obd_count lur_count; /* to destroy the lost precreated */ + __u32 lur_count; /* to destroy the lost precreated */ __u32 lur_padding1; __u64 lur_padding2; __u64 lur_padding3; @@ -3236,7 +3222,7 @@ enum llog_flag { struct llog_log_hdr { struct llog_rec_hdr llh_hdr; - obd_time llh_timestamp; + __s64 llh_timestamp; __u32 llh_count; __u32 llh_bitmap_offset; __u32 llh_size; @@ -3294,25 +3280,25 @@ struct llogd_conn_body { /* Note: 64-bit types are 64-bit aligned in structure */ struct obdo { - obd_valid o_valid; /* hot fields in this obdo */ - struct ost_id o_oi; - obd_id o_parent_seq; - obd_size o_size; /* o_size-o_blocks == ost_lvb */ - obd_time o_mtime; - obd_time o_atime; - obd_time o_ctime; - obd_blocks o_blocks; /* brw: cli sent cached bytes */ - obd_size o_grant; + __u64 o_valid; /* hot fields in this obdo */ + struct ost_id o_oi; + __u64 o_parent_seq; + __u64 o_size; /* o_size-o_blocks == ost_lvb */ + __s64 o_mtime; + __s64 o_atime; + __s64 o_ctime; + __u64 o_blocks; /* brw: cli sent cached bytes */ + __u64 o_grant; /* 32-bit fields start here: keep an even number of them via padding */ - obd_blksize o_blksize; /* optimal IO blocksize */ - obd_mode o_mode; /* brw: cli sent cache remain */ - obd_uid o_uid; - obd_gid o_gid; - obd_flag o_flags; - obd_count o_nlink; /* brw: checksum */ - obd_count o_parent_oid; - obd_count o_misc; /* brw: o_dropped */ + __u32 o_blksize; /* optimal IO blocksize */ + __u32 o_mode; /* brw: cli sent cache remain */ + __u32 o_uid; + __u32 o_gid; + __u32 o_flags; + __u32 o_nlink; /* brw: checksum */ + __u32 o_parent_oid; + __u32 o_misc; /* brw: o_dropped */ __u64 o_ioepoch; /* epoch in ost writes */ __u32 o_stripe_idx; /* holds stripe idx */ @@ -3361,7 +3347,7 @@ static inline void lustre_get_wire_obdo(struct obd_connect_data *ocd, struct obdo *lobdo, const struct obdo *wobdo) { - obd_flag local_flags = 0; + __u32 local_flags = 0; if (lobdo->o_valid & OBD_MD_FLFLAGS) local_flags = lobdo->o_flags & OBD_FL_LOCAL_MASK; @@ -3399,7 +3385,7 @@ struct ll_fiemap_info_key { }; extern void lustre_swab_ost_body (struct ost_body *b); -extern void lustre_swab_ost_last_id(obd_id *id); +extern void lustre_swab_ost_last_id(__u64 *id); extern void lustre_swab_fiemap(struct ll_user_fiemap *fiemap); extern void lustre_swab_lov_user_md_v1(struct lov_user_md_v1 *lum); diff --git a/drivers/staging/lustre/lustre/include/lustre_lib.h b/drivers/staging/lustre/lustre/include/lustre_lib.h index de493fabab46..6ab895864998 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lib.h +++ b/drivers/staging/lustre/lustre/include/lustre_lib.h @@ -65,8 +65,8 @@ struct l_wait_info; int target_pack_pool_reply(struct ptlrpc_request *req); int do_set_info_async(struct obd_import *imp, int opcode, int version, - obd_count keylen, void *key, - obd_count vallen, void *val, + u32 keylen, void *key, + u32 vallen, void *val, struct ptlrpc_request_set *set); #define OBD_RECOVERY_MAX_TIME (obd_timeout * 18) /* b13079 */ @@ -133,8 +133,8 @@ struct obd_ioctl_data { struct obdo ioc_obdo1; struct obdo ioc_obdo2; - obd_size ioc_count; - obd_off ioc_offset; + u64 ioc_count; + u64 ioc_offset; __u32 ioc_dev; __u32 ioc_command; diff --git a/drivers/staging/lustre/lustre/include/lustre_lite.h b/drivers/staging/lustre/lustre/include/lustre_lite.h index eee900638720..c10c0d388b66 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lite.h +++ b/drivers/staging/lustre/lustre/include/lustre_lite.h @@ -60,7 +60,7 @@ struct lustre_rw_params { int lrp_lock_mode; ldlm_policy_data_t lrp_policy; - obd_flag lrp_brw_flags; + u32 lrp_brw_flags; int lrp_ast_flags; }; diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index b4721367c17f..808cb0e04037 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -252,10 +252,10 @@ struct obd_type { }; struct brw_page { - obd_off off; + u64 off; struct page *pg; int count; - obd_flag flag; + u32 flag; }; /* llog contexts */ @@ -442,7 +442,7 @@ struct client_obd { struct obd_id_info { __u32 idx; - obd_id *data; + u64 *data; }; struct echo_client_obd { @@ -1059,7 +1059,7 @@ struct md_op_data { struct lu_fid op_fid4; /* to the operation locks. */ u32 op_mds; /* what mds server open will go to */ struct lustre_handle op_handle; - obd_time op_mod_time; + s64 op_mod_time; const char *op_name; int op_namelen; __u32 op_mode; @@ -1138,14 +1138,13 @@ struct obd_ops { __u32 keylen, void *key, __u32 vallen, void *val, struct ptlrpc_request_set *set); - int (*o_attach)(struct obd_device *dev, obd_count len, void *data); + int (*o_attach)(struct obd_device *dev, u32 len, void *data); int (*o_detach)(struct obd_device *dev); int (*o_setup) (struct obd_device *dev, struct lustre_cfg *cfg); int (*o_precleanup)(struct obd_device *dev, enum obd_cleanup_stage cleanup_stage); int (*o_cleanup)(struct obd_device *dev); - int (*o_process_config)(struct obd_device *dev, obd_count len, - void *data); + int (*o_process_config)(struct obd_device *dev, u32 len, void *data); int (*o_postrecov)(struct obd_device *dev); int (*o_add_conn)(struct obd_import *imp, struct obd_uuid *uuid, int priority); @@ -1186,8 +1185,7 @@ struct obd_ops { struct lov_stripe_md *mem_src); int (*o_unpackmd)(struct obd_export *exp,struct lov_stripe_md **mem_tgt, struct lov_mds_md *disk_src, int disk_len); - int (*o_preallocate)(struct lustre_handle *, obd_count *req, - obd_id *ids); + int (*o_preallocate)(struct lustre_handle *, u32 *req, u64 *ids); /* FIXME: add fid capability support for create & destroy! */ int (*o_precreate)(struct obd_export *exp); int (*o_create)(const struct lu_env *env, struct obd_export *exp, @@ -1210,27 +1208,27 @@ struct obd_ops { int (*o_getattr_async)(struct obd_export *exp, struct obd_info *oinfo, struct ptlrpc_request_set *set); int (*o_brw)(int rw, struct obd_export *exp, struct obd_info *oinfo, - obd_count oa_bufs, struct brw_page *pgarr, + u32 oa_bufs, struct brw_page *pgarr, struct obd_trans_info *oti); int (*o_merge_lvb)(struct obd_export *exp, struct lov_stripe_md *lsm, struct ost_lvb *lvb, int kms_only); int (*o_adjust_kms)(struct obd_export *exp, struct lov_stripe_md *lsm, - obd_off size, int shrink); + u64 size, int shrink); int (*o_punch)(const struct lu_env *, struct obd_export *exp, struct obd_info *oinfo, struct obd_trans_info *oti, struct ptlrpc_request_set *rqset); int (*o_sync)(const struct lu_env *env, struct obd_export *exp, - struct obd_info *oinfo, obd_size start, obd_size end, + struct obd_info *oinfo, u64 start, u64 end, struct ptlrpc_request_set *set); int (*o_migrate)(struct lustre_handle *conn, struct lov_stripe_md *dst, - struct lov_stripe_md *src, obd_size start, - obd_size end, struct obd_trans_info *oti); + struct lov_stripe_md *src, u64 start, + u64 end, struct obd_trans_info *oti); int (*o_copy)(struct lustre_handle *dstconn, struct lov_stripe_md *dst, struct lustre_handle *srconn, struct lov_stripe_md *src, - obd_size start, obd_size end, struct obd_trans_info *); + u64 start, u64 end, struct obd_trans_info *); int (*o_iterate)(struct lustre_handle *conn, - int (*)(obd_id, obd_seq, void *), - obd_id *startid, obd_seq seq, void *data); + int (*)(u64, u64, void *), + u64 *startid, u64 seq, void *data); int (*o_preprw)(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *remote, @@ -1256,7 +1254,7 @@ struct obd_ops { int (*o_init_export)(struct obd_export *exp); int (*o_destroy_export)(struct obd_export *exp); int (*o_extent_calc)(struct obd_export *, struct lov_stripe_md *, - int cmd, obd_off *); + int cmd, u64 *); /* llog related obd_methods */ int (*o_llog_init)(struct obd_device *obd, struct obd_llog_group *grp, @@ -1385,12 +1383,12 @@ struct md_ops { struct ptlrpc_request **); int (*m_setxattr)(struct obd_export *, const struct lu_fid *, - struct obd_capa *, obd_valid, const char *, + struct obd_capa *, u64, const char *, const char *, int, int, int, __u32, struct ptlrpc_request **); int (*m_getxattr)(struct obd_export *, const struct lu_fid *, - struct obd_capa *, obd_valid, const char *, + struct obd_capa *, u64, const char *, const char *, int, int, int, struct ptlrpc_request **); @@ -1444,10 +1442,10 @@ struct lsm_operations { void (*lsm_free)(struct lov_stripe_md *); int (*lsm_destroy)(struct lov_stripe_md *, struct obdo *oa, struct obd_export *md_exp); - void (*lsm_stripe_by_index)(struct lov_stripe_md *, int *, obd_off *, - obd_off *); - void (*lsm_stripe_by_offset)(struct lov_stripe_md *, int *, obd_off *, - obd_off *); + void (*lsm_stripe_by_index)(struct lov_stripe_md *, int *, u64 *, + u64 *); + void (*lsm_stripe_by_offset)(struct lov_stripe_md *, int *, u64 *, + u64 *); int (*lsm_lmm_verify) (struct lov_mds_md *lmm, int lmm_bytes, __u16 *stripe_count); int (*lsm_unpackmd) (struct lov_obd *lov, struct lov_stripe_md *lsm, @@ -1498,7 +1496,7 @@ static inline struct md_open_data *obd_mod_alloc(void) } \ }) -void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid); +void obdo_from_inode(struct obdo *dst, struct inode *src, u32 valid); void obdo_set_parent_fid(struct obdo *dst, const struct lu_fid *parent); /* return 1 if client should be resend request */ diff --git a/drivers/staging/lustre/lustre/include/obd_cksum.h b/drivers/staging/lustre/lustre/include/obd_cksum.h index 662a78062963..3a63462aa943 100644 --- a/drivers/staging/lustre/lustre/include/obd_cksum.h +++ b/drivers/staging/lustre/lustre/include/obd_cksum.h @@ -64,10 +64,10 @@ static inline unsigned char cksum_obd2cfs(cksum_type_t cksum_type) * because that is supported by all clients since 1.8 * * In case multiple algorithms are supported the best one is used. */ -static inline obd_flag cksum_type_pack(cksum_type_t cksum_type) +static inline u32 cksum_type_pack(cksum_type_t cksum_type) { unsigned int performance = 0, tmp; - obd_flag flag = OBD_FL_CKSUM_ADLER; + u32 flag = OBD_FL_CKSUM_ADLER; if (cksum_type & OBD_CKSUM_CRC32) { tmp = cfs_crypto_hash_speed(cksum_obd2cfs(OBD_CKSUM_CRC32)); @@ -98,7 +98,7 @@ static inline obd_flag cksum_type_pack(cksum_type_t cksum_type) return flag; } -static inline cksum_type_t cksum_type_unpack(obd_flag o_flags) +static inline cksum_type_t cksum_type_unpack(u32 o_flags) { switch (o_flags & OBD_FL_CKSUM_ALL) { case OBD_FL_CKSUM_CRC32C: diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index 1d401c9e5e8c..3597226f070c 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -308,12 +308,12 @@ static inline enum obd_option exp_flags_from_obd(struct obd_device *obd) } -void obdo_cpy_md(struct obdo *dst, struct obdo *src, obd_flag valid); +void obdo_cpy_md(struct obdo *dst, struct obdo *src, u32 valid); void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj); void obdo_from_iattr(struct obdo *oa, struct iattr *attr, unsigned int ia_valid); -void iattr_from_obdo(struct iattr *attr, struct obdo *oa, obd_flag valid); -void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, obd_flag valid); +void iattr_from_obdo(struct iattr *attr, struct obdo *oa, u32 valid); +void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, u32 valid); void obdo_from_md(struct obdo *oa, struct md_op_data *op_data, unsigned int valid); @@ -510,8 +510,8 @@ static inline int obd_get_info(const struct lu_env *env, } static inline int obd_set_info_async(const struct lu_env *env, - struct obd_export *exp, obd_count keylen, - void *key, obd_count vallen, void *val, + struct obd_export *exp, u32 keylen, + void *key, u32 vallen, void *val, struct ptlrpc_request_set *set) { int rc; @@ -1123,7 +1123,7 @@ static inline int obd_destroy_export(struct obd_export *exp) static inline int obd_extent_calc(struct obd_export *exp, struct lov_stripe_md *md, - int cmd, obd_off *offset) + int cmd, u64 *offset) { int rc; @@ -1239,7 +1239,7 @@ static inline int obd_statfs(const struct lu_env *env, struct obd_export *exp, } static inline int obd_sync_rqset(struct obd_export *exp, struct obd_info *oinfo, - obd_size start, obd_size end) + u64 start, u64 end) { struct ptlrpc_request_set *set = NULL; int rc; @@ -1259,7 +1259,7 @@ static inline int obd_sync_rqset(struct obd_export *exp, struct obd_info *oinfo, } static inline int obd_sync(const struct lu_env *env, struct obd_export *exp, - struct obd_info *oinfo, obd_size start, obd_size end, + struct obd_info *oinfo, u64 start, u64 end, struct ptlrpc_request_set *set) { int rc; @@ -1306,7 +1306,7 @@ static inline int obd_punch(const struct lu_env *env, struct obd_export *exp, } static inline int obd_brw(int cmd, struct obd_export *exp, - struct obd_info *oinfo, obd_count oa_bufs, + struct obd_info *oinfo, u32 oa_bufs, struct brw_page *pg, struct obd_trans_info *oti) { int rc; @@ -1371,7 +1371,7 @@ static inline int obd_merge_lvb(struct obd_export *exp, } static inline int obd_adjust_kms(struct obd_export *exp, - struct lov_stripe_md *lsm, obd_off size, + struct lov_stripe_md *lsm, u64 size, int shrink) { int rc; @@ -1962,7 +1962,7 @@ static inline int md_free_lustre_md(struct obd_export *exp, static inline int md_setxattr(struct obd_export *exp, const struct lu_fid *fid, struct obd_capa *oc, - obd_valid valid, const char *name, + u64 valid, const char *name, const char *input, int input_size, int output_size, int flags, __u32 suppgid, struct ptlrpc_request **request) @@ -1976,7 +1976,7 @@ static inline int md_setxattr(struct obd_export *exp, static inline int md_getxattr(struct obd_export *exp, const struct lu_fid *fid, struct obd_capa *oc, - obd_valid valid, const char *name, + u64 valid, const char *name, const char *input, int input_size, int output_size, int flags, struct ptlrpc_request **request) diff --git a/drivers/staging/lustre/lustre/include/obd_ost.h b/drivers/staging/lustre/lustre/include/obd_ost.h index 60de42972ec9..a679bb15671b 100644 --- a/drivers/staging/lustre/lustre/include/obd_ost.h +++ b/drivers/staging/lustre/lustre/include/obd_ost.h @@ -49,7 +49,7 @@ struct osc_brw_async_args { struct obdo *aa_oa; int aa_requested_nob; int aa_nio_count; - obd_count aa_page_count; + u32 aa_page_count; int aa_resends; struct brw_page **aa_ppga; struct client_obd *aa_cli; diff --git a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c index 94f759d0b5ad..24d26ab35346 100644 --- a/drivers/staging/lustre/lustre/lclient/lcommon_cl.c +++ b/drivers/staging/lustre/lustre/lclient/lcommon_cl.c @@ -895,11 +895,11 @@ void ccc_req_completion(const struct lu_env *env, void ccc_req_attr_set(const struct lu_env *env, const struct cl_req_slice *slice, const struct cl_object *obj, - struct cl_req_attr *attr, obd_valid flags) + struct cl_req_attr *attr, u64 flags) { struct inode *inode; struct obdo *oa; - obd_flag valid_flags; + u32 valid_flags; oa = attr->cra_oa; inode = ccc_object_inode(obj); diff --git a/drivers/staging/lustre/lustre/llite/file.c b/drivers/staging/lustre/lustre/llite/file.c index 4a33638bef25..6ffbe7cbe895 100644 --- a/drivers/staging/lustre/lustre/llite/file.c +++ b/drivers/staging/lustre/lustre/llite/file.c @@ -1248,8 +1248,7 @@ static ssize_t ll_file_splice_read(struct file *in_file, loff_t *ppos, return result; } -static int ll_lov_recreate(struct inode *inode, struct ost_id *oi, - obd_count ost_idx) +static int ll_lov_recreate(struct inode *inode, struct ost_id *oi, u32 ost_idx) { struct obd_export *exp = ll_i2dtexp(inode); struct obd_trans_info oti = { 0 }; @@ -1314,7 +1313,7 @@ static int ll_lov_recreate_fid(struct inode *inode, unsigned long arg) { struct lu_fid fid; struct ost_id oi; - obd_count ost_idx; + u32 ost_idx; if (!capable(CFS_CAP_SYS_ADMIN)) return -EPERM; @@ -2893,7 +2892,7 @@ static int __ll_inode_revalidate(struct dentry *dentry, __u64 ibits) ll_lookup_finish_locks(&oit, dentry); } else if (!ll_have_md_lock(dentry->d_inode, &ibits, LCK_MINMODE)) { struct ll_sb_info *sbi = ll_i2sbi(dentry->d_inode); - obd_valid valid = OBD_MD_FLGETATTR; + u64 valid = OBD_MD_FLGETATTR; struct md_op_data *op_data; int ealen = 0; diff --git a/drivers/staging/lustre/lustre/llite/llite_internal.h b/drivers/staging/lustre/lustre/llite/llite_internal.h index b42d87971f5e..acfb078c1bb0 100644 --- a/drivers/staging/lustre/lustre/llite/llite_internal.h +++ b/drivers/staging/lustre/lustre/llite/llite_internal.h @@ -1128,7 +1128,7 @@ struct eacl_entry { ext_acl_xattr_header *ee_acl; }; -obd_valid rce_ops2valid(int ops); +u64 rce_ops2valid(int ops); struct rmtacl_ctl_entry *rct_search(struct rmtacl_ctl_table *rct, pid_t key); int rct_add(struct rmtacl_ctl_table *rct, pid_t key, int ops); int rct_del(struct rmtacl_ctl_table *rct, pid_t key); @@ -1144,7 +1144,7 @@ void et_search_free(struct eacl_table *et, pid_t key); void et_init(struct eacl_table *et); void et_fini(struct eacl_table *et); #else -static inline obd_valid rce_ops2valid(int ops) +static inline u64 rce_ops2valid(int ops) { return 0; } diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 0367f5a2cfe4..ff375d37cc56 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -162,7 +162,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, struct obd_uuid *uuid; struct md_op_data *op_data; struct lustre_md lmd; - obd_valid valid; + u64 valid; int size, err, checksum; obd = class_name2obd(md); diff --git a/drivers/staging/lustre/lustre/llite/llite_rmtacl.c b/drivers/staging/lustre/lustre/llite/llite_rmtacl.c index be0c3eff108c..df6671748c12 100644 --- a/drivers/staging/lustre/lustre/llite/llite_rmtacl.c +++ b/drivers/staging/lustre/lustre/llite/llite_rmtacl.c @@ -58,7 +58,7 @@ static inline __u32 ee_hashfunc(uid_t id) return id & (EE_HASHES - 1); } -obd_valid rce_ops2valid(int ops) +u64 rce_ops2valid(int ops) { switch (ops) { case RMT_LSETFACL: diff --git a/drivers/staging/lustre/lustre/llite/lloop.c b/drivers/staging/lustre/lustre/llite/lloop.c index 808663898b73..3c29c3870360 100644 --- a/drivers/staging/lustre/lustre/llite/lloop.c +++ b/drivers/staging/lustre/lustre/llite/lloop.c @@ -192,7 +192,7 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head) pgoff_t offset; int ret; int rw; - obd_count page_count = 0; + u32 page_count = 0; struct bio_vec bvec; struct bvec_iter iter; struct bio *bio; diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 0b1e4a1364d3..a48818a890eb 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -1377,7 +1377,7 @@ static int lmv_cleanup(struct obd_device *obd) return 0; } -static int lmv_process_config(struct obd_device *obd, obd_count len, void *buf) +static int lmv_process_config(struct obd_device *obd, u32 len, void *buf) { struct lustre_cfg *lcfg = buf; struct obd_uuid obd_uuid; @@ -1478,7 +1478,7 @@ static int lmv_getstatus(struct obd_export *exp, } static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid, - struct obd_capa *oc, obd_valid valid, const char *name, + struct obd_capa *oc, u64 valid, const char *name, const char *input, int input_size, int output_size, int flags, struct ptlrpc_request **request) { @@ -1502,7 +1502,7 @@ static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid, } static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid, - struct obd_capa *oc, obd_valid valid, const char *name, + struct obd_capa *oc, u64 valid, const char *name, const char *input, int input_size, int output_size, int flags, __u32 suppgid, struct ptlrpc_request **request) @@ -2369,7 +2369,7 @@ static int lmv_get_info(const struct lu_env *env, struct obd_export *exp, } int lmv_set_info_async(const struct lu_env *env, struct obd_export *exp, - obd_count keylen, void *key, obd_count vallen, + u32 keylen, void *key, u32 vallen, void *val, struct ptlrpc_request_set *set) { struct lmv_tgt_desc *tgt; diff --git a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h index 99ade92c5e64..314ce8525aed 100644 --- a/drivers/staging/lustre/lustre/lov/lov_cl_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_cl_internal.h @@ -515,12 +515,12 @@ struct lov_io { * starting position within a file, for the current io loop iteration * (stripe), used by ci_io_loop(). */ - obd_off lis_pos; + u64 lis_pos; /** * end position with in a file, for the current stripe io. This is * exclusive (i.e., next offset after last byte affected by io). */ - obd_off lis_endpos; + u64 lis_endpos; int lis_mem_frozen; int lis_stripe_count; diff --git a/drivers/staging/lustre/lustre/lov/lov_ea.c b/drivers/staging/lustre/lustre/lov/lov_ea.c index 2401ca872507..9e21e5efcdb6 100644 --- a/drivers/staging/lustre/lustre/lov/lov_ea.c +++ b/drivers/staging/lustre/lustre/lov/lov_ea.c @@ -143,18 +143,18 @@ static void lsm_unpackmd_common(struct lov_stripe_md *lsm, static void lsm_stripe_by_index_plain(struct lov_stripe_md *lsm, int *stripeno, - obd_off *lov_off, obd_off *swidth) + u64 *lov_off, u64 *swidth) { if (swidth) - *swidth = (obd_off)lsm->lsm_stripe_size * lsm->lsm_stripe_count; + *swidth = (u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count; } static void lsm_stripe_by_offset_plain(struct lov_stripe_md *lsm, int *stripeno, - obd_off *lov_off, obd_off *swidth) + u64 *lov_off, u64 *swidth) { if (swidth) - *swidth = (obd_off)lsm->lsm_stripe_size * lsm->lsm_stripe_count; + *swidth = (u64)lsm->lsm_stripe_size * lsm->lsm_stripe_count; } static int lsm_destroy_plain(struct lov_stripe_md *lsm, struct obdo *oa, diff --git a/drivers/staging/lustre/lustre/lov/lov_internal.h b/drivers/staging/lustre/lustre/lov/lov_internal.h index 017961a5cc3e..1b96fac4889d 100644 --- a/drivers/staging/lustre/lustre/lov/lov_internal.h +++ b/drivers/staging/lustre/lustre/lov/lov_internal.h @@ -90,8 +90,8 @@ struct lov_request { int rq_rc; int rq_buflen; /* length of sub_md */ - obd_count rq_oabufs; - obd_count rq_pgaidx; + u32 rq_oabufs; + u32 rq_pgaidx; }; struct lov_request_set { @@ -109,7 +109,7 @@ struct lov_request_set { struct llog_cookie *set_cookies; int set_cookie_sent; struct obd_trans_info *set_oti; - obd_count set_oabufs; + u32 set_oabufs; struct brw_page *set_pga; struct lov_lock_handles *set_lockh; struct list_head set_list; @@ -166,26 +166,26 @@ static inline void lov_llh_put(struct lov_lock_handles *llh) (char *)((lv)->lov_tgts[index]->ltd_uuid.uuid) /* lov_merge.c */ -void lov_merge_attrs(struct obdo *tgt, struct obdo *src, obd_valid valid, +void lov_merge_attrs(struct obdo *tgt, struct obdo *src, u64 valid, struct lov_stripe_md *lsm, int stripeno, int *set); int lov_merge_lvb(struct obd_export *exp, struct lov_stripe_md *lsm, struct ost_lvb *lvb, int kms_only); int lov_adjust_kms(struct obd_export *exp, struct lov_stripe_md *lsm, - obd_off size, int shrink); + u64 size, int shrink); int lov_merge_lvb_kms(struct lov_stripe_md *lsm, struct ost_lvb *lvb, __u64 *kms_place); /* lov_offset.c */ -obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size, +u64 lov_stripe_size(struct lov_stripe_md *lsm, u64 ost_size, int stripeno); -int lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off, - int stripeno, obd_off *obd_off); -obd_off lov_size_to_stripe(struct lov_stripe_md *lsm, obd_off file_size, +int lov_stripe_offset(struct lov_stripe_md *lsm, u64 lov_off, + int stripeno, u64 *u64); +u64 lov_size_to_stripe(struct lov_stripe_md *lsm, u64 file_size, int stripeno); int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno, - obd_off start, obd_off end, - obd_off *obd_start, obd_off *obd_end); -int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off); + u64 start, u64 end, + u64 *obd_start, u64 *obd_end); +int lov_stripe_number(struct lov_stripe_md *lsm, u64 lov_off); /* lov_qos.c */ #define LOV_USES_ASSIGNED_STRIPE 0 @@ -214,7 +214,7 @@ int lov_prep_create_set(struct obd_export *exp, struct obd_info *oifo, int cb_create_update(void *cookie, int rc); int lov_fini_create_set(struct lov_request_set *set, struct lov_stripe_md **ea); int lov_prep_brw_set(struct obd_export *exp, struct obd_info *oinfo, - obd_count oa_bufs, struct brw_page *pga, + u32 oa_bufs, struct brw_page *pga, struct obd_trans_info *oti, struct lov_request_set **reqset); int lov_fini_brw_set(struct lov_request_set *set); @@ -239,7 +239,7 @@ int lov_prep_punch_set(struct obd_export *exp, struct obd_info *oinfo, struct lov_request_set **reqset); int lov_fini_punch_set(struct lov_request_set *set); int lov_prep_sync_set(struct obd_export *exp, struct obd_info *obd_info, - obd_off start, obd_off end, + u64 start, u64 end, struct lov_request_set **reqset); int lov_fini_sync_set(struct lov_request_set *set); int lov_prep_enqueue_set(struct obd_export *exp, struct obd_info *oinfo, diff --git a/drivers/staging/lustre/lustre/lov/lov_io.c b/drivers/staging/lustre/lustre/lov/lov_io.c index ce074c54a003..f1f6db3f664a 100644 --- a/drivers/staging/lustre/lustre/lov/lov_io.c +++ b/drivers/staging/lustre/lustre/lov/lov_io.c @@ -366,7 +366,7 @@ static void lov_io_fini(const struct lu_env *env, const struct cl_io_slice *ios) wake_up_all(&lov->lo_waitq); } -static obd_off lov_offset_mod(obd_off val, int delta) +static u64 lov_offset_mod(u64 val, int delta) { if (val != OBD_OBJECT_EOF) val += delta; @@ -379,9 +379,9 @@ static int lov_io_iter_init(const struct lu_env *env, struct lov_io *lio = cl2lov_io(env, ios); struct lov_stripe_md *lsm = lio->lis_object->lo_lsm; struct lov_io_sub *sub; - obd_off endpos; - obd_off start; - obd_off end; + u64 endpos; + u64 start; + u64 end; int stripe; int rc = 0; diff --git a/drivers/staging/lustre/lustre/lov/lov_lock.c b/drivers/staging/lustre/lustre/lov/lov_lock.c index 08ac3745f0da..49e694222ac8 100644 --- a/drivers/staging/lustre/lustre/lov/lov_lock.c +++ b/drivers/staging/lustre/lustre/lov/lov_lock.c @@ -290,10 +290,10 @@ static int lov_lock_sub_init(const struct lu_env *env, int result = 0; int i; int nr; - obd_off start; - obd_off end; - obd_off file_start; - obd_off file_end; + u64 start; + u64 end; + u64 file_start; + u64 file_end; struct lov_object *loo = cl2lov(lck->lls_cl.cls_obj); struct lov_layout_raid0 *r0 = lov_r0(loo); @@ -860,10 +860,10 @@ static int lock_lock_multi_match() struct lov_layout_raid0 *r0 = lov_r0(loo); struct lov_lock_sub *sub; struct cl_object *subobj; - obd_off fstart; - obd_off fend; - obd_off start; - obd_off end; + u64 fstart; + u64 fend; + u64 start; + u64 end; int i; fstart = cl_offset(need->cld_obj, need->cld_start); @@ -900,8 +900,8 @@ static int lov_lock_stripe_is_matching(const struct lu_env *env, const struct cl_lock_descr *descr) { struct lov_stripe_md *lsm = lov->lo_lsm; - obd_off start; - obd_off end; + u64 start; + u64 end; int result; if (lov_r0(lov)->lo_nr == 1) @@ -919,8 +919,8 @@ static int lov_lock_stripe_is_matching(const struct lu_env *env, stripe == lov_stripe_number(lsm, end); if (result) { struct cl_lock_descr *subd = &lov_env_info(env)->lti_ldescr; - obd_off sub_start; - obd_off sub_end; + u64 sub_start; + u64 sub_end; subd->cld_obj = NULL; /* don't need sub object at all */ subd->cld_mode = descr->cld_mode; diff --git a/drivers/staging/lustre/lustre/lov/lov_merge.c b/drivers/staging/lustre/lustre/lov/lov_merge.c index 85144b8da96d..15ebb5d8b713 100644 --- a/drivers/staging/lustre/lustre/lov/lov_merge.c +++ b/drivers/staging/lustre/lustre/lov/lov_merge.c @@ -52,9 +52,9 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm, __u64 size = 0; __u64 kms = 0; __u64 blocks = 0; - obd_time current_mtime = lvb->lvb_mtime; - obd_time current_atime = lvb->lvb_atime; - obd_time current_ctime = lvb->lvb_ctime; + s64 current_mtime = lvb->lvb_mtime; + s64 current_atime = lvb->lvb_atime; + s64 current_ctime = lvb->lvb_ctime; int i; int rc = 0; @@ -66,7 +66,7 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm, lvb->lvb_atime, lvb->lvb_ctime, lvb->lvb_blocks); for (i = 0; i < lsm->lsm_stripe_count; i++) { struct lov_oinfo *loi = lsm->lsm_oinfo[i]; - obd_size lov_size, tmpsize; + u64 lov_size, tmpsize; if (OST_LVB_IS_ERR(loi->loi_lvb.lvb_blocks)) { rc = OST_LVB_GET_ERR(loi->loi_lvb.lvb_blocks); @@ -138,7 +138,7 @@ int lov_merge_lvb(struct obd_export *exp, /* Must be called under the lov_stripe_lock() */ int lov_adjust_kms(struct obd_export *exp, struct lov_stripe_md *lsm, - obd_off size, int shrink) + u64 size, int shrink) { struct lov_oinfo *loi; int stripe = 0; @@ -173,7 +173,7 @@ int lov_adjust_kms(struct obd_export *exp, struct lov_stripe_md *lsm, return 0; } -void lov_merge_attrs(struct obdo *tgt, struct obdo *src, obd_valid valid, +void lov_merge_attrs(struct obdo *tgt, struct obdo *src, u64 valid, struct lov_stripe_md *lsm, int stripeno, int *set) { valid &= src->o_valid; @@ -181,7 +181,7 @@ void lov_merge_attrs(struct obdo *tgt, struct obdo *src, obd_valid valid, if (*set) { if (valid & OBD_MD_FLSIZE) { /* this handles sparse files properly */ - obd_size lov_size; + u64 lov_size; lov_size = lov_stripe_size(lsm, src->o_size, stripeno); if (lov_size > tgt->o_size) diff --git a/drivers/staging/lustre/lustre/lov/lov_obd.c b/drivers/staging/lustre/lustre/lov/lov_obd.c index e4f4fe3f71c7..cb778df86d09 100644 --- a/drivers/staging/lustre/lustre/lov/lov_obd.c +++ b/drivers/staging/lustre/lustre/lov/lov_obd.c @@ -1442,7 +1442,7 @@ static int lov_sync_interpret(struct ptlrpc_request_set *rqset, } static int lov_sync(const struct lu_env *env, struct obd_export *exp, - struct obd_info *oinfo, obd_off start, obd_off end, + struct obd_info *oinfo, u64 start, u64 end, struct ptlrpc_request_set *rqset) { struct lov_request_set *set = NULL; @@ -1497,7 +1497,7 @@ static int lov_sync(const struct lu_env *env, struct obd_export *exp, } static int lov_brw_check(struct lov_obd *lov, struct obd_info *lov_oinfo, - obd_count oa_bufs, struct brw_page *pga) + u32 oa_bufs, struct brw_page *pga) { struct obd_info oinfo = { { { 0 } } }; int i, rc = 0; @@ -1509,7 +1509,7 @@ static int lov_brw_check(struct lov_obd *lov, struct obd_info *lov_oinfo, for (i = 0; i < oa_bufs; i++) { int stripe = lov_stripe_number(lov_oinfo->oi_md, pga[i].off); int ost = lov_oinfo->oi_md->lsm_oinfo[stripe]->loi_ost_idx; - obd_off start, end; + u64 start, end; if (!lov_stripe_intersects(lov_oinfo->oi_md, i, pga[i].off, pga[i].off + pga[i].count - 1, @@ -1530,7 +1530,7 @@ static int lov_brw_check(struct lov_obd *lov, struct obd_info *lov_oinfo, } static int lov_brw(int cmd, struct obd_export *exp, struct obd_info *oinfo, - obd_count oa_bufs, struct brw_page *pga, + u32 oa_bufs, struct brw_page *pga, struct obd_trans_info *oti) { struct lov_request_set *set; @@ -2080,13 +2080,13 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, * \param fm_end logical end of mapping * \param start_stripe starting stripe will be returned in this */ -obd_size fiemap_calc_fm_end_offset(struct ll_user_fiemap *fiemap, - struct lov_stripe_md *lsm, obd_size fm_start, - obd_size fm_end, int *start_stripe) +u64 fiemap_calc_fm_end_offset(struct ll_user_fiemap *fiemap, + struct lov_stripe_md *lsm, u64 fm_start, + u64 fm_end, int *start_stripe) { - obd_size local_end = fiemap->fm_extents[0].fe_logical; - obd_off lun_start, lun_end; - obd_size fm_end_offset; + u64 local_end = fiemap->fm_extents[0].fe_logical; + u64 lun_start, lun_end; + u64 fm_end_offset; int stripe_no = -1, i; if (fiemap->fm_extent_count == 0 || @@ -2137,12 +2137,12 @@ obd_size fiemap_calc_fm_end_offset(struct ll_user_fiemap *fiemap, * * \retval last_stripe return the last stripe of the mapping */ -int fiemap_calc_last_stripe(struct lov_stripe_md *lsm, obd_size fm_start, - obd_size fm_end, int start_stripe, +int fiemap_calc_last_stripe(struct lov_stripe_md *lsm, u64 fm_start, + u64 fm_end, int start_stripe, int *stripe_count) { int last_stripe; - obd_off obd_start, obd_end; + u64 obd_start, obd_end; int i, j; if (fm_end - fm_start > lsm->lsm_stripe_size * lsm->lsm_stripe_count) { @@ -2206,8 +2206,8 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key, int count_local; unsigned int get_num_extents = 0; int ost_index = 0, actual_start_stripe, start_stripe; - obd_size fm_start, fm_end, fm_length, fm_end_offset; - obd_size curr_loc; + u64 fm_start, fm_end, fm_length, fm_end_offset; + u64 curr_loc; int current_extent = 0, rc = 0, i; int ost_eof = 0; /* EOF for object */ int ost_done = 0; /* done with required mapping for this OST? */ @@ -2256,9 +2256,9 @@ static int lov_fiemap(struct lov_obd *lov, __u32 keylen, void *key, /* Check each stripe */ for (cur_stripe = start_stripe, i = 0; i < stripe_count; i++, cur_stripe = (cur_stripe + 1) % lsm->lsm_stripe_count) { - obd_size req_fm_len; /* Stores length of required mapping */ - obd_size len_mapped_single_call; - obd_off lun_start, lun_end, obd_object_end; + u64 req_fm_len; /* Stores length of required mapping */ + u64 len_mapped_single_call; + u64 lun_start, lun_end, obd_object_end; unsigned int ext_count; cur_stripe_wrap = cur_stripe; @@ -2467,7 +2467,7 @@ static int lov_get_info(const struct lu_env *env, struct obd_export *exp, GOTO(out, rc = -ENXIO); } else if (KEY_IS(KEY_LAST_ID)) { struct obd_id_info *info = val; - __u32 size = sizeof(obd_id); + __u32 size = sizeof(u64); struct lov_tgt_desc *tgt; LASSERT(*vallen == sizeof(struct obd_id_info)); @@ -2513,12 +2513,12 @@ static int lov_get_info(const struct lu_env *env, struct obd_export *exp, } static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp, - obd_count keylen, void *key, obd_count vallen, + u32 keylen, void *key, u32 vallen, void *val, struct ptlrpc_request_set *set) { struct obd_device *obddev = class_exp2obd(exp); struct lov_obd *lov = &obddev->u.lov; - obd_count count; + u32 count; int i, rc = 0, err; struct lov_tgt_desc *tgt; unsigned incr, check_uuid, @@ -2538,7 +2538,7 @@ static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp, if (KEY_IS(KEY_NEXT_ID)) { count = vallen / sizeof(struct obd_id_info); - vallen = sizeof(obd_id); + vallen = sizeof(u64); incr = sizeof(struct obd_id_info); do_inactive = 1; next_id = 1; diff --git a/drivers/staging/lustre/lustre/lov/lov_offset.c b/drivers/staging/lustre/lustre/lov/lov_offset.c index 8e1c3bacc0a0..9c8c77c05a8a 100644 --- a/drivers/staging/lustre/lustre/lov/lov_offset.c +++ b/drivers/staging/lustre/lustre/lov/lov_offset.c @@ -43,13 +43,13 @@ #include "lov_internal.h" /* compute object size given "stripeno" and the ost size */ -obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size, +u64 lov_stripe_size(struct lov_stripe_md *lsm, u64 ost_size, int stripeno) { unsigned long ssize = lsm->lsm_stripe_size; unsigned long stripe_size; - obd_off swidth; - obd_size lov_size; + u64 swidth; + u64 lov_size; int magic = lsm->lsm_magic; if (ost_size == 0) @@ -116,11 +116,11 @@ obd_size lov_stripe_size(struct lov_stripe_md *lsm, obd_size ost_size, * was moved forward to the start of the stripe in question; 0 when it * falls in the stripe and no shifting was done; > 0 when the offset * was outside the stripe and was pulled back to its final byte. */ -int lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off, - int stripeno, obd_off *obdoff) +int lov_stripe_offset(struct lov_stripe_md *lsm, u64 lov_off, + int stripeno, u64 *obdoff) { unsigned long ssize = lsm->lsm_stripe_size; - obd_off stripe_off, this_stripe, swidth; + u64 stripe_off, this_stripe, swidth; int magic = lsm->lsm_magic; int ret = 0; @@ -137,7 +137,7 @@ int lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off, /* lov_do_div64(a, b) returns a % b, and a = a / b */ stripe_off = lov_do_div64(lov_off, swidth); - this_stripe = (obd_off)stripeno * ssize; + this_stripe = (u64)stripeno * ssize; if (stripe_off < this_stripe) { stripe_off = 0; ret = -1; @@ -173,11 +173,11 @@ int lov_stripe_offset(struct lov_stripe_md *lsm, obd_off lov_off, * | 0 | 1 | 2 | 0 | 1 | 2 | * --------------------------------------------------------------------- */ -obd_off lov_size_to_stripe(struct lov_stripe_md *lsm, obd_off file_size, - int stripeno) +u64 lov_size_to_stripe(struct lov_stripe_md *lsm, u64 file_size, + int stripeno) { unsigned long ssize = lsm->lsm_stripe_size; - obd_off stripe_off, this_stripe, swidth; + u64 stripe_off, this_stripe, swidth; int magic = lsm->lsm_magic; if (file_size == OBD_OBJECT_EOF) @@ -190,7 +190,7 @@ obd_off lov_size_to_stripe(struct lov_stripe_md *lsm, obd_off file_size, /* lov_do_div64(a, b) returns a % b, and a = a / b */ stripe_off = lov_do_div64(file_size, swidth); - this_stripe = (obd_off)stripeno * ssize; + this_stripe = (u64)stripeno * ssize; if (stripe_off < this_stripe) { /* Move to end of previous stripe, or zero */ if (file_size > 0) { @@ -215,8 +215,7 @@ obd_off lov_size_to_stripe(struct lov_stripe_md *lsm, obd_off file_size, * that is contained within the lov extent. this returns true if the given * stripe does intersect with the lov extent. */ int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno, - obd_off start, obd_off end, - obd_off *obd_start, obd_off *obd_end) + u64 start, u64 end, u64 *obd_start, u64 *obd_end) { int start_side, end_side; @@ -247,10 +246,10 @@ int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno, } /* compute which stripe number "lov_off" will be written into */ -int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off) +int lov_stripe_number(struct lov_stripe_md *lsm, u64 lov_off) { unsigned long ssize = lsm->lsm_stripe_size; - obd_off stripe_off, swidth; + u64 stripe_off, swidth; int magic = lsm->lsm_magic; LASSERT(lsm_op_find(magic) != NULL); diff --git a/drivers/staging/lustre/lustre/lov/lov_pack.c b/drivers/staging/lustre/lustre/lov/lov_pack.c index a5b190f32c0f..20e587052a29 100644 --- a/drivers/staging/lustre/lustre/lov/lov_pack.c +++ b/drivers/staging/lustre/lustre/lov/lov_pack.c @@ -125,7 +125,7 @@ void lov_dump_lmm(int level, void *lmm) * * XXX In the future, this will be enhanced to get the EA size from the * underlying OSC device(s) to get their EA sizes so we can stack - * LOVs properly. For now lov_mds_md_size() just assumes one obd_id + * LOVs properly. For now lov_mds_md_size() just assumes one u64 * per stripe. */ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, @@ -538,7 +538,7 @@ int lov_setea(struct obd_export *exp, struct lov_stripe_md **lsmp, int rc; struct obd_export *oexp; struct lov_obd *lov = &exp->exp_obd->u.lov; - obd_id last_id = 0; + u64 last_id = 0; struct lov_user_ost_data_v1 *lmm_objects; if (lump->lmm_magic == LOV_USER_MAGIC_V3) diff --git a/drivers/staging/lustre/lustre/lov/lov_page.c b/drivers/staging/lustre/lustre/lov/lov_page.c index 674e61781c20..24f4e2047fed 100644 --- a/drivers/staging/lustre/lustre/lov/lov_page.c +++ b/drivers/staging/lustre/lustre/lov/lov_page.c @@ -165,7 +165,7 @@ int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, struct lov_io_sub *sub; struct lov_page *lpg = cl_object_page_slice(obj, page); loff_t offset; - obd_off suboff; + u64 suboff; int stripe; int rc; diff --git a/drivers/staging/lustre/lustre/lov/lov_request.c b/drivers/staging/lustre/lustre/lov/lov_request.c index e4bb02a54b0d..174a5fe4a149 100644 --- a/drivers/staging/lustre/lustre/lov/lov_request.c +++ b/drivers/staging/lustre/lustre/lov/lov_request.c @@ -375,7 +375,7 @@ int lov_prep_enqueue_set(struct obd_export *exp, struct obd_info *oinfo, for (i = 0; i < oinfo->oi_md->lsm_stripe_count; i++) { struct lov_oinfo *loi; struct lov_request *req; - obd_off start, end; + u64 start, end; loi = oinfo->oi_md->lsm_oinfo[i]; if (!lov_stripe_intersects(oinfo->oi_md, i, @@ -481,7 +481,7 @@ int lov_prep_match_set(struct obd_export *exp, struct obd_info *oinfo, for (i = 0; i < lsm->lsm_stripe_count; i++) { struct lov_oinfo *loi; struct lov_request *req; - obd_off start, end; + u64 start, end; loi = lsm->lsm_oinfo[i]; if (!lov_stripe_intersects(lsm, i, policy->l_extent.start, @@ -696,14 +696,14 @@ int lov_fini_brw_set(struct lov_request_set *set) } int lov_prep_brw_set(struct obd_export *exp, struct obd_info *oinfo, - obd_count oa_bufs, struct brw_page *pga, + u32 oa_bufs, struct brw_page *pga, struct obd_trans_info *oti, struct lov_request_set **reqset) { struct { - obd_count index; - obd_count count; - obd_count off; + u32 index; + u32 count; + u32 off; } *info = NULL; struct lov_request_set *set; struct lov_obd *lov = &exp->exp_obd->u.lov; @@ -1167,7 +1167,7 @@ int lov_prep_punch_set(struct obd_export *exp, struct obd_info *oinfo, for (i = 0; i < oinfo->oi_md->lsm_stripe_count; i++) { struct lov_oinfo *loi = oinfo->oi_md->lsm_oinfo[i]; struct lov_request *req; - obd_off rs, re; + u64 rs, re; if (!lov_stripe_intersects(oinfo->oi_md, i, oinfo->oi_policy.l_extent.start, @@ -1246,7 +1246,7 @@ static int cb_sync_update(void *cookie, int rc) } int lov_prep_sync_set(struct obd_export *exp, struct obd_info *oinfo, - obd_off start, obd_off end, + u64 start, u64 end, struct lov_request_set **reqset) { struct lov_request_set *set; @@ -1264,7 +1264,7 @@ int lov_prep_sync_set(struct obd_export *exp, struct obd_info *oinfo, for (i = 0; i < oinfo->oi_md->lsm_stripe_count; i++) { struct lov_oinfo *loi = oinfo->oi_md->lsm_oinfo[i]; struct lov_request *req; - obd_off rs, re; + u64 rs, re; if (!lov_check_and_wait_active(lov, loi->loi_ost_idx)) { CDEBUG(D_HA, "lov idx %d inactive\n", loi->loi_ost_idx); diff --git a/drivers/staging/lustre/lustre/lov/lovsub_dev.c b/drivers/staging/lustre/lustre/lov/lovsub_dev.c index 52fb6c162ad7..42336f13a76f 100644 --- a/drivers/staging/lustre/lustre/lov/lovsub_dev.c +++ b/drivers/staging/lustre/lustre/lov/lovsub_dev.c @@ -67,7 +67,7 @@ static void lovsub_req_completion(const struct lu_env *env, static void lovsub_req_attr_set(const struct lu_env *env, const struct cl_req_slice *slice, const struct cl_object *obj, - struct cl_req_attr *attr, obd_valid flags) + struct cl_req_attr *attr, u64 flags) { struct lovsub_object *subobj; diff --git a/drivers/staging/lustre/lustre/mdc/mdc_internal.h b/drivers/staging/lustre/lustre/mdc/mdc_internal.h index f4da8f3523d2..81780c943a08 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_internal.h +++ b/drivers/staging/lustre/lustre/mdc/mdc_internal.h @@ -108,7 +108,7 @@ int mdc_resource_get_unused(struct obd_export *exp, const struct lu_fid *fid, int mdc_fid_alloc(struct obd_export *exp, struct lu_fid *fid, struct md_op_data *op_data); -int mdc_open(struct obd_export *exp, obd_id ino, int type, int flags, +int mdc_open(struct obd_export *exp, u64 ino, int type, int flags, struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh, struct ptlrpc_request **); diff --git a/drivers/staging/lustre/lustre/mdc/mdc_locks.c b/drivers/staging/lustre/lustre/mdc/mdc_locks.c index d02bf313d591..9c3e53385602 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_locks.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_locks.c @@ -455,7 +455,7 @@ static struct ptlrpc_request *mdc_intent_getattr_pack(struct obd_export *exp, { struct ptlrpc_request *req; struct obd_device *obddev = class_exp2obd(exp); - obd_valid valid = OBD_MD_FLGETATTR | OBD_MD_FLEASIZE | + u64 valid = OBD_MD_FLGETATTR | OBD_MD_FLEASIZE | OBD_MD_FLMODEASIZE | OBD_MD_FLDIREA | OBD_MD_FLMDSCAPA | OBD_MD_MEA | (client_is_remote(exp) ? diff --git a/drivers/staging/lustre/lustre/mdc/mdc_request.c b/drivers/staging/lustre/lustre/mdc/mdc_request.c index 57f4952f6391..fce8567aba38 100644 --- a/drivers/staging/lustre/lustre/mdc/mdc_request.c +++ b/drivers/staging/lustre/lustre/mdc/mdc_request.c @@ -331,7 +331,7 @@ static int mdc_is_subdir(struct obd_export *exp, static int mdc_xattr_common(struct obd_export *exp, const struct req_format *fmt, const struct lu_fid *fid, - struct obd_capa *oc, int opcode, obd_valid valid, + struct obd_capa *oc, int opcode, u64 valid, const char *xattr_name, const char *input, int input_size, int output_size, int flags, __u32 suppgid, struct ptlrpc_request **request) @@ -440,7 +440,7 @@ static int mdc_xattr_common(struct obd_export *exp, } int mdc_setxattr(struct obd_export *exp, const struct lu_fid *fid, - struct obd_capa *oc, obd_valid valid, const char *xattr_name, + struct obd_capa *oc, u64 valid, const char *xattr_name, const char *input, int input_size, int output_size, int flags, __u32 suppgid, struct ptlrpc_request **request) { @@ -451,7 +451,7 @@ int mdc_setxattr(struct obd_export *exp, const struct lu_fid *fid, } int mdc_getxattr(struct obd_export *exp, const struct lu_fid *fid, - struct obd_capa *oc, obd_valid valid, const char *xattr_name, + struct obd_capa *oc, u64 valid, const char *xattr_name, const char *input, int input_size, int output_size, int flags, struct ptlrpc_request **request) { @@ -1926,7 +1926,7 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, } int mdc_get_info_rpc(struct obd_export *exp, - obd_count keylen, void *key, + u32 keylen, void *key, int vallen, void *val) { struct obd_import *imp = class_exp2cliimp(exp); @@ -2101,8 +2101,8 @@ static int mdc_kuc_reregister(struct obd_import *imp) int mdc_set_info_async(const struct lu_env *env, struct obd_export *exp, - obd_count keylen, void *key, - obd_count vallen, void *val, + u32 keylen, void *key, + u32 vallen, void *val, struct ptlrpc_request_set *set) { struct obd_import *imp = class_exp2cliimp(exp); @@ -2573,7 +2573,7 @@ static int mdc_llog_finish(struct obd_device *obd, int count) return 0; } -static int mdc_process_config(struct obd_device *obd, obd_count len, void *buf) +static int mdc_process_config(struct obd_device *obd, u32 len, void *buf) { struct lustre_cfg *lcfg = buf; struct lprocfs_static_vars lvars = { NULL }; diff --git a/drivers/staging/lustre/lustre/mgc/mgc_request.c b/drivers/staging/lustre/lustre/mgc/mgc_request.c index f520591d5784..aeaa2bfd7f82 100644 --- a/drivers/staging/lustre/lustre/mgc/mgc_request.c +++ b/drivers/staging/lustre/lustre/mgc/mgc_request.c @@ -1100,7 +1100,7 @@ static int mgc_target_register(struct obd_export *exp, } int mgc_set_info_async(const struct lu_env *env, struct obd_export *exp, - obd_count keylen, void *key, obd_count vallen, + u32 keylen, void *key, u32 vallen, void *val, struct ptlrpc_request_set *set) { int rc = -EINVAL; @@ -1844,7 +1844,7 @@ int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld) * LCFG_LOG_START gets the config log from the MGS, processes it to start * any services, and adds it to the list logs to watch (follow). */ -static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf) +static int mgc_process_config(struct obd_device *obd, u32 len, void *buf) { struct lustre_cfg *lcfg = buf; struct config_llog_instance *cfg = NULL; diff --git a/drivers/staging/lustre/lustre/obdclass/cl_io.c b/drivers/staging/lustre/lustre/obdclass/cl_io.c index 4265821b8e09..c0e06040b811 100644 --- a/drivers/staging/lustre/lustre/obdclass/cl_io.c +++ b/drivers/staging/lustre/lustre/obdclass/cl_io.c @@ -1560,7 +1560,7 @@ EXPORT_SYMBOL(cl_req_prep); * for the same request. */ void cl_req_attr_set(const struct lu_env *env, struct cl_req *req, - struct cl_req_attr *attr, obd_valid flags) + struct cl_req_attr *attr, u64 flags) { const struct cl_req_slice *slice; struct cl_page *page; diff --git a/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c b/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c index bb15202f1aae..62ed706b136d 100644 --- a/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c +++ b/drivers/staging/lustre/lustre/obdclass/linux/linux-obdo.c @@ -52,7 +52,7 @@ /*FIXME: Just copy from obdo_from_inode*/ void obdo_from_la(struct obdo *dst, struct lu_attr *la, __u64 valid) { - obd_flag newvalid = 0; + u32 newvalid = 0; if (valid & LA_ATIME) { dst->o_atime = la->la_atime; @@ -97,7 +97,7 @@ void obdo_from_la(struct obdo *dst, struct lu_attr *la, __u64 valid) EXPORT_SYMBOL(obdo_from_la); /*FIXME: Just copy from obdo_from_inode*/ -void la_from_obdo(struct lu_attr *dst, struct obdo *obdo, obd_flag valid) +void la_from_obdo(struct lu_attr *dst, struct obdo *obdo, u32 valid) { __u64 newvalid = 0; @@ -145,7 +145,7 @@ void la_from_obdo(struct lu_attr *dst, struct obdo *obdo, obd_flag valid) } EXPORT_SYMBOL(la_from_obdo); -void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid) +void obdo_refresh_inode(struct inode *dst, struct obdo *src, u32 valid) { valid &= src->o_valid; @@ -180,7 +180,7 @@ void obdo_refresh_inode(struct inode *dst, struct obdo *src, obd_flag valid) } EXPORT_SYMBOL(obdo_refresh_inode); -void obdo_to_inode(struct inode *dst, struct obdo *src, obd_flag valid) +void obdo_to_inode(struct inode *dst, struct obdo *src, u32 valid) { valid &= src->o_valid; diff --git a/drivers/staging/lustre/lustre/obdclass/local_storage.c b/drivers/staging/lustre/lustre/obdclass/local_storage.c index 78190225ac7a..6e0f6f2f1231 100644 --- a/drivers/staging/lustre/lustre/obdclass/local_storage.c +++ b/drivers/staging/lustre/lustre/obdclass/local_storage.c @@ -745,7 +745,7 @@ int local_oid_storage_init(const struct lu_env *env, struct dt_device *dev, { struct dt_thread_info *dti = dt_info(env); struct ls_device *ls; - obd_id lastid; + u64 lastid; struct dt_object *o = NULL; struct thandle *th; __u32 first_oid = fid_oid(first_fid); diff --git a/drivers/staging/lustre/lustre/obdclass/obdo.c b/drivers/staging/lustre/lustre/obdclass/obdo.c index c9fa36b17919..07469524773b 100644 --- a/drivers/staging/lustre/lustre/obdclass/obdo.c +++ b/drivers/staging/lustre/lustre/obdclass/obdo.c @@ -56,9 +56,9 @@ EXPORT_SYMBOL(obdo_set_parent_fid); /* WARNING: the file systems must take care not to tinker with attributes they don't manage (such as blocks). */ -void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid) +void obdo_from_inode(struct obdo *dst, struct inode *src, u32 valid) { - obd_flag newvalid = 0; + u32 newvalid = 0; if (valid & (OBD_MD_FLCTIME | OBD_MD_FLMTIME)) CDEBUG(D_INODE, "valid %x, new time %lu/%lu\n", @@ -115,7 +115,7 @@ void obdo_from_inode(struct obdo *dst, struct inode *src, obd_flag valid) } EXPORT_SYMBOL(obdo_from_inode); -void obdo_cpy_md(struct obdo *dst, struct obdo *src, obd_flag valid) +void obdo_cpy_md(struct obdo *dst, struct obdo *src, u32 valid) { CDEBUG(D_INODE, "src obdo "DOSTID" valid %#llx, dst obdo "DOSTID"\n", POSTID(&src->o_oi), src->o_valid, POSTID(&dst->o_oi)); @@ -157,7 +157,7 @@ void obdo_cpy_md(struct obdo *dst, struct obdo *src, obd_flag valid) EXPORT_SYMBOL(obdo_cpy_md); /* returns FALSE if comparison (by flags) is same, TRUE if changed */ -int obdo_cmp_md(struct obdo *dst, struct obdo *src, obd_flag compare) +int obdo_cmp_md(struct obdo *dst, struct obdo *src, u32 compare) { int res = 0; @@ -247,7 +247,7 @@ void obdo_from_iattr(struct obdo *oa, struct iattr *attr, unsigned int ia_valid) } EXPORT_SYMBOL(obdo_from_iattr); -void iattr_from_obdo(struct iattr *attr, struct obdo *oa, obd_flag valid) +void iattr_from_obdo(struct iattr *attr, struct obdo *oa, u32 valid) { valid &= oa->o_valid; @@ -296,7 +296,7 @@ void iattr_from_obdo(struct iattr *attr, struct obdo *oa, obd_flag valid) } EXPORT_SYMBOL(iattr_from_obdo); -void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, obd_flag valid) +void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, u32 valid) { iattr_from_obdo(&op_data->op_attr, oa, valid); if (valid & OBD_MD_FLBLOCKS) { diff --git a/drivers/staging/lustre/lustre/obdecho/echo.c b/drivers/staging/lustre/lustre/obdecho/echo.c index dae1599af384..358be902c872 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo.c +++ b/drivers/staging/lustre/lustre/obdecho/echo.c @@ -104,7 +104,7 @@ static int echo_destroy_export(struct obd_export *exp) static __u64 echo_next_id(struct obd_device *obddev) { - obd_id id; + u64 id; spin_lock(&obddev->u.echo.eo_lock); id = ++obddev->u.echo.eo_lastino; @@ -173,7 +173,7 @@ static int echo_getattr(const struct lu_env *env, struct obd_export *exp, struct obd_info *oinfo) { struct obd_device *obd = class_exp2obd(exp); - obd_id id = ostid_id(&oinfo->oi_oa->o_oi); + u64 id = ostid_id(&oinfo->oi_oa->o_oi); if (!obd) { CERROR("invalid client cookie %#llx\n", @@ -224,7 +224,7 @@ static int echo_setattr(const struct lu_env *env, struct obd_export *exp, } static void -echo_page_debug_setup(struct page *page, int rw, obd_id id, +echo_page_debug_setup(struct page *page, int rw, u64 id, __u64 offset, int len) { int page_offset = offset & ~CFS_PAGE_MASK; @@ -251,7 +251,7 @@ echo_page_debug_setup(struct page *page, int rw, obd_id id, } static int -echo_page_debug_check(struct page *page, obd_id id, +echo_page_debug_check(struct page *page, u64 id, __u64 offset, int len) { int page_offset = offset & ~CFS_PAGE_MASK; @@ -293,7 +293,7 @@ static int echo_map_nb_to_lb(struct obdo *oa, struct obd_ioobj *obj, (oa->o_valid & OBD_MD_FLFLAGS) != 0 && (oa->o_flags & OBD_FL_DEBUG_CHECK) != 0); struct niobuf_local *res = lb; - obd_off offset = nb->offset; + u64 offset = nb->offset; int len = nb->len; while (len > 0) { @@ -354,11 +354,12 @@ static int echo_finalize_lb(struct obdo *oa, struct obd_ioobj *obj, struct niobuf_local *lb, int verify) { struct niobuf_local *res = lb; - obd_off start = rb->offset >> PAGE_CACHE_SHIFT; - obd_off end = (rb->offset + rb->len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - int count = (int)(end - start); - int rc = 0; - int i; + u64 start = rb->offset >> PAGE_CACHE_SHIFT; + u64 end = (rb->offset + rb->len + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT; + int count = (int)(end - start); + int rc = 0; + int i; for (i = 0; i < count; i++, (*pgs) ++, res++) { struct page *page = res->page; diff --git a/drivers/staging/lustre/lustre/obdecho/echo_client.c b/drivers/staging/lustre/lustre/obdecho/echo_client.c index f1847f3f579d..22736698ffff 100644 --- a/drivers/staging/lustre/lustre/obdecho/echo_client.c +++ b/drivers/staging/lustre/lustre/obdecho/echo_client.c @@ -175,10 +175,10 @@ struct echo_object_conf *cl2echo_conf(const struct cl_object_conf *c) static struct echo_object *cl_echo_object_find(struct echo_device *d, struct lov_stripe_md **lsm); static int cl_echo_object_put(struct echo_object *eco); -static int cl_echo_enqueue (struct echo_object *eco, obd_off start, - obd_off end, int mode, __u64 *cookie); -static int cl_echo_cancel (struct echo_device *d, __u64 cookie); -static int cl_echo_object_brw(struct echo_object *eco, int rw, obd_off offset, +static int cl_echo_enqueue(struct echo_object *eco, u64 start, + u64 end, int mode, __u64 *cookie); +static int cl_echo_cancel(struct echo_device *d, __u64 cookie); +static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, struct page **pages, int npages, int async); static struct echo_thread_info *echo_env_info(const struct lu_env *env); @@ -1141,7 +1141,7 @@ static int cl_echo_object_put(struct echo_object *eco) } static int cl_echo_enqueue0(struct lu_env *env, struct echo_object *eco, - obd_off start, obd_off end, int mode, + u64 start, u64 end, int mode, __u64 *cookie , __u32 enqflags) { struct cl_io *io; @@ -1186,7 +1186,7 @@ static int cl_echo_enqueue0(struct lu_env *env, struct echo_object *eco, return rc; } -static int cl_echo_enqueue(struct echo_object *eco, obd_off start, obd_off end, +static int cl_echo_enqueue(struct echo_object *eco, u64 start, u64 end, int mode, __u64 *cookie) { struct echo_thread_info *info; @@ -1280,7 +1280,7 @@ static int cl_echo_async_brw(const struct lu_env *env, struct cl_io *io, return result; } -static int cl_echo_object_brw(struct echo_object *eco, int rw, obd_off offset, +static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset, struct page **pages, int npages, int async) { struct lu_env *env; @@ -1374,7 +1374,7 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, obd_off offset, /** @} echo_exports */ -static obd_id last_object_id; +static u64 last_object_id; static int echo_copyout_lsm (struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob) @@ -2324,14 +2324,14 @@ static void echo_put_object(struct echo_object *eco) } static void -echo_get_stripe_off_id (struct lov_stripe_md *lsm, obd_off *offp, obd_id *idp) +echo_get_stripe_off_id(struct lov_stripe_md *lsm, u64 *offp, u64 *idp) { unsigned long stripe_count; unsigned long stripe_size; unsigned long width; unsigned long woffset; int stripe_index; - obd_off offset; + u64 offset; if (lsm->lsm_stripe_count <= 1) return; @@ -2354,12 +2354,12 @@ echo_get_stripe_off_id (struct lov_stripe_md *lsm, obd_off *offp, obd_id *idp) static void echo_client_page_debug_setup(struct lov_stripe_md *lsm, - struct page *page, int rw, obd_id id, - obd_off offset, obd_off count) + struct page *page, int rw, u64 id, + u64 offset, u64 count) { char *addr; - obd_off stripe_off; - obd_id stripe_id; + u64 stripe_off; + u64 stripe_id; int delta; /* no partial pages on the client */ @@ -2384,11 +2384,11 @@ echo_client_page_debug_setup(struct lov_stripe_md *lsm, } static int echo_client_page_debug_check(struct lov_stripe_md *lsm, - struct page *page, obd_id id, - obd_off offset, obd_off count) + struct page *page, u64 id, + u64 offset, u64 count) { - obd_off stripe_off; - obd_id stripe_id; + u64 stripe_off; + u64 stripe_id; char *addr; int delta; int rc; @@ -2418,16 +2418,16 @@ static int echo_client_page_debug_check(struct lov_stripe_md *lsm, } static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa, - struct echo_object *eco, obd_off offset, - obd_size count, int async, + struct echo_object *eco, u64 offset, + u64 count, int async, struct obd_trans_info *oti) { struct lov_stripe_md *lsm = eco->eo_lsm; - obd_count npages; + u32 npages; struct brw_page *pga; struct brw_page *pgp; struct page **pages; - obd_off off; + u64 off; int i; int rc; int verify; @@ -2516,16 +2516,16 @@ static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa, static int echo_client_prep_commit(const struct lu_env *env, struct obd_export *exp, int rw, struct obdo *oa, struct echo_object *eco, - obd_off offset, obd_size count, - obd_size batch, struct obd_trans_info *oti, + u64 offset, u64 count, + u64 batch, struct obd_trans_info *oti, int async) { struct lov_stripe_md *lsm = eco->eo_lsm; struct obd_ioobj ioo; struct niobuf_local *lnb; struct niobuf_remote *rnb; - obd_off off; - obd_size npages, tot_pages; + u64 off; + u64 npages, tot_pages; int i, ret = 0, brw_flags = 0; if (count <= 0 || (count & (~CFS_PAGE_MASK)) != 0 || @@ -2677,12 +2677,12 @@ static int echo_client_brw_ioctl(const struct lu_env *env, int rw, static int echo_client_enqueue(struct obd_export *exp, struct obdo *oa, - int mode, obd_off offset, obd_size nob) + int mode, u64 offset, u64 nob) { struct echo_device *ed = obd2echo_dev(exp->exp_obd); struct lustre_handle *ulh = &oa->o_handle; struct echo_object *eco; - obd_off end; + u64 end; int rc; if (ed->ed_next == NULL) @@ -2699,7 +2699,7 @@ echo_client_enqueue(struct obd_export *exp, struct obdo *oa, if (rc != 0) return rc; - end = (nob == 0) ? ((obd_off) -1) : (offset + nob - 1); + end = (nob == 0) ? ((u64) -1) : (offset + nob - 1); rc = cl_echo_enqueue(eco, offset, end, mode, &ulh->cookie); if (rc == 0) { oa->o_valid |= OBD_MD_FLHANDLE; diff --git a/drivers/staging/lustre/lustre/osc/lproc_osc.c b/drivers/staging/lustre/lustre/osc/lproc_osc.c index 2ab403548b5e..ad2777fc217d 100644 --- a/drivers/staging/lustre/lustre/osc/lproc_osc.c +++ b/drivers/staging/lustre/lustre/osc/lproc_osc.c @@ -148,7 +148,7 @@ static ssize_t osc_max_dirty_mb_seq_write(struct file *file, const char *buffer, return -ERANGE; client_obd_list_lock(&cli->cl_loi_list_lock); - cli->cl_dirty_max = (obd_count)(pages_number << PAGE_CACHE_SHIFT); + cli->cl_dirty_max = (u32)(pages_number << PAGE_CACHE_SHIFT); osc_wake_cache_waiters(cli); client_obd_list_unlock(&cli->cl_loi_list_lock); diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index 57d7dba23479..7734d666b7a1 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -1885,7 +1885,7 @@ osc_send_write_rpc(const struct lu_env *env, struct client_obd *cli, struct osc_extent *ext; struct osc_extent *tmp; struct osc_extent *first = NULL; - obd_count page_count = 0; + u32 page_count = 0; int srvlock = 0; int rc = 0; diff --git a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h index 2d1f977dca36..3aa80d949b27 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cl_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_cl_internal.h @@ -435,7 +435,7 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg, enum cl_req_type crt, int brw_flags); int osc_cancel_async_page(const struct lu_env *env, struct osc_page *ops); int osc_set_async_flags(struct osc_object *obj, struct osc_page *opg, - obd_flag async_flags); + u32 async_flags); int osc_prep_async_page(struct osc_object *osc, struct osc_page *ops, struct page *page, loff_t offset); int osc_queue_async_io(const struct lu_env *env, struct cl_io *io, diff --git a/drivers/staging/lustre/lustre/osc/osc_internal.h b/drivers/staging/lustre/lustre/osc/osc_internal.h index f67a70083621..0f182da96dc4 100644 --- a/drivers/staging/lustre/lustre/osc/osc_internal.h +++ b/drivers/staging/lustre/lustre/osc/osc_internal.h @@ -59,7 +59,7 @@ struct osc_async_page { struct list_head oap_pending_item; struct list_head oap_rpc_item; - obd_off oap_obj_off; + u64 oap_obj_off; unsigned oap_page_off; enum async_flags oap_async_flags; @@ -192,12 +192,12 @@ extern struct kmem_cache *osc_quota_kmem; struct osc_quota_info { /** linkage for quota hash table */ struct hlist_node oqi_hash; - obd_uid oqi_id; + u32 oqi_id; }; int osc_quota_setup(struct obd_device *obd); int osc_quota_cleanup(struct obd_device *obd); int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], - obd_flag valid, obd_flag flags); + u32 valid, u32 flags); int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]); int osc_quotactl(struct obd_device *unused, struct obd_export *exp, struct obd_quotactl *oqctl); diff --git a/drivers/staging/lustre/lustre/osc/osc_io.c b/drivers/staging/lustre/lustre/osc/osc_io.c index 54fe836a64cd..886b1ef8f6ea 100644 --- a/drivers/staging/lustre/lustre/osc/osc_io.c +++ b/drivers/staging/lustre/lustre/osc/osc_io.c @@ -711,7 +711,7 @@ static void osc_req_completion(const struct lu_env *env, static void osc_req_attr_set(const struct lu_env *env, const struct cl_req_slice *slice, const struct cl_object *obj, - struct cl_req_attr *attr, obd_valid flags) + struct cl_req_attr *attr, u64 flags) { struct lov_oinfo *oinfo; struct cl_req *clerq; diff --git a/drivers/staging/lustre/lustre/osc/osc_quota.c b/drivers/staging/lustre/lustre/osc/osc_quota.c index 3563809072b4..db4540a0a495 100644 --- a/drivers/staging/lustre/lustre/osc/osc_quota.c +++ b/drivers/staging/lustre/lustre/osc/osc_quota.c @@ -31,7 +31,7 @@ #include "../include/obd_ost.h" #include "osc_internal.h" -static inline struct osc_quota_info *osc_oqi_alloc(obd_uid id) +static inline struct osc_quota_info *osc_oqi_alloc(u32 id) { struct osc_quota_info *oqi; @@ -71,7 +71,7 @@ int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]) : OBD_FL_NO_GRPQUOTA) int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], - obd_flag valid, obd_flag flags) + u32 valid, u32 flags) { int type; int rc = 0; @@ -145,10 +145,10 @@ static int oqi_keycmp(const void *key, struct hlist_node *hnode) { struct osc_quota_info *oqi; - obd_uid uid; + u32 uid; LASSERT(key != NULL); - uid = *((obd_uid*)key); + uid = *((u32 *)key); oqi = hlist_entry(hnode, struct osc_quota_info, oqi_hash); return uid == oqi->oqi_id; diff --git a/drivers/staging/lustre/lustre/osc/osc_request.c b/drivers/staging/lustre/lustre/osc/osc_request.c index fb0d9fb9cebc..c502f346db9a 100644 --- a/drivers/staging/lustre/lustre/osc/osc_request.c +++ b/drivers/staging/lustre/lustre/osc/osc_request.c @@ -54,7 +54,7 @@ #include "osc_internal.h" #include "osc_cl_internal.h" -static void osc_release_ppga(struct brw_page **ppga, obd_count count); +static void osc_release_ppga(struct brw_page **ppga, u32 count); static int brw_interpret(const struct lu_env *env, struct ptlrpc_request *req, void *data, int rc); int osc_cleanup(struct obd_device *obd); @@ -615,7 +615,7 @@ int osc_sync_base(struct obd_export *exp, struct obd_info *oinfo, } static int osc_sync(const struct lu_env *env, struct obd_export *exp, - struct obd_info *oinfo, obd_size start, obd_size end, + struct obd_info *oinfo, u64 start, u64 end, struct ptlrpc_request_set *set) { if (!oinfo->oi_oa) { @@ -799,7 +799,7 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp, static void osc_announce_cached(struct client_obd *cli, struct obdo *oa, long writing_bytes) { - obd_flag bits = OBD_MD_FLBLOCKS|OBD_MD_FLGRANT; + u32 bits = OBD_MD_FLBLOCKS|OBD_MD_FLGRANT; LASSERT(!(oa->o_valid & bits)); @@ -849,7 +849,7 @@ void osc_update_next_shrink(struct client_obd *cli) cli->cl_next_shrink_grant); } -static void __osc_update_grant(struct client_obd *cli, obd_size grant) +static void __osc_update_grant(struct client_obd *cli, u64 grant) { client_obd_list_lock(&cli->cl_loi_list_lock); cli->cl_avail_grant += grant; @@ -865,7 +865,7 @@ static void osc_update_grant(struct client_obd *cli, struct ost_body *body) } static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp, - obd_count keylen, void *key, obd_count vallen, + u32 keylen, void *key, u32 vallen, void *val, struct ptlrpc_request_set *set); static int osc_shrink_grant_interpret(const struct lu_env *env, @@ -1067,7 +1067,7 @@ static void osc_init_grant(struct client_obd *cli, struct obd_connect_data *ocd) * beyond the end of a stripe file; i.e. lustre is reading a sparse file * via the LOV, and it _knows_ it's reading inside the file, it's just that * this stripe never got written at or beyond this stripe offset yet. */ -static void handle_short_read(int nob_read, obd_count page_count, +static void handle_short_read(int nob_read, u32 page_count, struct brw_page **pga) { char *ptr; @@ -1104,7 +1104,7 @@ static void handle_short_read(int nob_read, obd_count page_count, static int check_write_rcs(struct ptlrpc_request *req, int requested_nob, int niocount, - obd_count page_count, struct brw_page **pga) + u32 page_count, struct brw_page **pga) { int i; __u32 *remote_rcs; @@ -1157,7 +1157,7 @@ static inline int can_merge_pages(struct brw_page *p1, struct brw_page *p2) return (p1->off + p1->count == p2->off); } -static obd_count osc_checksum_bulk(int nob, obd_count pg_count, +static u32 osc_checksum_bulk(int nob, u32 pg_count, struct brw_page **pga, int opc, cksum_type_t cksum_type) { @@ -1219,7 +1219,7 @@ static obd_count osc_checksum_bulk(int nob, obd_count pg_count, } static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa, - struct lov_stripe_md *lsm, obd_count page_count, + struct lov_stripe_md *lsm, u32 page_count, struct brw_page **pga, struct ptlrpc_request **reqp, struct obd_capa *ocapa, int reserve, @@ -1422,7 +1422,7 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa, static int check_write_checksum(struct obdo *oa, const lnet_process_id_t *peer, __u32 client_cksum, __u32 server_cksum, int nob, - obd_count page_count, struct brw_page **pga, + u32 page_count, struct brw_page **pga, cksum_type_t client_cksum_type) { __u32 new_cksum; @@ -1618,7 +1618,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) static int osc_brw_internal(int cmd, struct obd_export *exp, struct obdo *oa, struct lov_stripe_md *lsm, - obd_count page_count, struct brw_page **pga, + u32 page_count, struct brw_page **pga, struct obd_capa *ocapa) { struct ptlrpc_request *req; @@ -1787,7 +1787,7 @@ static void sort_brw_pages(struct brw_page **array, int num) } while (stride > 1); } -static obd_count max_unfragmented_pages(struct brw_page **pg, obd_count pages) +static u32 max_unfragmented_pages(struct brw_page **pg, u32 pages) { int count = 1; int offset; @@ -1813,7 +1813,7 @@ static obd_count max_unfragmented_pages(struct brw_page **pg, obd_count pages) } } -static struct brw_page **osc_build_ppga(struct brw_page *pga, obd_count count) +static struct brw_page **osc_build_ppga(struct brw_page *pga, u32 count) { struct brw_page **ppga; int i; @@ -1827,14 +1827,14 @@ static struct brw_page **osc_build_ppga(struct brw_page *pga, obd_count count) return ppga; } -static void osc_release_ppga(struct brw_page **ppga, obd_count count) +static void osc_release_ppga(struct brw_page **ppga, u32 count) { LASSERT(ppga != NULL); OBD_FREE(ppga, sizeof(*ppga) * count); } static int osc_brw(int cmd, struct obd_export *exp, struct obd_info *oinfo, - obd_count page_count, struct brw_page *pga, + u32 page_count, struct brw_page *pga, struct obd_trans_info *oti) { struct obdo *saved_oa = NULL; @@ -1867,7 +1867,7 @@ static int osc_brw(int cmd, struct obd_export *exp, struct obd_info *oinfo, sort_brw_pages(ppga, page_count); while (page_count) { - obd_count pages_per_brw; + u32 pages_per_brw; if (page_count > cli->cl_max_pages_per_rpc) pages_per_brw = cli->cl_max_pages_per_rpc; @@ -2029,8 +2029,8 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli, CRT_READ; struct ldlm_lock *lock = NULL; struct cl_req_attr *crattr = NULL; - obd_off starting_offset = OBD_OBJECT_EOF; - obd_off ending_offset = 0; + u64 starting_offset = OBD_OBJECT_EOF; + u64 ending_offset = 0; int mpflag = 0; int mem_tight = 0; int page_count = 0; @@ -2965,7 +2965,7 @@ static int osc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, } static int osc_get_info(const struct lu_env *env, struct obd_export *exp, - obd_count keylen, void *key, __u32 *vallen, void *val, + u32 keylen, void *key, __u32 *vallen, void *val, struct lov_stripe_md *lsm) { if (!vallen || !val) @@ -2978,7 +2978,7 @@ static int osc_get_info(const struct lu_env *env, struct obd_export *exp, return 0; } else if (KEY_IS(KEY_LAST_ID)) { struct ptlrpc_request *req; - obd_id *reply; + u64 *reply; char *tmp; int rc; @@ -3008,7 +3008,7 @@ static int osc_get_info(const struct lu_env *env, struct obd_export *exp, if (reply == NULL) GOTO(out, rc = -EPROTO); - *((obd_id *)val) = *reply; + *((u64 *)val) = *reply; out: ptlrpc_req_finished(req); return rc; @@ -3100,7 +3100,7 @@ static int osc_get_info(const struct lu_env *env, struct obd_export *exp, } static int osc_set_info_async(const struct lu_env *env, struct obd_export *exp, - obd_count keylen, void *key, obd_count vallen, + u32 keylen, void *key, u32 vallen, void *val, struct ptlrpc_request_set *set) { struct ptlrpc_request *req; @@ -3562,7 +3562,7 @@ int osc_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg) return(rc); } -static int osc_process_config(struct obd_device *obd, obd_count len, void *buf) +static int osc_process_config(struct obd_device *obd, u32 len, void *buf) { return osc_process_config_base(obd, buf); } diff --git a/drivers/staging/lustre/lustre/ptlrpc/layout.c b/drivers/staging/lustre/lustre/ptlrpc/layout.c index 511cb9cbf0d4..5b8337187b59 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/layout.c +++ b/drivers/staging/lustre/lustre/ptlrpc/layout.c @@ -1094,8 +1094,8 @@ struct req_msg_field RMF_EAVALS_LENS = EXPORT_SYMBOL(RMF_EAVALS_LENS); struct req_msg_field RMF_OBD_ID = - DEFINE_MSGF("obd_id", 0, - sizeof(obd_id), lustre_swab_ost_last_id, NULL); + DEFINE_MSGF("u64", 0, + sizeof(u64), lustre_swab_ost_last_id, NULL); EXPORT_SYMBOL(RMF_OBD_ID); struct req_msg_field RMF_FID = diff --git a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c index ac562932ccdf..50556db15f79 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c +++ b/drivers/staging/lustre/lustre/ptlrpc/pack_generic.c @@ -1600,8 +1600,8 @@ EXPORT_SYMBOL(ptlrpc_req_set_repsize); */ int do_set_info_async(struct obd_import *imp, int opcode, int version, - obd_count keylen, void *key, - obd_count vallen, void *val, + u32 keylen, void *key, + u32 vallen, void *val, struct ptlrpc_request_set *set) { struct ptlrpc_request *req; @@ -1797,7 +1797,7 @@ void lustre_swab_ost_body(struct ost_body *b) } EXPORT_SYMBOL(lustre_swab_ost_body); -void lustre_swab_ost_last_id(obd_id *id) +void lustre_swab_ost_last_id(u64 *id) { __swab64s(id); } -- GitLab From 74bb9d4fef9ff789094e85ee1324616611d77baa Mon Sep 17 00:00:00 2001 From: Hema Prathaban Date: Sun, 17 Aug 2014 00:27:48 +0530 Subject: [PATCH 0815/9167] staging: lustre: lustre: libcfs: do not use assignment in if condition This patch fixes the following error using checkpatch.pl Error: do not use assignment in if condition Signed-off-by: Hema Prathaban Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/debug.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index 6b584698d3ae..e86b28d2cb03 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -314,9 +314,8 @@ libcfs_debug_str2mask(int *mask, const char *str, int is_subsys) if (!isspace(str[n-1])) break; matched = n; - - if ((t = sscanf(str, "%i%n", &m, &matched)) >= 1 && - matched == n) { + t = sscanf(str, "%i%n", &m, &matched); + 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 " -- GitLab From b553a1a81565b14efb00ac4c984fb74106666503 Mon Sep 17 00:00:00 2001 From: Hema Prathaban Date: Sun, 17 Aug 2014 00:07:32 +0530 Subject: [PATCH 0816/9167] staging: lustre: lustre: libcfs: pr_warn instead printk This patch fixes the following warning using checkpatch.pl WARNING: Prefer [subsystem eg: netdev]_warn([subsystem]dev, ... then dev_warn(dev, ... then pr_warn(... to printk(KERN_WARNING ... Signed-off-by: Hema Prathaban Signed-off-by: Greg Kroah-Hartman --- drivers/staging/lustre/lustre/libcfs/debug.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/lustre/lustre/libcfs/debug.c b/drivers/staging/lustre/lustre/libcfs/debug.c index e86b28d2cb03..5a5b7fcb2630 100644 --- a/drivers/staging/lustre/lustre/libcfs/debug.c +++ b/drivers/staging/lustre/lustre/libcfs/debug.c @@ -343,7 +343,7 @@ void libcfs_debug_dumplog_internal(void *arg) snprintf(debug_file_name, sizeof(debug_file_name) - 1, "%s.%ld.%ld", libcfs_debug_file_path_arr, get_seconds(), (long_ptr_t)arg); - printk(KERN_ALERT "LustreError: dumping log to %s\n", + pr_alert("LustreError: dumping log to %s\n", debug_file_name); cfs_tracefile_dump_all_pages(debug_file_name); libcfs_run_debug_log_upcall(debug_file_name); @@ -375,7 +375,7 @@ void libcfs_debug_dumplog(void) (void *)(long)current_pid(), "libcfs_debug_dumper"); if (IS_ERR(dumper)) - printk(KERN_ERR "LustreError: cannot start log dump thread:" + pr_err("LustreError: cannot start log dump thread:" " %ld\n", PTR_ERR(dumper)); else schedule(); @@ -452,7 +452,7 @@ int libcfs_debug_mark_buffer(const char *text) void libcfs_debug_set_level(unsigned int debug_level) { - printk(KERN_WARNING "Lustre: Setting portals debug level to %08x\n", + pr_warn("Lustre: Setting portals debug level to %08x\n", debug_level); libcfs_debug = debug_level; } -- GitLab From 230fa11f5fab094512b6ad131ae1de86b12466f2 Mon Sep 17 00:00:00 2001 From: Jeshwanth Kumar N K Date: Fri, 15 Aug 2014 01:41:04 +0530 Subject: [PATCH 0817/9167] staging: wlan-ng: prism2mgmt.c Fix break not useful Fixed up warnings, break is not useful after return statement. And the exit Label is deleted, now returning inline. Signed-off-by: Jeshwanth Kumar N K Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2mgmt.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index e6a82d3303c1..013a6240f193 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -1107,8 +1107,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) if (wlandev->netdev->type == ARPHRD_ETHER) { msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; - result = 0; - goto exit; + return 0; } /* Disable monitor mode */ result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE); @@ -1166,9 +1165,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) netdev_info(wlandev->netdev, "monitor mode disabled\n"); msg->resultcode.data = P80211ENUM_resultcode_success; - result = 0; - goto exit; - break; + return 0; case P80211ENUM_truth_true: /* Disable the port (if enabled), only check Port 0 */ if (hw->port_enabled[0]) { @@ -1313,19 +1310,13 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) } msg->resultcode.data = P80211ENUM_resultcode_success; - result = 0; - goto exit; - break; + return 0; default: msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; - result = 0; - goto exit; - break; + return 0; } failed: msg->resultcode.data = P80211ENUM_resultcode_refused; - result = 0; -exit: - return result; + return 0; } -- GitLab From 2fd2914a2e456048e2a176185cb8e7576def452c Mon Sep 17 00:00:00 2001 From: Purnendu Kapadia Date: Fri, 15 Aug 2014 18:20:30 +0100 Subject: [PATCH 0818/9167] staging: android: fix attribute as suggested by checkpatch we should use __packed attribute Signed-off-by: Purnendu Kapadia Signed-off-by: Greg Kroah-Hartman --- drivers/staging/android/uapi/binder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/android/uapi/binder.h b/drivers/staging/android/uapi/binder.h index 904adb7600cf..dba4cef3a8d3 100644 --- a/drivers/staging/android/uapi/binder.h +++ b/drivers/staging/android/uapi/binder.h @@ -169,7 +169,7 @@ struct binder_ptr_cookie { struct binder_handle_cookie { __u32 handle; binder_uintptr_t cookie; -} __attribute__((packed)); +} __packed; struct binder_pri_desc { __s32 priority; -- GitLab From 1d8c5aa329e7a7a17d9c99122d89d76663195ddb Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sat, 16 Aug 2014 16:58:05 +0200 Subject: [PATCH 0819/9167] staging: dgnc: Remove driver-wide state variable This commit removes the driver's global state variable. This is ok because the state was changed only once at the end of init phase thus the future usage of this variable is pointless. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 19 ------------------- drivers/staging/dgnc/dgnc_driver.h | 2 -- drivers/staging/dgnc/dgnc_sysfs.c | 9 --------- 3 files changed, 30 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 7bbe98080edf..d3fc3c2b5645 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -90,7 +90,6 @@ static const struct file_operations dgnc_BoardFops = { uint dgnc_NumBoards; struct dgnc_board *dgnc_Board[MAXBOARDS]; DEFINE_SPINLOCK(dgnc_global_lock); -int dgnc_driver_state = DRIVER_INITIALIZED; ulong dgnc_poll_counter; uint dgnc_Major; int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ @@ -174,12 +173,6 @@ char *dgnc_state_text[] = { "Board READY", }; -char *dgnc_driver_state_text[] = { - "Driver Initialized", - "Driver Ready." -}; - - /************************************************************************ * @@ -331,8 +324,6 @@ static int dgnc_start(void) add_timer(&dgnc_poll_timer); - dgnc_driver_state = DRIVER_READY; - return rc; } @@ -747,14 +738,6 @@ static void dgnc_poll_handler(ulong dummy) dgnc_poll_counter++; - /* - * Do not start the board state machine until - * driver tells us its up and running, and has - * everything it needs. - */ - if (dgnc_driver_state != DRIVER_READY) - goto schedule_poller; - /* Go thru each board, kicking off a tasklet for each if needed */ for (i = 0; i < dgnc_NumBoards; i++) { brd = dgnc_Board[i]; @@ -773,8 +756,6 @@ static void dgnc_poll_handler(ulong dummy) DGNC_UNLOCK(brd->bd_lock, lock_flags); } -schedule_poller: - /* * Schedule ourself back at the nominal wakeup interval. */ diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index eae04940062c..ac0fe3640060 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -484,7 +484,6 @@ struct channel_t { /* * Our Global Variables. */ -extern int dgnc_driver_state; /* The state of the driver */ extern uint dgnc_Major; /* Our driver/mgmt major */ extern int dgnc_debug; /* Debug variable */ extern int dgnc_rawreadok; /* Set if user wants rawreads */ @@ -495,6 +494,5 @@ extern uint dgnc_NumBoards; /* Total number of boards */ extern struct dgnc_board *dgnc_Board[MAXBOARDS]; /* Array of board structs */ extern ulong dgnc_poll_counter; /* Times the poller has run */ extern char *dgnc_state_text[]; /* Array of state text */ -extern char *dgnc_driver_state_text[];/* Array of driver state text */ #endif diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c index 3f321bb2b79d..4765ba5484e5 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ b/drivers/staging/dgnc/dgnc_sysfs.c @@ -71,13 +71,6 @@ static ssize_t dgnc_driver_pollcounter_show(struct device_driver *ddp, char *buf static DRIVER_ATTR(pollcounter, S_IRUSR, dgnc_driver_pollcounter_show, NULL); -static ssize_t dgnc_driver_state_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%s\n", dgnc_driver_state_text[dgnc_driver_state]); -} -static DRIVER_ATTR(state, S_IRUSR, dgnc_driver_state_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); @@ -129,7 +122,6 @@ void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver) rc |= driver_create_file(driverfs, &driver_attr_rawreadok); rc |= driver_create_file(driverfs, &driver_attr_pollrate); rc |= driver_create_file(driverfs, &driver_attr_pollcounter); - rc |= driver_create_file(driverfs, &driver_attr_state); if (rc) { printk(KERN_ERR "DGNC: sysfs driver_create_file failed!\n"); } @@ -146,7 +138,6 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver) driver_remove_file(driverfs, &driver_attr_rawreadok); driver_remove_file(driverfs, &driver_attr_pollrate); driver_remove_file(driverfs, &driver_attr_pollcounter); - driver_remove_file(driverfs, &driver_attr_state); } -- GitLab From 3599abafcc51594f1629f19a6a12ff92f6e94017 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sat, 16 Aug 2014 16:58:06 +0200 Subject: [PATCH 0820/9167] staging: dgnc: Remove driver-wide polling counter variable The polling counter variable is only exposed via sysfs and has no other purpose. Now, since the polling shall be implemented as a board specific feature rather than being global in the driver this counter is obsolete. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 3 --- drivers/staging/dgnc/dgnc_driver.h | 1 - drivers/staging/dgnc/dgnc_sysfs.c | 10 ---------- 3 files changed, 14 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index d3fc3c2b5645..223075a57968 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -90,7 +90,6 @@ static const struct file_operations dgnc_BoardFops = { uint dgnc_NumBoards; struct dgnc_board *dgnc_Board[MAXBOARDS]; DEFINE_SPINLOCK(dgnc_global_lock); -ulong dgnc_poll_counter; uint dgnc_Major; int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ @@ -736,8 +735,6 @@ static void dgnc_poll_handler(ulong dummy) int i; unsigned long new_time; - dgnc_poll_counter++; - /* Go thru each board, kicking off a tasklet for each if needed */ for (i = 0; i < dgnc_NumBoards; i++) { brd = dgnc_Board[i]; diff --git a/drivers/staging/dgnc/dgnc_driver.h b/drivers/staging/dgnc/dgnc_driver.h index ac0fe3640060..d16d76128f93 100644 --- a/drivers/staging/dgnc/dgnc_driver.h +++ b/drivers/staging/dgnc/dgnc_driver.h @@ -492,7 +492,6 @@ 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 */ -extern ulong dgnc_poll_counter; /* Times the poller has run */ extern char *dgnc_state_text[]; /* Array of state text */ #endif diff --git a/drivers/staging/dgnc/dgnc_sysfs.c b/drivers/staging/dgnc/dgnc_sysfs.c index 4765ba5484e5..60d247b72b9b 100644 --- a/drivers/staging/dgnc/dgnc_sysfs.c +++ b/drivers/staging/dgnc/dgnc_sysfs.c @@ -63,14 +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_pollcounter_show(struct device_driver *ddp, char *buf) -{ - return snprintf(buf, PAGE_SIZE, "%ld\n", dgnc_poll_counter); -} -static DRIVER_ATTR(pollcounter, S_IRUSR, dgnc_driver_pollcounter_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); @@ -121,7 +113,6 @@ void dgnc_create_driver_sysfiles(struct pci_driver *dgnc_driver) rc |= driver_create_file(driverfs, &driver_attr_debug); rc |= driver_create_file(driverfs, &driver_attr_rawreadok); rc |= driver_create_file(driverfs, &driver_attr_pollrate); - rc |= driver_create_file(driverfs, &driver_attr_pollcounter); if (rc) { printk(KERN_ERR "DGNC: sysfs driver_create_file failed!\n"); } @@ -137,7 +128,6 @@ void dgnc_remove_driver_sysfiles(struct pci_driver *dgnc_driver) driver_remove_file(driverfs, &driver_attr_debug); driver_remove_file(driverfs, &driver_attr_rawreadok); driver_remove_file(driverfs, &driver_attr_pollrate); - driver_remove_file(driverfs, &driver_attr_pollcounter); } -- GitLab From 0b3a07ede37d0c1a0985032c9f2044d71813282a Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sat, 16 Aug 2014 16:58:07 +0200 Subject: [PATCH 0821/9167] staging: dgnc: Remove not needed dgnc_driver_start variable The dgnc_driver_start variable purpose was to indicate if the driver 'start' routine has been called. Now, because the 'start' routine can only be called once this variable is not needed thus this commit removes it. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 223075a57968..726b5ddb8107 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -97,7 +97,6 @@ int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ * Static vars. */ static uint dgnc_Major_Control_Registered = FALSE; -static uint dgnc_driver_start = FALSE; static struct class *dgnc_class; @@ -270,10 +269,6 @@ static int dgnc_start(void) int rc = 0; unsigned long flags; - if (dgnc_driver_start == TRUE) - return rc; - dgnc_driver_start = TRUE; - /* make sure that the globals are init'd before we do anything else */ dgnc_init_globals(); -- GitLab From ed7f92da59f24dd966555efef978fe14085b3318 Mon Sep 17 00:00:00 2001 From: Konrad Zapalowicz Date: Sat, 16 Aug 2014 16:58:08 +0200 Subject: [PATCH 0822/9167] staging: dgnc: Remove unnecessary dgnc_Major_Control_Registered variable The dgnc_Major_Control_Registered variable purpose was to act as a flag to indicate if the character device has been successfully registered into the kernel. This flag was later checked in the module cleanup function to know if the character device needs to be deregistered. However the {device,class}_destroy and unregister_chrdev functions may be called with 'invalid' data perfectly fine. This means that this variable is not needed and can safely be removed which is what this commit does. Signed-off-by: Konrad Zapalowicz Signed-off-by: Greg Kroah-Hartman --- drivers/staging/dgnc/dgnc_driver.c | 38 ++++++++++++------------------ 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/drivers/staging/dgnc/dgnc_driver.c b/drivers/staging/dgnc/dgnc_driver.c index 726b5ddb8107..a9f1a8c09725 100644 --- a/drivers/staging/dgnc/dgnc_driver.c +++ b/drivers/staging/dgnc/dgnc_driver.c @@ -96,8 +96,6 @@ int dgnc_poll_tick = 20; /* Poll interval - 20 ms */ /* * Static vars. */ -static uint dgnc_Major_Control_Registered = FALSE; - static struct class *dgnc_class; /* @@ -197,11 +195,9 @@ static void dgnc_cleanup_module(void) dgnc_remove_driver_sysfiles(&dgnc_driver); - if (dgnc_Major_Control_Registered) { - device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); - class_destroy(dgnc_class); - unregister_chrdev(dgnc_Major, "dgnc"); - } + device_destroy(dgnc_class, MKDEV(dgnc_Major, 0)); + class_destroy(dgnc_class); + unregister_chrdev(dgnc_Major, "dgnc"); for (i = 0; i < dgnc_NumBoards; ++i) { dgnc_remove_ports_sysfiles(dgnc_Board[i]); @@ -278,24 +274,20 @@ static int dgnc_start(void) * Register our base character device into the kernel. * This allows the download daemon to connect to the downld device * before any of the boards are init'ed. + * + * Register management/dpa devices */ - if (!dgnc_Major_Control_Registered) { - /* - * Register management/dpa devices - */ - rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); - if (rc <= 0) { - APR(("Can't register dgnc driver device (%d)\n", rc)); - return -ENXIO; - } - dgnc_Major = rc; - - dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); - device_create(dgnc_class, NULL, - MKDEV(dgnc_Major, 0), - NULL, "dgnc_mgmt"); - dgnc_Major_Control_Registered = TRUE; + rc = register_chrdev(0, "dgnc", &dgnc_BoardFops); + if (rc <= 0) { + APR(("Can't register dgnc driver device (%d)\n", rc)); + return -ENXIO; } + dgnc_Major = rc; + + dgnc_class = class_create(THIS_MODULE, "dgnc_mgmt"); + device_create(dgnc_class, NULL, + MKDEV(dgnc_Major, 0), + NULL, "dgnc_mgmt"); /* * Init any global tty stuff. -- GitLab From dd2d62dfede7aa2bd87b3fb07db0c7450ca7ea41 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Thu, 31 Jul 2014 16:32:02 +0200 Subject: [PATCH 0823/9167] ARM: mvebu: Add RTC support for Armada 375 The Armada 375 SoC has the same real time clock as the one used in other Marvell EBU platforms. This patch consequently updates the Device Tree of the Armada 375 SoC to describe the internal RTC. Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1406817122-15675-1-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 c1e49e7bf0fa..de6571445cef 100644 --- a/arch/arm/boot/dts/armada-375.dtsi +++ b/arch/arm/boot/dts/armada-375.dtsi @@ -185,6 +185,12 @@ }; }; + rtc@10300 { + compatible = "marvell,orion-rtc"; + reg = <0x10300 0x20>; + interrupts = ; + }; + spi0: spi@10600 { compatible = "marvell,orion-spi"; reg = <0x10600 0x50>; -- GitLab From a43f99d260d30be8480f76b2c3eeb283a7115623 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 Aug 2014 09:14:36 -0300 Subject: [PATCH 0824/9167] ARM: mvebu: Add network pin mux configuration for the Armada 370 SoC This commit adds the pin mux configuration for the two network interfaces and the MDIO interface in the Armada 370 SoC .dtsi file. Only the configuration for RGMII is added for now. Acked-by: Sebastian Hesselbarth Signed-off-by: Ezequiel Garcia Acked-by: Andrew Lunn Link: https://lkml.kernel.org/r/1407759281-11513-2-git-send-email-ezequiel.garcia@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370.dtsi | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/armada-370.dtsi b/arch/arm/boot/dts/armada-370.dtsi index 21b588b6f6bd..f2c55f3e6e8f 100644 --- a/arch/arm/boot/dts/armada-370.dtsi +++ b/arch/arm/boot/dts/armada-370.dtsi @@ -151,6 +151,25 @@ "mpp62", "mpp60", "mpp58"; marvell,function = "audio"; }; + + mdio_pins: mdio-pins { + marvell,pins = "mpp17", "mpp18"; + marvell,function = "ge"; + }; + + ge0_rgmii_pins: ge0-rgmii-pins { + marvell,pins = "mpp5", "mpp6", "mpp7", "mpp8", + "mpp9", "mpp10", "mpp11", "mpp12", + "mpp13", "mpp14", "mpp15", "mpp16"; + marvell,function = "ge0"; + }; + + ge1_rgmii_pins: ge1-rgmii-pins { + marvell,pins = "mpp19", "mpp20", "mpp21", "mpp22", + "mpp23", "mpp24", "mpp25", "mpp26", + "mpp27", "mpp28", "mpp29", "mpp30"; + marvell,function = "ge1"; + }; }; gpio0: gpio@18100 { -- GitLab From 7d9d5d28ddb5b93a5445b5460d5da52d5143837f Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 Aug 2014 09:14:37 -0300 Subject: [PATCH 0825/9167] ARM: mvebu: Add proper pin muxing on Globalscale Mirabox board This commit adds the required pin muxing for the network interfaces and the MDIO interface to be properly initialized. For instance, this makes it possible for a bootloader to initialize and access the network interfaces. Signed-off-by: Ezequiel Garcia Acked-by: Andrew Lunn Link: https://lkml.kernel.org/r/1407759281-11513-3-git-send-email-ezequiel.garcia@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-mirabox.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/armada-370-mirabox.dts b/arch/arm/boot/dts/armada-370-mirabox.dts index 097df7d8f0f6..2b6d24e0d1e8 100644 --- a/arch/arm/boot/dts/armada-370-mirabox.dts +++ b/arch/arm/boot/dts/armada-370-mirabox.dts @@ -91,6 +91,8 @@ }; mdio { + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; phy0: ethernet-phy@0 { reg = <0>; }; @@ -100,11 +102,15 @@ }; }; ethernet@70000 { + pinctrl-0 = <&ge0_rgmii_pins>; + pinctrl-names = "default"; status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; }; ethernet@74000 { + pinctrl-0 = <&ge1_rgmii_pins>; + pinctrl-names = "default"; status = "okay"; phy = <&phy1>; phy-mode = "rgmii-id"; -- GitLab From fea038ed55aec9a1dc59719e5e2728fe7e2148f8 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 Aug 2014 09:14:38 -0300 Subject: [PATCH 0826/9167] ARM: mvebu: Add proper pin muxing on the Armada 370 DB board This commit adds the required pin muxing for the network interfaces and the MDIO interface to be properly initialized. For instance, this makes it possible for a bootloader to initialize and access the network interfaces Signed-off-by: Ezequiel Garcia Acked-by: Andrew Lunn Link: https://lkml.kernel.org/r/1407759281-11513-4-git-send-email-ezequiel.garcia@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-db.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/armada-370-db.dts b/arch/arm/boot/dts/armada-370-db.dts index 416f4e5a69c1..a495e5821ab8 100644 --- a/arch/arm/boot/dts/armada-370-db.dts +++ b/arch/arm/boot/dts/armada-370-db.dts @@ -43,6 +43,8 @@ }; mdio { + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; phy0: ethernet-phy@0 { reg = <0>; }; @@ -53,11 +55,15 @@ }; ethernet@70000 { + pinctrl-0 = <&ge0_rgmii_pins>; + pinctrl-names = "default"; status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; }; ethernet@74000 { + pinctrl-0 = <&ge1_rgmii_pins>; + pinctrl-names = "default"; status = "okay"; phy = <&phy1>; phy-mode = "rgmii-id"; -- GitLab From 8c640da6ac8b9a15429473114e0b8b248cf67080 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 Aug 2014 09:14:39 -0300 Subject: [PATCH 0827/9167] ARM: mvebu: Add proper pin muxing on Netgear ReadyNAS 102 This commit adds the required pin muxing for the network interfaces and the MDIO interface to be properly initialized. For instance, this makes it possible for a bootloader to initialize and access the network interfaces Signed-off-by: Ezequiel Garcia Acked-by: Andrew Lunn Link: https://lkml.kernel.org/r/1407759281-11513-5-git-send-email-ezequiel.garcia@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-netgear-rn102.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts index d6d572e5af32..03f917e9b65a 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts @@ -101,12 +101,16 @@ }; mdio { + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; phy0: ethernet-phy@0 { /* Marvell 88E1318 */ reg = <0>; }; }; ethernet@74000 { + pinctrl-0 = <&ge1_rgmii_pins>; + pinctrl-names = "default"; status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; -- GitLab From a1451ab2f024be656fc1b5e560e5854b9d7e70fe Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 Aug 2014 09:14:40 -0300 Subject: [PATCH 0828/9167] ARM: mvebu: Add proper pin muxing on Netgear ReadyNAS 104 This commit adds the required pin muxing for the network interfaces and the MDIO interface to be properly initialized. For instance, this makes it possible for a bootloader to initialize and access the network interfaces Signed-off-by: Ezequiel Garcia Acked-by: Andrew Lunn Link: https://lkml.kernel.org/r/1407759281-11513-6-git-send-email-ezequiel.garcia@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-netgear-rn104.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts index c5fe8b5dcdc7..f56bb1bfe8d7 100644 --- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts +++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts @@ -86,6 +86,8 @@ }; mdio { + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; phy0: ethernet-phy@0 { /* Marvell 88E1318 */ reg = <0>; }; @@ -96,12 +98,16 @@ }; ethernet@70000 { + pinctrl-0 = <&ge0_rgmii_pins>; + pinctrl-names = "default"; status = "okay"; phy = <&phy0>; phy-mode = "rgmii-id"; }; ethernet@74000 { + pinctrl-0 = <&ge1_rgmii_pins>; + pinctrl-names = "default"; status = "okay"; phy = <&phy1>; phy-mode = "rgmii-id"; -- GitLab From 9dfb5c417c3210fe84a74b4cd30549e06962bd06 Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 11 Aug 2014 09:14:41 -0300 Subject: [PATCH 0829/9167] ARM: mvebu: Add proper pin muxing on Armada 370 RD board This commit adds the required pin muxing for the network interfaces and the MDIO interface to be properly initialized. For instance, this makes it possible for a bootloader to initialize and access the network interfaces Only the second network interface is pin muxed. The first network interface is connected to the PHY using SGMII, which uses a dedicated SerDes lane. Signed-off-by: Ezequiel Garcia Acked-by: Andrew Lunn Link: https://lkml.kernel.org/r/1407759281-11513-7-git-send-email-ezequiel.garcia@free-electrons.com Signed-off-by: Jason Cooper --- arch/arm/boot/dts/armada-370-rd.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/boot/dts/armada-370-rd.dts b/arch/arm/boot/dts/armada-370-rd.dts index 4169f4096ea3..ca13d9c8c5f8 100644 --- a/arch/arm/boot/dts/armada-370-rd.dts +++ b/arch/arm/boot/dts/armada-370-rd.dts @@ -59,6 +59,8 @@ }; mdio { + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; phy0: ethernet-phy@0 { reg = <0>; }; @@ -74,6 +76,8 @@ phy-mode = "sgmii"; }; ethernet@74000 { + pinctrl-0 = <&ge1_rgmii_pins>; + pinctrl-names = "default"; status = "okay"; phy = <&phy1>; phy-mode = "rgmii-id"; -- GitLab From 89323f8c504a8653c66fe4a314723b36b07e29e1 Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Wed, 23 Jul 2014 17:40:30 +0300 Subject: [PATCH 0830/9167] irqchip: keystone: Add irq controller ip driver On Keystone SOCs, DSP cores can send interrupts to ARM host using the IRQ controller IP. It provides 28 IRQ signals to ARM. The IRQ handler running on HOST OS can identify DSP signal source by analyzing SRCCx bits in IPCARx registers. This is one of the component used by the IPC mechanism used on Keystone SOCs. Signed-off-by: Grygorii Strashko Link: https://lkml.kernel.org/r/1406126430-9978-1-git-send-email-grygorii.strashko@ti.com Signed-off-by: Jason Cooper --- .../interrupt-controller/ti,keystone-irq.txt | 36 +++ drivers/irqchip/Kconfig | 7 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-keystone.c | 232 ++++++++++++++++++ 4 files changed, 276 insertions(+) create mode 100644 Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt create mode 100644 drivers/irqchip/irq-keystone.c diff --git a/Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt b/Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt new file mode 100644 index 000000000000..d9bb106bdd16 --- /dev/null +++ b/Documentation/devicetree/bindings/interrupt-controller/ti,keystone-irq.txt @@ -0,0 +1,36 @@ +Keystone 2 IRQ controller IP + +On Keystone SOCs, DSP cores can send interrupts to ARM +host using the IRQ controller IP. It provides 28 IRQ signals to ARM. +The IRQ handler running on HOST OS can identify DSP signal source by +analyzing SRCCx bits in IPCARx registers. This is one of the component +used by the IPC mechanism used on Keystone SOCs. + +Required Properties: +- compatible: should be "ti,keystone-irq" +- ti,syscon-dev : phandle and offset pair. The phandle to syscon used to + access device control registers and the offset inside + device control registers range. +- interrupt-controller : Identifies the node as an interrupt controller +- #interrupt-cells : Specifies the number of cells needed to encode interrupt + source should be 1. +- interrupts: interrupt reference to primary interrupt controller + +Please refer to interrupts.txt in this directory for details of the common +Interrupt Controllers bindings used by client devices. + +Example: + kirq0: keystone_irq0@026202a0 { + compatible = "ti,keystone-irq"; + ti,syscon-dev = <&devctrl 0x2a0>; + interrupts = ; + interrupt-controller; + #interrupt-cells = <1>; + }; + + dsp0: dsp0 { + compatible = "linux,rproc-user"; + ... + interrupt-parent = <&kirq0>; + interrupts = <10 2>; + }; diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index b8632bf9a7f3..c88896478e70 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -113,3 +113,10 @@ config IRQ_CROSSBAR The primary irqchip invokes the crossbar's callback which inturn allocates a free irq and configures the IP. Thus the peripheral interrupts are routed to one of the free irqchip interrupt lines. + +config KEYSTONE_IRQ + tristate "Keystone 2 IRQ controller IP" + depends on ARCH_KEYSTONE + help + Support for Texas Instruments Keystone 2 IRQ controller IP which + is part of the Keystone 2 IPC mechanism diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 73052ba9ca62..69fc7fc8d1bb 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -34,3 +34,4 @@ obj-$(CONFIG_XTENSA) += irq-xtensa-pic.o obj-$(CONFIG_XTENSA_MX) += irq-xtensa-mx.o obj-$(CONFIG_IRQ_CROSSBAR) += irq-crossbar.o obj-$(CONFIG_BRCMSTB_L2_IRQ) += irq-brcmstb-l2.o +obj-$(CONFIG_KEYSTONE_IRQ) += irq-keystone.o diff --git a/drivers/irqchip/irq-keystone.c b/drivers/irqchip/irq-keystone.c new file mode 100644 index 000000000000..fea26bcfd4ea --- /dev/null +++ b/drivers/irqchip/irq-keystone.c @@ -0,0 +1,232 @@ +/* + * Texas Instruments Keystone IRQ controller IP driver + * + * Copyright (C) 2014 Texas Instruments, Inc. + * Author: Sajesh Kumar Saran + * Grygorii Strashko + * + * 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. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "irqchip.h" + + +/* The source ID bits start from 4 to 31 (total 28 bits)*/ +#define BIT_OFS 4 +#define KEYSTONE_N_IRQ (32 - BIT_OFS) + +struct keystone_irq_device { + struct device *dev; + struct irq_chip chip; + u32 mask; + u32 irq; + struct irq_domain *irqd; + struct regmap *devctrl_regs; + u32 devctrl_offset; +}; + +static inline u32 keystone_irq_readl(struct keystone_irq_device *kirq) +{ + int ret; + u32 val = 0; + + ret = regmap_read(kirq->devctrl_regs, kirq->devctrl_offset, &val); + if (ret < 0) + dev_dbg(kirq->dev, "irq read failed ret(%d)\n", ret); + return val; +} + +static inline void +keystone_irq_writel(struct keystone_irq_device *kirq, u32 value) +{ + int ret; + + ret = regmap_write(kirq->devctrl_regs, kirq->devctrl_offset, value); + if (ret < 0) + dev_dbg(kirq->dev, "irq write failed ret(%d)\n", ret); +} + +static void keystone_irq_setmask(struct irq_data *d) +{ + struct keystone_irq_device *kirq = irq_data_get_irq_chip_data(d); + + kirq->mask |= BIT(d->hwirq); + dev_dbg(kirq->dev, "mask %lu [%x]\n", d->hwirq, kirq->mask); +} + +static void keystone_irq_unmask(struct irq_data *d) +{ + struct keystone_irq_device *kirq = irq_data_get_irq_chip_data(d); + + kirq->mask &= ~BIT(d->hwirq); + dev_dbg(kirq->dev, "unmask %lu [%x]\n", d->hwirq, kirq->mask); +} + +static void keystone_irq_ack(struct irq_data *d) +{ + /* nothing to do here */ +} + +static void keystone_irq_handler(unsigned irq, struct irq_desc *desc) +{ + struct keystone_irq_device *kirq = irq_desc_get_handler_data(desc); + unsigned long pending; + int src, virq; + + dev_dbg(kirq->dev, "start irq %d\n", irq); + + chained_irq_enter(irq_desc_get_chip(desc), desc); + + pending = keystone_irq_readl(kirq); + keystone_irq_writel(kirq, pending); + + dev_dbg(kirq->dev, "pending 0x%lx, mask 0x%x\n", pending, kirq->mask); + + pending = (pending >> BIT_OFS) & ~kirq->mask; + + dev_dbg(kirq->dev, "pending after mask 0x%lx\n", pending); + + for (src = 0; src < KEYSTONE_N_IRQ; src++) { + if (BIT(src) & pending) { + virq = irq_find_mapping(kirq->irqd, src); + dev_dbg(kirq->dev, "dispatch bit %d, virq %d\n", + src, virq); + if (!virq) + dev_warn(kirq->dev, "sporious irq detected hwirq %d, virq %d\n", + src, virq); + generic_handle_irq(virq); + } + } + + chained_irq_exit(irq_desc_get_chip(desc), desc); + + dev_dbg(kirq->dev, "end irq %d\n", irq); +} + +static int keystone_irq_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + struct keystone_irq_device *kirq = h->host_data; + + irq_set_chip_data(virq, kirq); + irq_set_chip_and_handler(virq, &kirq->chip, handle_level_irq); + set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); + return 0; +} + +static struct irq_domain_ops keystone_irq_ops = { + .map = keystone_irq_map, + .xlate = irq_domain_xlate_onecell, +}; + +static int keystone_irq_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct keystone_irq_device *kirq; + int ret; + + if (np == NULL) + return -EINVAL; + + kirq = devm_kzalloc(dev, sizeof(*kirq), GFP_KERNEL); + if (!kirq) + return -ENOMEM; + + kirq->devctrl_regs = + syscon_regmap_lookup_by_phandle(np, "ti,syscon-dev"); + if (IS_ERR(kirq->devctrl_regs)) + return PTR_ERR(kirq->devctrl_regs); + + ret = of_property_read_u32_index(np, "ti,syscon-dev", 1, + &kirq->devctrl_offset); + if (ret) { + dev_err(dev, "couldn't read the devctrl_offset offset!\n"); + return ret; + } + + kirq->irq = platform_get_irq(pdev, 0); + if (kirq->irq < 0) { + dev_err(dev, "no irq resource %d\n", kirq->irq); + return kirq->irq; + } + + kirq->dev = dev; + kirq->mask = ~0x0; + kirq->chip.name = "keystone-irq"; + kirq->chip.irq_ack = keystone_irq_ack; + kirq->chip.irq_mask = keystone_irq_setmask; + kirq->chip.irq_unmask = keystone_irq_unmask; + + kirq->irqd = irq_domain_add_linear(np, KEYSTONE_N_IRQ, + &keystone_irq_ops, kirq); + if (!kirq->irqd) { + dev_err(dev, "IRQ domain registration failed\n"); + return -ENODEV; + } + + platform_set_drvdata(pdev, kirq); + + irq_set_chained_handler(kirq->irq, keystone_irq_handler); + irq_set_handler_data(kirq->irq, kirq); + + /* clear all source bits */ + keystone_irq_writel(kirq, ~0x0); + + dev_info(dev, "irqchip registered, nr_irqs %u\n", KEYSTONE_N_IRQ); + + return 0; +} + +static int keystone_irq_remove(struct platform_device *pdev) +{ + struct keystone_irq_device *kirq = platform_get_drvdata(pdev); + int hwirq; + + for (hwirq = 0; hwirq < KEYSTONE_N_IRQ; hwirq++) + irq_dispose_mapping(irq_find_mapping(kirq->irqd, hwirq)); + + irq_domain_remove(kirq->irqd); + return 0; +} + +static const struct of_device_id keystone_irq_dt_ids[] = { + { .compatible = "ti,keystone-irq", }, + {}, +}; +MODULE_DEVICE_TABLE(of, keystone_irq_dt_ids); + +static struct platform_driver keystone_irq_device_driver = { + .probe = keystone_irq_probe, + .remove = keystone_irq_remove, + .driver = { + .name = "keystone_irq", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(keystone_irq_dt_ids), + } +}; + +module_platform_driver(keystone_irq_device_driver); + +MODULE_AUTHOR("Texas Instruments"); +MODULE_AUTHOR("Sajesh Kumar Saran"); +MODULE_AUTHOR("Grygorii Strashko"); +MODULE_DESCRIPTION("Keystone IRQ chip"); +MODULE_LICENSE("GPL v2"); -- GitLab From 9a1cb47112eff140659f04c261ca19fb1f002607 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 10 Mar 2014 13:03:10 -0700 Subject: [PATCH 0831/9167] x86, boot: Use the usual -y -n mechanism for objects in vmlinux Switch VMLINUX_OBJS to vmlinux-objs-y, to eliminate Makefile conditionals in favor of vmlinux-objs-$(CONFIG_*) constructs. This does not change the generated code at all. Signed-off-by: Josh Triplett --- arch/x86/boot/compressed/Makefile | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 7a801a310e37..80709a98cc9c 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -26,18 +26,16 @@ LDFLAGS_vmlinux := -T hostprogs-y := mkpiggy HOST_EXTRACFLAGS += -I$(srctree)/tools/include -VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ +vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \ $(obj)/piggy.o $(obj)/cpuflags.o $(obj)/aslr.o $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone -ifeq ($(CONFIG_EFI_STUB), y) - VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \ - $(objtree)/drivers/firmware/efi/libstub/lib.a -endif +vmlinux-objs-$(CONFIG_EFI_STUB) += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \ + $(objtree)/drivers/firmware/efi/libstub/lib.a -$(obj)/vmlinux: $(VMLINUX_OBJS) FORCE +$(obj)/vmlinux: $(vmlinux-objs-y) FORCE $(call if_changed,ld) @: @@ -45,7 +43,7 @@ OBJCOPYFLAGS_vmlinux.bin := -R .comment -S $(obj)/vmlinux.bin: vmlinux FORCE $(call if_changed,objcopy) -targets += $(patsubst $(obj)/%,%,$(VMLINUX_OBJS)) vmlinux.bin.all vmlinux.relocs +targets += $(patsubst $(obj)/%,%,$(vmlinux-objs-y)) vmlinux.bin.all vmlinux.relocs CMD_RELOCS = arch/x86/tools/relocs quiet_cmd_relocs = RELOCS $@ -- GitLab From 9e6abd2a98ca599e0efb8c46acc17f17dc1a6fe9 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 10 Mar 2014 13:11:26 -0700 Subject: [PATCH 0832/9167] x86, boot: Don't compile aslr.c when !CONFIG_RANDOMIZE_BASE All the code in aslr.c gets compiled out if !CONFIG_RANDOMIZE_BASE, but aslr.o itself still gets compiled in. Eliminate it from the compile entirely in that case. This does not change the generated code at all, in either case. Signed-off-by: Josh Triplett --- arch/x86/boot/compressed/Makefile | 4 +++- arch/x86/boot/compressed/aslr.c | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 80709a98cc9c..3b9b00c68fd8 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -28,7 +28,9 @@ HOST_EXTRACFLAGS += -I$(srctree)/tools/include vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \ - $(obj)/piggy.o $(obj)/cpuflags.o $(obj)/aslr.o + $(obj)/piggy.o $(obj)/cpuflags.o + +vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/aslr.o $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c index fc6091abedb7..913c999b0045 100644 --- a/arch/x86/boot/compressed/aslr.c +++ b/arch/x86/boot/compressed/aslr.c @@ -1,6 +1,5 @@ #include "misc.h" -#ifdef CONFIG_RANDOMIZE_BASE #include #include #include @@ -320,5 +319,3 @@ unsigned char *choose_kernel_location(unsigned char *input, out: return (unsigned char *)choice; } - -#endif /* CONFIG_RANDOMIZE_BASE */ -- GitLab From 3afed06a355b5525d9a87bcb76567ef2e2e7b3a2 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 10 Mar 2014 13:26:10 -0700 Subject: [PATCH 0833/9167] x86, boot: Don't compile early_serial_console.c when !CONFIG_EARLY_PRINTK All the code in early_serial_console.c gets compiled out if !CONFIG_EARLY_PRINTK, but early_serial_console.o itself still gets compiled in. Eliminate it from the compile entirely in that case. This does not change the generated code at all, in either case. Signed-off-by: Josh Triplett --- arch/x86/boot/compressed/Makefile | 3 ++- arch/x86/boot/compressed/early_serial_console.c | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 3b9b00c68fd8..20db5b3609de 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -27,9 +27,10 @@ hostprogs-y := mkpiggy HOST_EXTRACFLAGS += -I$(srctree)/tools/include vmlinux-objs-y := $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ - $(obj)/string.o $(obj)/cmdline.o $(obj)/early_serial_console.o \ + $(obj)/string.o $(obj)/cmdline.o \ $(obj)/piggy.o $(obj)/cpuflags.o +vmlinux-objs-$(CONFIG_EARLY_PRINTK) += $(obj)/early_serial_console.o vmlinux-objs-$(CONFIG_RANDOMIZE_BASE) += $(obj)/aslr.o $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone diff --git a/arch/x86/boot/compressed/early_serial_console.c b/arch/x86/boot/compressed/early_serial_console.c index d3d003cb5481..261e81fb9582 100644 --- a/arch/x86/boot/compressed/early_serial_console.c +++ b/arch/x86/boot/compressed/early_serial_console.c @@ -1,9 +1,5 @@ #include "misc.h" -#ifdef CONFIG_EARLY_PRINTK - int early_serial_base; #include "../early_serial_console.c" - -#endif -- GitLab From 39f838e06f46576694d425ac30fe8ff1e214fc0b Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 30 Oct 2013 14:21:53 +0000 Subject: [PATCH 0834/9167] x86: Drop support for /proc files when !CONFIG_PROC_FS arch/x86/kernel/cpu/proc.c only exists to support files in /proc; omit that file when compiling without CONFIG_PROC_FS. Saves 645 additional bytes on 32-bit x86 when !CONFIG_PROC_FS: add/remove: 0/5 grow/shrink: 0/0 up/down: 0/-645 (-645) function old new delta c_stop 1 - -1 c_next 11 - -11 cpuinfo_op 16 - -16 c_start 24 - -24 show_cpuinfo 593 - -593 Signed-off-by: Josh Triplett --- arch/x86/kernel/cpu/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 7fd54f09b011..64038d842c57 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -13,10 +13,12 @@ nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_common.o := $(nostackp) obj-y := intel_cacheinfo.o scattered.o topology.o -obj-y += proc.o capflags.o powerflags.o common.o +obj-y += capflags.o powerflags.o common.o obj-y += rdrand.o obj-y += match.o +obj-$(CONFIG_PROC_FS) += proc.o + obj-$(CONFIG_X86_32) += bugs.o obj-$(CONFIG_X86_64) += bugs_64.o -- GitLab From 9def39be4e960917fcb80514ff23651f9ec97193 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Wed, 30 Oct 2013 08:09:45 -0700 Subject: [PATCH 0835/9167] x86: Support compiling out human-friendly processor feature names The table mapping CPUID bits to human-readable strings takes up a non-trivial amount of space, and only exists to support /proc/cpuinfo and a couple of kernel messages. Since programs depend on the format of /proc/cpuinfo, force inclusion of the table when building with /proc support; otherwise, support omitting that table to save space, in which case the kernel messages will print features numerically instead. In addition to saving 1408 bytes out of vmlinux, this also saves 1373 bytes out of the uncompressed setup code, which contributes directly to the size of bzImage. Signed-off-by: Josh Triplett --- arch/x86/Kconfig | 12 ++++++ arch/x86/boot/Makefile | 7 +++- arch/x86/boot/cpu.c | 68 +++++++++++++++++++------------ arch/x86/include/asm/cpufeature.h | 7 ++++ arch/x86/kernel/cpu/Makefile | 5 ++- arch/x86/kernel/cpu/common.c | 4 +- 6 files changed, 71 insertions(+), 32 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 5d0bf1aa9dcb..a11f27c4266a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -136,6 +136,7 @@ config X86 select HAVE_ACPI_APEI if ACPI select HAVE_ACPI_APEI_NMI if ACPI select ACPI_LEGACY_TABLES_LOOKUP if ACPI + select X86_FEATURE_NAMES if PROC_FS config INSTRUCTION_DECODER def_bool y @@ -313,6 +314,17 @@ config SMP If you don't know what to do here, say N. +config X86_FEATURE_NAMES + bool "Processor feature human-readable names" if EMBEDDED + default y + ---help--- + This option compiles in a table of x86 feature bits and corresponding + names. This is required to support /proc/cpuinfo and a few kernel + messages. You can disable this to save space, at the expense of + making those few kernel messages show numeric feature bits instead. + + If in doubt, say Y. + config X86_X2APIC bool "Support x2apic" depends on X86_LOCAL_APIC && X86_64 && IRQ_REMAP diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index dbe8dd2fe247..5b016e2498f3 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile @@ -35,19 +35,22 @@ setup-y += video-vesa.o setup-y += video-bios.o targets += $(setup-y) -hostprogs-y := mkcpustr tools/build +hostprogs-y := tools/build +hostprogs-$(CONFIG_X86_FEATURE_NAMES) += mkcpustr HOST_EXTRACFLAGS += -I$(srctree)/tools/include \ -include include/generated/autoconf.h \ -D__EXPORTED_HEADERS__ +ifdef CONFIG_X86_FEATURE_NAMES $(obj)/cpu.o: $(obj)/cpustr.h quiet_cmd_cpustr = CPUSTR $@ cmd_cpustr = $(obj)/mkcpustr > $@ -targets += cpustr.h +targets += cpustr.h $(obj)/cpustr.h: $(obj)/mkcpustr FORCE $(call if_changed,cpustr) +endif # --------------------------------------------------------------------------- diff --git a/arch/x86/boot/cpu.c b/arch/x86/boot/cpu.c index 6ec6bb6e9957..29207f69ae8c 100644 --- a/arch/x86/boot/cpu.c +++ b/arch/x86/boot/cpu.c @@ -16,7 +16,9 @@ */ #include "boot.h" +#ifdef CONFIG_X86_FEATURE_NAMES #include "cpustr.h" +#endif static char *cpu_name(int level) { @@ -32,11 +34,48 @@ static char *cpu_name(int level) } } +static void show_cap_strs(u32 *err_flags) +{ + int i, j; +#ifdef CONFIG_X86_FEATURE_NAMES + const unsigned char *msg_strs = (const unsigned char *)x86_cap_strs; + for (i = 0; i < NCAPINTS; i++) { + u32 e = err_flags[i]; + for (j = 0; j < 32; j++) { + if (msg_strs[0] < i || + (msg_strs[0] == i && msg_strs[1] < j)) { + /* Skip to the next string */ + msg_strs += 2; + while (*msg_strs++) + ; + } + if (e & 1) { + if (msg_strs[0] == i && + msg_strs[1] == j && + msg_strs[2]) + printf("%s ", msg_strs+2); + else + printf("%d:%d ", i, j); + } + e >>= 1; + } + } +#else + for (i = 0; i < NCAPINTS; i++) { + u32 e = err_flags[i]; + for (j = 0; j < 32; j++) { + if (e & 1) + printf("%d:%d ", i, j); + e >>= 1; + } + } +#endif +} + int validate_cpu(void) { u32 *err_flags; int cpu_level, req_level; - const unsigned char *msg_strs; check_cpu(&cpu_level, &req_level, &err_flags); @@ -49,34 +88,9 @@ int validate_cpu(void) } if (err_flags) { - int i, j; puts("This kernel requires the following features " "not present on the CPU:\n"); - - msg_strs = (const unsigned char *)x86_cap_strs; - - for (i = 0; i < NCAPINTS; i++) { - u32 e = err_flags[i]; - - for (j = 0; j < 32; j++) { - if (msg_strs[0] < i || - (msg_strs[0] == i && msg_strs[1] < j)) { - /* Skip to the next string */ - msg_strs += 2; - while (*msg_strs++) - ; - } - if (e & 1) { - if (msg_strs[0] == i && - msg_strs[1] == j && - msg_strs[2]) - printf("%s ", msg_strs+2); - else - printf("%d:%d ", i, j); - } - e >>= 1; - } - } + show_cap_strs(err_flags); putchar('\n'); return -1; } else { diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index bb9b258d60e7..516903b98e06 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h @@ -250,8 +250,15 @@ #include #include +#ifdef CONFIG_X86_FEATURE_NAMES extern const char * const x86_cap_flags[NCAPINTS*32]; extern const char * const x86_power_flags[32]; +#define X86_CAP_FMT "%s" +#define x86_cap_flag(flag) x86_cap_flags[flag] +#else +#define X86_CAP_FMT "%d:%d" +#define x86_cap_flag(flag) ((flag) >> 5), ((flag) & 31) +#endif /* * In order to save room, we index into this array by doing diff --git a/arch/x86/kernel/cpu/Makefile b/arch/x86/kernel/cpu/Makefile index 64038d842c57..77dcab277710 100644 --- a/arch/x86/kernel/cpu/Makefile +++ b/arch/x86/kernel/cpu/Makefile @@ -13,11 +13,12 @@ nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_common.o := $(nostackp) obj-y := intel_cacheinfo.o scattered.o topology.o -obj-y += capflags.o powerflags.o common.o +obj-y += common.o obj-y += rdrand.o obj-y += match.o obj-$(CONFIG_PROC_FS) += proc.o +obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o obj-$(CONFIG_X86_32) += bugs.o obj-$(CONFIG_X86_64) += bugs_64.o @@ -50,6 +51,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += perfctr-watchdog.o perf_event_amd_ibs.o obj-$(CONFIG_HYPERVISOR_GUEST) += vmware.o hypervisor.o mshyperv.o +ifdef CONFIG_X86_FEATURE_NAMES quiet_cmd_mkcapflags = MKCAP $@ cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@ @@ -58,3 +60,4 @@ cpufeature = $(src)/../../include/asm/cpufeature.h targets += capflags.c $(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE $(call if_changed,mkcapflags) +endif diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index e4ab2b42bd6f..c649f236e288 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -346,8 +346,8 @@ static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn) continue; printk(KERN_WARNING - "CPU: CPU feature %s disabled, no CPUID level 0x%x\n", - x86_cap_flags[df->feature], df->level); + "CPU: CPU feature " X86_CAP_FMT " disabled, no CPUID level 0x%x\n", + x86_cap_flag(df->feature), df->level); } } -- GitLab From 4ade6feb52262eae0c40d6714e3446bfa4d19a5f Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sun, 17 Aug 2014 17:38:24 -0500 Subject: [PATCH 0836/9167] net: can: use kbuild magic to inherit debug settings No need to manually copy debug settings into subdir Makefiles. kbuild has a mechanism for inheriting, so let's use it. Signed-off-by: Wolfram Sang Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Makefile | 2 +- drivers/net/can/c_can/Makefile | 2 -- drivers/net/can/cc770/Makefile | 2 -- drivers/net/can/mscan/Makefile | 2 -- drivers/net/can/sja1000/Makefile | 2 -- drivers/net/can/softing/Makefile | 2 -- drivers/net/can/spi/Makefile | 2 -- drivers/net/can/usb/Makefile | 2 -- 8 files changed, 1 insertion(+), 15 deletions(-) diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 1697f22353a9..14b4c2af1e5d 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -28,4 +28,4 @@ obj-$(CONFIG_CAN_GRCAN) += grcan.o obj-$(CONFIG_CAN_RCAR) += rcar_can.o obj-$(CONFIG_CAN_XILINXCAN) += xilinx_can.o -ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG +subdir-ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/c_can/Makefile b/drivers/net/can/c_can/Makefile index ad1cc842170a..9fdc678b5b37 100644 --- a/drivers/net/can/c_can/Makefile +++ b/drivers/net/can/c_can/Makefile @@ -5,5 +5,3 @@ obj-$(CONFIG_CAN_C_CAN) += c_can.o obj-$(CONFIG_CAN_C_CAN_PLATFORM) += c_can_platform.o obj-$(CONFIG_CAN_C_CAN_PCI) += c_can_pci.o - -ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile index 9fb8321b33eb..8657f879ae19 100644 --- a/drivers/net/can/cc770/Makefile +++ b/drivers/net/can/cc770/Makefile @@ -5,5 +5,3 @@ obj-$(CONFIG_CAN_CC770) += cc770.o obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o obj-$(CONFIG_CAN_CC770_PLATFORM) += cc770_platform.o - -ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/mscan/Makefile b/drivers/net/can/mscan/Makefile index c9fab17cd8b4..58903b45f5fb 100644 --- a/drivers/net/can/mscan/Makefile +++ b/drivers/net/can/mscan/Makefile @@ -1,5 +1,3 @@ obj-$(CONFIG_CAN_MPC5XXX) += mscan-mpc5xxx.o mscan-mpc5xxx-objs := mscan.o mpc5xxx_can.o - -ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/sja1000/Makefile b/drivers/net/can/sja1000/Makefile index 531d5fcc97e5..be11ddd11b87 100644 --- a/drivers/net/can/sja1000/Makefile +++ b/drivers/net/can/sja1000/Makefile @@ -12,5 +12,3 @@ obj-$(CONFIG_CAN_PEAK_PCMCIA) += peak_pcmcia.o obj-$(CONFIG_CAN_PEAK_PCI) += peak_pci.o obj-$(CONFIG_CAN_PLX_PCI) += plx_pci.o obj-$(CONFIG_CAN_TSCAN1) += tscan1.o - -ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/softing/Makefile b/drivers/net/can/softing/Makefile index c5e5016c742e..a23da492dad5 100644 --- a/drivers/net/can/softing/Makefile +++ b/drivers/net/can/softing/Makefile @@ -2,5 +2,3 @@ softing-y := softing_main.o softing_fw.o obj-$(CONFIG_CAN_SOFTING) += softing.o obj-$(CONFIG_CAN_SOFTING_CS) += softing_cs.o - -ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile index 90bcacffbc65..0e86040cdd8c 100644 --- a/drivers/net/can/spi/Makefile +++ b/drivers/net/can/spi/Makefile @@ -4,5 +4,3 @@ obj-$(CONFIG_CAN_MCP251X) += mcp251x.o - -ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile index 7b9a393b1ac8..a64cf983fb87 100644 --- a/drivers/net/can/usb/Makefile +++ b/drivers/net/can/usb/Makefile @@ -8,5 +8,3 @@ obj-$(CONFIG_CAN_GS_USB) += gs_usb.o obj-$(CONFIG_CAN_KVASER_USB) += kvaser_usb.o obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/ obj-$(CONFIG_CAN_8DEV_USB) += usb_8dev.o - -ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG -- GitLab From ec56acfef2af184ca485ffeba16adbd56c110c94 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 15 Jul 2014 14:56:20 +0200 Subject: [PATCH 0837/9167] can: flexcan: flexcan_get_berr_counter(): switch on clocks before accessing ecr register The funcion flexcan_get_berr_counter() may be called from userspace even if the interface is down, this the clocks are disabled. This patch switches on the clocks before accessing the ecr register. Reported-by: Ashutosh Singh Signed-off-by: Stefan Agner Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index f425ec2c7839..6bfe24aefea0 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -378,8 +378,9 @@ static int flexcan_chip_softreset(struct flexcan_priv *priv) return 0; } -static int flexcan_get_berr_counter(const struct net_device *dev, - struct can_berr_counter *bec) + +static int __flexcan_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) { const struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_regs __iomem *regs = priv->base; @@ -391,6 +392,29 @@ static int flexcan_get_berr_counter(const struct net_device *dev, return 0; } +static int flexcan_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + const struct flexcan_priv *priv = netdev_priv(dev); + int err; + + err = clk_prepare_enable(priv->clk_ipg); + if (err) + return err; + + err = clk_prepare_enable(priv->clk_per); + if (err) + goto out_disable_ipg; + + err = __flexcan_get_berr_counter(dev, bec); + + clk_disable_unprepare(priv->clk_per); + out_disable_ipg: + clk_disable_unprepare(priv->clk_ipg); + + return err; +} + static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) { const struct flexcan_priv *priv = netdev_priv(dev); @@ -503,7 +527,7 @@ static void do_state(struct net_device *dev, struct flexcan_priv *priv = netdev_priv(dev); struct can_berr_counter bec; - flexcan_get_berr_counter(dev, &bec); + __flexcan_get_berr_counter(dev, &bec); switch (priv->can.state) { case CAN_STATE_ERROR_ACTIVE: -- GitLab From cdce844865bea6869b34bacc98af3711774f5bb5 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 15 Jul 2014 14:56:21 +0200 Subject: [PATCH 0838/9167] can: flexcan: add vf610 support for FlexCAN Extend FlexCAN driver to support Vybrid. Vybrids variant of the IP has ECC support which is controlled through the memory error control register (MECR). There is also an errata which leads to false positive error detections (ID e5295). This patch disables the memory error detection completely. Signed-off-by: Stefan Agner Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 81 ++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 10 deletions(-) diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 6bfe24aefea0..ff1beb92a985 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -92,6 +92,27 @@ #define FLEXCAN_CTRL_ERR_ALL \ (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) +/* FLEXCAN control register 2 (CTRL2) bits */ +#define FLEXCAN_CRL2_ECRWRE BIT(29) +#define FLEXCAN_CRL2_WRMFRZ BIT(28) +#define FLEXCAN_CRL2_RFFN(x) (((x) & 0x0f) << 24) +#define FLEXCAN_CRL2_TASD(x) (((x) & 0x1f) << 19) +#define FLEXCAN_CRL2_MRP BIT(18) +#define FLEXCAN_CRL2_RRS BIT(17) +#define FLEXCAN_CRL2_EACEN BIT(16) + +/* FLEXCAN memory error control register (MECR) bits */ +#define FLEXCAN_MECR_ECRWRDIS BIT(31) +#define FLEXCAN_MECR_HANCEI_MSK BIT(19) +#define FLEXCAN_MECR_FANCEI_MSK BIT(18) +#define FLEXCAN_MECR_CEI_MSK BIT(16) +#define FLEXCAN_MECR_HAERRIE BIT(15) +#define FLEXCAN_MECR_FAERRIE BIT(14) +#define FLEXCAN_MECR_EXTERRIE BIT(13) +#define FLEXCAN_MECR_RERRDIS BIT(9) +#define FLEXCAN_MECR_ECCDIS BIT(8) +#define FLEXCAN_MECR_NCEFAFRZ BIT(7) + /* FLEXCAN error and status register (ESR) bits */ #define FLEXCAN_ESR_TWRN_INT BIT(17) #define FLEXCAN_ESR_RWRN_INT BIT(16) @@ -150,18 +171,20 @@ * FLEXCAN hardware feature flags * * Below is some version info we got: - * SOC Version IP-Version Glitch- [TR]WRN_INT - * Filter? connected? - * MX25 FlexCAN2 03.00.00.00 no no - * MX28 FlexCAN2 03.00.04.00 yes yes - * MX35 FlexCAN2 03.00.00.00 no no - * MX53 FlexCAN2 03.00.00.00 yes no - * MX6s FlexCAN3 10.00.12.00 yes yes + * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err + * Filter? connected? detection + * MX25 FlexCAN2 03.00.00.00 no no no + * MX28 FlexCAN2 03.00.04.00 yes yes no + * MX35 FlexCAN2 03.00.00.00 no no no + * MX53 FlexCAN2 03.00.00.00 yes no no + * MX6s FlexCAN3 10.00.12.00 yes yes no + * VF610 FlexCAN3 ? no yes yes * * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. */ #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ +#define FLEXCAN_HAS_MECR_FEATURES BIT(3) /* Memory error detection */ /* Structure of the message buffer */ struct flexcan_mb { @@ -192,8 +215,17 @@ struct flexcan_regs { u32 crcr; /* 0x44 */ u32 rxfgmask; /* 0x48 */ u32 rxfir; /* 0x4c */ - u32 _reserved3[12]; - struct flexcan_mb cantxfg[64]; + u32 _reserved3[12]; /* 0x50 */ + struct flexcan_mb cantxfg[64]; /* 0x80 */ + u32 _reserved4[408]; + u32 mecr; /* 0xae0 */ + u32 erriar; /* 0xae4 */ + u32 erridpr; /* 0xae8 */ + u32 errippr; /* 0xaec */ + u32 rerrar; /* 0xaf0 */ + u32 rerrdr; /* 0xaf4 */ + u32 rerrsynr; /* 0xaf8 */ + u32 errsr; /* 0xafc */ }; struct flexcan_devtype_data { @@ -223,6 +255,9 @@ static struct flexcan_devtype_data fsl_imx28_devtype_data; static struct flexcan_devtype_data fsl_imx6q_devtype_data = { .features = FLEXCAN_HAS_V10_FEATURES, }; +static struct flexcan_devtype_data fsl_vf610_devtype_data = { + .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_MECR_FEATURES, +}; static const struct can_bittiming_const flexcan_bittiming_const = { .name = DRV_NAME, @@ -817,7 +852,7 @@ static int flexcan_chip_start(struct net_device *dev) struct flexcan_priv *priv = netdev_priv(dev); struct flexcan_regs __iomem *regs = priv->base; int err; - u32 reg_mcr, reg_ctrl; + u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr; /* enable module */ err = flexcan_chip_enable(priv); @@ -894,6 +929,31 @@ static int flexcan_chip_start(struct net_device *dev) if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) flexcan_write(0x0, ®s->rxfgmask); + /* + * On Vybrid, disable memory error detection interrupts + * and freeze mode. + * This also works around errata e5295 which generates + * false positive memory errors and put the device in + * freeze mode. + */ + if (priv->devtype_data->features & FLEXCAN_HAS_MECR_FEATURES) { + /* + * Follow the protocol as described in "Detection + * and Correction of Memory Errors" to write to + * MECR register + */ + reg_crl2 = flexcan_read(®s->crl2); + reg_crl2 |= FLEXCAN_CRL2_ECRWRE; + flexcan_write(reg_crl2, ®s->crl2); + + reg_mecr = flexcan_read(®s->mecr); + reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; + flexcan_write(reg_mecr, ®s->mecr); + reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK | + FLEXCAN_MECR_FANCEI_MSK); + flexcan_write(reg_mecr, ®s->mecr); + } + err = flexcan_transceiver_enable(priv); if (err) goto out_chip_disable; @@ -1104,6 +1164,7 @@ static const struct of_device_id flexcan_of_match[] = { { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, + { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, flexcan_of_match); -- GitLab From e35430807dad7f89e2a27e70ea1d6c29819cb749 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 16 Jul 2014 17:30:49 +0800 Subject: [PATCH 0839/9167] can: m_can: add device tree binding documentation add M_CAN device tree binding documentation Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: Mark Rutland Cc: Oliver Hartkopp Cc: Varka Bhadram Signed-off-by: Dong Aisheng Reviewed-by: Varka Bhadram Signed-off-by: Marc Kleine-Budde --- .../devicetree/bindings/net/can/m_can.txt | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/can/m_can.txt diff --git a/Documentation/devicetree/bindings/net/can/m_can.txt b/Documentation/devicetree/bindings/net/can/m_can.txt new file mode 100644 index 000000000000..9e331777c203 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/m_can.txt @@ -0,0 +1,67 @@ +Bosch MCAN controller Device Tree Bindings +------------------------------------------------- + +Required properties: +- compatible : Should be "bosch,m_can" for M_CAN controllers +- reg : physical base address and size of the M_CAN + registers map and Message RAM +- reg-names : Should be "m_can" and "message_ram" +- interrupts : Should be the interrupt number of M_CAN interrupt + line 0 and line 1, could be same if sharing + the same interrupt. +- interrupt-names : Should contain "int0" and "int1" +- clocks : Clocks used by controller, should be host clock + and CAN clock. +- clock-names : Should contain "hclk" and "cclk" +- pinctrl- : Pinctrl states as described in bindings/pinctrl/pinctrl-bindings.txt +- pinctrl-names : Names corresponding to the numbered pinctrl states +- bosch,mram-cfg : Message RAM configuration data. + Multiple M_CAN instances can share the same Message + RAM and each element(e.g Rx FIFO or Tx Buffer and etc) + number in Message RAM is also configurable, + so this property is telling driver how the shared or + private Message RAM are used by this M_CAN controller. + + The format should be as follows: + + The 'offset' is an address offset of the Message RAM + where the following elements start from. This is + usually set to 0x0 if you're using a private Message + RAM. The remain cells are used to specify how many + elements are used for each FIFO/Buffer. + + M_CAN includes the following elements according to user manual: + 11-bit Filter 0-128 elements / 0-128 words + 29-bit Filter 0-64 elements / 0-128 words + Rx FIFO 0 0-64 elements / 0-1152 words + Rx FIFO 1 0-64 elements / 0-1152 words + Rx Buffers 0-64 elements / 0-1152 words + Tx Event FIFO 0-32 elements / 0-64 words + Tx Buffers 0-32 elements / 0-576 words + + Please refer to 2.4.1 Message RAM Configuration in + Bosch M_CAN user manual for details. + +Example: +SoC dtsi: +m_can1: can@020e8000 { + compatible = "bosch,m_can"; + reg = <0x020e8000 0x4000>, <0x02298000 0x4000>; + reg-names = "m_can", "message_ram"; + interrupts = <0 114 0x04>, + <0 114 0x04>; + interrupt-names = "int0", "int1"; + clocks = <&clks IMX6SX_CLK_CANFD>, + <&clks IMX6SX_CLK_CANFD>; + clock-names = "hclk", "cclk"; + bosch,mram-cfg = <0x0 0 0 32 0 0 0 1>; + status = "disabled"; +}; + +Board dts: +&m_can1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_m_can1>; + status = "enabled"; +}; -- GitLab From e0d1f4816f2a7e311321db40ce69fbb1a4b1f1cf Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Wed, 16 Jul 2014 17:30:50 +0800 Subject: [PATCH 0840/9167] can: m_can: add Bosch M_CAN controller support The patch adds the basic CAN TX/RX function support for Bosch M_CAN controller. For TX, only one dedicated tx buffer is used for sending data. For RX, RXFIFO 0 is used for receiving data to avoid overflow. Rx FIFO 1 and Rx Buffers are not used currently, as well as Tx Event FIFO. Due to the message ram can be shared by multi m_can instances and the fifo element is configurable which is SoC dependant, the design is to parse the message ram related configuration data from device tree rather than hardcode define it in driver which can make the message ram sharing fully transparent to M_CAN controller driver, then we can gain better driver maintainability and future features upgrade. M_CAN also supports CANFD protocol features like data payload up to 64 bytes and bitrate switch at runtime, however, this patch still does not add the support for these features. Cc: Wolfgang Grandegger Cc: Marc Kleine-Budde Cc: Mark Rutland Cc: Oliver Hartkopp Cc: Varka Bhadram Signed-off-by: Dong Aisheng Reviewed-by: Varka Bhadram Signed-off-by: Fengguang Wu [mkl: Squahed semicolon cleanup by Fengguang Wu] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 2 + drivers/net/can/Makefile | 1 + drivers/net/can/m_can/Kconfig | 4 + drivers/net/can/m_can/Makefile | 5 + drivers/net/can/m_can/m_can.c | 1202 ++++++++++++++++++++++++++++++++ 5 files changed, 1214 insertions(+) create mode 100644 drivers/net/can/m_can/Kconfig create mode 100644 drivers/net/can/m_can/Makefile create mode 100644 drivers/net/can/m_can/m_can.c diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index 41688229c570..e78d6b32431d 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -143,6 +143,8 @@ source "drivers/net/can/sja1000/Kconfig" source "drivers/net/can/c_can/Kconfig" +source "drivers/net/can/m_can/Kconfig" + source "drivers/net/can/cc770/Kconfig" source "drivers/net/can/spi/Kconfig" diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile index 14b4c2af1e5d..fc9304143f44 100644 --- a/drivers/net/can/Makefile +++ b/drivers/net/can/Makefile @@ -17,6 +17,7 @@ obj-y += softing/ obj-$(CONFIG_CAN_SJA1000) += sja1000/ obj-$(CONFIG_CAN_MSCAN) += mscan/ obj-$(CONFIG_CAN_C_CAN) += c_can/ +obj-$(CONFIG_CAN_M_CAN) += m_can/ obj-$(CONFIG_CAN_CC770) += cc770/ obj-$(CONFIG_CAN_AT91) += at91_can.o obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o diff --git a/drivers/net/can/m_can/Kconfig b/drivers/net/can/m_can/Kconfig new file mode 100644 index 000000000000..fca5482c09ac --- /dev/null +++ b/drivers/net/can/m_can/Kconfig @@ -0,0 +1,4 @@ +config CAN_M_CAN + tristate "Bosch M_CAN devices" + ---help--- + Say Y here if you want to support for Bosch M_CAN controller. diff --git a/drivers/net/can/m_can/Makefile b/drivers/net/can/m_can/Makefile new file mode 100644 index 000000000000..8bbd7f24f5be --- /dev/null +++ b/drivers/net/can/m_can/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for the Bosch M_CAN controller driver. +# + +obj-$(CONFIG_CAN_M_CAN) += m_can.o diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c new file mode 100644 index 000000000000..10d571eaed85 --- /dev/null +++ b/drivers/net/can/m_can/m_can.c @@ -0,0 +1,1202 @@ +/* + * CAN bus driver for Bosch M_CAN controller + * + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * Dong Aisheng + * + * Bosch M_CAN user manual can be obtained from: + * http://www.bosch-semiconductors.de/media/pdf_1/ipmodules_1/m_can/ + * mcan_users_manual_v302.pdf + * + * 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 + +#include + +/* napi related */ +#define M_CAN_NAPI_WEIGHT 64 + +/* message ram configuration data length */ +#define MRAM_CFG_LEN 8 + +/* registers definition */ +enum m_can_reg { + M_CAN_CREL = 0x0, + M_CAN_ENDN = 0x4, + M_CAN_CUST = 0x8, + M_CAN_FBTP = 0xc, + M_CAN_TEST = 0x10, + M_CAN_RWD = 0x14, + M_CAN_CCCR = 0x18, + M_CAN_BTP = 0x1c, + M_CAN_TSCC = 0x20, + M_CAN_TSCV = 0x24, + M_CAN_TOCC = 0x28, + M_CAN_TOCV = 0x2c, + M_CAN_ECR = 0x40, + M_CAN_PSR = 0x44, + M_CAN_IR = 0x50, + M_CAN_IE = 0x54, + M_CAN_ILS = 0x58, + M_CAN_ILE = 0x5c, + M_CAN_GFC = 0x80, + M_CAN_SIDFC = 0x84, + M_CAN_XIDFC = 0x88, + M_CAN_XIDAM = 0x90, + M_CAN_HPMS = 0x94, + M_CAN_NDAT1 = 0x98, + M_CAN_NDAT2 = 0x9c, + M_CAN_RXF0C = 0xa0, + M_CAN_RXF0S = 0xa4, + M_CAN_RXF0A = 0xa8, + M_CAN_RXBC = 0xac, + M_CAN_RXF1C = 0xb0, + M_CAN_RXF1S = 0xb4, + M_CAN_RXF1A = 0xb8, + M_CAN_RXESC = 0xbc, + M_CAN_TXBC = 0xc0, + M_CAN_TXFQS = 0xc4, + M_CAN_TXESC = 0xc8, + M_CAN_TXBRP = 0xcc, + M_CAN_TXBAR = 0xd0, + M_CAN_TXBCR = 0xd4, + M_CAN_TXBTO = 0xd8, + M_CAN_TXBCF = 0xdc, + M_CAN_TXBTIE = 0xe0, + M_CAN_TXBCIE = 0xe4, + M_CAN_TXEFC = 0xf0, + M_CAN_TXEFS = 0xf4, + M_CAN_TXEFA = 0xf8, +}; + +/* m_can lec values */ +enum m_can_lec_type { + LEC_NO_ERROR = 0, + LEC_STUFF_ERROR, + LEC_FORM_ERROR, + LEC_ACK_ERROR, + LEC_BIT1_ERROR, + LEC_BIT0_ERROR, + LEC_CRC_ERROR, + LEC_UNUSED, +}; + +enum m_can_mram_cfg { + MRAM_SIDF = 0, + MRAM_XIDF, + MRAM_RXF0, + MRAM_RXF1, + MRAM_RXB, + MRAM_TXE, + MRAM_TXB, + MRAM_CFG_NUM, +}; + +/* Test Register (TEST) */ +#define TEST_LBCK BIT(4) + +/* CC Control Register(CCCR) */ +#define CCCR_TEST BIT(7) +#define CCCR_MON BIT(5) +#define CCCR_CCE BIT(1) +#define CCCR_INIT BIT(0) + +/* Bit Timing & Prescaler Register (BTP) */ +#define BTR_BRP_MASK 0x3ff +#define BTR_BRP_SHIFT 16 +#define BTR_TSEG1_SHIFT 8 +#define BTR_TSEG1_MASK (0x3f << BTR_TSEG1_SHIFT) +#define BTR_TSEG2_SHIFT 4 +#define BTR_TSEG2_MASK (0xf << BTR_TSEG2_SHIFT) +#define BTR_SJW_SHIFT 0 +#define BTR_SJW_MASK 0xf + +/* Error Counter Register(ECR) */ +#define ECR_RP BIT(15) +#define ECR_REC_SHIFT 8 +#define ECR_REC_MASK (0x7f << ECR_REC_SHIFT) +#define ECR_TEC_SHIFT 0 +#define ECR_TEC_MASK 0xff + +/* Protocol Status Register(PSR) */ +#define PSR_BO BIT(7) +#define PSR_EW BIT(6) +#define PSR_EP BIT(5) +#define PSR_LEC_MASK 0x7 + +/* Interrupt Register(IR) */ +#define IR_ALL_INT 0xffffffff +#define IR_STE BIT(31) +#define IR_FOE BIT(30) +#define IR_ACKE BIT(29) +#define IR_BE BIT(28) +#define IR_CRCE BIT(27) +#define IR_WDI BIT(26) +#define IR_BO BIT(25) +#define IR_EW BIT(24) +#define IR_EP BIT(23) +#define IR_ELO BIT(22) +#define IR_BEU BIT(21) +#define IR_BEC BIT(20) +#define IR_DRX BIT(19) +#define IR_TOO BIT(18) +#define IR_MRAF BIT(17) +#define IR_TSW BIT(16) +#define IR_TEFL BIT(15) +#define IR_TEFF BIT(14) +#define IR_TEFW BIT(13) +#define IR_TEFN BIT(12) +#define IR_TFE BIT(11) +#define IR_TCF BIT(10) +#define IR_TC BIT(9) +#define IR_HPM BIT(8) +#define IR_RF1L BIT(7) +#define IR_RF1F BIT(6) +#define IR_RF1W BIT(5) +#define IR_RF1N BIT(4) +#define IR_RF0L BIT(3) +#define IR_RF0F BIT(2) +#define IR_RF0W BIT(1) +#define IR_RF0N BIT(0) +#define IR_ERR_STATE (IR_BO | IR_EW | IR_EP) +#define IR_ERR_LEC (IR_STE | IR_FOE | IR_ACKE | IR_BE | IR_CRCE) +#define IR_ERR_BUS (IR_ERR_LEC | IR_WDI | IR_ELO | IR_BEU | \ + IR_BEC | IR_TOO | IR_MRAF | IR_TSW | IR_TEFL | \ + IR_RF1L | IR_RF0L) +#define IR_ERR_ALL (IR_ERR_STATE | IR_ERR_BUS) + +/* Interrupt Line Select (ILS) */ +#define ILS_ALL_INT0 0x0 +#define ILS_ALL_INT1 0xFFFFFFFF + +/* Interrupt Line Enable (ILE) */ +#define ILE_EINT0 BIT(0) +#define ILE_EINT1 BIT(1) + +/* Rx FIFO 0/1 Configuration (RXF0C/RXF1C) */ +#define RXFC_FWM_OFF 24 +#define RXFC_FWM_MASK 0x7f +#define RXFC_FWM_1 (1 << RXFC_FWM_OFF) +#define RXFC_FS_OFF 16 +#define RXFC_FS_MASK 0x7f + +/* Rx FIFO 0/1 Status (RXF0S/RXF1S) */ +#define RXFS_RFL BIT(25) +#define RXFS_FF BIT(24) +#define RXFS_FPI_OFF 16 +#define RXFS_FPI_MASK 0x3f0000 +#define RXFS_FGI_OFF 8 +#define RXFS_FGI_MASK 0x3f00 +#define RXFS_FFL_MASK 0x7f + +/* Rx Buffer / FIFO Element Size Configuration (RXESC) */ +#define M_CAN_RXESC_8BYTES 0x0 + +/* Tx Buffer Configuration(TXBC) */ +#define TXBC_NDTB_OFF 16 +#define TXBC_NDTB_MASK 0x3f + +/* Tx Buffer Element Size Configuration(TXESC) */ +#define TXESC_TBDS_8BYTES 0x0 + +/* Tx Event FIFO Con.guration (TXEFC) */ +#define TXEFC_EFS_OFF 16 +#define TXEFC_EFS_MASK 0x3f + +/* Message RAM Configuration (in bytes) */ +#define SIDF_ELEMENT_SIZE 4 +#define XIDF_ELEMENT_SIZE 8 +#define RXF0_ELEMENT_SIZE 16 +#define RXF1_ELEMENT_SIZE 16 +#define RXB_ELEMENT_SIZE 16 +#define TXE_ELEMENT_SIZE 8 +#define TXB_ELEMENT_SIZE 16 + +/* Message RAM Elements */ +#define M_CAN_FIFO_ID 0x0 +#define M_CAN_FIFO_DLC 0x4 +#define M_CAN_FIFO_DATA(n) (0x8 + ((n) << 2)) + +/* Rx Buffer Element */ +#define RX_BUF_ESI BIT(31) +#define RX_BUF_XTD BIT(30) +#define RX_BUF_RTR BIT(29) + +/* Tx Buffer Element */ +#define TX_BUF_XTD BIT(30) +#define TX_BUF_RTR BIT(29) + +/* address offset and element number for each FIFO/Buffer in the Message RAM */ +struct mram_cfg { + u16 off; + u8 num; +}; + +/* m_can private data structure */ +struct m_can_priv { + struct can_priv can; /* must be the first member */ + struct napi_struct napi; + struct net_device *dev; + struct device *device; + struct clk *hclk; + struct clk *cclk; + void __iomem *base; + u32 irqstatus; + + /* message ram configuration */ + void __iomem *mram_base; + struct mram_cfg mcfg[MRAM_CFG_NUM]; +}; + +static inline u32 m_can_read(const struct m_can_priv *priv, enum m_can_reg reg) +{ + return readl(priv->base + reg); +} + +static inline void m_can_write(const struct m_can_priv *priv, + enum m_can_reg reg, u32 val) +{ + writel(val, priv->base + reg); +} + +static inline u32 m_can_fifo_read(const struct m_can_priv *priv, + u32 fgi, unsigned int offset) +{ + return readl(priv->mram_base + priv->mcfg[MRAM_RXF0].off + + fgi * RXF0_ELEMENT_SIZE + offset); +} + +static inline void m_can_fifo_write(const struct m_can_priv *priv, + u32 fpi, unsigned int offset, u32 val) +{ + return writel(val, priv->mram_base + priv->mcfg[MRAM_TXB].off + + fpi * TXB_ELEMENT_SIZE + offset); +} + +static inline void m_can_config_endisable(const struct m_can_priv *priv, + bool enable) +{ + u32 cccr = m_can_read(priv, M_CAN_CCCR); + u32 timeout = 10; + u32 val = 0; + + if (enable) { + /* enable m_can configuration */ + m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT); + /* CCCR.CCE can only be set/reset while CCCR.INIT = '1' */ + m_can_write(priv, M_CAN_CCCR, cccr | CCCR_INIT | CCCR_CCE); + } else { + m_can_write(priv, M_CAN_CCCR, cccr & ~(CCCR_INIT | CCCR_CCE)); + } + + /* there's a delay for module initialization */ + if (enable) + val = CCCR_INIT | CCCR_CCE; + + while ((m_can_read(priv, M_CAN_CCCR) & (CCCR_INIT | CCCR_CCE)) != val) { + if (timeout == 0) { + netdev_warn(priv->dev, "Failed to init module\n"); + return; + } + timeout--; + udelay(1); + } +} + +static inline void m_can_enable_all_interrupts(const struct m_can_priv *priv) +{ + m_can_write(priv, M_CAN_ILE, ILE_EINT0 | ILE_EINT1); +} + +static inline void m_can_disable_all_interrupts(const struct m_can_priv *priv) +{ + m_can_write(priv, M_CAN_ILE, 0x0); +} + +static void m_can_read_fifo(const struct net_device *dev, struct can_frame *cf, + u32 rxfs) +{ + struct m_can_priv *priv = netdev_priv(dev); + u32 id, fgi; + + /* calculate the fifo get index for where to read data */ + fgi = (rxfs & RXFS_FGI_MASK) >> RXFS_FGI_OFF; + id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_ID); + if (id & RX_BUF_XTD) + cf->can_id = (id & CAN_EFF_MASK) | CAN_EFF_FLAG; + else + cf->can_id = (id >> 18) & CAN_SFF_MASK; + + if (id & RX_BUF_RTR) { + cf->can_id |= CAN_RTR_FLAG; + } else { + id = m_can_fifo_read(priv, fgi, M_CAN_FIFO_DLC); + cf->can_dlc = get_can_dlc((id >> 16) & 0x0F); + *(u32 *)(cf->data + 0) = m_can_fifo_read(priv, fgi, + M_CAN_FIFO_DATA(0)); + *(u32 *)(cf->data + 4) = m_can_fifo_read(priv, fgi, + M_CAN_FIFO_DATA(1)); + } + + /* acknowledge rx fifo 0 */ + m_can_write(priv, M_CAN_RXF0A, fgi); +} + +static int m_can_do_rx_poll(struct net_device *dev, int quota) +{ + struct m_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct sk_buff *skb; + struct can_frame *frame; + u32 pkts = 0; + u32 rxfs; + + rxfs = m_can_read(priv, M_CAN_RXF0S); + if (!(rxfs & RXFS_FFL_MASK)) { + netdev_dbg(dev, "no messages in fifo0\n"); + return 0; + } + + while ((rxfs & RXFS_FFL_MASK) && (quota > 0)) { + if (rxfs & RXFS_RFL) + netdev_warn(dev, "Rx FIFO 0 Message Lost\n"); + + skb = alloc_can_skb(dev, &frame); + if (!skb) { + stats->rx_dropped++; + return pkts; + } + + m_can_read_fifo(dev, frame, rxfs); + + stats->rx_packets++; + stats->rx_bytes += frame->can_dlc; + + netif_receive_skb(skb); + + quota--; + pkts++; + rxfs = m_can_read(priv, M_CAN_RXF0S); + } + + if (pkts) + can_led_event(dev, CAN_LED_EVENT_RX); + + return pkts; +} + +static int m_can_handle_lost_msg(struct net_device *dev) +{ + struct net_device_stats *stats = &dev->stats; + struct sk_buff *skb; + struct can_frame *frame; + + netdev_err(dev, "msg lost in rxf0\n"); + + stats->rx_errors++; + stats->rx_over_errors++; + + skb = alloc_can_err_skb(dev, &frame); + if (unlikely(!skb)) + return 0; + + frame->can_id |= CAN_ERR_CRTL; + frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; + + netif_receive_skb(skb); + + return 1; +} + +static int m_can_handle_lec_err(struct net_device *dev, + enum m_can_lec_type lec_type) +{ + struct m_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct can_frame *cf; + struct sk_buff *skb; + + priv->can.can_stats.bus_error++; + stats->rx_errors++; + + /* propagate the error condition to the CAN stack */ + skb = alloc_can_err_skb(dev, &cf); + if (unlikely(!skb)) + return 0; + + /* check for 'last error code' which tells us the + * type of the last error to occur on the CAN bus + */ + cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; + cf->data[2] |= CAN_ERR_PROT_UNSPEC; + + switch (lec_type) { + case LEC_STUFF_ERROR: + netdev_dbg(dev, "stuff error\n"); + cf->data[2] |= CAN_ERR_PROT_STUFF; + break; + case LEC_FORM_ERROR: + netdev_dbg(dev, "form error\n"); + cf->data[2] |= CAN_ERR_PROT_FORM; + break; + case LEC_ACK_ERROR: + netdev_dbg(dev, "ack error\n"); + cf->data[3] |= (CAN_ERR_PROT_LOC_ACK | + CAN_ERR_PROT_LOC_ACK_DEL); + break; + case LEC_BIT1_ERROR: + netdev_dbg(dev, "bit1 error\n"); + cf->data[2] |= CAN_ERR_PROT_BIT1; + break; + case LEC_BIT0_ERROR: + netdev_dbg(dev, "bit0 error\n"); + cf->data[2] |= CAN_ERR_PROT_BIT0; + break; + case LEC_CRC_ERROR: + netdev_dbg(dev, "CRC error\n"); + cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | + CAN_ERR_PROT_LOC_CRC_DEL); + break; + default: + break; + } + + stats->rx_packets++; + stats->rx_bytes += cf->can_dlc; + netif_receive_skb(skb); + + return 1; +} + +static int m_can_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + struct m_can_priv *priv = netdev_priv(dev); + unsigned int ecr; + int err; + + err = clk_prepare_enable(priv->hclk); + if (err) + return err; + + err = clk_prepare_enable(priv->cclk); + if (err) { + clk_disable_unprepare(priv->hclk); + return err; + } + + ecr = m_can_read(priv, M_CAN_ECR); + bec->rxerr = (ecr & ECR_REC_MASK) >> ECR_REC_SHIFT; + bec->txerr = ecr & ECR_TEC_MASK; + + clk_disable_unprepare(priv->cclk); + clk_disable_unprepare(priv->hclk); + + return 0; +} + +static int m_can_handle_state_change(struct net_device *dev, + enum can_state new_state) +{ + struct m_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + struct can_frame *cf; + struct sk_buff *skb; + struct can_berr_counter bec; + unsigned int ecr; + + switch (new_state) { + case CAN_STATE_ERROR_ACTIVE: + /* error warning state */ + priv->can.can_stats.error_warning++; + priv->can.state = CAN_STATE_ERROR_WARNING; + break; + case CAN_STATE_ERROR_PASSIVE: + /* error passive state */ + priv->can.can_stats.error_passive++; + priv->can.state = CAN_STATE_ERROR_PASSIVE; + break; + case CAN_STATE_BUS_OFF: + /* bus-off state */ + priv->can.state = CAN_STATE_BUS_OFF; + m_can_disable_all_interrupts(priv); + can_bus_off(dev); + break; + default: + break; + } + + /* propagate the error condition to the CAN stack */ + skb = alloc_can_err_skb(dev, &cf); + if (unlikely(!skb)) + return 0; + + m_can_get_berr_counter(dev, &bec); + + switch (new_state) { + case CAN_STATE_ERROR_ACTIVE: + /* error warning state */ + cf->can_id |= CAN_ERR_CRTL; + cf->data[1] = (bec.txerr > bec.rxerr) ? + CAN_ERR_CRTL_TX_WARNING : + CAN_ERR_CRTL_RX_WARNING; + cf->data[6] = bec.txerr; + cf->data[7] = bec.rxerr; + break; + case CAN_STATE_ERROR_PASSIVE: + /* error passive state */ + cf->can_id |= CAN_ERR_CRTL; + ecr = m_can_read(priv, M_CAN_ECR); + if (ecr & ECR_RP) + cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; + if (bec.txerr > 127) + cf->data[1] |= CAN_ERR_CRTL_TX_PASSIVE; + cf->data[6] = bec.txerr; + cf->data[7] = bec.rxerr; + break; + case CAN_STATE_BUS_OFF: + /* bus-off state */ + cf->can_id |= CAN_ERR_BUSOFF; + break; + default: + break; + } + + stats->rx_packets++; + stats->rx_bytes += cf->can_dlc; + netif_receive_skb(skb); + + return 1; +} + +static int m_can_handle_state_errors(struct net_device *dev, u32 psr) +{ + struct m_can_priv *priv = netdev_priv(dev); + int work_done = 0; + + if ((psr & PSR_EW) && + (priv->can.state != CAN_STATE_ERROR_WARNING)) { + netdev_dbg(dev, "entered error warning state\n"); + work_done += m_can_handle_state_change(dev, + CAN_STATE_ERROR_WARNING); + } + + if ((psr & PSR_EP) && + (priv->can.state != CAN_STATE_ERROR_PASSIVE)) { + netdev_dbg(dev, "entered error warning state\n"); + work_done += m_can_handle_state_change(dev, + CAN_STATE_ERROR_PASSIVE); + } + + if ((psr & PSR_BO) && + (priv->can.state != CAN_STATE_BUS_OFF)) { + netdev_dbg(dev, "entered error warning state\n"); + work_done += m_can_handle_state_change(dev, + CAN_STATE_BUS_OFF); + } + + return work_done; +} + +static void m_can_handle_other_err(struct net_device *dev, u32 irqstatus) +{ + if (irqstatus & IR_WDI) + netdev_err(dev, "Message RAM Watchdog event due to missing READY\n"); + if (irqstatus & IR_BEU) + netdev_err(dev, "Error Logging Overflow\n"); + if (irqstatus & IR_BEU) + netdev_err(dev, "Bit Error Uncorrected\n"); + if (irqstatus & IR_BEC) + netdev_err(dev, "Bit Error Corrected\n"); + if (irqstatus & IR_TOO) + netdev_err(dev, "Timeout reached\n"); + if (irqstatus & IR_MRAF) + netdev_err(dev, "Message RAM access failure occurred\n"); +} + +static inline bool is_lec_err(u32 psr) +{ + psr &= LEC_UNUSED; + + return psr && (psr != LEC_UNUSED); +} + +static int m_can_handle_bus_errors(struct net_device *dev, u32 irqstatus, + u32 psr) +{ + struct m_can_priv *priv = netdev_priv(dev); + int work_done = 0; + + if (irqstatus & IR_RF0L) + work_done += m_can_handle_lost_msg(dev); + + /* handle lec errors on the bus */ + if ((priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && + is_lec_err(psr)) + work_done += m_can_handle_lec_err(dev, psr & LEC_UNUSED); + + /* other unproccessed error interrupts */ + m_can_handle_other_err(dev, irqstatus); + + return work_done; +} + +static int m_can_poll(struct napi_struct *napi, int quota) +{ + struct net_device *dev = napi->dev; + struct m_can_priv *priv = netdev_priv(dev); + int work_done = 0; + u32 irqstatus, psr; + + irqstatus = priv->irqstatus | m_can_read(priv, M_CAN_IR); + if (!irqstatus) + goto end; + + psr = m_can_read(priv, M_CAN_PSR); + if (irqstatus & IR_ERR_STATE) + work_done += m_can_handle_state_errors(dev, psr); + + if (irqstatus & IR_ERR_BUS) + work_done += m_can_handle_bus_errors(dev, irqstatus, psr); + + if (irqstatus & IR_RF0N) + work_done += m_can_do_rx_poll(dev, (quota - work_done)); + + if (work_done < quota) { + napi_complete(napi); + m_can_enable_all_interrupts(priv); + } + +end: + return work_done; +} + +static irqreturn_t m_can_isr(int irq, void *dev_id) +{ + struct net_device *dev = (struct net_device *)dev_id; + struct m_can_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + u32 ir; + + ir = m_can_read(priv, M_CAN_IR); + if (!ir) + return IRQ_NONE; + + /* ACK all irqs */ + if (ir & IR_ALL_INT) + m_can_write(priv, M_CAN_IR, ir); + + /* schedule NAPI in case of + * - rx IRQ + * - state change IRQ + * - bus error IRQ and bus error reporting + */ + if ((ir & IR_RF0N) || (ir & IR_ERR_ALL)) { + priv->irqstatus = ir; + m_can_disable_all_interrupts(priv); + napi_schedule(&priv->napi); + } + + /* transmission complete interrupt */ + if (ir & IR_TC) { + stats->tx_bytes += can_get_echo_skb(dev, 0); + stats->tx_packets++; + can_led_event(dev, CAN_LED_EVENT_TX); + netif_wake_queue(dev); + } + + return IRQ_HANDLED; +} + +static const struct can_bittiming_const m_can_bittiming_const = { + .name = KBUILD_MODNAME, + .tseg1_min = 2, /* Time segment 1 = prop_seg + phase_seg1 */ + .tseg1_max = 64, + .tseg2_min = 1, /* Time segment 2 = phase_seg2 */ + .tseg2_max = 16, + .sjw_max = 16, + .brp_min = 1, + .brp_max = 1024, + .brp_inc = 1, +}; + +static int m_can_set_bittiming(struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + const struct can_bittiming *bt = &priv->can.bittiming; + u16 brp, sjw, tseg1, tseg2; + u32 reg_btp; + + brp = bt->brp - 1; + sjw = bt->sjw - 1; + tseg1 = bt->prop_seg + bt->phase_seg1 - 1; + tseg2 = bt->phase_seg2 - 1; + reg_btp = (brp << BTR_BRP_SHIFT) | (sjw << BTR_SJW_SHIFT) | + (tseg1 << BTR_TSEG1_SHIFT) | (tseg2 << BTR_TSEG2_SHIFT); + m_can_write(priv, M_CAN_BTP, reg_btp); + netdev_dbg(dev, "setting BTP 0x%x\n", reg_btp); + + return 0; +} + +/* Configure M_CAN chip: + * - set rx buffer/fifo element size + * - configure rx fifo + * - accept non-matching frame into fifo 0 + * - configure tx buffer + * - configure mode + * - setup bittiming + */ +static void m_can_chip_config(struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + u32 cccr, test; + + m_can_config_endisable(priv, true); + + /* RX Buffer/FIFO Element Size 8 bytes data field */ + m_can_write(priv, M_CAN_RXESC, M_CAN_RXESC_8BYTES); + + /* Accept Non-matching Frames Into FIFO 0 */ + m_can_write(priv, M_CAN_GFC, 0x0); + + /* only support one Tx Buffer currently */ + m_can_write(priv, M_CAN_TXBC, (1 << TXBC_NDTB_OFF) | + priv->mcfg[MRAM_TXB].off); + + /* only support 8 bytes firstly */ + m_can_write(priv, M_CAN_TXESC, TXESC_TBDS_8BYTES); + + m_can_write(priv, M_CAN_TXEFC, (1 << TXEFC_EFS_OFF) | + priv->mcfg[MRAM_TXE].off); + + /* rx fifo configuration, blocking mode, fifo size 1 */ + m_can_write(priv, M_CAN_RXF0C, + (priv->mcfg[MRAM_RXF0].num << RXFC_FS_OFF) | + RXFC_FWM_1 | priv->mcfg[MRAM_RXF0].off); + + m_can_write(priv, M_CAN_RXF1C, + (priv->mcfg[MRAM_RXF1].num << RXFC_FS_OFF) | + RXFC_FWM_1 | priv->mcfg[MRAM_RXF1].off); + + cccr = m_can_read(priv, M_CAN_CCCR); + cccr &= ~(CCCR_TEST | CCCR_MON); + test = m_can_read(priv, M_CAN_TEST); + test &= ~TEST_LBCK; + + if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) + cccr |= CCCR_MON; + + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { + cccr |= CCCR_TEST; + test |= TEST_LBCK; + } + + m_can_write(priv, M_CAN_CCCR, cccr); + m_can_write(priv, M_CAN_TEST, test); + + /* enable interrupts */ + m_can_write(priv, M_CAN_IR, IR_ALL_INT); + if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) + m_can_write(priv, M_CAN_IE, IR_ALL_INT & ~IR_ERR_LEC); + else + m_can_write(priv, M_CAN_IE, IR_ALL_INT); + + /* route all interrupts to INT0 */ + m_can_write(priv, M_CAN_ILS, ILS_ALL_INT0); + + /* set bittiming params */ + m_can_set_bittiming(dev); + + m_can_config_endisable(priv, false); +} + +static void m_can_start(struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + + /* basic m_can configuration */ + m_can_chip_config(dev); + + priv->can.state = CAN_STATE_ERROR_ACTIVE; + + m_can_enable_all_interrupts(priv); +} + +static int m_can_set_mode(struct net_device *dev, enum can_mode mode) +{ + switch (mode) { + case CAN_MODE_START: + m_can_start(dev); + netif_wake_queue(dev); + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static void free_m_can_dev(struct net_device *dev) +{ + free_candev(dev); +} + +static struct net_device *alloc_m_can_dev(void) +{ + struct net_device *dev; + struct m_can_priv *priv; + + dev = alloc_candev(sizeof(*priv), 1); + if (!dev) + return NULL; + + priv = netdev_priv(dev); + netif_napi_add(dev, &priv->napi, m_can_poll, M_CAN_NAPI_WEIGHT); + + priv->dev = dev; + priv->can.bittiming_const = &m_can_bittiming_const; + priv->can.do_set_mode = m_can_set_mode; + priv->can.do_get_berr_counter = m_can_get_berr_counter; + priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | + CAN_CTRLMODE_LISTENONLY | + CAN_CTRLMODE_BERR_REPORTING; + + return dev; +} + +static int m_can_open(struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + int err; + + err = clk_prepare_enable(priv->hclk); + if (err) + return err; + + err = clk_prepare_enable(priv->cclk); + if (err) + goto exit_disable_hclk; + + /* open the can device */ + err = open_candev(dev); + if (err) { + netdev_err(dev, "failed to open can device\n"); + goto exit_disable_cclk; + } + + /* register interrupt handler */ + err = request_irq(dev->irq, m_can_isr, IRQF_SHARED, dev->name, + dev); + if (err < 0) { + netdev_err(dev, "failed to request interrupt\n"); + goto exit_irq_fail; + } + + /* start the m_can controller */ + m_can_start(dev); + + can_led_event(dev, CAN_LED_EVENT_OPEN); + napi_enable(&priv->napi); + netif_start_queue(dev); + + return 0; + +exit_irq_fail: + close_candev(dev); +exit_disable_cclk: + clk_disable_unprepare(priv->cclk); +exit_disable_hclk: + clk_disable_unprepare(priv->hclk); + return err; +} + +static void m_can_stop(struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + + /* disable all interrupts */ + m_can_disable_all_interrupts(priv); + + clk_disable_unprepare(priv->hclk); + clk_disable_unprepare(priv->cclk); + + /* set the state as STOPPED */ + priv->can.state = CAN_STATE_STOPPED; +} + +static int m_can_close(struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + + netif_stop_queue(dev); + napi_disable(&priv->napi); + m_can_stop(dev); + free_irq(dev->irq, dev); + close_candev(dev); + can_led_event(dev, CAN_LED_EVENT_STOP); + + return 0; +} + +static netdev_tx_t m_can_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct m_can_priv *priv = netdev_priv(dev); + struct can_frame *cf = (struct can_frame *)skb->data; + u32 id; + + if (can_dropped_invalid_skb(dev, skb)) + return NETDEV_TX_OK; + + netif_stop_queue(dev); + + if (cf->can_id & CAN_EFF_FLAG) { + id = cf->can_id & CAN_EFF_MASK; + id |= TX_BUF_XTD; + } else { + id = ((cf->can_id & CAN_SFF_MASK) << 18); + } + + if (cf->can_id & CAN_RTR_FLAG) + id |= TX_BUF_RTR; + + /* message ram configuration */ + m_can_fifo_write(priv, 0, M_CAN_FIFO_ID, id); + m_can_fifo_write(priv, 0, M_CAN_FIFO_DLC, cf->can_dlc << 16); + m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(0), *(u32 *)(cf->data + 0)); + m_can_fifo_write(priv, 0, M_CAN_FIFO_DATA(1), *(u32 *)(cf->data + 4)); + can_put_echo_skb(skb, dev, 0); + + /* enable first TX buffer to start transfer */ + m_can_write(priv, M_CAN_TXBTIE, 0x1); + m_can_write(priv, M_CAN_TXBAR, 0x1); + + return NETDEV_TX_OK; +} + +static const struct net_device_ops m_can_netdev_ops = { + .ndo_open = m_can_open, + .ndo_stop = m_can_close, + .ndo_start_xmit = m_can_start_xmit, +}; + +static int register_m_can_dev(struct net_device *dev) +{ + dev->flags |= IFF_ECHO; /* we support local echo */ + dev->netdev_ops = &m_can_netdev_ops; + + return register_candev(dev); +} + +static int m_can_of_parse_mram(struct platform_device *pdev, + struct m_can_priv *priv) +{ + struct device_node *np = pdev->dev.of_node; + struct resource *res; + void __iomem *addr; + u32 out_val[MRAM_CFG_LEN]; + int ret; + + /* message ram could be shared */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "message_ram"); + if (!res) + return -ENODEV; + + addr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!addr) + return -ENOMEM; + + /* get message ram configuration */ + ret = of_property_read_u32_array(np, "bosch,mram-cfg", + out_val, sizeof(out_val) / 4); + if (ret) { + dev_err(&pdev->dev, "can not get message ram configuration\n"); + return -ENODEV; + } + + priv->mram_base = addr; + priv->mcfg[MRAM_SIDF].off = out_val[0]; + priv->mcfg[MRAM_SIDF].num = out_val[1]; + priv->mcfg[MRAM_XIDF].off = priv->mcfg[MRAM_SIDF].off + + priv->mcfg[MRAM_SIDF].num * SIDF_ELEMENT_SIZE; + priv->mcfg[MRAM_XIDF].num = out_val[2]; + priv->mcfg[MRAM_RXF0].off = priv->mcfg[MRAM_XIDF].off + + priv->mcfg[MRAM_XIDF].num * XIDF_ELEMENT_SIZE; + priv->mcfg[MRAM_RXF0].num = out_val[3] & RXFC_FS_MASK; + priv->mcfg[MRAM_RXF1].off = priv->mcfg[MRAM_RXF0].off + + priv->mcfg[MRAM_RXF0].num * RXF0_ELEMENT_SIZE; + priv->mcfg[MRAM_RXF1].num = out_val[4] & RXFC_FS_MASK; + priv->mcfg[MRAM_RXB].off = priv->mcfg[MRAM_RXF1].off + + priv->mcfg[MRAM_RXF1].num * RXF1_ELEMENT_SIZE; + priv->mcfg[MRAM_RXB].num = out_val[5]; + priv->mcfg[MRAM_TXE].off = priv->mcfg[MRAM_RXB].off + + priv->mcfg[MRAM_RXB].num * RXB_ELEMENT_SIZE; + priv->mcfg[MRAM_TXE].num = out_val[6]; + priv->mcfg[MRAM_TXB].off = priv->mcfg[MRAM_TXE].off + + priv->mcfg[MRAM_TXE].num * TXE_ELEMENT_SIZE; + priv->mcfg[MRAM_TXB].num = out_val[7] & TXBC_NDTB_MASK; + + dev_dbg(&pdev->dev, "mram_base %p sidf 0x%x %d xidf 0x%x %d rxf0 0x%x %d rxf1 0x%x %d rxb 0x%x %d txe 0x%x %d txb 0x%x %d\n", + priv->mram_base, + priv->mcfg[MRAM_SIDF].off, priv->mcfg[MRAM_SIDF].num, + priv->mcfg[MRAM_XIDF].off, priv->mcfg[MRAM_XIDF].num, + priv->mcfg[MRAM_RXF0].off, priv->mcfg[MRAM_RXF0].num, + priv->mcfg[MRAM_RXF1].off, priv->mcfg[MRAM_RXF1].num, + priv->mcfg[MRAM_RXB].off, priv->mcfg[MRAM_RXB].num, + priv->mcfg[MRAM_TXE].off, priv->mcfg[MRAM_TXE].num, + priv->mcfg[MRAM_TXB].off, priv->mcfg[MRAM_TXB].num); + + return 0; +} + +static int m_can_plat_probe(struct platform_device *pdev) +{ + struct net_device *dev; + struct m_can_priv *priv; + struct resource *res; + void __iomem *addr; + struct clk *hclk, *cclk; + int irq, ret; + + hclk = devm_clk_get(&pdev->dev, "hclk"); + cclk = devm_clk_get(&pdev->dev, "cclk"); + if (IS_ERR(hclk) || IS_ERR(cclk)) { + dev_err(&pdev->dev, "no clock find\n"); + return -ENODEV; + } + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "m_can"); + addr = devm_ioremap_resource(&pdev->dev, res); + irq = platform_get_irq_byname(pdev, "int0"); + if (IS_ERR(addr) || irq < 0) + return -EINVAL; + + /* allocate the m_can device */ + dev = alloc_m_can_dev(); + if (!dev) + return -ENOMEM; + + priv = netdev_priv(dev); + dev->irq = irq; + priv->base = addr; + priv->device = &pdev->dev; + priv->hclk = hclk; + priv->cclk = cclk; + priv->can.clock.freq = clk_get_rate(cclk); + + ret = m_can_of_parse_mram(pdev, priv); + if (ret) + goto failed_free_dev; + + platform_set_drvdata(pdev, dev); + SET_NETDEV_DEV(dev, &pdev->dev); + + ret = register_m_can_dev(dev); + if (ret) { + dev_err(&pdev->dev, "registering %s failed (err=%d)\n", + KBUILD_MODNAME, ret); + goto failed_free_dev; + } + + devm_can_led_init(dev); + + dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n", + KBUILD_MODNAME, priv->base, dev->irq); + + return 0; + +failed_free_dev: + free_m_can_dev(dev); + return ret; +} + +static __maybe_unused int m_can_suspend(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct m_can_priv *priv = netdev_priv(ndev); + + if (netif_running(ndev)) { + netif_stop_queue(ndev); + netif_device_detach(ndev); + } + + /* TODO: enter low power */ + + priv->can.state = CAN_STATE_SLEEPING; + + return 0; +} + +static __maybe_unused int m_can_resume(struct device *dev) +{ + struct net_device *ndev = dev_get_drvdata(dev); + struct m_can_priv *priv = netdev_priv(ndev); + + /* TODO: exit low power */ + + priv->can.state = CAN_STATE_ERROR_ACTIVE; + + if (netif_running(ndev)) { + netif_device_attach(ndev); + netif_start_queue(ndev); + } + + return 0; +} + +static void unregister_m_can_dev(struct net_device *dev) +{ + unregister_candev(dev); +} + +static int m_can_plat_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + unregister_m_can_dev(dev); + platform_set_drvdata(pdev, NULL); + + free_m_can_dev(dev); + + return 0; +} + +static const struct dev_pm_ops m_can_pmops = { + SET_SYSTEM_SLEEP_PM_OPS(m_can_suspend, m_can_resume) +}; + +static const struct of_device_id m_can_of_table[] = { + { .compatible = "bosch,m_can", .data = NULL }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, m_can_of_table); + +static struct platform_driver m_can_plat_driver = { + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = m_can_of_table, + .pm = &m_can_pmops, + }, + .probe = m_can_plat_probe, + .remove = m_can_plat_remove, +}; + +module_platform_driver(m_can_plat_driver); + +MODULE_AUTHOR("Dong Aisheng "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("CAN bus driver for Bosch M_CAN controller"); -- GitLab From 862e2b6af9413b43ef044979b934cab07bfd33e5 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 1 Aug 2014 01:23:32 +0400 Subject: [PATCH 0841/9167] can: rcar_can: support all input clocks When writing the driver, I didn't give enough attention to the possible sources of the CAN clock: although the value of the CLKR register was specified by the platform data, the driver only handled one case, that is CAN clock being sourced from the clkp1 clock, the same that clocks the whole CAN module. In order to fix that overlook, we'll have to handle the CAN clock separately from the peripheral clock (however, clkp1 will be specified for a CAN device only once)... Signed-off-by: Sergei Shtylyov Signed-off-by: Marc Kleine-Budde --- drivers/net/can/rcar_can.c | 42 ++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c index 5268d216ecfa..c02fcf369afd 100644 --- a/drivers/net/can/rcar_can.c +++ b/drivers/net/can/rcar_can.c @@ -87,6 +87,7 @@ struct rcar_can_priv { struct napi_struct napi; struct rcar_can_regs __iomem *regs; struct clk *clk; + struct clk *can_clk; u8 tx_dlc[RCAR_CAN_FIFO_DEPTH]; u32 tx_head; u32 tx_tail; @@ -505,14 +506,20 @@ static int rcar_can_open(struct net_device *ndev) err = clk_prepare_enable(priv->clk); if (err) { - netdev_err(ndev, "clk_prepare_enable() failed, error %d\n", + netdev_err(ndev, "failed to enable periperal clock, error %d\n", err); goto out; } + err = clk_prepare_enable(priv->can_clk); + if (err) { + netdev_err(ndev, "failed to enable CAN clock, error %d\n", + err); + goto out_clock; + } err = open_candev(ndev); if (err) { netdev_err(ndev, "open_candev() failed, error %d\n", err); - goto out_clock; + goto out_can_clock; } napi_enable(&priv->napi); err = request_irq(ndev->irq, rcar_can_interrupt, 0, ndev->name, ndev); @@ -527,6 +534,8 @@ static int rcar_can_open(struct net_device *ndev) out_close: napi_disable(&priv->napi); close_candev(ndev); +out_can_clock: + clk_disable_unprepare(priv->can_clk); out_clock: clk_disable_unprepare(priv->clk); out: @@ -565,6 +574,7 @@ static int rcar_can_close(struct net_device *ndev) rcar_can_stop(ndev); free_irq(ndev->irq, ndev); napi_disable(&priv->napi); + clk_disable_unprepare(priv->can_clk); clk_disable_unprepare(priv->clk); close_candev(ndev); can_led_event(ndev, CAN_LED_EVENT_STOP); @@ -715,6 +725,12 @@ static int rcar_can_get_berr_counter(const struct net_device *dev, return 0; } +static const char * const clock_names[] = { + [CLKR_CLKP1] = "clkp1", + [CLKR_CLKP2] = "clkp2", + [CLKR_CLKEXT] = "can_clk", +}; + static int rcar_can_probe(struct platform_device *pdev) { struct rcar_can_platform_data *pdata; @@ -722,6 +738,7 @@ static int rcar_can_probe(struct platform_device *pdev) struct net_device *ndev; struct resource *mem; void __iomem *addr; + u32 clock_select; int err = -ENODEV; int irq; @@ -730,6 +747,7 @@ static int rcar_can_probe(struct platform_device *pdev) dev_err(&pdev->dev, "No platform data provided!\n"); goto fail; } + clock_select = pdata->clock_select; irq = platform_get_irq(pdev, 0); if (!irq) { @@ -753,10 +771,22 @@ static int rcar_can_probe(struct platform_device *pdev) priv = netdev_priv(ndev); - priv->clk = devm_clk_get(&pdev->dev, NULL); + priv->clk = devm_clk_get(&pdev->dev, "clkp1"); if (IS_ERR(priv->clk)) { err = PTR_ERR(priv->clk); - dev_err(&pdev->dev, "cannot get clock: %d\n", err); + dev_err(&pdev->dev, "cannot get peripheral clock: %d\n", err); + goto fail_clk; + } + + if (clock_select >= ARRAY_SIZE(clock_names)) { + err = -EINVAL; + dev_err(&pdev->dev, "invalid CAN clock selected\n"); + goto fail_clk; + } + priv->can_clk = devm_clk_get(&pdev->dev, clock_names[clock_select]); + if (IS_ERR(priv->can_clk)) { + err = PTR_ERR(priv->can_clk); + dev_err(&pdev->dev, "cannot get CAN clock: %d\n", err); goto fail_clk; } @@ -765,8 +795,8 @@ static int rcar_can_probe(struct platform_device *pdev) ndev->flags |= IFF_ECHO; priv->ndev = ndev; priv->regs = addr; - priv->clock_select = pdata->clock_select; - priv->can.clock.freq = clk_get_rate(priv->clk); + priv->clock_select = clock_select; + priv->can.clock.freq = clk_get_rate(priv->can_clk); priv->can.bittiming_const = &rcar_can_bittiming_const; priv->can.do_set_mode = rcar_can_do_set_mode; priv->can.do_get_berr_counter = rcar_can_get_berr_counter; -- GitLab From 632e25ca722e5361a1b40d89e77808f8f1c6799f Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 1 Aug 2014 01:24:25 +0400 Subject: [PATCH 0842/9167] can: rcar_can: document device tree bindings Document the R-Car CAN device tree bindings. Signed-off-by: Sergei Shtylyov Signed-off-by: Marc Kleine-Budde --- .../devicetree/bindings/net/can/rcar_can.txt | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/can/rcar_can.txt diff --git a/Documentation/devicetree/bindings/net/can/rcar_can.txt b/Documentation/devicetree/bindings/net/can/rcar_can.txt new file mode 100644 index 000000000000..002d8440bf66 --- /dev/null +++ b/Documentation/devicetree/bindings/net/can/rcar_can.txt @@ -0,0 +1,43 @@ +Renesas R-Car CAN controller Device Tree Bindings +------------------------------------------------- + +Required properties: +- compatible: "renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC. + "renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC. + "renesas,can-r8a7790" if CAN controller is a part of R8A7790 SoC. + "renesas,can-r8a7791" if CAN controller is a part of R8A7791 SoC. +- reg: physical base address and size of the R-Car CAN register map. +- interrupts: interrupt specifier for the sole interrupt. +- clocks: phandles and clock specifiers for 3 CAN clock inputs. +- clock-names: 3 clock input name strings: "clkp1", "clkp2", "can_clk". +- pinctrl-0: pin control group to be used for this controller. +- pinctrl-names: must be "default". + +Optional properties: +- renesas,can-clock-select: R-Car CAN Clock Source Select. Valid values are: + <0x0> (default) : Peripheral clock (clkp1) + <0x1> : Peripheral clock (clkp2) + <0x3> : Externally input clock + +Example +------- + +SoC common .dtsi file: + + can0: can@e6e80000 { + compatible = "renesas,can-r8a7791"; + reg = <0 0xe6e80000 0 0x1000>; + interrupts = <0 186 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&mstp9_clks R8A7791_CLK_RCAN0>, + <&cpg_clocks R8A7791_CLK_RCAN>, <&can_clk>; + clock-names = "clkp1", "clkp2", "can_clk"; + status = "disabled"; + }; + +Board specific .dts file: + +&can0 { + pinctrl-0 = <&can0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; -- GitLab From a268de6c68e4933234e9ac62f2ab7ff8264ce0b4 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 1 Aug 2014 01:25:53 +0400 Subject: [PATCH 0843/9167] can: rcar_can: add device tree support Add support of the device tree probing for the Renesas R-Car CAN controllers. Signed-off-by: Sergei Shtylyov Signed-off-by: Marc Kleine-Budde --- drivers/net/can/rcar_can.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c index c02fcf369afd..1abe133d1594 100644 --- a/drivers/net/can/rcar_can.c +++ b/drivers/net/can/rcar_can.c @@ -20,6 +20,7 @@ #include #include #include +#include #define RCAR_CAN_DRV_NAME "rcar_can" @@ -738,16 +739,21 @@ static int rcar_can_probe(struct platform_device *pdev) struct net_device *ndev; struct resource *mem; void __iomem *addr; - u32 clock_select; + u32 clock_select = CLKR_CLKP1; int err = -ENODEV; int irq; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - dev_err(&pdev->dev, "No platform data provided!\n"); - goto fail; + if (pdev->dev.of_node) { + of_property_read_u32(pdev->dev.of_node, + "renesas,can-clock-select", &clock_select); + } else { + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + dev_err(&pdev->dev, "No platform data provided!\n"); + goto fail; + } + clock_select = pdata->clock_select; } - clock_select = pdata->clock_select; irq = platform_get_irq(pdev, 0); if (!irq) { @@ -888,10 +894,20 @@ static int __maybe_unused rcar_can_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(rcar_can_pm_ops, rcar_can_suspend, rcar_can_resume); +static const struct of_device_id rcar_can_of_table[] __maybe_unused = { + { .compatible = "renesas,can-r8a7778" }, + { .compatible = "renesas,can-r8a7779" }, + { .compatible = "renesas,can-r8a7790" }, + { .compatible = "renesas,can-r8a7791" }, + { } +}; +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, }, .probe = rcar_can_probe, -- GitLab From b25a437206ed5d45087bc40bd48bc34ce3bfa008 Mon Sep 17 00:00:00 2001 From: "Lad, Prabhakar" Date: Thu, 7 Aug 2014 09:17:24 +0100 Subject: [PATCH 0844/9167] can: dev: remove unused variable from can_calc_bittiming() function this patch removes best_rate variable from can_calc_bittiming() function which was set but was never used. Signed-off-by: Lad, Prabhakar Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 9f91fcba43f8..02492d241e4c 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -103,11 +103,11 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, const struct can_bittiming_const *btc) { struct can_priv *priv = netdev_priv(dev); - long rate, best_rate = 0; long best_error = 1000000000, error = 0; int best_tseg = 0, best_brp = 0, brp = 0; int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0; int spt_error = 1000, spt = 0, sampl_pt; + long rate; u64 v64; /* Use CIA recommended sample points */ @@ -152,7 +152,6 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt, } best_tseg = tseg / 2; best_brp = brp; - best_rate = rate; if (error == 0) break; } -- GitLab From 3a73aeff37c2e425b11d19c19e42e8269d58d417 Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Sat, 2 Aug 2014 19:22:04 +0530 Subject: [PATCH 0845/9167] can: mcp251x: Use dmam_alloc_coherent This patch moves the data allocated using dma_alloc_coherent to the corresponding managed interface and does away with the calls to free the allocated memory in the probe and remove functions. Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251x.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c index 5df239e68812..c66d699640a9 100644 --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c @@ -1107,10 +1107,10 @@ static int mcp251x_can_probe(struct spi_device *spi) * Minimum coherent DMA allocation is PAGE_SIZE, so allocate * that much and share it between Tx and Rx DMA buffers. */ - priv->spi_tx_buf = dma_alloc_coherent(&spi->dev, - PAGE_SIZE, - &priv->spi_tx_dma, - GFP_DMA); + priv->spi_tx_buf = dmam_alloc_coherent(&spi->dev, + PAGE_SIZE, + &priv->spi_tx_dma, + GFP_DMA); if (priv->spi_tx_buf) { priv->spi_rx_buf = (priv->spi_tx_buf + (PAGE_SIZE / 2)); @@ -1156,9 +1156,6 @@ static int mcp251x_can_probe(struct spi_device *spi) return 0; error_probe: - if (mcp251x_enable_dma) - dma_free_coherent(&spi->dev, PAGE_SIZE, - priv->spi_tx_buf, priv->spi_tx_dma); mcp251x_power_enable(priv->power, 0); out_clk: @@ -1178,11 +1175,6 @@ static int mcp251x_can_remove(struct spi_device *spi) unregister_candev(net); - if (mcp251x_enable_dma) { - dma_free_coherent(&spi->dev, PAGE_SIZE, - priv->spi_tx_buf, priv->spi_tx_dma); - } - mcp251x_power_enable(priv->power, 0); if (!IS_ERR(priv->clk)) -- GitLab From 874ee23c83d888f8824305c277e047c7799f30b9 Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Wed, 13 Aug 2014 17:07:15 -0700 Subject: [PATCH 0846/9167] ARM: shmobile: defconfig: enable initrd Enable initrd support. Signed-off-by: Kevin Hilman [horms+renesas@verge.net.au: dropped enabling atag dtb compat] Signed-off-by: Simon Horman --- arch/arm/configs/shmobile_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 0cd63f584665..b7ebf1ecab0b 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig @@ -3,6 +3,7 @@ CONFIG_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=16 +CONFIG_BLK_DEV_INITRD=y CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL_SYSCALL=y CONFIG_EMBEDDED=y -- GitLab From d3ac21cacc24790eb45d735769f35753f5b56ceb Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 17 Aug 2014 19:41:09 -0500 Subject: [PATCH 0847/9167] mm: Support compiling out madvise and fadvise Many embedded systems will not need these syscalls, and omitting them saves space. Add a new EXPERT config option CONFIG_ADVISE_SYSCALLS (default y) to support compiling them out. bloat-o-meter: add/remove: 0/3 grow/shrink: 0/0 up/down: 0/-2250 (-2250) function old new delta sys_fadvise64 57 - -57 sys_fadvise64_64 691 - -691 sys_madvise 1502 - -1502 Signed-off-by: Josh Triplett --- init/Kconfig | 10 ++++++++++ kernel/sys_ni.c | 3 +++ mm/Makefile | 7 +++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/init/Kconfig b/init/Kconfig index e84c6423a2e5..782a65bf76ea 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -1537,6 +1537,16 @@ config AIO by some high performance threaded applications. Disabling this option saves about 7k. +config ADVISE_SYSCALLS + bool "Enable madvise/fadvise syscalls" if EXPERT + default y + help + This option enables the madvise and fadvise syscalls, used by + applications to advise the kernel about their future memory or file + usage, improving performance. If building an embedded system where no + applications use these syscalls, you can disable this option to save + space. + config PCI_QUIRKS default y bool "Enable PCI quirk workarounds" if EXPERT diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 391d4ddb6f4b..d4709d481053 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c @@ -156,6 +156,9 @@ cond_syscall(sys_process_vm_writev); cond_syscall(compat_sys_process_vm_readv); cond_syscall(compat_sys_process_vm_writev); cond_syscall(sys_uselib); +cond_syscall(sys_fadvise64); +cond_syscall(sys_fadvise64_64); +cond_syscall(sys_madvise); /* arch-specific weak syscall entries */ cond_syscall(sys_pciconfig_read); diff --git a/mm/Makefile b/mm/Makefile index 632ae77e6070..fe7a053c0f45 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -3,7 +3,7 @@ # mmu-y := nommu.o -mmu-$(CONFIG_MMU) := fremap.o gup.o highmem.o madvise.o memory.o mincore.o \ +mmu-$(CONFIG_MMU) := fremap.o gup.o highmem.o memory.o mincore.o \ mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \ vmalloc.o pagewalk.o pgtable-generic.o @@ -11,7 +11,7 @@ ifdef CONFIG_CROSS_MEMORY_ATTACH mmu-$(CONFIG_MMU) += process_vm_access.o endif -obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ +obj-y := filemap.o mempool.o oom_kill.o \ maccess.o page_alloc.o page-writeback.o \ readahead.o swap.o truncate.o vmscan.o shmem.o \ util.o mmzone.o vmstat.o backing-dev.o \ @@ -28,6 +28,9 @@ else obj-y += bootmem.o endif +ifdef CONFIG_MMU + obj-$(CONFIG_ADVISE_SYSCALLS) += fadvise.o madvise.o +endif obj-$(CONFIG_HAVE_MEMBLOCK) += memblock.o obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o -- GitLab From f530504a063cfa028971e4b26ea8e0c32908de25 Mon Sep 17 00:00:00 2001 From: chai wen Date: Mon, 11 Aug 2014 10:49:23 -0400 Subject: [PATCH 0848/9167] watchdog: Remove unnecessary header files Signed-off-by: chai wen Signed-off-by: Don Zickus Cc: pbonzini@redhat.com Link: http://lkml.kernel.org/r/1407768567-171794-2-git-send-email-dzickus@redhat.com Signed-off-by: Ingo Molnar --- kernel/watchdog.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/kernel/watchdog.c b/kernel/watchdog.c index c3319bd1b040..4c2e11ce5425 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -15,11 +15,6 @@ #include #include #include -#include -#include -#include -#include -#include #include #include #include -- GitLab From df577149594cefacd62740e86de080c6336d699e Mon Sep 17 00:00:00 2001 From: Ulrich Obergfell Date: Mon, 11 Aug 2014 10:49:25 -0400 Subject: [PATCH 0849/9167] watchdog: Fix print-once on enable This patch avoids printing the message 'enabled on all CPUs, ...' multiple times. For example, the issue can occur in the following scenario: 1) watchdog_nmi_enable() fails to enable PMU counters and sets cpu0_err. 2) 'echo [0|1] > /proc/sys/kernel/nmi_watchdog' is executed to disable and re-enable the watchdog mechanism 'on the fly'. 3) If watchdog_nmi_enable() succeeds to enable PMU counters, each CPU will print the message because step1 left behind a non-zero cpu0_err. if (!IS_ERR(event)) { if (cpu == 0 || cpu0_err) pr_info("enabled on all CPUs, ...") The patch avoids this by clearing cpu0_err in watchdog_nmi_disable(). Signed-off-by: Ulrich Obergfell Signed-off-by: Andrew Jones Signed-off-by: Don Zickus Cc: pbonzini@redhat.com Link: http://lkml.kernel.org/r/1407768567-171794-4-git-send-email-dzickus@redhat.com [ Applied small cleanups. ] Signed-off-by: Ingo Molnar --- kernel/watchdog.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 4c2e11ce5425..df5494edf694 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -506,7 +506,10 @@ static void watchdog_nmi_disable(unsigned int cpu) /* should be in cleanup, but blocks oprofile */ perf_event_release_kernel(event); } - return; + if (cpu == 0) { + /* watchdog_nmi_enable() expects this to be zero initially. */ + cpu0_err = 0; + } } #else static int watchdog_nmi_enable(unsigned int cpu) { return 0; } -- GitLab From 7d2691da901d71ff62ad974510ea7149b391bdfe Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Wed, 25 Jun 2014 18:05:47 -0700 Subject: [PATCH 0850/9167] gpu: ipu-v3: Add ipu-cpmem unit Move channel parameter memory setup functions and macros into a new submodule ipu-cpmem. In the process, cleanup arguments to the functions to take a channel pointer instead of a pointer into cpmem for that channel. That allows the structure of the parameter memory to be private to ipu-cpmem.c. Signed-off-by: Steve Longerbeam Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/Makefile | 3 +- drivers/gpu/ipu-v3/ipu-common.c | 457 +----------------------- drivers/gpu/ipu-v3/ipu-cpmem.c | 597 ++++++++++++++++++++++++++++++++ drivers/gpu/ipu-v3/ipu-prv.h | 14 +- include/video/imx-ipu-v3.h | 188 ++-------- 5 files changed, 658 insertions(+), 601 deletions(-) create mode 100644 drivers/gpu/ipu-v3/ipu-cpmem.c diff --git a/drivers/gpu/ipu-v3/Makefile b/drivers/gpu/ipu-v3/Makefile index 1887972b4ac2..0b42836caae1 100644 --- a/drivers/gpu/ipu-v3/Makefile +++ b/drivers/gpu/ipu-v3/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_IMX_IPUV3_CORE) += imx-ipu-v3.o -imx-ipu-v3-objs := ipu-common.o ipu-dc.o ipu-di.o ipu-dp.o ipu-dmfc.o ipu-smfc.o +imx-ipu-v3-objs := ipu-common.o ipu-cpmem.o ipu-dc.o ipu-di.o \ + ipu-dp.o ipu-dmfc.o ipu-smfc.o diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 04e7b2eafbdd..5978e7aab8ed 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -44,17 +44,6 @@ static inline void ipu_cm_write(struct ipu_soc *ipu, u32 value, unsigned offset) writel(value, ipu->cm_reg + offset); } -static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset) -{ - return readl(ipu->idmac_reg + offset); -} - -static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value, - unsigned offset) -{ - writel(value, ipu->idmac_reg + offset); -} - void ipu_srm_dp_sync_update(struct ipu_soc *ipu) { u32 val; @@ -65,379 +54,6 @@ void ipu_srm_dp_sync_update(struct ipu_soc *ipu) } EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update); -struct ipu_ch_param __iomem *ipu_get_cpmem(struct ipuv3_channel *channel) -{ - struct ipu_soc *ipu = channel->ipu; - - return ipu->cpmem_base + channel->num; -} -EXPORT_SYMBOL_GPL(ipu_get_cpmem); - -void ipu_cpmem_set_high_priority(struct ipuv3_channel *channel) -{ - struct ipu_soc *ipu = channel->ipu; - struct ipu_ch_param __iomem *p = ipu_get_cpmem(channel); - u32 val; - - if (ipu->ipu_type == IPUV3EX) - ipu_ch_param_write_field(p, IPU_FIELD_ID, 1); - - val = ipu_idmac_read(ipu, IDMAC_CHA_PRI(channel->num)); - val |= 1 << (channel->num % 32); - ipu_idmac_write(ipu, val, IDMAC_CHA_PRI(channel->num)); -}; -EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority); - -void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v) -{ - u32 bit = (wbs >> 8) % 160; - u32 size = wbs & 0xff; - u32 word = (wbs >> 8) / 160; - u32 i = bit / 32; - u32 ofs = bit % 32; - u32 mask = (1 << size) - 1; - u32 val; - - pr_debug("%s %d %d %d\n", __func__, word, bit , size); - - val = readl(&base->word[word].data[i]); - val &= ~(mask << ofs); - val |= v << ofs; - writel(val, &base->word[word].data[i]); - - if ((bit + size - 1) / 32 > i) { - val = readl(&base->word[word].data[i + 1]); - val &= ~(mask >> (ofs ? (32 - ofs) : 0)); - val |= v >> (ofs ? (32 - ofs) : 0); - writel(val, &base->word[word].data[i + 1]); - } -} -EXPORT_SYMBOL_GPL(ipu_ch_param_write_field); - -u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs) -{ - u32 bit = (wbs >> 8) % 160; - u32 size = wbs & 0xff; - u32 word = (wbs >> 8) / 160; - u32 i = bit / 32; - u32 ofs = bit % 32; - u32 mask = (1 << size) - 1; - u32 val = 0; - - pr_debug("%s %d %d %d\n", __func__, word, bit , size); - - val = (readl(&base->word[word].data[i]) >> ofs) & mask; - - if ((bit + size - 1) / 32 > i) { - u32 tmp; - tmp = readl(&base->word[word].data[i + 1]); - tmp &= mask >> (ofs ? (32 - ofs) : 0); - val |= tmp << (ofs ? (32 - ofs) : 0); - } - - return val; -} -EXPORT_SYMBOL_GPL(ipu_ch_param_read_field); - -int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *p, - const struct ipu_rgb *rgb) -{ - int bpp = 0, npb = 0, ro, go, bo, to; - - ro = rgb->bits_per_pixel - rgb->red.length - rgb->red.offset; - go = rgb->bits_per_pixel - rgb->green.length - rgb->green.offset; - bo = rgb->bits_per_pixel - rgb->blue.length - rgb->blue.offset; - to = rgb->bits_per_pixel - rgb->transp.length - rgb->transp.offset; - - ipu_ch_param_write_field(p, IPU_FIELD_WID0, rgb->red.length - 1); - ipu_ch_param_write_field(p, IPU_FIELD_OFS0, ro); - ipu_ch_param_write_field(p, IPU_FIELD_WID1, rgb->green.length - 1); - ipu_ch_param_write_field(p, IPU_FIELD_OFS1, go); - ipu_ch_param_write_field(p, IPU_FIELD_WID2, rgb->blue.length - 1); - ipu_ch_param_write_field(p, IPU_FIELD_OFS2, bo); - - if (rgb->transp.length) { - ipu_ch_param_write_field(p, IPU_FIELD_WID3, - rgb->transp.length - 1); - ipu_ch_param_write_field(p, IPU_FIELD_OFS3, to); - } else { - ipu_ch_param_write_field(p, IPU_FIELD_WID3, 7); - ipu_ch_param_write_field(p, IPU_FIELD_OFS3, - rgb->bits_per_pixel); - } - - switch (rgb->bits_per_pixel) { - case 32: - bpp = 0; - npb = 15; - break; - case 24: - bpp = 1; - npb = 19; - break; - case 16: - bpp = 3; - npb = 31; - break; - case 8: - bpp = 5; - npb = 63; - break; - default: - return -EINVAL; - } - ipu_ch_param_write_field(p, IPU_FIELD_BPP, bpp); - ipu_ch_param_write_field(p, IPU_FIELD_NPB, npb); - ipu_ch_param_write_field(p, IPU_FIELD_PFS, 7); /* rgb mode */ - - return 0; -} -EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb); - -int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p, - int width) -{ - int bpp = 0, npb = 0; - - switch (width) { - case 32: - bpp = 0; - npb = 15; - break; - case 24: - bpp = 1; - npb = 19; - break; - case 16: - bpp = 3; - npb = 31; - break; - case 8: - bpp = 5; - npb = 63; - break; - default: - return -EINVAL; - } - - ipu_ch_param_write_field(p, IPU_FIELD_BPP, bpp); - ipu_ch_param_write_field(p, IPU_FIELD_NPB, npb); - ipu_ch_param_write_field(p, IPU_FIELD_PFS, 6); /* raw mode */ - - return 0; -} -EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough); - -void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param __iomem *p, - u32 pixel_format) -{ - switch (pixel_format) { - case V4L2_PIX_FMT_UYVY: - ipu_ch_param_write_field(p, IPU_FIELD_BPP, 3); /* bits/pixel */ - ipu_ch_param_write_field(p, IPU_FIELD_PFS, 0xA); /* pix format */ - ipu_ch_param_write_field(p, IPU_FIELD_NPB, 31); /* burst size */ - break; - case V4L2_PIX_FMT_YUYV: - ipu_ch_param_write_field(p, IPU_FIELD_BPP, 3); /* bits/pixel */ - ipu_ch_param_write_field(p, IPU_FIELD_PFS, 0x8); /* pix format */ - ipu_ch_param_write_field(p, IPU_FIELD_NPB, 31); /* burst size */ - break; - } -} -EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved); - -void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p, - u32 pixel_format, int stride, int u_offset, int v_offset) -{ - switch (pixel_format) { - case V4L2_PIX_FMT_YUV420: - ipu_ch_param_write_field(p, IPU_FIELD_SLUV, (stride / 2) - 1); - ipu_ch_param_write_field(p, IPU_FIELD_UBO, u_offset / 8); - ipu_ch_param_write_field(p, IPU_FIELD_VBO, v_offset / 8); - break; - case V4L2_PIX_FMT_YVU420: - ipu_ch_param_write_field(p, IPU_FIELD_SLUV, (stride / 2) - 1); - ipu_ch_param_write_field(p, IPU_FIELD_UBO, v_offset / 8); - ipu_ch_param_write_field(p, IPU_FIELD_VBO, u_offset / 8); - break; - } -} -EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full); - -void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format, - int stride, int height) -{ - int u_offset, v_offset; - int uv_stride = 0; - - switch (pixel_format) { - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YVU420: - uv_stride = stride / 2; - u_offset = stride * height; - v_offset = u_offset + (uv_stride * height / 2); - ipu_cpmem_set_yuv_planar_full(p, pixel_format, stride, - u_offset, v_offset); - break; - } -} -EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar); - -static const struct ipu_rgb def_rgb_32 = { - .red = { .offset = 16, .length = 8, }, - .green = { .offset = 8, .length = 8, }, - .blue = { .offset = 0, .length = 8, }, - .transp = { .offset = 24, .length = 8, }, - .bits_per_pixel = 32, -}; - -static const struct ipu_rgb def_bgr_32 = { - .red = { .offset = 0, .length = 8, }, - .green = { .offset = 8, .length = 8, }, - .blue = { .offset = 16, .length = 8, }, - .transp = { .offset = 24, .length = 8, }, - .bits_per_pixel = 32, -}; - -static const struct ipu_rgb def_rgb_24 = { - .red = { .offset = 16, .length = 8, }, - .green = { .offset = 8, .length = 8, }, - .blue = { .offset = 0, .length = 8, }, - .transp = { .offset = 0, .length = 0, }, - .bits_per_pixel = 24, -}; - -static const struct ipu_rgb def_bgr_24 = { - .red = { .offset = 0, .length = 8, }, - .green = { .offset = 8, .length = 8, }, - .blue = { .offset = 16, .length = 8, }, - .transp = { .offset = 0, .length = 0, }, - .bits_per_pixel = 24, -}; - -static const struct ipu_rgb def_rgb_16 = { - .red = { .offset = 11, .length = 5, }, - .green = { .offset = 5, .length = 6, }, - .blue = { .offset = 0, .length = 5, }, - .transp = { .offset = 0, .length = 0, }, - .bits_per_pixel = 16, -}; - -static const struct ipu_rgb def_bgr_16 = { - .red = { .offset = 0, .length = 5, }, - .green = { .offset = 5, .length = 6, }, - .blue = { .offset = 11, .length = 5, }, - .transp = { .offset = 0, .length = 0, }, - .bits_per_pixel = 16, -}; - -#define Y_OFFSET(pix, x, y) ((x) + pix->width * (y)) -#define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * (y) / 4) + (x) / 2) -#define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \ - (pix->width * pix->height / 4) + \ - (pix->width * (y) / 4) + (x) / 2) - -int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 drm_fourcc) -{ - switch (drm_fourcc) { - case DRM_FORMAT_YUV420: - case DRM_FORMAT_YVU420: - /* pix format */ - ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 2); - /* burst size */ - ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 63); - break; - case DRM_FORMAT_UYVY: - /* bits/pixel */ - ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3); - /* pix format */ - ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 0xA); - /* burst size */ - ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31); - break; - case DRM_FORMAT_YUYV: - /* bits/pixel */ - ipu_ch_param_write_field(cpmem, IPU_FIELD_BPP, 3); - /* pix format */ - ipu_ch_param_write_field(cpmem, IPU_FIELD_PFS, 0x8); - /* burst size */ - ipu_ch_param_write_field(cpmem, IPU_FIELD_NPB, 31); - break; - case DRM_FORMAT_ABGR8888: - case DRM_FORMAT_XBGR8888: - ipu_cpmem_set_format_rgb(cpmem, &def_bgr_32); - break; - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_XRGB8888: - ipu_cpmem_set_format_rgb(cpmem, &def_rgb_32); - break; - case DRM_FORMAT_BGR888: - ipu_cpmem_set_format_rgb(cpmem, &def_bgr_24); - break; - case DRM_FORMAT_RGB888: - ipu_cpmem_set_format_rgb(cpmem, &def_rgb_24); - break; - case DRM_FORMAT_RGB565: - ipu_cpmem_set_format_rgb(cpmem, &def_rgb_16); - break; - case DRM_FORMAT_BGR565: - ipu_cpmem_set_format_rgb(cpmem, &def_bgr_16); - break; - default: - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt); - -/* - * The V4L2 spec defines packed RGB formats in memory byte order, which from - * point of view of the IPU corresponds to little-endian words with the first - * component in the least significant bits. - * The DRM pixel formats and IPU internal representation are ordered the other - * way around, with the first named component ordered at the most significant - * bits. Further, V4L2 formats are not well defined: - * http://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html - * We choose the interpretation which matches GStreamer behavior. - */ -static int v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat) -{ - switch (pixelformat) { - case V4L2_PIX_FMT_RGB565: - /* - * Here we choose the 'corrected' interpretation of RGBP, a - * little-endian 16-bit word with the red component at the most - * significant bits: - * g[2:0]b[4:0] r[4:0]g[5:3] <=> [16:0] R:G:B - */ - return DRM_FORMAT_RGB565; - case V4L2_PIX_FMT_BGR24: - /* B G R <=> [24:0] R:G:B */ - return DRM_FORMAT_RGB888; - case V4L2_PIX_FMT_RGB24: - /* R G B <=> [24:0] B:G:R */ - return DRM_FORMAT_BGR888; - case V4L2_PIX_FMT_BGR32: - /* B G R A <=> [32:0] A:B:G:R */ - return DRM_FORMAT_XRGB8888; - case V4L2_PIX_FMT_RGB32: - /* R G B A <=> [32:0] A:B:G:R */ - return DRM_FORMAT_XBGR8888; - case V4L2_PIX_FMT_UYVY: - return DRM_FORMAT_UYVY; - case V4L2_PIX_FMT_YUYV: - return DRM_FORMAT_YUYV; - case V4L2_PIX_FMT_YUV420: - return DRM_FORMAT_YUV420; - case V4L2_PIX_FMT_YVU420: - return DRM_FORMAT_YVU420; - } - - return -EINVAL; -} - enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc) { switch (drm_fourcc) { @@ -465,66 +81,6 @@ enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc) } EXPORT_SYMBOL_GPL(ipu_drm_fourcc_to_colorspace); -int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem, - struct ipu_image *image) -{ - struct v4l2_pix_format *pix = &image->pix; - int y_offset, u_offset, v_offset; - - pr_debug("%s: resolution: %dx%d stride: %d\n", - __func__, pix->width, pix->height, - pix->bytesperline); - - ipu_cpmem_set_resolution(cpmem, image->rect.width, - image->rect.height); - ipu_cpmem_set_stride(cpmem, pix->bytesperline); - - ipu_cpmem_set_fmt(cpmem, v4l2_pix_fmt_to_drm_fourcc(pix->pixelformat)); - - switch (pix->pixelformat) { - case V4L2_PIX_FMT_YUV420: - case V4L2_PIX_FMT_YVU420: - y_offset = Y_OFFSET(pix, image->rect.left, image->rect.top); - u_offset = U_OFFSET(pix, image->rect.left, - image->rect.top) - y_offset; - v_offset = V_OFFSET(pix, image->rect.left, - image->rect.top) - y_offset; - - ipu_cpmem_set_yuv_planar_full(cpmem, pix->pixelformat, - pix->bytesperline, u_offset, v_offset); - ipu_cpmem_set_buffer(cpmem, 0, image->phys + y_offset); - break; - case V4L2_PIX_FMT_UYVY: - case V4L2_PIX_FMT_YUYV: - ipu_cpmem_set_buffer(cpmem, 0, image->phys + - image->rect.left * 2 + - image->rect.top * image->pix.bytesperline); - break; - case V4L2_PIX_FMT_RGB32: - case V4L2_PIX_FMT_BGR32: - ipu_cpmem_set_buffer(cpmem, 0, image->phys + - image->rect.left * 4 + - image->rect.top * image->pix.bytesperline); - break; - case V4L2_PIX_FMT_RGB565: - ipu_cpmem_set_buffer(cpmem, 0, image->phys + - image->rect.left * 2 + - image->rect.top * image->pix.bytesperline); - break; - case V4L2_PIX_FMT_RGB24: - case V4L2_PIX_FMT_BGR24: - ipu_cpmem_set_buffer(cpmem, 0, image->phys + - image->rect.left * 3 + - image->rect.top * image->pix.bytesperline); - break; - default: - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL_GPL(ipu_cpmem_set_image); - enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat) { switch (pixelformat) { @@ -895,6 +451,12 @@ static int ipu_submodules_init(struct ipu_soc *ipu, struct device *dev = &pdev->dev; const struct ipu_devtype *devtype = ipu->devtype; + ret = ipu_cpmem_init(ipu, dev, ipu_base + devtype->cpmem_ofs); + if (ret) { + unit = "cpmem"; + goto err_cpmem; + } + ret = ipu_di_init(ipu, dev, 0, ipu_base + devtype->disp0_ofs, IPU_CONF_DI0_EN, ipu_clk); if (ret) { @@ -949,6 +511,8 @@ static int ipu_submodules_init(struct ipu_soc *ipu, err_di_1: ipu_di_exit(ipu, 0); err_di_0: + ipu_cpmem_exit(ipu); +err_cpmem: dev_err(&pdev->dev, "init %s failed with %d\n", unit, ret); return ret; } @@ -1025,6 +589,7 @@ static void ipu_submodules_exit(struct ipu_soc *ipu) ipu_dc_exit(ipu); ipu_di_exit(ipu, 1); ipu_di_exit(ipu, 0); + ipu_cpmem_exit(ipu); } static int platform_remove_devices_fn(struct device *dev, void *unused) @@ -1265,10 +830,8 @@ static int ipu_probe(struct platform_device *pdev) ipu->idmac_reg = devm_ioremap(&pdev->dev, ipu_base + devtype->cm_ofs + IPU_CM_IDMAC_REG_OFS, PAGE_SIZE); - ipu->cpmem_base = devm_ioremap(&pdev->dev, - ipu_base + devtype->cpmem_ofs, PAGE_SIZE); - if (!ipu->cm_reg || !ipu->idmac_reg || !ipu->cpmem_base) + if (!ipu->cm_reg || !ipu->idmac_reg) return -ENOMEM; ipu->clk = devm_clk_get(&pdev->dev, "bus"); diff --git a/drivers/gpu/ipu-v3/ipu-cpmem.c b/drivers/gpu/ipu-v3/ipu-cpmem.c new file mode 100644 index 000000000000..7adfa78a48bc --- /dev/null +++ b/drivers/gpu/ipu-v3/ipu-cpmem.c @@ -0,0 +1,597 @@ +/* + * Copyright (C) 2012 Mentor Graphics Inc. + * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include "ipu-prv.h" + +struct ipu_cpmem_word { + u32 data[5]; + u32 res[3]; +}; + +struct ipu_ch_param { + struct ipu_cpmem_word word[2]; +}; + +struct ipu_cpmem { + struct ipu_ch_param __iomem *base; + u32 module; + spinlock_t lock; + int use_count; + struct ipu_soc *ipu; +}; + +#define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size)) + +#define IPU_FIELD_UBO IPU_CPMEM_WORD(0, 46, 22) +#define IPU_FIELD_VBO IPU_CPMEM_WORD(0, 68, 22) +#define IPU_FIELD_IOX IPU_CPMEM_WORD(0, 90, 4) +#define IPU_FIELD_RDRW IPU_CPMEM_WORD(0, 94, 1) +#define IPU_FIELD_SO IPU_CPMEM_WORD(0, 113, 1) +#define IPU_FIELD_SLY IPU_CPMEM_WORD(1, 102, 14) +#define IPU_FIELD_SLUV IPU_CPMEM_WORD(1, 128, 14) + +#define IPU_FIELD_XV IPU_CPMEM_WORD(0, 0, 10) +#define IPU_FIELD_YV IPU_CPMEM_WORD(0, 10, 9) +#define IPU_FIELD_XB IPU_CPMEM_WORD(0, 19, 13) +#define IPU_FIELD_YB IPU_CPMEM_WORD(0, 32, 12) +#define IPU_FIELD_NSB_B IPU_CPMEM_WORD(0, 44, 1) +#define IPU_FIELD_CF IPU_CPMEM_WORD(0, 45, 1) +#define IPU_FIELD_SX IPU_CPMEM_WORD(0, 46, 12) +#define IPU_FIELD_SY IPU_CPMEM_WORD(0, 58, 11) +#define IPU_FIELD_NS IPU_CPMEM_WORD(0, 69, 10) +#define IPU_FIELD_SDX IPU_CPMEM_WORD(0, 79, 7) +#define IPU_FIELD_SM IPU_CPMEM_WORD(0, 86, 10) +#define IPU_FIELD_SCC IPU_CPMEM_WORD(0, 96, 1) +#define IPU_FIELD_SCE IPU_CPMEM_WORD(0, 97, 1) +#define IPU_FIELD_SDY IPU_CPMEM_WORD(0, 98, 7) +#define IPU_FIELD_SDRX IPU_CPMEM_WORD(0, 105, 1) +#define IPU_FIELD_SDRY IPU_CPMEM_WORD(0, 106, 1) +#define IPU_FIELD_BPP IPU_CPMEM_WORD(0, 107, 3) +#define IPU_FIELD_DEC_SEL IPU_CPMEM_WORD(0, 110, 2) +#define IPU_FIELD_DIM IPU_CPMEM_WORD(0, 112, 1) +#define IPU_FIELD_BNDM IPU_CPMEM_WORD(0, 114, 3) +#define IPU_FIELD_BM IPU_CPMEM_WORD(0, 117, 2) +#define IPU_FIELD_ROT IPU_CPMEM_WORD(0, 119, 1) +#define IPU_FIELD_HF IPU_CPMEM_WORD(0, 120, 1) +#define IPU_FIELD_VF IPU_CPMEM_WORD(0, 121, 1) +#define IPU_FIELD_THE IPU_CPMEM_WORD(0, 122, 1) +#define IPU_FIELD_CAP IPU_CPMEM_WORD(0, 123, 1) +#define IPU_FIELD_CAE IPU_CPMEM_WORD(0, 124, 1) +#define IPU_FIELD_FW IPU_CPMEM_WORD(0, 125, 13) +#define IPU_FIELD_FH IPU_CPMEM_WORD(0, 138, 12) +#define IPU_FIELD_EBA0 IPU_CPMEM_WORD(1, 0, 29) +#define IPU_FIELD_EBA1 IPU_CPMEM_WORD(1, 29, 29) +#define IPU_FIELD_ILO IPU_CPMEM_WORD(1, 58, 20) +#define IPU_FIELD_NPB IPU_CPMEM_WORD(1, 78, 7) +#define IPU_FIELD_PFS IPU_CPMEM_WORD(1, 85, 4) +#define IPU_FIELD_ALU IPU_CPMEM_WORD(1, 89, 1) +#define IPU_FIELD_ALBM IPU_CPMEM_WORD(1, 90, 3) +#define IPU_FIELD_ID IPU_CPMEM_WORD(1, 93, 2) +#define IPU_FIELD_TH IPU_CPMEM_WORD(1, 95, 7) +#define IPU_FIELD_SL IPU_CPMEM_WORD(1, 102, 14) +#define IPU_FIELD_WID0 IPU_CPMEM_WORD(1, 116, 3) +#define IPU_FIELD_WID1 IPU_CPMEM_WORD(1, 119, 3) +#define IPU_FIELD_WID2 IPU_CPMEM_WORD(1, 122, 3) +#define IPU_FIELD_WID3 IPU_CPMEM_WORD(1, 125, 3) +#define IPU_FIELD_OFS0 IPU_CPMEM_WORD(1, 128, 5) +#define IPU_FIELD_OFS1 IPU_CPMEM_WORD(1, 133, 5) +#define IPU_FIELD_OFS2 IPU_CPMEM_WORD(1, 138, 5) +#define IPU_FIELD_OFS3 IPU_CPMEM_WORD(1, 143, 5) +#define IPU_FIELD_SXYS IPU_CPMEM_WORD(1, 148, 1) +#define IPU_FIELD_CRE IPU_CPMEM_WORD(1, 149, 1) +#define IPU_FIELD_DEC_SEL2 IPU_CPMEM_WORD(1, 150, 1) + +static inline struct ipu_ch_param __iomem * +ipu_get_cpmem(struct ipuv3_channel *ch) +{ + struct ipu_cpmem *cpmem = ch->ipu->cpmem_priv; + + return cpmem->base + ch->num; +} + +static void ipu_ch_param_write_field(struct ipuv3_channel *ch, u32 wbs, u32 v) +{ + struct ipu_ch_param __iomem *base = ipu_get_cpmem(ch); + u32 bit = (wbs >> 8) % 160; + u32 size = wbs & 0xff; + u32 word = (wbs >> 8) / 160; + u32 i = bit / 32; + u32 ofs = bit % 32; + u32 mask = (1 << size) - 1; + u32 val; + + pr_debug("%s %d %d %d\n", __func__, word, bit , size); + + val = readl(&base->word[word].data[i]); + val &= ~(mask << ofs); + val |= v << ofs; + writel(val, &base->word[word].data[i]); + + if ((bit + size - 1) / 32 > i) { + val = readl(&base->word[word].data[i + 1]); + val &= ~(mask >> (ofs ? (32 - ofs) : 0)); + val |= v >> (ofs ? (32 - ofs) : 0); + writel(val, &base->word[word].data[i + 1]); + } +} + +static u32 ipu_ch_param_read_field(struct ipuv3_channel *ch, u32 wbs) +{ + struct ipu_ch_param __iomem *base = ipu_get_cpmem(ch); + u32 bit = (wbs >> 8) % 160; + u32 size = wbs & 0xff; + u32 word = (wbs >> 8) / 160; + u32 i = bit / 32; + u32 ofs = bit % 32; + u32 mask = (1 << size) - 1; + u32 val = 0; + + pr_debug("%s %d %d %d\n", __func__, word, bit , size); + + val = (readl(&base->word[word].data[i]) >> ofs) & mask; + + if ((bit + size - 1) / 32 > i) { + u32 tmp; + + tmp = readl(&base->word[word].data[i + 1]); + tmp &= mask >> (ofs ? (32 - ofs) : 0); + val |= tmp << (ofs ? (32 - ofs) : 0); + } + + return val; +} + +/* + * The V4L2 spec defines packed RGB formats in memory byte order, which from + * point of view of the IPU corresponds to little-endian words with the first + * component in the least significant bits. + * The DRM pixel formats and IPU internal representation are ordered the other + * way around, with the first named component ordered at the most significant + * bits. Further, V4L2 formats are not well defined: + * http://linuxtv.org/downloads/v4l-dvb-apis/packed-rgb.html + * We choose the interpretation which matches GStreamer behavior. + */ +static int v4l2_pix_fmt_to_drm_fourcc(u32 pixelformat) +{ + switch (pixelformat) { + case V4L2_PIX_FMT_RGB565: + /* + * Here we choose the 'corrected' interpretation of RGBP, a + * little-endian 16-bit word with the red component at the most + * significant bits: + * g[2:0]b[4:0] r[4:0]g[5:3] <=> [16:0] R:G:B + */ + return DRM_FORMAT_RGB565; + case V4L2_PIX_FMT_BGR24: + /* B G R <=> [24:0] R:G:B */ + return DRM_FORMAT_RGB888; + case V4L2_PIX_FMT_RGB24: + /* R G B <=> [24:0] B:G:R */ + return DRM_FORMAT_BGR888; + case V4L2_PIX_FMT_BGR32: + /* B G R A <=> [32:0] A:B:G:R */ + return DRM_FORMAT_XRGB8888; + case V4L2_PIX_FMT_RGB32: + /* R G B A <=> [32:0] A:B:G:R */ + return DRM_FORMAT_XBGR8888; + case V4L2_PIX_FMT_UYVY: + return DRM_FORMAT_UYVY; + case V4L2_PIX_FMT_YUYV: + return DRM_FORMAT_YUYV; + case V4L2_PIX_FMT_YUV420: + return DRM_FORMAT_YUV420; + case V4L2_PIX_FMT_YVU420: + return DRM_FORMAT_YVU420; + } + + return -EINVAL; +} + +void ipu_cpmem_zero(struct ipuv3_channel *ch) +{ + struct ipu_ch_param __iomem *p = ipu_get_cpmem(ch); + void __iomem *base = p; + int i; + + for (i = 0; i < sizeof(*p) / sizeof(u32); i++) + writel(0, base + i * sizeof(u32)); +} +EXPORT_SYMBOL_GPL(ipu_cpmem_zero); + +void ipu_cpmem_set_resolution(struct ipuv3_channel *ch, int xres, int yres) +{ + ipu_ch_param_write_field(ch, IPU_FIELD_FW, xres - 1); + ipu_ch_param_write_field(ch, IPU_FIELD_FH, yres - 1); +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_resolution); + +void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride) +{ + ipu_ch_param_write_field(ch, IPU_FIELD_SLY, stride - 1); +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_stride); + +void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch) +{ + struct ipu_soc *ipu = ch->ipu; + u32 val; + + if (ipu->ipu_type == IPUV3EX) + ipu_ch_param_write_field(ch, IPU_FIELD_ID, 1); + + val = ipu_idmac_read(ipu, IDMAC_CHA_PRI(ch->num)); + val |= 1 << (ch->num % 32); + ipu_idmac_write(ipu, val, IDMAC_CHA_PRI(ch->num)); +}; +EXPORT_SYMBOL_GPL(ipu_cpmem_set_high_priority); + +void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf) +{ + if (bufnum) + ipu_ch_param_write_field(ch, IPU_FIELD_EBA1, buf >> 3); + else + ipu_ch_param_write_field(ch, IPU_FIELD_EBA0, buf >> 3); +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_buffer); + +void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride) +{ + ipu_ch_param_write_field(ch, IPU_FIELD_SO, 1); + ipu_ch_param_write_field(ch, IPU_FIELD_ILO, stride / 8); + ipu_ch_param_write_field(ch, IPU_FIELD_SLY, (stride * 2) - 1); +}; +EXPORT_SYMBOL_GPL(ipu_cpmem_interlaced_scan); + +void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize) +{ + ipu_ch_param_write_field(ch, IPU_FIELD_NPB, burstsize - 1); +}; +EXPORT_SYMBOL_GPL(ipu_cpmem_set_burstsize); + +int ipu_cpmem_set_format_rgb(struct ipuv3_channel *ch, + const struct ipu_rgb *rgb) +{ + int bpp = 0, npb = 0, ro, go, bo, to; + + ro = rgb->bits_per_pixel - rgb->red.length - rgb->red.offset; + go = rgb->bits_per_pixel - rgb->green.length - rgb->green.offset; + bo = rgb->bits_per_pixel - rgb->blue.length - rgb->blue.offset; + to = rgb->bits_per_pixel - rgb->transp.length - rgb->transp.offset; + + ipu_ch_param_write_field(ch, IPU_FIELD_WID0, rgb->red.length - 1); + ipu_ch_param_write_field(ch, IPU_FIELD_OFS0, ro); + ipu_ch_param_write_field(ch, IPU_FIELD_WID1, rgb->green.length - 1); + ipu_ch_param_write_field(ch, IPU_FIELD_OFS1, go); + ipu_ch_param_write_field(ch, IPU_FIELD_WID2, rgb->blue.length - 1); + ipu_ch_param_write_field(ch, IPU_FIELD_OFS2, bo); + + if (rgb->transp.length) { + ipu_ch_param_write_field(ch, IPU_FIELD_WID3, + rgb->transp.length - 1); + ipu_ch_param_write_field(ch, IPU_FIELD_OFS3, to); + } else { + ipu_ch_param_write_field(ch, IPU_FIELD_WID3, 7); + ipu_ch_param_write_field(ch, IPU_FIELD_OFS3, + rgb->bits_per_pixel); + } + + switch (rgb->bits_per_pixel) { + case 32: + bpp = 0; + npb = 15; + break; + case 24: + bpp = 1; + npb = 19; + break; + case 16: + bpp = 3; + npb = 31; + break; + case 8: + bpp = 5; + npb = 63; + break; + default: + return -EINVAL; + } + ipu_ch_param_write_field(ch, IPU_FIELD_BPP, bpp); + ipu_ch_param_write_field(ch, IPU_FIELD_NPB, npb); + ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 7); /* rgb mode */ + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_rgb); + +int ipu_cpmem_set_format_passthrough(struct ipuv3_channel *ch, int width) +{ + int bpp = 0, npb = 0; + + switch (width) { + case 32: + bpp = 0; + npb = 15; + break; + case 24: + bpp = 1; + npb = 19; + break; + case 16: + bpp = 3; + npb = 31; + break; + case 8: + bpp = 5; + npb = 63; + break; + default: + return -EINVAL; + } + + ipu_ch_param_write_field(ch, IPU_FIELD_BPP, bpp); + ipu_ch_param_write_field(ch, IPU_FIELD_NPB, npb); + ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 6); /* raw mode */ + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_format_passthrough); + +void ipu_cpmem_set_yuv_interleaved(struct ipuv3_channel *ch, u32 pixel_format) +{ + switch (pixel_format) { + case V4L2_PIX_FMT_UYVY: + ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3); /* bits/pixel */ + ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0xA);/* pix fmt */ + ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);/* burst size */ + break; + case V4L2_PIX_FMT_YUYV: + ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3); /* bits/pixel */ + ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0x8);/* pix fmt */ + ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31);/* burst size */ + break; + } +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_interleaved); + +void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch, + u32 pixel_format, int stride, + int u_offset, int v_offset) +{ + switch (pixel_format) { + case V4L2_PIX_FMT_YUV420: + ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, (stride / 2) - 1); + ipu_ch_param_write_field(ch, IPU_FIELD_UBO, u_offset / 8); + ipu_ch_param_write_field(ch, IPU_FIELD_VBO, v_offset / 8); + break; + case V4L2_PIX_FMT_YVU420: + ipu_ch_param_write_field(ch, IPU_FIELD_SLUV, (stride / 2) - 1); + ipu_ch_param_write_field(ch, IPU_FIELD_UBO, v_offset / 8); + ipu_ch_param_write_field(ch, IPU_FIELD_VBO, u_offset / 8); + break; + } +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar_full); + +void ipu_cpmem_set_yuv_planar(struct ipuv3_channel *ch, + u32 pixel_format, int stride, int height) +{ + int u_offset, v_offset; + int uv_stride = 0; + + switch (pixel_format) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + uv_stride = stride / 2; + u_offset = stride * height; + v_offset = u_offset + (uv_stride * height / 2); + ipu_cpmem_set_yuv_planar_full(ch, pixel_format, stride, + u_offset, v_offset); + break; + } +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_yuv_planar); + +static const struct ipu_rgb def_rgb_32 = { + .red = { .offset = 16, .length = 8, }, + .green = { .offset = 8, .length = 8, }, + .blue = { .offset = 0, .length = 8, }, + .transp = { .offset = 24, .length = 8, }, + .bits_per_pixel = 32, +}; + +static const struct ipu_rgb def_bgr_32 = { + .red = { .offset = 0, .length = 8, }, + .green = { .offset = 8, .length = 8, }, + .blue = { .offset = 16, .length = 8, }, + .transp = { .offset = 24, .length = 8, }, + .bits_per_pixel = 32, +}; + +static const struct ipu_rgb def_rgb_24 = { + .red = { .offset = 16, .length = 8, }, + .green = { .offset = 8, .length = 8, }, + .blue = { .offset = 0, .length = 8, }, + .transp = { .offset = 0, .length = 0, }, + .bits_per_pixel = 24, +}; + +static const struct ipu_rgb def_bgr_24 = { + .red = { .offset = 0, .length = 8, }, + .green = { .offset = 8, .length = 8, }, + .blue = { .offset = 16, .length = 8, }, + .transp = { .offset = 0, .length = 0, }, + .bits_per_pixel = 24, +}; + +static const struct ipu_rgb def_rgb_16 = { + .red = { .offset = 11, .length = 5, }, + .green = { .offset = 5, .length = 6, }, + .blue = { .offset = 0, .length = 5, }, + .transp = { .offset = 0, .length = 0, }, + .bits_per_pixel = 16, +}; + +static const struct ipu_rgb def_bgr_16 = { + .red = { .offset = 0, .length = 5, }, + .green = { .offset = 5, .length = 6, }, + .blue = { .offset = 11, .length = 5, }, + .transp = { .offset = 0, .length = 0, }, + .bits_per_pixel = 16, +}; + +#define Y_OFFSET(pix, x, y) ((x) + pix->width * (y)) +#define U_OFFSET(pix, x, y) ((pix->width * pix->height) + \ + (pix->width * (y) / 4) + (x) / 2) +#define V_OFFSET(pix, x, y) ((pix->width * pix->height) + \ + (pix->width * pix->height / 4) + \ + (pix->width * (y) / 4) + (x) / 2) + +int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc) +{ + switch (drm_fourcc) { + case DRM_FORMAT_YUV420: + case DRM_FORMAT_YVU420: + /* pix format */ + ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 2); + /* burst size */ + ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31); + break; + case DRM_FORMAT_UYVY: + /* bits/pixel */ + ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3); + /* pix format */ + ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0xA); + /* burst size */ + ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31); + break; + case DRM_FORMAT_YUYV: + /* bits/pixel */ + ipu_ch_param_write_field(ch, IPU_FIELD_BPP, 3); + /* pix format */ + ipu_ch_param_write_field(ch, IPU_FIELD_PFS, 0x8); + /* burst size */ + ipu_ch_param_write_field(ch, IPU_FIELD_NPB, 31); + break; + case DRM_FORMAT_ABGR8888: + case DRM_FORMAT_XBGR8888: + ipu_cpmem_set_format_rgb(ch, &def_bgr_32); + break; + case DRM_FORMAT_ARGB8888: + case DRM_FORMAT_XRGB8888: + ipu_cpmem_set_format_rgb(ch, &def_rgb_32); + break; + case DRM_FORMAT_BGR888: + ipu_cpmem_set_format_rgb(ch, &def_bgr_24); + break; + case DRM_FORMAT_RGB888: + ipu_cpmem_set_format_rgb(ch, &def_rgb_24); + break; + case DRM_FORMAT_RGB565: + ipu_cpmem_set_format_rgb(ch, &def_rgb_16); + break; + case DRM_FORMAT_BGR565: + ipu_cpmem_set_format_rgb(ch, &def_bgr_16); + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_fmt); + +int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image) +{ + struct v4l2_pix_format *pix = &image->pix; + int y_offset, u_offset, v_offset; + + pr_debug("%s: resolution: %dx%d stride: %d\n", + __func__, pix->width, pix->height, + pix->bytesperline); + + ipu_cpmem_set_resolution(ch, image->rect.width, image->rect.height); + ipu_cpmem_set_stride(ch, pix->bytesperline); + + ipu_cpmem_set_fmt(ch, v4l2_pix_fmt_to_drm_fourcc(pix->pixelformat)); + + switch (pix->pixelformat) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + y_offset = Y_OFFSET(pix, image->rect.left, image->rect.top); + u_offset = U_OFFSET(pix, image->rect.left, + image->rect.top) - y_offset; + v_offset = V_OFFSET(pix, image->rect.left, + image->rect.top) - y_offset; + + ipu_cpmem_set_yuv_planar_full(ch, pix->pixelformat, + pix->bytesperline, u_offset, v_offset); + ipu_cpmem_set_buffer(ch, 0, image->phys + y_offset); + break; + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: + ipu_cpmem_set_buffer(ch, 0, image->phys + + image->rect.left * 2 + + image->rect.top * image->pix.bytesperline); + break; + case V4L2_PIX_FMT_RGB32: + case V4L2_PIX_FMT_BGR32: + ipu_cpmem_set_buffer(ch, 0, image->phys + + image->rect.left * 4 + + image->rect.top * image->pix.bytesperline); + break; + case V4L2_PIX_FMT_RGB565: + ipu_cpmem_set_buffer(ch, 0, image->phys + + image->rect.left * 2 + + image->rect.top * image->pix.bytesperline); + break; + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + ipu_cpmem_set_buffer(ch, 0, image->phys + + image->rect.left * 3 + + image->rect.top * image->pix.bytesperline); + break; + default: + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ipu_cpmem_set_image); + +int ipu_cpmem_init(struct ipu_soc *ipu, struct device *dev, unsigned long base) +{ + struct ipu_cpmem *cpmem; + + cpmem = devm_kzalloc(dev, sizeof(*cpmem), GFP_KERNEL); + if (!cpmem) + return -ENOMEM; + + ipu->cpmem_priv = cpmem; + + spin_lock_init(&cpmem->lock); + cpmem->base = devm_ioremap(dev, base, SZ_128K); + if (!cpmem->base) + return -ENOMEM; + + dev_dbg(dev, "CPMEM base: 0x%08lx remapped to %p\n", + base, cpmem->base); + cpmem->ipu = ipu; + + return 0; +} + +void ipu_cpmem_exit(struct ipu_soc *ipu) +{ +} diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index c93f50ec04f7..0a7b2adaba39 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -148,6 +148,7 @@ struct ipuv3_channel { struct ipu_soc *ipu; }; +struct ipu_cpmem; struct ipu_dc_priv; struct ipu_dmfc_priv; struct ipu_di; @@ -164,7 +165,6 @@ struct ipu_soc { void __iomem *cm_reg; void __iomem *idmac_reg; - struct ipu_ch_param __iomem *cpmem_base; int usecount; @@ -176,6 +176,7 @@ struct ipu_soc { int irq_err; struct irq_domain *domain; + struct ipu_cpmem *cpmem_priv; struct ipu_dc_priv *dc_priv; struct ipu_dp_priv *dp_priv; struct ipu_dmfc_priv *dmfc_priv; @@ -183,6 +184,17 @@ struct ipu_soc { struct ipu_smfc_priv *smfc_priv; }; +static inline u32 ipu_idmac_read(struct ipu_soc *ipu, unsigned offset) +{ + return readl(ipu->idmac_reg + offset); +} + +static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value, + unsigned offset) +{ + writel(value, ipu->idmac_reg + offset); +} + void ipu_srm_dp_sync_update(struct ipu_soc *ipu); int ipu_module_enable(struct ipu_soc *ipu, u32 mask); diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index 3e43e22cdff9..ef64b66b18df 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -107,6 +107,42 @@ void ipu_idmac_set_double_buffer(struct ipuv3_channel *channel, int ipu_idmac_get_current_buffer(struct ipuv3_channel *channel); void ipu_idmac_select_buffer(struct ipuv3_channel *channel, u32 buf_num); +/* + * IPU Channel Parameter Memory (cpmem) functions + */ +struct ipu_rgb { + struct fb_bitfield red; + struct fb_bitfield green; + struct fb_bitfield blue; + struct fb_bitfield transp; + int bits_per_pixel; +}; + +struct ipu_image { + struct v4l2_pix_format pix; + struct v4l2_rect rect; + dma_addr_t phys; +}; + +void ipu_cpmem_zero(struct ipuv3_channel *ch); +void ipu_cpmem_set_resolution(struct ipuv3_channel *ch, int xres, int yres); +void ipu_cpmem_set_stride(struct ipuv3_channel *ch, int stride); +void ipu_cpmem_set_high_priority(struct ipuv3_channel *ch); +void ipu_cpmem_set_buffer(struct ipuv3_channel *ch, int bufnum, dma_addr_t buf); +void ipu_cpmem_interlaced_scan(struct ipuv3_channel *ch, int stride); +void ipu_cpmem_set_burstsize(struct ipuv3_channel *ch, int burstsize); +int ipu_cpmem_set_format_rgb(struct ipuv3_channel *ch, + const struct ipu_rgb *rgb); +int ipu_cpmem_set_format_passthrough(struct ipuv3_channel *ch, int width); +void ipu_cpmem_set_yuv_interleaved(struct ipuv3_channel *ch, u32 pixel_format); +void ipu_cpmem_set_yuv_planar_full(struct ipuv3_channel *ch, + u32 pixel_format, int stride, + int u_offset, int v_offset); +void ipu_cpmem_set_yuv_planar(struct ipuv3_channel *ch, + u32 pixel_format, int stride, int height); +int ipu_cpmem_set_fmt(struct ipuv3_channel *ch, u32 drm_fourcc); +int ipu_cpmem_set_image(struct ipuv3_channel *ch, struct ipu_image *image); + /* * IPU Display Controller (dc) functions */ @@ -180,161 +216,9 @@ int ipu_smfc_disable(struct ipu_soc *ipu); int ipu_smfc_map_channel(struct ipu_soc *ipu, int channel, int csi_id, int mipi_id); int ipu_smfc_set_burstsize(struct ipu_soc *ipu, int channel, int burstsize); -#define IPU_CPMEM_WORD(word, ofs, size) ((((word) * 160 + (ofs)) << 8) | (size)) - -#define IPU_FIELD_UBO IPU_CPMEM_WORD(0, 46, 22) -#define IPU_FIELD_VBO IPU_CPMEM_WORD(0, 68, 22) -#define IPU_FIELD_IOX IPU_CPMEM_WORD(0, 90, 4) -#define IPU_FIELD_RDRW IPU_CPMEM_WORD(0, 94, 1) -#define IPU_FIELD_SO IPU_CPMEM_WORD(0, 113, 1) -#define IPU_FIELD_SLY IPU_CPMEM_WORD(1, 102, 14) -#define IPU_FIELD_SLUV IPU_CPMEM_WORD(1, 128, 14) - -#define IPU_FIELD_XV IPU_CPMEM_WORD(0, 0, 10) -#define IPU_FIELD_YV IPU_CPMEM_WORD(0, 10, 9) -#define IPU_FIELD_XB IPU_CPMEM_WORD(0, 19, 13) -#define IPU_FIELD_YB IPU_CPMEM_WORD(0, 32, 12) -#define IPU_FIELD_NSB_B IPU_CPMEM_WORD(0, 44, 1) -#define IPU_FIELD_CF IPU_CPMEM_WORD(0, 45, 1) -#define IPU_FIELD_SX IPU_CPMEM_WORD(0, 46, 12) -#define IPU_FIELD_SY IPU_CPMEM_WORD(0, 58, 11) -#define IPU_FIELD_NS IPU_CPMEM_WORD(0, 69, 10) -#define IPU_FIELD_SDX IPU_CPMEM_WORD(0, 79, 7) -#define IPU_FIELD_SM IPU_CPMEM_WORD(0, 86, 10) -#define IPU_FIELD_SCC IPU_CPMEM_WORD(0, 96, 1) -#define IPU_FIELD_SCE IPU_CPMEM_WORD(0, 97, 1) -#define IPU_FIELD_SDY IPU_CPMEM_WORD(0, 98, 7) -#define IPU_FIELD_SDRX IPU_CPMEM_WORD(0, 105, 1) -#define IPU_FIELD_SDRY IPU_CPMEM_WORD(0, 106, 1) -#define IPU_FIELD_BPP IPU_CPMEM_WORD(0, 107, 3) -#define IPU_FIELD_DEC_SEL IPU_CPMEM_WORD(0, 110, 2) -#define IPU_FIELD_DIM IPU_CPMEM_WORD(0, 112, 1) -#define IPU_FIELD_BNDM IPU_CPMEM_WORD(0, 114, 3) -#define IPU_FIELD_BM IPU_CPMEM_WORD(0, 117, 2) -#define IPU_FIELD_ROT IPU_CPMEM_WORD(0, 119, 1) -#define IPU_FIELD_HF IPU_CPMEM_WORD(0, 120, 1) -#define IPU_FIELD_VF IPU_CPMEM_WORD(0, 121, 1) -#define IPU_FIELD_THE IPU_CPMEM_WORD(0, 122, 1) -#define IPU_FIELD_CAP IPU_CPMEM_WORD(0, 123, 1) -#define IPU_FIELD_CAE IPU_CPMEM_WORD(0, 124, 1) -#define IPU_FIELD_FW IPU_CPMEM_WORD(0, 125, 13) -#define IPU_FIELD_FH IPU_CPMEM_WORD(0, 138, 12) -#define IPU_FIELD_EBA0 IPU_CPMEM_WORD(1, 0, 29) -#define IPU_FIELD_EBA1 IPU_CPMEM_WORD(1, 29, 29) -#define IPU_FIELD_ILO IPU_CPMEM_WORD(1, 58, 20) -#define IPU_FIELD_NPB IPU_CPMEM_WORD(1, 78, 7) -#define IPU_FIELD_PFS IPU_CPMEM_WORD(1, 85, 4) -#define IPU_FIELD_ALU IPU_CPMEM_WORD(1, 89, 1) -#define IPU_FIELD_ALBM IPU_CPMEM_WORD(1, 90, 3) -#define IPU_FIELD_ID IPU_CPMEM_WORD(1, 93, 2) -#define IPU_FIELD_TH IPU_CPMEM_WORD(1, 95, 7) -#define IPU_FIELD_SL IPU_CPMEM_WORD(1, 102, 14) -#define IPU_FIELD_WID0 IPU_CPMEM_WORD(1, 116, 3) -#define IPU_FIELD_WID1 IPU_CPMEM_WORD(1, 119, 3) -#define IPU_FIELD_WID2 IPU_CPMEM_WORD(1, 122, 3) -#define IPU_FIELD_WID3 IPU_CPMEM_WORD(1, 125, 3) -#define IPU_FIELD_OFS0 IPU_CPMEM_WORD(1, 128, 5) -#define IPU_FIELD_OFS1 IPU_CPMEM_WORD(1, 133, 5) -#define IPU_FIELD_OFS2 IPU_CPMEM_WORD(1, 138, 5) -#define IPU_FIELD_OFS3 IPU_CPMEM_WORD(1, 143, 5) -#define IPU_FIELD_SXYS IPU_CPMEM_WORD(1, 148, 1) -#define IPU_FIELD_CRE IPU_CPMEM_WORD(1, 149, 1) -#define IPU_FIELD_DEC_SEL2 IPU_CPMEM_WORD(1, 150, 1) - -struct ipu_cpmem_word { - u32 data[5]; - u32 res[3]; -}; - -struct ipu_ch_param { - struct ipu_cpmem_word word[2]; -}; - -void ipu_ch_param_write_field(struct ipu_ch_param __iomem *base, u32 wbs, u32 v); -u32 ipu_ch_param_read_field(struct ipu_ch_param __iomem *base, u32 wbs); -struct ipu_ch_param __iomem *ipu_get_cpmem(struct ipuv3_channel *channel); -void ipu_ch_param_dump(struct ipu_ch_param __iomem *p); - -static inline void ipu_ch_param_zero(struct ipu_ch_param __iomem *p) -{ - int i; - void __iomem *base = p; - - for (i = 0; i < sizeof(*p) / sizeof(u32); i++) - writel(0, base + i * sizeof(u32)); -} - -static inline void ipu_cpmem_set_buffer(struct ipu_ch_param __iomem *p, - int bufnum, dma_addr_t buf) -{ - if (bufnum) - ipu_ch_param_write_field(p, IPU_FIELD_EBA1, buf >> 3); - else - ipu_ch_param_write_field(p, IPU_FIELD_EBA0, buf >> 3); -} - -static inline void ipu_cpmem_set_resolution(struct ipu_ch_param __iomem *p, - int xres, int yres) -{ - ipu_ch_param_write_field(p, IPU_FIELD_FW, xres - 1); - ipu_ch_param_write_field(p, IPU_FIELD_FH, yres - 1); -} - -static inline void ipu_cpmem_set_stride(struct ipu_ch_param __iomem *p, - int stride) -{ - ipu_ch_param_write_field(p, IPU_FIELD_SLY, stride - 1); -} - -void ipu_cpmem_set_high_priority(struct ipuv3_channel *channel); - -struct ipu_rgb { - struct fb_bitfield red; - struct fb_bitfield green; - struct fb_bitfield blue; - struct fb_bitfield transp; - int bits_per_pixel; -}; - -struct ipu_image { - struct v4l2_pix_format pix; - struct v4l2_rect rect; - dma_addr_t phys; -}; - -int ipu_cpmem_set_format_passthrough(struct ipu_ch_param __iomem *p, - int width); - -int ipu_cpmem_set_format_rgb(struct ipu_ch_param __iomem *, - const struct ipu_rgb *rgb); - -static inline void ipu_cpmem_interlaced_scan(struct ipu_ch_param *p, - int stride) -{ - ipu_ch_param_write_field(p, IPU_FIELD_SO, 1); - ipu_ch_param_write_field(p, IPU_FIELD_ILO, stride / 8); - ipu_ch_param_write_field(p, IPU_FIELD_SLY, (stride * 2) - 1); -}; - -void ipu_cpmem_set_yuv_planar(struct ipu_ch_param __iomem *p, u32 pixel_format, - int stride, int height); -void ipu_cpmem_set_yuv_interleaved(struct ipu_ch_param __iomem *p, - u32 pixel_format); -void ipu_cpmem_set_yuv_planar_full(struct ipu_ch_param __iomem *p, - u32 pixel_format, int stride, int u_offset, int v_offset); -int ipu_cpmem_set_fmt(struct ipu_ch_param __iomem *cpmem, u32 pixelformat); -int ipu_cpmem_set_image(struct ipu_ch_param __iomem *cpmem, - struct ipu_image *image); - enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc); enum ipu_color_space ipu_pixelformat_to_colorspace(u32 pixelformat); -static inline void ipu_cpmem_set_burstsize(struct ipu_ch_param __iomem *p, - int burstsize) -{ - ipu_ch_param_write_field(p, IPU_FIELD_NPB, burstsize - 1); -}; - struct ipu_client_platformdata { int csi; int di; -- GitLab From 2eb671c485c06133ff0b568d5ec3c09fda0f4359 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Wed, 25 Jun 2014 18:05:48 -0700 Subject: [PATCH 0851/9167] staging: imx-drm: Convert to new ipu_cpmem API The ipu_cpmem_*() calls now take a channel pointer instead of a pointer into cpmem for that channel. Signed-off-by: Steve Longerbeam Signed-off-by: Philipp Zabel --- drivers/staging/imx-drm/ipuv3-plane.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/staging/imx-drm/ipuv3-plane.c b/drivers/staging/imx-drm/ipuv3-plane.c index 6f393a11f44d..6ffe1bbbcf16 100644 --- a/drivers/staging/imx-drm/ipuv3-plane.c +++ b/drivers/staging/imx-drm/ipuv3-plane.c @@ -62,7 +62,6 @@ static inline int calc_bandwidth(int width, int height, unsigned int vref) int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, int x, int y) { - struct ipu_ch_param __iomem *cpmem; struct drm_gem_cma_object *cma_obj; unsigned long eba; @@ -75,13 +74,12 @@ 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); - cpmem = ipu_get_cpmem(ipu_plane->ipu_ch); - ipu_cpmem_set_stride(cpmem, fb->pitches[0]); + 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(cpmem, 0, eba); - ipu_cpmem_set_buffer(cpmem, 1, eba); + 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; @@ -97,7 +95,6 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) { - struct ipu_ch_param __iomem *cpmem; struct device *dev = ipu_plane->base.dev->dev; int ret; @@ -175,10 +172,9 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, return ret; } - cpmem = ipu_get_cpmem(ipu_plane->ipu_ch); - ipu_ch_param_zero(cpmem); - ipu_cpmem_set_resolution(cpmem, src_w, src_h); - ret = ipu_cpmem_set_fmt(cpmem, fb->pixel_format); + ipu_cpmem_zero(ipu_plane->ipu_ch); + ipu_cpmem_set_resolution(ipu_plane->ipu_ch, src_w, src_h); + ret = ipu_cpmem_set_fmt(ipu_plane->ipu_ch, fb->pixel_format); if (ret < 0) { dev_err(dev, "unsupported pixel format 0x%08x\n", fb->pixel_format); -- GitLab From ba07975f0fe5bf95107d71d0df0405c16f5c3266 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Wed, 25 Jun 2014 18:05:30 -0700 Subject: [PATCH 0852/9167] gpu: ipu-v3: Add functions to set CSI/IC source muxes Adds two new functions, ipu_set_csi_src_mux() and ipu_set_ic_src_mux(), that select the inputs to the CSI and IC respectively. Both muxes are programmed in the IPU_CONF register. Signed-off-by: Steve Longerbeam Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-common.c | 51 +++++++++++++++++++++++++++++++++ include/video/imx-ipu-v3.h | 6 ++++ 2 files changed, 57 insertions(+) diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 5978e7aab8ed..cae543115856 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -382,6 +382,57 @@ static int ipu_memory_reset(struct ipu_soc *ipu) return 0; } +/* + * Set the source mux for the given CSI. Selects either parallel or + * MIPI CSI2 sources. + */ +void ipu_set_csi_src_mux(struct ipu_soc *ipu, int csi_id, bool mipi_csi2) +{ + unsigned long flags; + u32 val, mask; + + mask = (csi_id == 1) ? IPU_CONF_CSI1_DATA_SOURCE : + IPU_CONF_CSI0_DATA_SOURCE; + + spin_lock_irqsave(&ipu->lock, flags); + + val = ipu_cm_read(ipu, IPU_CONF); + if (mipi_csi2) + val |= mask; + else + val &= ~mask; + ipu_cm_write(ipu, val, IPU_CONF); + + spin_unlock_irqrestore(&ipu->lock, flags); +} +EXPORT_SYMBOL_GPL(ipu_set_csi_src_mux); + +/* + * Set the source mux for the IC. Selects either CSI[01] or the VDI. + */ +void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi) +{ + unsigned long flags; + u32 val; + + spin_lock_irqsave(&ipu->lock, flags); + + val = ipu_cm_read(ipu, IPU_CONF); + if (vdi) { + val |= IPU_CONF_IC_INPUT; + } else { + val &= ~IPU_CONF_IC_INPUT; + if (csi_id == 1) + val |= IPU_CONF_CSI_SEL; + else + val &= ~IPU_CONF_CSI_SEL; + } + ipu_cm_write(ipu, val, IPU_CONF); + + spin_unlock_irqrestore(&ipu->lock, flags); +} +EXPORT_SYMBOL_GPL(ipu_set_ic_src_mux); + struct ipu_devtype { const char *name; unsigned long cm_ofs; diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index ef64b66b18df..f80fe13b0d4d 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -92,6 +92,12 @@ int ipu_idmac_channel_irq(struct ipu_soc *ipu, struct ipuv3_channel *channel, #define IPU_IRQ_VSYNC_PRE_0 (448 + 14) #define IPU_IRQ_VSYNC_PRE_1 (448 + 15) +/* + * IPU Common functions + */ +void ipu_set_csi_src_mux(struct ipu_soc *ipu, int csi_id, bool mipi_csi2); +void ipu_set_ic_src_mux(struct ipu_soc *ipu, int csi_id, bool vdi); + /* * IPU Image DMA Controller (idmac) functions */ -- GitLab From c2d670fd3b16304124162bef99313eaa289f2bc3 Mon Sep 17 00:00:00 2001 From: Steve Longerbeam Date: Wed, 25 Jun 2014 18:05:31 -0700 Subject: [PATCH 0853/9167] gpu: ipu-v3: Rename and add IDMAC channels Rename the ENC/VF/PP rotation channel names, to be more consistent with the convention that *_MEM is write-to-memory channels and MEM_* is read-from-memory channels. Also add the channels who's source and destination is the IC. Signed-off-by: Steve Longerbeam Signed-off-by: Philipp Zabel --- drivers/gpu/ipu-v3/ipu-prv.h | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index 0a7b2adaba39..1a5c55c05fe8 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -28,17 +28,25 @@ struct ipu_soc; #define IPUV3_CHANNEL_CSI1 1 #define IPUV3_CHANNEL_CSI2 2 #define IPUV3_CHANNEL_CSI3 3 +#define IPUV3_CHANNEL_VDI_MEM_IC_VF 5 +#define IPUV3_CHANNEL_MEM_IC_PP 11 +#define IPUV3_CHANNEL_MEM_IC_PRP_VF 12 +#define IPUV3_CHANNEL_G_MEM_IC_PRP_VF 14 +#define IPUV3_CHANNEL_G_MEM_IC_PP 15 +#define IPUV3_CHANNEL_IC_PRP_ENC_MEM 20 +#define IPUV3_CHANNEL_IC_PRP_VF_MEM 21 +#define IPUV3_CHANNEL_IC_PP_MEM 22 #define IPUV3_CHANNEL_MEM_BG_SYNC 23 #define IPUV3_CHANNEL_MEM_FG_SYNC 27 #define IPUV3_CHANNEL_MEM_DC_SYNC 28 #define IPUV3_CHANNEL_MEM_FG_SYNC_ALPHA 31 #define IPUV3_CHANNEL_MEM_DC_ASYNC 41 -#define IPUV3_CHANNEL_ROT_ENC_MEM 45 -#define IPUV3_CHANNEL_ROT_VF_MEM 46 -#define IPUV3_CHANNEL_ROT_PP_MEM 47 -#define IPUV3_CHANNEL_ROT_ENC_MEM_OUT 48 -#define IPUV3_CHANNEL_ROT_VF_MEM_OUT 49 -#define IPUV3_CHANNEL_ROT_PP_MEM_OUT 50 +#define IPUV3_CHANNEL_MEM_ROT_ENC 45 +#define IPUV3_CHANNEL_MEM_ROT_VF 46 +#define IPUV3_CHANNEL_MEM_ROT_PP 47 +#define IPUV3_CHANNEL_ROT_ENC_MEM 48 +#define IPUV3_CHANNEL_ROT_VF_MEM 49 +#define IPUV3_CHANNEL_ROT_PP_MEM 50 #define IPUV3_CHANNEL_MEM_BG_SYNC_ALPHA 51 #define IPU_MCU_T_DEFAULT 8 -- GitLab From effd8c363d2c76d1941402cc23835fc986a445d8 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-Koenig Date: Wed, 23 Jul 2014 08:40:05 +0900 Subject: [PATCH 0854/9167] ARM: EXYNOS: remove unused ARCH_EXYNOS doesn't select NEED_MACH_MEMORY_H, so doesn't include and so this file is not used and can go away. Signed-off-by: Uwe Kleine-Koenig Reviewed-by: Tomasz Figa [t.figa@samsung.com: boot tested on Exynos4412-based Trats2 board] Tested-by: Tomasz Figa Reviewed-by: Sachin Kamat [sachin.kamat: Tested on Arndale octa board (Exynos 5420)] Tested-by: Sachin Kamat Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/include/mach/memory.h | 26 ---------------------- 1 file changed, 26 deletions(-) delete mode 100644 arch/arm/mach-exynos/include/mach/memory.h diff --git a/arch/arm/mach-exynos/include/mach/memory.h b/arch/arm/mach-exynos/include/mach/memory.h deleted file mode 100644 index e19df1f18c0d..000000000000 --- a/arch/arm/mach-exynos/include/mach/memory.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. - * http://www.samsung.com - * - * EXYNOS4 - Memory definitions - * - * 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_ARCH_MEMORY_H -#define __ASM_ARCH_MEMORY_H __FILE__ - -#define PLAT_PHYS_OFFSET UL(0x40000000) - -#ifndef CONFIG_ARM_LPAE -/* Maximum of 256MiB in one bank */ -#define MAX_PHYSMEM_BITS 32 -#define SECTION_SIZE_BITS 28 -#else -#define MAX_PHYSMEM_BITS 36 -#define SECTION_SIZE_BITS 31 -#endif - -#endif /* __ASM_ARCH_MEMORY_H */ -- GitLab From 9740bdd985277a7f71423738c34a2c88cd533f1c Mon Sep 17 00:00:00 2001 From: Kukjin Kim Date: Fri, 1 Aug 2014 03:22:04 +0900 Subject: [PATCH 0855/9167] ARM: S5PV210: move into mach-s5pv210/ This moves into mach-s5pv210 so no more include/mach/ under mach-s5pv210. Signed-off-by: Kukjin Kim Cc: Tomasz Figa --- arch/arm/mach-s5pv210/pm.c | 3 +-- arch/arm/mach-s5pv210/{include/mach => }/regs-clock.h | 3 +-- arch/arm/mach-s5pv210/s5pv210.c | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) rename arch/arm/mach-s5pv210/{include/mach => }/regs-clock.h (99%) diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index 123163dd2ab0..21b4b13c5ab7 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c @@ -24,9 +24,8 @@ #include -#include - #include "common.h" +#include "regs-clock.h" static struct sleep_save s5pv210_core_save[] = { /* Clock ETC */ diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/regs-clock.h similarity index 99% rename from arch/arm/mach-s5pv210/include/mach/regs-clock.h rename to arch/arm/mach-s5pv210/regs-clock.h index b14ffcd7f6cc..4640f0f03c12 100644 --- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv210/regs-clock.h @@ -1,5 +1,4 @@ -/* linux/arch/arm/mach-s5pv210/include/mach/regs-clock.h - * +/* * Copyright (c) 2010 Samsung Electronics Co., Ltd. * http://www.samsung.com/ * diff --git a/arch/arm/mach-s5pv210/s5pv210.c b/arch/arm/mach-s5pv210/s5pv210.c index 53feff33d129..43eb1eaea0c9 100644 --- a/arch/arm/mach-s5pv210/s5pv210.c +++ b/arch/arm/mach-s5pv210/s5pv210.c @@ -18,9 +18,9 @@ #include #include -#include #include "common.h" +#include "regs-clock.h" static int __init s5pv210_fdt_map_sys(unsigned long node, const char *uname, int depth, void *data) -- GitLab From 716845ebeb505353d900320b4a74e8330520410d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 18 Aug 2014 10:34:08 +0800 Subject: [PATCH 0856/9167] regulator: core: Fix build error due to const qualifier for ops Drop const qualifier for ops of struct regulator_desc. Allow regulator drivers to update ops before registering regulator. Fix below build error: CC [M] drivers/regulator/mc13892-regulator.o drivers/regulator/mc13892-regulator.c: In function 'mc13892_regulator_probe': drivers/regulator/mc13892-regulator.c:586:3: error: assignment of member 'set_mode' in read-only object drivers/regulator/mc13892-regulator.c:588:3: error: assignment of member 'get_mode' in read-only object make[2]: *** [drivers/regulator/mc13892-regulator.o] Error 1 make[1]: *** [drivers/regulator] Error 2 make: *** [drivers] Error 2 Reported-by: Stephen Rothwell Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- include/linux/regulator/driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index efe058f8f746..3abda7554d82 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -246,7 +246,7 @@ struct regulator_desc { int id; bool continuous_voltage_range; unsigned n_voltages; - const struct regulator_ops *ops; + struct regulator_ops *ops; int irq; enum regulator_type type; struct module *owner; -- GitLab From c99428d035908b9c0b8be452f9b091bc5e090256 Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Mon, 18 Aug 2014 15:48:20 +0800 Subject: [PATCH 0857/9167] spi: fsl-dspi: Convert to use regmap framework's endianness method. Signed-off-by: Xiubo Li Acked-by: Chao Fu Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt | 7 ++++++- drivers/spi/spi-fsl-dspi.c | 3 --- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt index 5376de40f10b..cbbe16ed3874 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt @@ -10,7 +10,12 @@ Required properties: - pinctrl-names: must contain a "default" entry. - spi-num-chipselects : the number of the chipselect signals. - bus-num : the slave chip chipselect signal number. -- big-endian : if DSPI modudle is big endian, the bool will be set in node. + +Optional property: +- big-endian: If present the dspi device's registers are implemented + in big endian mode, otherwise in native mode(same with CPU), for more + detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. + Example: dspi0@4002c000 { diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 5021ddf03f60..ebc4d1fd76e2 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -493,9 +493,6 @@ static int dspi_probe(struct platform_device *pdev) } dspi_regmap_config.lock_arg = dspi; - dspi_regmap_config.val_format_endian = - of_property_read_bool(np, "big-endian") - ? REGMAP_ENDIAN_BIG : REGMAP_ENDIAN_DEFAULT; dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dspi", base, &dspi_regmap_config); if (IS_ERR(dspi->regmap)) { -- GitLab From 5f37671e004eeca017b93f6b26f2425acbb8d411 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 18 Aug 2014 16:38:39 +0800 Subject: [PATCH 0858/9167] ASoC: fsl-asoc-card: Fix build warning for maybe-uninitialized When build fsl-asoc-card as module, there is following error: sound/soc/fsl/fsl-asoc-card.c: In function 'fsl_asoc_card_probe': >> sound/soc/fsl/fsl-asoc-card.c:547:13: warning: 'asrc_np' may be used uninitialized in this function [-Wmaybe-uninitialized] of_node_put(asrc_np); ^ vim +/asrc_np +547 sound/soc/fsl/fsl-asoc-card.c 531 if (width == 24) 532 priv->asrc_format = SNDRV_PCM_FORMAT_S24_LE; 533 else 534 priv->asrc_format = SNDRV_PCM_FORMAT_S16_LE; 535 } 536 537 /* Finish card registering */ 538 platform_set_drvdata(pdev, priv); 539 snd_soc_card_set_drvdata(&priv->card, priv); 540 541 ret = devm_snd_soc_register_card(&pdev->dev, &priv->card); 542 if (ret) 543 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); 544 545 fail: 546 of_node_put(codec_np); > 547 of_node_put(asrc_np); 548 of_node_put(cpu_np); 549 550 return ret; 551 } 552 553 static const struct of_device_id fsl_asoc_card_dt_ids[] = { 554 { .compatible = "fsl,imx-audio-cs42888", }, 555 { .compatible = "fsl,imx-audio-sgtl5000", }, Add 'asrc_fail' branch for error jump after asrc_np initialized. Reported-by: kbuild test robot Signed-off-by: Shengjiu Wang Signed-off-by: Mark Brown --- sound/soc/fsl/fsl-asoc-card.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index cf3f1f47f1e8..007c772f3cef 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -469,7 +469,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) ret = fsl_asoc_card_audmux_init(np, priv); if (ret) { dev_err(&pdev->dev, "failed to init audmux\n"); - goto fail; + goto asrc_fail; } } else if (strstr(cpu_np->name, "esai")) { priv->cpu_priv.sysclk_id[1] = ESAI_HCKT_EXTAL; @@ -518,14 +518,14 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "failed to get output rate\n"); ret = -EINVAL; - goto fail; + goto asrc_fail; } ret = of_property_read_u32(asrc_np, "fsl,asrc-width", &width); if (ret) { dev_err(&pdev->dev, "failed to get output rate\n"); ret = -EINVAL; - goto fail; + goto asrc_fail; } if (width == 24) @@ -542,9 +542,10 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) if (ret) dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); +asrc_fail: + of_node_put(asrc_np); fail: of_node_put(codec_np); - of_node_put(asrc_np); of_node_put(cpu_np); return ret; -- GitLab From 499898d66d88cc626a2e01b02c3b819536bdf169 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Mon, 18 Aug 2014 16:38:40 +0800 Subject: [PATCH 0859/9167] ASoC: fsl: fsl-asoc-card: Select SND_SOC_IMX_AUDMUX Building kernel with SND_SOC_IMX_AUDMUX=n leads to the following error: sound/built-in.o: In function `fsl_asoc_card_probe': >> fsl-asoc-card.c:(.text+0x1467b5): undefined reference to `imx_audmux_v2_configure_port' >> fsl-asoc-card.c:(.text+0x1467d0): undefined reference to `imx_audmux_v2_configure_port' >> fsl-asoc-card.c:(.text+0x1467ed): undefined reference to `imx_audmux_v2_configure_port' >> fsl-asoc-card.c:(.text+0x146807): undefined reference to `imx_audmux_v2_configure_port' Update Kconfig to select SND_SOC_IMX_AUDMUX when SND_SOC_FSL_ASOC_CARD=y. Reported-by: kbuild test robot Signed-off-by: Shengjiu Wang Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index fa90340dc13a..4698c01af684 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -62,6 +62,7 @@ config SND_SOC_FSL_UTILS config SND_SOC_FSL_ASOC_CARD tristate "Generic ASoC Sound Card with ASRC support" depends on OF && I2C + select SND_SOC_IMX_AUDMUX select SND_SOC_IMX_PCM_DMA select SND_SOC_FSL_ESAI select SND_SOC_FSL_SAI -- GitLab From e6f2f805d722bf94efe89755372bcc6ff60d8d90 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 18 Aug 2014 10:32:41 +0200 Subject: [PATCH 0860/9167] regulator: Add driver for max77802 PMIC PMIC regulators The MAX77802 PMIC has 10 high-efficiency Buck and 32 Low-dropout (LDO) regulators. This patch adds support for all these regulators found on the MAX77802 PMIC and is based on a driver added by Simon Glass to the Chrome OS kernel 3.8 tree. Signed-off-by: Javier Martinez Canillas Tested-by: Naveen Krishna Chatradhi Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 9 + drivers/regulator/Makefile | 1 + drivers/regulator/max77802.c | 578 +++++++++++++++++++++++++++++++++++ 3 files changed, 588 insertions(+) create mode 100644 drivers/regulator/max77802.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc8289e5dba..8134a99e2a09 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -387,6 +387,15 @@ config REGULATOR_MAX77693 and one current regulator 'CHARGER'. This is suitable for Exynos-4x12 chips. +config REGULATOR_MAX77802 + tristate "Maxim 77802 regulator" + depends on MFD_MAX77686 + help + This driver controls a Maxim 77802 regulator + via I2C bus. The provided regulator is suitable for + Exynos5420/Exynos5800 SoCs to control various voltages. + It includes support for control of voltage and ramp speed. + config REGULATOR_MC13XXX_CORE tristate diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index aa4a6aa7b558..b4ec6c85307c 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o +obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o diff --git a/drivers/regulator/max77802.c b/drivers/regulator/max77802.c new file mode 100644 index 000000000000..5f022f859d49 --- /dev/null +++ b/drivers/regulator/max77802.c @@ -0,0 +1,578 @@ +/* + * max77802.c - Regulator driver for the Maxim 77802 + * + * Copyright (C) 2013-2014 Google, Inc + * Simon Glass + * + * Copyright (C) 2012 Samsung Electronics + * Chiwoong Byun + * Jonghwa Lee + * + * 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. + * + * This driver is based on max8997.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Default ramp delay in case it is not manually set */ +#define MAX77802_RAMP_DELAY 100000 /* uV/us */ + +#define MAX77802_OPMODE_SHIFT_LDO 6 +#define MAX77802_OPMODE_BUCK234_SHIFT 4 +#define MAX77802_OPMODE_MASK 0x3 + +#define MAX77802_VSEL_MASK 0x3F +#define MAX77802_DVS_VSEL_MASK 0xFF + +#define MAX77802_RAMP_RATE_MASK_2BIT 0xC0 +#define MAX77802_RAMP_RATE_SHIFT_2BIT 6 +#define MAX77802_RAMP_RATE_MASK_4BIT 0xF0 +#define MAX77802_RAMP_RATE_SHIFT_4BIT 4 + +/* MAX77802 has two register formats: 2-bit and 4-bit */ +static const unsigned int ramp_table_77802_2bit[] = { + 12500, + 25000, + 50000, + 100000, +}; + +static unsigned int ramp_table_77802_4bit[] = { + 1000, 2000, 3030, 4000, + 5000, 5880, 7140, 8330, + 9090, 10000, 11110, 12500, + 16670, 25000, 50000, 100000, +}; + +struct max77802_regulator_prv { + int num_regulators; + struct regulator_dev *rdev[MAX77802_REG_MAX]; + unsigned int opmode[MAX77802_REG_MAX]; +}; + +static int max77802_get_opmode_shift(int id) +{ + if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 && + id <= MAX77802_BUCK10)) + return 0; + + if (id >= MAX77802_BUCK2 && id <= MAX77802_BUCK4) + return MAX77802_OPMODE_BUCK234_SHIFT; + + if (id >= MAX77802_LDO1 && id <= MAX77802_LDO35) + return MAX77802_OPMODE_SHIFT_LDO; + + return -EINVAL; +} + +/* + * Some BUCKS supports Normal[ON/OFF] mode during suspend + * + * BUCK 1, 6, 2-4, 5, 7-10 (all) + * + * The other mode (0x02) will make PWRREQ switch between normal + * and low power. + */ +static int max77802_buck_set_suspend_disable(struct regulator_dev *rdev) +{ + unsigned int val = MAX77802_OPMODE_STANDBY; + struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + int shift = max77802_get_opmode_shift(id); + + max77802->opmode[id] = val; + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, val << shift); +} + +/* + * Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state + * (Enable Control Logic1 by PWRREQ) + * + * LDOs 2, 4-19, 22-35. + * + */ +static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev, + unsigned int mode) +{ + struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + unsigned int val; + int shift = max77802_get_opmode_shift(id); + + switch (mode) { + case REGULATOR_MODE_IDLE: /* ON in LP Mode */ + val = MAX77802_OPMODE_LP; + break; + case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ + val = MAX77802_OPMODE_NORMAL; + break; + case REGULATOR_MODE_STANDBY: /* ON/OFF by PWRREQ */ + val = MAX77802_OPMODE_STANDBY; + break; + default: + dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", + rdev->desc->name, mode); + return -EINVAL; + } + + max77802->opmode[rdev_get_id(rdev)] = val; + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, val << shift); +} + +/* + * Mode 1 (Output[ON/OFF] by PWRREQ) is not supported on some LDOs + * (Enable Control Logic2 by PWRREQ) + * + * LDOs 1, 20, 21, and 3, + * + */ +static int max77802_ldo_set_suspend_mode_logic2(struct regulator_dev *rdev, + unsigned int mode) +{ + struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + unsigned int val; + int shift = max77802_get_opmode_shift(id); + + switch (mode) { + case REGULATOR_MODE_IDLE: /* ON in LP Mode */ + val = MAX77802_OPMODE_LP; + break; + case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */ + val = MAX77802_OPMODE_NORMAL; + break; + default: + dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n", + rdev->desc->name, mode); + return -EINVAL; + } + + max77802->opmode[rdev_get_id(rdev)] = val; + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, val << shift); +} + +static int max77802_enable(struct regulator_dev *rdev) +{ + struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev); + int id = rdev_get_id(rdev); + int shift = max77802_get_opmode_shift(id); + + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, + max77802->opmode[id] << shift); +} + +static int max77802_find_ramp_value(struct regulator_dev *rdev, + const unsigned int limits[], int size, + unsigned int ramp_delay) +{ + int i; + + for (i = 0; i < size; i++) { + if (ramp_delay <= limits[i]) + return i; + } + + /* Use maximum value for no ramp control */ + dev_warn(&rdev->dev, "%s: ramp_delay: %d not supported, setting 100000\n", + rdev->desc->name, ramp_delay); + return size - 1; +} + +/* Used for BUCKs 2-4 */ +static int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev, + int ramp_delay) +{ + int id = rdev_get_id(rdev); + unsigned int ramp_value; + + if (id > MAX77802_BUCK4) { + dev_warn(&rdev->dev, + "%s: regulator: ramp delay not supported\n", + rdev->desc->name); + return -EINVAL; + } + ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_2bit, + ARRAY_SIZE(ramp_table_77802_2bit), ramp_delay); + + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + MAX77802_RAMP_RATE_MASK_2BIT, + ramp_value << MAX77802_RAMP_RATE_SHIFT_2BIT); +} + +/* For BUCK1, 6 */ +static int max77802_set_ramp_delay_4bit(struct regulator_dev *rdev, + int ramp_delay) +{ + unsigned int ramp_value; + + ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_4bit, + ARRAY_SIZE(ramp_table_77802_4bit), ramp_delay); + + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + MAX77802_RAMP_RATE_MASK_4BIT, + ramp_value << MAX77802_RAMP_RATE_SHIFT_4BIT); +} + +/* + * LDOs 2, 4-19, 22-35 + */ +static struct regulator_ops max77802_ldo_ops_logic1 = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = max77802_enable, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_suspend_mode = max77802_ldo_set_suspend_mode_logic1, +}; + +/* + * LDOs 1, 20, 21, 3 + */ +static struct regulator_ops max77802_ldo_ops_logic2 = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = max77802_enable, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_suspend_mode = max77802_ldo_set_suspend_mode_logic2, +}; + +/* BUCKS 1, 6 */ +static struct regulator_ops max77802_buck_16_dvs_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = max77802_enable, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = max77802_set_ramp_delay_4bit, + .set_suspend_disable = max77802_buck_set_suspend_disable, +}; + +/* BUCKs 2-4, 5, 7-10 */ +static struct regulator_ops max77802_buck_dvs_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .is_enabled = regulator_is_enabled_regmap, + .enable = max77802_enable, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = max77802_set_ramp_delay_2bit, + .set_suspend_disable = max77802_buck_set_suspend_disable, +}; + +/* LDOs 3-7, 9-14, 18-26, 28, 29, 32-34 */ +#define regulator_77802_desc_p_ldo(num, supply, log) { \ + .name = "LDO"#num, \ + .id = MAX77802_LDO##num, \ + .supply_name = "inl"#supply, \ + .ops = &max77802_ldo_ops_logic##log, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = 800000, \ + .uV_step = 50000, \ + .ramp_delay = MAX77802_RAMP_DELAY, \ + .n_voltages = 1 << 6, \ + .vsel_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ + .vsel_mask = MAX77802_VSEL_MASK, \ + .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ + .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ +} + +/* LDOs 1, 2, 8, 15, 17, 27, 30, 35 */ +#define regulator_77802_desc_n_ldo(num, supply, log) { \ + .name = "LDO"#num, \ + .id = MAX77802_LDO##num, \ + .supply_name = "inl"#supply, \ + .ops = &max77802_ldo_ops_logic##log, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = 800000, \ + .uV_step = 25000, \ + .ramp_delay = MAX77802_RAMP_DELAY, \ + .n_voltages = 1 << 6, \ + .vsel_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ + .vsel_mask = MAX77802_VSEL_MASK, \ + .enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \ + .enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \ +} + +/* BUCKs 1, 6 */ +#define regulator_77802_desc_16_buck(num) { \ + .name = "BUCK"#num, \ + .id = MAX77802_BUCK##num, \ + .supply_name = "inb"#num, \ + .ops = &max77802_buck_16_dvs_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = 612500, \ + .uV_step = 6250, \ + .ramp_delay = MAX77802_RAMP_DELAY, \ + .n_voltages = 1 << 8, \ + .vsel_reg = MAX77802_REG_BUCK ## num ## DVS1, \ + .vsel_mask = MAX77802_DVS_VSEL_MASK, \ + .enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \ + .enable_mask = MAX77802_OPMODE_MASK, \ +} + +/* BUCKS 2-4 */ +#define regulator_77802_desc_234_buck(num) { \ + .name = "BUCK"#num, \ + .id = MAX77802_BUCK##num, \ + .supply_name = "inb"#num, \ + .ops = &max77802_buck_dvs_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = 600000, \ + .uV_step = 6250, \ + .ramp_delay = MAX77802_RAMP_DELAY, \ + .n_voltages = 0x91, \ + .vsel_reg = MAX77802_REG_BUCK ## num ## DVS1, \ + .vsel_mask = MAX77802_DVS_VSEL_MASK, \ + .enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \ + .enable_mask = MAX77802_OPMODE_MASK << \ + MAX77802_OPMODE_BUCK234_SHIFT, \ +} + +/* BUCK 5 */ +#define regulator_77802_desc_buck5(num) { \ + .name = "BUCK"#num, \ + .id = MAX77802_BUCK##num, \ + .supply_name = "inb"#num, \ + .ops = &max77802_buck_dvs_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = 750000, \ + .uV_step = 50000, \ + .ramp_delay = MAX77802_RAMP_DELAY, \ + .n_voltages = 1 << 6, \ + .vsel_reg = MAX77802_REG_BUCK5OUT, \ + .vsel_mask = MAX77802_VSEL_MASK, \ + .enable_reg = MAX77802_REG_BUCK5CTRL, \ + .enable_mask = MAX77802_OPMODE_MASK, \ +} + +/* BUCKs 7-10 */ +#define regulator_77802_desc_buck7_10(num) { \ + .name = "BUCK"#num, \ + .id = MAX77802_BUCK##num, \ + .supply_name = "inb"#num, \ + .ops = &max77802_buck_dvs_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .min_uV = 750000, \ + .uV_step = 50000, \ + .ramp_delay = MAX77802_RAMP_DELAY, \ + .n_voltages = 1 << 6, \ + .vsel_reg = MAX77802_REG_BUCK7OUT + (num - 7) * 3, \ + .vsel_mask = MAX77802_VSEL_MASK, \ + .enable_reg = MAX77802_REG_BUCK7CTRL + (num - 7) * 3, \ + .enable_mask = MAX77802_OPMODE_MASK, \ +} + +static struct regulator_desc regulators[] = { + regulator_77802_desc_16_buck(1), + regulator_77802_desc_234_buck(2), + regulator_77802_desc_234_buck(3), + regulator_77802_desc_234_buck(4), + regulator_77802_desc_buck5(5), + regulator_77802_desc_16_buck(6), + regulator_77802_desc_buck7_10(7), + regulator_77802_desc_buck7_10(8), + regulator_77802_desc_buck7_10(9), + regulator_77802_desc_buck7_10(10), + regulator_77802_desc_n_ldo(1, 10, 2), + regulator_77802_desc_n_ldo(2, 10, 1), + regulator_77802_desc_p_ldo(3, 3, 2), + regulator_77802_desc_p_ldo(4, 6, 1), + regulator_77802_desc_p_ldo(5, 3, 1), + regulator_77802_desc_p_ldo(6, 3, 1), + regulator_77802_desc_p_ldo(7, 3, 1), + regulator_77802_desc_n_ldo(8, 1, 1), + regulator_77802_desc_p_ldo(9, 5, 1), + regulator_77802_desc_p_ldo(10, 4, 1), + regulator_77802_desc_p_ldo(11, 4, 1), + regulator_77802_desc_p_ldo(12, 9, 1), + regulator_77802_desc_p_ldo(13, 4, 1), + regulator_77802_desc_p_ldo(14, 4, 1), + regulator_77802_desc_n_ldo(15, 1, 1), + regulator_77802_desc_n_ldo(17, 2, 1), + regulator_77802_desc_p_ldo(18, 7, 1), + regulator_77802_desc_p_ldo(19, 5, 1), + regulator_77802_desc_p_ldo(20, 7, 2), + regulator_77802_desc_p_ldo(21, 6, 2), + regulator_77802_desc_p_ldo(23, 9, 1), + regulator_77802_desc_p_ldo(24, 6, 1), + regulator_77802_desc_p_ldo(25, 9, 1), + regulator_77802_desc_p_ldo(26, 9, 1), + regulator_77802_desc_n_ldo(27, 2, 1), + regulator_77802_desc_p_ldo(28, 7, 1), + regulator_77802_desc_p_ldo(29, 7, 1), + regulator_77802_desc_n_ldo(30, 2, 1), + regulator_77802_desc_p_ldo(32, 9, 1), + regulator_77802_desc_p_ldo(33, 6, 1), + regulator_77802_desc_p_ldo(34, 9, 1), + regulator_77802_desc_n_ldo(35, 2, 1), +}; + +#ifdef CONFIG_OF +static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev, + struct max77686_platform_data *pdata) +{ + struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); + struct device_node *pmic_np, *regulators_np; + struct max77686_regulator_data *rdata; + struct of_regulator_match rmatch; + unsigned int i; + + pmic_np = iodev->dev->of_node; + regulators_np = of_get_child_by_name(pmic_np, "regulators"); + if (!regulators_np) { + dev_err(&pdev->dev, "could not find regulators sub-node\n"); + return -EINVAL; + } + + pdata->num_regulators = ARRAY_SIZE(regulators); + rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) * + pdata->num_regulators, GFP_KERNEL); + if (!rdata) { + of_node_put(regulators_np); + return -ENOMEM; + } + + for (i = 0; i < pdata->num_regulators; i++) { + rmatch.name = regulators[i].name; + rmatch.init_data = NULL; + rmatch.of_node = NULL; + if (of_regulator_match(&pdev->dev, regulators_np, &rmatch, + 1) != 1) { + dev_warn(&pdev->dev, "No matching regulator for '%s'\n", + rmatch.name); + continue; + } + rdata[i].initdata = rmatch.init_data; + rdata[i].of_node = rmatch.of_node; + rdata[i].id = regulators[i].id; + } + + pdata->regulators = rdata; + of_node_put(regulators_np); + + return 0; +} +#else +static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev, + struct max77686_platform_data *pdata) +{ + return 0; +} +#endif /* CONFIG_OF */ + +static int max77802_pmic_probe(struct platform_device *pdev) +{ + struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); + struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev); + struct max77802_regulator_prv *max77802; + int i, ret = 0, val; + struct regulator_config config = { }; + + /* This is allocated by the MFD driver */ + if (!pdata) { + dev_err(&pdev->dev, "no platform data found for regulator\n"); + return -ENODEV; + } + + max77802 = devm_kzalloc(&pdev->dev, + sizeof(struct max77802_regulator_prv), + GFP_KERNEL); + if (!max77802) + return -ENOMEM; + + if (iodev->dev->of_node) { + ret = max77802_pmic_dt_parse_pdata(pdev, pdata); + if (ret) + return ret; + } + + config.dev = iodev->dev; + config.regmap = iodev->regmap; + config.driver_data = max77802; + platform_set_drvdata(pdev, max77802); + + for (i = 0; i < MAX77802_REG_MAX; i++) { + struct regulator_dev *rdev; + int id = pdata->regulators[i].id; + int shift = max77802_get_opmode_shift(id); + + config.init_data = pdata->regulators[i].initdata; + config.of_node = pdata->regulators[i].of_node; + + ret = regmap_read(iodev->regmap, regulators[i].enable_reg, &val); + max77802->opmode[id] = val >> shift & MAX77802_OPMODE_MASK; + + rdev = devm_regulator_register(&pdev->dev, + ®ulators[i], &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, + "regulator init failed for %d\n", i); + return PTR_ERR(rdev); + } + } + + return 0; +} + +static const struct platform_device_id max77802_pmic_id[] = { + {"max77802-pmic", 0}, + { }, +}; +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, +}; + +module_platform_driver(max77802_pmic_driver); + +MODULE_DESCRIPTION("MAXIM 77802 Regulator Driver"); +MODULE_AUTHOR("Simon Glass "); +MODULE_LICENSE("GPL"); -- GitLab From 4ece7045eb7cceaff9667b4ee2eec78915d3ee3b Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 18 Aug 2014 10:32:42 +0200 Subject: [PATCH 0861/9167] regulator: Add DT bindings for max77802 PMIC regulators Add Device Tree binding documentation for the regulators present in the Maxim 77802 Power Management IC. Signed-off-by: Javier Martinez Canillas Signed-off-by: Mark Brown --- .../bindings/regulator/max77802.txt | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/regulator/max77802.txt diff --git a/Documentation/devicetree/bindings/regulator/max77802.txt b/Documentation/devicetree/bindings/regulator/max77802.txt new file mode 100644 index 000000000000..5aeaffc0f1f0 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/max77802.txt @@ -0,0 +1,53 @@ +Binding for Maxim MAX77802 regulators + +This is a part of device tree bindings of MAX77802 multi-function device. +More information can be found in bindings/mfd/max77802.txt file. + +The MAX77802 PMIC has 10 high-efficiency Buck and 32 Low-dropout (LDO) +regulators that can be controlled over I2C. + +Following properties should be present in main device node of the MFD chip. + +Optional node: +- regulators : The regulators of max77802 have to be instantiated + under subnode named "regulators" using the following format. + + regulator-name { + standard regulator constraints.... + }; + refer Documentation/devicetree/bindings/regulator/regulator.txt + +The regulator node name should be initialized with a string to get matched +with their hardware counterparts as follow. The valid names are: + + -LDOn : for LDOs, where n can lie in ranges 1-15, 17-21, 23-30 + and 32-35. + example: LDO1, LDO2, LDO35. + -BUCKn : for BUCKs, where n can lie in range 1 to 10. + example: BUCK1, BUCK5, BUCK10. +Example: + + max77802@09 { + compatible = "maxim,max77802"; + interrupt-parent = <&wakeup_eint>; + interrupts = <26 0>; + reg = <0x09>; + #address-cells = <1>; + #size-cells = <0>; + + regulators { + ldo11_reg: LDO11 { + regulator-name = "vdd_ldo11"; + regulator-min-microvolt = <1900000>; + regulator-max-microvolt = <1900000>; + regulator-always-on; + }; + + buck1_reg: BUCK1 { + regulator-name = "vdd_mif"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + regulator-boot-on; + }; + }; -- GitLab From 33f4dcdb28aff083be5367cd3d56b4d00c331c60 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 30 Jul 2014 20:56:08 +0800 Subject: [PATCH 0862/9167] ARM: sunxi: Add A31 RTC driver to sunxi_defconfig Now that we have a driver for A31's RTC, enable it in the default sunxi config. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/configs/sunxi_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 7209bfd62074..0abc2abb316d 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -93,6 +93,7 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_RTC_CLASS=y # CONFIG_RTC_INTF_SYSFS is not set # CONFIG_RTC_INTF_PROC is not set +CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_SUNXI=y # CONFIG_IOMMU_SUPPORT is not set CONFIG_PHY_SUN4I_USB=y -- GitLab From 60fbce7f29ec8106c86e7ef74dacd5c9be3d4284 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Wed, 30 Jul 2014 20:56:09 +0800 Subject: [PATCH 0863/9167] ARM: sunxi: Add A31 RTC driver to multi_v7_defconfig Now that we have a driver for A31's RTC, enable it in multi_v7_defconfig. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/configs/multi_v7_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index 5fb95fb758d9..9320138abb7a 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig @@ -349,6 +349,7 @@ CONFIG_RTC_DRV_TPS65910=y CONFIG_RTC_DRV_EM3027=y CONFIG_RTC_DRV_PL031=y CONFIG_RTC_DRV_VT8500=y +CONFIG_RTC_DRV_SUN6I=y CONFIG_RTC_DRV_SUNXI=y CONFIG_RTC_DRV_MV=y CONFIG_RTC_DRV_TEGRA=y -- GitLab From 9524fa523e10c75750962c4079e6d002d7487280 Mon Sep 17 00:00:00 2001 From: Luc Verhaegen Date: Sat, 2 Aug 2014 15:06:30 +0200 Subject: [PATCH 0864/9167] ARM: sunxi_defconfig: add NLS_CODEPAGE_437 and NLS_ISO8859_1 Otherwise CONFIG_VFAT_FS is useless as mounting vfat fails. Signed-off-by: Luc Verhaegen Signed-off-by: Maxime Ripard --- arch/arm/configs/sunxi_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig index 0abc2abb316d..6c037f956e36 100644 --- a/arch/arm/configs/sunxi_defconfig +++ b/arch/arm/configs/sunxi_defconfig @@ -104,5 +104,7 @@ CONFIG_NFS_FS=y CONFIG_NFS_V3_ACL=y CONFIG_NFS_V4=y CONFIG_ROOT_NFS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_FS=y -- GitLab From ba1b53feb8cacbd84bcf0e48925e30ad29e141a6 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 18 Aug 2014 15:09:02 +0200 Subject: [PATCH 0865/9167] regmap: Fix DT endianess parsing logic Commit d647c199510c ("regmap: add DT endianness binding support.") added support to parse the device endianness from the device tree but unfortunately the added logic doesn't have the same semantics than the old code. This leads to a NULL dereference pointer error when these properties are not provided by the Device Tree: Unable to handle kernel NULL pointer dereference at virtual address 00000044 pgd = c0004000 [00000044] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT SMP ARM Modules linked in: CPU: 5 PID: 1 Comm: swapper/0 Not tainted 3.17.0-rc1-next-20140818ccu #671 task: ea412800 ti: ea484000 task.ti: ea484000 PC is at regmap_update_bits+0xc/0x5c The problem is that platforms that rely on the default value now gets different values due two related issues in the current code: a) It only parses the endianness from DT for the regmap registers and not for the regmap values but it checks unconditionally in both cases if the resulting endiannes is REGMAP_ENDIAN_NATIVE. b) REGMAP_ENDIAN_NATIVE is not even a valid DT property according to the regmap DT binding documentation so it shouldn't be set. Signed-off-by: Javier Martinez Canillas Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e4e567e82b84..055a9c3a3b12 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -499,7 +499,6 @@ static int of_regmap_get_endian(struct device *dev, * From the DT node the endianness value maybe: * REGMAP_ENDIAN_BIG, * REGMAP_ENDIAN_LITTLE, - * REGMAP_ENDIAN_NATIVE, */ switch (type) { case REGMAP_ENDIAN_VAL: @@ -507,8 +506,10 @@ static int of_regmap_get_endian(struct device *dev, *endian = REGMAP_ENDIAN_BIG; else if (of_property_read_bool(np, "little-endian")) *endian = REGMAP_ENDIAN_LITTLE; - else - *endian = REGMAP_ENDIAN_NATIVE; + + if (*endian != REGMAP_ENDIAN_DEFAULT) + return 0; + break; case REGMAP_ENDIAN_REG: break; @@ -516,15 +517,6 @@ static int of_regmap_get_endian(struct device *dev, return -EINVAL; } - /* - * If the endianness parsed from DT node is REGMAP_ENDIAN_NATIVE, that - * maybe means the DT does not care the endianness or it should use - * the regmap bus's default endianness, then we should try to check - * whether the regmap bus has specified the default endianness. - */ - if (*endian != REGMAP_ENDIAN_NATIVE) - return 0; - /* * Finally, try to parse the endianness from regmap bus config * if in device's DT node the endianness property is absent. -- GitLab From eea6653aae7bc85e38104f9c3a22471cba04da68 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 18 Aug 2014 11:39:50 -0500 Subject: [PATCH 0866/9167] ARM: dts: Enable PMIC interrupts for exynos4412-odroid-common The ODROID kernel shows that the PMIC interrupt line is hooked up to pin GPX3-2. This is needed for the max77686-irq driver to create the PMIC IRQ domain, which is needed by max77686-rtc. Signed-off-by: Daniel Drake Reviewed-by: Tomasz Figa Tested-by: Tomeu Vizoso Signed-off-by: Kukjin Kim --- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index 6d6d23c83d30..cb6f55f24ccf 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -148,6 +148,10 @@ max77686: pmic@09 { compatible = "maxim,max77686"; + interrupt-parent = <&gpx3>; + interrupts = <2 0>; + pinctrl-names = "default"; + pinctrl-0 = <&max77686_irq>; reg = <0x09>; #clock-cells = <1>; @@ -368,4 +372,11 @@ samsung,pins = "gpx1-3"; samsung,pin-pud = <0>; }; + + max77686_irq: max77686-irq { + samsung,pins = "gpx3-2"; + samsung,pin-function = <0>; + samsung,pin-pud = <0>; + samsung,pin-drv = <0>; + }; }; -- GitLab From cc3fe7abda0abb9936598a90feaa2e323d62200d Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 18 Aug 2014 11:39:53 -0500 Subject: [PATCH 0867/9167] ARM: dts: ODROID i2c improvements for exynos4412-odroid-common Increase max i2c bus frequency beyond the default for faster data transfers. According to the manual, these faster speeds are only available when the board is wired up the right way. In this case, the vendor kernel has run at this speed for a long time. sda-delay is needed for talking to RTC on PMIC, otherwise the i2c controller never sees an ACK. Strangely the other PMIC i2c slave (the main one) works fine even without this delay. I Chose value 100 to match the vendor kernel. Signed-off-by: Daniel Drake Reviewed-by: Tomasz Figa Tested-by: Tomeu Vizoso Signed-off-by: Kukjin Kim --- arch/arm/boot/dts/exynos4412-odroid-common.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index cb6f55f24ccf..adadaf97ac01 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -134,6 +134,8 @@ i2c@13860000 { pinctrl-0 = <&i2c0_bus>; pinctrl-names = "default"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <400000>; status = "okay"; usb3503: usb3503@08 { -- GitLab From 8ea21348868f37f5b2e6ebbaf336d2a415b2b9ff Mon Sep 17 00:00:00 2001 From: Xiubo Li Date: Mon, 18 Aug 2014 15:00:15 +0800 Subject: [PATCH 0868/9167] ASoC: simple-card: Fix the compile warning. sound/soc/generic/simple-card.c: In function simple_card_dai_link_of: sound/soc/generic/simple-card.c:198:10: warning: passing argument 3 of asoc_simple_card_sub_parse_of from incompatible pointer type [enabled by default] &dai_link->cpu_dai_name); ^ sound/soc/generic/simple-card.c:112:1: note: expected const struct device_node ** but argument is of type struct device_node ** asoc_simple_card_sub_parse_of(struct device_node *np, ^ sound/soc/generic/simple-card.c:229:10: warning: passing argument 3 of asoc_simple_card_sub_parse_of from incompatible pointer type [enabled by default] &dai_link->codec_dai_name); ^ sound/soc/generic/simple-card.c:112:1: note: expected const struct device_node ** but argument is of type struct device_node ** asoc_simple_card_sub_parse_of(struct device_node *np, ^ Since the asoc_simple_card_sub_parse_of() is used in simple-card module only, and the third argument is just used to get the node ponters address, so there is no need it must to be 'const' type. Signed-off-by: Xiubo Li Signed-off-by: Mark Brown --- sound/soc/generic/simple-card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 159e517fa09a..21b0ea24bc1d 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -111,7 +111,7 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) static int asoc_simple_card_sub_parse_of(struct device_node *np, struct asoc_simple_dai *dai, - const struct device_node **p_node, + struct device_node **p_node, const char **name) { struct device_node *node; -- GitLab From 0a97ea3b62fabc1c0eaca49bc584376b5cf0961b Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 19 Aug 2014 00:51:50 +0800 Subject: [PATCH 0869/9167] ARM: dts: sun8i: Add i2c controller nodes Add nodes for the 3 i2c controllers found on A23 SoCs to the sun8i DTSI. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23.dtsi | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi index 9386d1f565b9..2ec86d3614ad 100644 --- a/arch/arm/boot/dts/sun8i-a23.dtsi +++ b/arch/arm/boot/dts/sun8i-a23.dtsi @@ -387,6 +387,39 @@ status = "disabled"; }; + i2c0: i2c@01c2ac00 { + compatible = "allwinner,sun6i-a31-i2c"; + reg = <0x01c2ac00 0x400>; + interrupts = <0 6 4>; + clocks = <&apb2_gates 0>; + resets = <&apb2_rst 0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c1: i2c@01c2b000 { + compatible = "allwinner,sun6i-a31-i2c"; + reg = <0x01c2b000 0x400>; + interrupts = <0 7 4>; + clocks = <&apb2_gates 1>; + resets = <&apb2_rst 1>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c2: i2c@01c2b400 { + compatible = "allwinner,sun6i-a31-i2c"; + reg = <0x01c2b400 0x400>; + interrupts = <0 8 4>; + clocks = <&apb2_gates 2>; + resets = <&apb2_rst 2>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + gic: interrupt-controller@01c81000 { compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; reg = <0x01c81000 0x1000>, -- GitLab From dc66085b7a03c1c73774254ff7ac59159810b628 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 19 Aug 2014 00:51:51 +0800 Subject: [PATCH 0870/9167] ARM: dts: sun8i: Enable i2c controllers on ippo-q8h-v5 i2c0 is connected to the gsl1680 capacitive touch panel controller. i2c1 is connected to an mma7660 3-axis accelerometer. i2c2 is connected to the front and back gc0309 camera sensors. The camera sensors require additional regulators be enabled before they are available. All these peripherals are not supported by the kernel yet. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts index ef1e4f3aaf39..e9b8cca8dcc1 100644 --- a/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts +++ b/arch/arm/boot/dts/sun8i-a23-ippo-q8h-v5.dts @@ -43,6 +43,25 @@ }; }; + i2c0: i2c@01c2ac00 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + }; + + i2c1: i2c@01c2b000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; + }; + + i2c2: i2c@01c2b400 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + /* pull-ups and devices require PMIC regulator */ + status = "failed"; + }; + r_uart: serial@01f02800 { pinctrl-names = "default"; pinctrl-0 = <&r_uart_pins_a>; -- GitLab From 447a0470a7b9745fc91a75182f37f7710fa91290 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 19 Aug 2014 01:45:45 +0800 Subject: [PATCH 0871/9167] ARM: dt: sunxi: Remove i2c controller clock-frequency that matches default The clock-frequency values of the i2c controller nodes match the defaults of the driver. Remove the properties to use the defaults, and be consistent with sun8i. Signed-off-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun4i-a10.dtsi | 3 --- arch/arm/boot/dts/sun5i-a10s.dtsi | 3 --- arch/arm/boot/dts/sun5i-a13.dtsi | 3 --- arch/arm/boot/dts/sun6i-a31.dtsi | 4 ---- arch/arm/boot/dts/sun7i-a20.dtsi | 5 ----- 5 files changed, 18 deletions(-) diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi index 14cf43653341..380f914b226d 100644 --- a/arch/arm/boot/dts/sun4i-a10.dtsi +++ b/arch/arm/boot/dts/sun4i-a10.dtsi @@ -765,7 +765,6 @@ reg = <0x01c2ac00 0x400>; interrupts = <7>; clocks = <&apb1_gates 0>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -776,7 +775,6 @@ reg = <0x01c2b000 0x400>; interrupts = <8>; clocks = <&apb1_gates 1>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -787,7 +785,6 @@ reg = <0x01c2b400 0x400>; interrupts = <9>; clocks = <&apb1_gates 2>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi index 02aa41f6fdc4..d73a2287b37a 100644 --- a/arch/arm/boot/dts/sun5i-a10s.dtsi +++ b/arch/arm/boot/dts/sun5i-a10s.dtsi @@ -578,7 +578,6 @@ reg = <0x01c2ac00 0x400>; interrupts = <7>; clocks = <&apb1_gates 0>; - clock-frequency = <100000>; status = "disabled"; }; @@ -589,7 +588,6 @@ reg = <0x01c2b000 0x400>; interrupts = <8>; clocks = <&apb1_gates 1>; - clock-frequency = <100000>; status = "disabled"; }; @@ -600,7 +598,6 @@ reg = <0x01c2b400 0x400>; interrupts = <9>; clocks = <&apb1_gates 2>; - clock-frequency = <100000>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi index d8f02ee1b4dc..c4b5d7825b9f 100644 --- a/arch/arm/boot/dts/sun5i-a13.dtsi +++ b/arch/arm/boot/dts/sun5i-a13.dtsi @@ -504,7 +504,6 @@ reg = <0x01c2ac00 0x400>; interrupts = <7>; clocks = <&apb1_gates 0>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -515,7 +514,6 @@ reg = <0x01c2b000 0x400>; interrupts = <8>; clocks = <&apb1_gates 1>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -526,7 +524,6 @@ reg = <0x01c2b400 0x400>; interrupts = <9>; clocks = <&apb1_gates 2>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi index 8fdf90d52ab8..1c2ec913e650 100644 --- a/arch/arm/boot/dts/sun6i-a31.dtsi +++ b/arch/arm/boot/dts/sun6i-a31.dtsi @@ -657,7 +657,6 @@ reg = <0x01c2ac00 0x400>; interrupts = <0 6 4>; clocks = <&apb2_gates 0>; - clock-frequency = <100000>; resets = <&apb2_rst 0>; status = "disabled"; }; @@ -667,7 +666,6 @@ reg = <0x01c2b000 0x400>; interrupts = <0 7 4>; clocks = <&apb2_gates 1>; - clock-frequency = <100000>; resets = <&apb2_rst 1>; status = "disabled"; }; @@ -677,7 +675,6 @@ reg = <0x01c2b400 0x400>; interrupts = <0 8 4>; clocks = <&apb2_gates 2>; - clock-frequency = <100000>; resets = <&apb2_rst 2>; status = "disabled"; }; @@ -687,7 +684,6 @@ reg = <0x01c2b800 0x400>; interrupts = <0 9 4>; clocks = <&apb2_gates 3>; - clock-frequency = <100000>; resets = <&apb2_rst 3>; status = "disabled"; }; diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index db22ef9cbed8..c658e343ce11 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -915,7 +915,6 @@ reg = <0x01c2ac00 0x400>; interrupts = <0 7 4>; clocks = <&apb1_gates 0>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -926,7 +925,6 @@ reg = <0x01c2b000 0x400>; interrupts = <0 8 4>; clocks = <&apb1_gates 1>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -937,7 +935,6 @@ reg = <0x01c2b400 0x400>; interrupts = <0 9 4>; clocks = <&apb1_gates 2>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -948,7 +945,6 @@ reg = <0x01c2b800 0x400>; interrupts = <0 88 4>; clocks = <&apb1_gates 3>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; @@ -959,7 +955,6 @@ reg = <0x01c2c000 0x400>; interrupts = <0 89 4>; clocks = <&apb1_gates 15>; - clock-frequency = <100000>; status = "disabled"; #address-cells = <1>; #size-cells = <0>; -- GitLab From df08d2eb66d9805118d9a94c1df0129b193c9a4f Mon Sep 17 00:00:00 2001 From: Andreas Faerber Date: Mon, 18 Aug 2014 13:33:30 -0500 Subject: [PATCH 0872/9167] ARM: dts: Fix MMC pinctrl for exynos5250-snow The pinctrl properties should be on the device directly and not on the slot sub-node. Reported-by: Doug Anderson Cc: Jaehoon Chung Reviewed-by: Tomasz Figa Signed-off-by: Andreas Faerber Reviewed-by: Doug Anderson Signed-off-by: Kukjin Kim --- arch/arm/boot/dts/exynos5250-snow.dts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts index f2b8c4116541..eb437f6afec1 100644 --- a/arch/arm/boot/dts/exynos5250-snow.dts +++ b/arch/arm/boot/dts/exynos5250-snow.dts @@ -240,10 +240,8 @@ */ mmc@12230000 { status = "okay"; - slot@0 { - pinctrl-names = "default"; - pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>; - }; + pinctrl-names = "default"; + pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>; }; i2c@12CD0000 { -- GitLab From 5fbc3f20d0bbf72423152f145e30a1d9e01ceadb Mon Sep 17 00:00:00 2001 From: Andreas Faerber Date: Mon, 18 Aug 2014 14:00:35 -0500 Subject: [PATCH 0873/9167] ARM: dts: Fold exynos5250-cros-common into exynos5250-snow exynos5250-cros-common.dtsi was meant for sharing common pieces across ChromeOS devices. This turned out premature, as several devices ended up in the common file that are not common after all. Since the remaining common ChromeOS pieces are fairly minor, exynos5250-cros-common.dtsi was requested to be merged into the Snow device tree, sharing only the keyboard controller for now. This may be re-evaluated as both mature. Suggested-by: Doug Anderson Reviewed-by: Tomasz Figa Signed-off-by: Andreas Faerber Reviewed-by: Doug Anderson Signed-off-by: Kukjin Kim --- arch/arm/boot/dts/exynos5250-cros-common.dtsi | 164 ------------------ arch/arm/boot/dts/exynos5250-snow.dts | 164 ++++++++++++++++-- 2 files changed, 145 insertions(+), 183 deletions(-) delete mode 100644 arch/arm/boot/dts/exynos5250-cros-common.dtsi diff --git a/arch/arm/boot/dts/exynos5250-cros-common.dtsi b/arch/arm/boot/dts/exynos5250-cros-common.dtsi deleted file mode 100644 index e603e9c70142..000000000000 --- a/arch/arm/boot/dts/exynos5250-cros-common.dtsi +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Common device tree include for all Exynos 5250 boards based off of Daisy. - * - * Copyright (c) 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. -*/ - -/ { - aliases { - }; - - memory { - reg = <0x40000000 0x80000000>; - }; - - chosen { - }; - - pinctrl@11400000 { - /* - * Disabled pullups since external part has its own pullups and - * double-pulling gets us out of spec in some cases. - */ - i2c2_bus: i2c2-bus { - samsung,pin-pud = <0>; - }; - }; - - i2c@12C60000 { - status = "okay"; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <378000>; - }; - - i2c@12C70000 { - status = "okay"; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <378000>; - }; - - i2c@12C80000 { - status = "okay"; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <66000>; - - hdmiddc@50 { - compatible = "samsung,exynos4210-hdmiddc"; - reg = <0x50>; - }; - }; - - i2c@12C90000 { - status = "okay"; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <66000>; - }; - - i2c@12CA0000 { - status = "okay"; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <66000>; - }; - - i2c@12CB0000 { - status = "okay"; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <66000>; - }; - - i2c@12CD0000 { - status = "okay"; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <66000>; - }; - - i2c@12CE0000 { - status = "okay"; - samsung,i2c-sda-delay = <100>; - samsung,i2c-max-bus-freq = <378000>; - - hdmiphy: hdmiphy@38 { - compatible = "samsung,exynos4212-hdmiphy"; - reg = <0x38>; - }; - }; - - mmc@12200000 { - num-slots = <1>; - supports-highspeed; - broken-cd; - card-detect-delay = <200>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <2 3>; - samsung,dw-mshc-ddr-timing = <1 2>; - pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4 &sd0_bus8>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; - }; - - mmc@12220000 { - num-slots = <1>; - supports-highspeed; - card-detect-delay = <200>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <2 3>; - samsung,dw-mshc-ddr-timing = <1 2>; - pinctrl-names = "default"; - pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - wp-gpios = <&gpc2 1 0>; - }; - }; - - mmc@12230000 { - num-slots = <1>; - supports-highspeed; - broken-cd; - card-detect-delay = <200>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <2 3>; - samsung,dw-mshc-ddr-timing = <1 2>; - /* See board-specific dts files for pin setup */ - - slot@0 { - reg = <0>; - bus-width = <4>; - }; - }; - - spi_1: spi@12d30000 { - status = "okay"; - samsung,spi-src-clk = <0>; - num-cs = <1>; - }; - - hdmi { - hpd-gpio = <&gpx3 7 0>; - pinctrl-names = "default"; - pinctrl-0 = <&hdmi_hpd_irq>; - phy = <&hdmiphy>; - ddc = <&i2c_2>; - }; - - gpio-keys { - compatible = "gpio-keys"; - - power { - label = "Power"; - gpios = <&gpx1 3 1>; - linux,code = <116>; /* KEY_POWER */ - gpio-key,wakeup; - }; - }; -}; diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts index eb437f6afec1..1c36cd72905f 100644 --- a/arch/arm/boot/dts/exynos5250-snow.dts +++ b/arch/arm/boot/dts/exynos5250-snow.dts @@ -10,7 +10,6 @@ /dts-v1/; #include "exynos5250.dtsi" -#include "exynos5250-cros-common.dtsi" / { model = "Google Snow"; @@ -20,6 +19,13 @@ i2c104 = &i2c_104; }; + memory { + reg = <0x40000000 0x80000000>; + }; + + chosen { + }; + rtc@101E0000 { status = "okay"; }; @@ -93,6 +99,13 @@ gpio-keys { compatible = "gpio-keys"; + power { + label = "Power"; + gpios = <&gpx1 3 1>; + linux,code = <116>; /* KEY_POWER */ + gpio-key,wakeup; + }; + lid-switch { label = "Lid"; gpios = <&gpx3 5 1>; @@ -226,24 +239,6 @@ }; }; - mmc@12200000 { - status = "okay"; - }; - - mmc@12220000 { - status = "okay"; - }; - - /* - * On Snow we've got SIP WiFi and so can keep drive strengths low to - * reduce EMI. - */ - mmc@12230000 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>; - }; - i2c@12CD0000 { max98095: codec@11 { compatible = "maxim,max98095"; @@ -292,6 +287,11 @@ }; hdmi { + hpd-gpio = <&gpx3 7 0>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmi_hpd_irq>; + phy = <&hdmiphy>; + ddc = <&i2c_2>; hdmi-en-supply = <&tps65090_fet7>; vdd-supply = <&ldo8_reg>; vdd_osc-supply = <&ldo10_reg>; @@ -343,6 +343,10 @@ }; &i2c_0 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <378000>; + max77686@09 { compatible = "maxim,max77686"; interrupt-parent = <&gpx3>; @@ -489,6 +493,10 @@ }; &i2c_1 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <378000>; + trackpad { reg = <0x67>; compatible = "cypress,cyapa"; @@ -498,6 +506,118 @@ }; }; +/* + * Disabled pullups since external part has its own pullups and + * double-pulling gets us out of spec in some cases. + */ +&i2c2_bus { + samsung,pin-pud = <0>; +}; + +&i2c_2 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; + + hdmiddc@50 { + compatible = "samsung,exynos4210-hdmiddc"; + reg = <0x50>; + }; +}; + +&i2c_3 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; +}; + +&i2c_4 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; +}; + +&i2c_5 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; +}; + +&i2c_7 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <66000>; +}; + +&i2c_8 { + status = "okay"; + samsung,i2c-sda-delay = <100>; + samsung,i2c-max-bus-freq = <378000>; + + hdmiphy: hdmiphy@38 { + compatible = "samsung,exynos4212-hdmiphy"; + reg = <0x38>; + }; +}; + +&mmc_0 { + status = "okay"; + num-slots = <1>; + supports-highspeed; + broken-cd; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4 &sd0_bus8>; + + slot@0 { + reg = <0>; + bus-width = <8>; + }; +}; + +&mmc_2 { + status = "okay"; + num-slots = <1>; + supports-highspeed; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; + + slot@0 { + reg = <0>; + bus-width = <4>; + wp-gpios = <&gpc2 1 0>; + }; +}; + +/* + * On Snow we've got SIP WiFi and so can keep drive strengths low to + * reduce EMI. + */ +&mmc_3 { + status = "okay"; + num-slots = <1>; + supports-highspeed; + broken-cd; + card-detect-delay = <200>; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <2 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + pinctrl-names = "default"; + pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>; + + slot@0 { + reg = <0>; + bus-width = <4>; + }; +}; + &pinctrl_0 { max77686_irq: max77686-irq { samsung,pins = "gpx3-2"; @@ -507,4 +627,10 @@ }; }; +&spi_1 { + status = "okay"; + samsung,spi-src-clk = <0>; + num-cs = <1>; +}; + #include "cros-ec-keyboard.dtsi" -- GitLab From aaa25a5a33cb2f406e59ff06a86b7f91026c2fa2 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Mon, 18 Aug 2014 11:55:32 -0500 Subject: [PATCH 0874/9167] ARM: dts: unuse the slot-node and deprecate the supports-highspeed for dw-mmc in exynos dw-mmc controller can support multiple slots. But, there are no use-cases anywhere. So we don't need to support the slot-node for dw-mmc controller. And "supports-highspeed" property in dw-mmc is deprecated. "supports-highspeed" property can be replaced with "cap-sd/mmc-highspeed". Signed-off-by: Jaehoon Chung Reviewed-by: Tushar Behera Reviewed-by: Ulf Hansson Tested-by: Sachin Kamat [kgene.kim@samsung.com: rebased exynos5250-snow changes] Signed-off-by: Kukjin Kim --- .../boot/dts/exynos4412-odroid-common.dtsi | 8 ++---- arch/arm/boot/dts/exynos4412-origen.dts | 8 ++---- arch/arm/boot/dts/exynos4412-trats2.dts | 8 ++---- arch/arm/boot/dts/exynos5250-arndale.dts | 18 ++++--------- arch/arm/boot/dts/exynos5250-smdk5250.dts | 18 ++++--------- arch/arm/boot/dts/exynos5250-snow.dts | 26 +++++-------------- arch/arm/boot/dts/exynos5260-xyref5260.dts | 18 ++++--------- arch/arm/boot/dts/exynos5410-smdk5410.dts | 18 ++++--------- arch/arm/boot/dts/exynos5420-arndale-octa.dts | 16 +++--------- arch/arm/boot/dts/exynos5420-peach-pit.dts | 16 +++--------- arch/arm/boot/dts/exynos5420-smdk5420.dts | 16 +++--------- arch/arm/boot/dts/exynos5800-peach-pi.dts | 16 +++--------- 12 files changed, 49 insertions(+), 137 deletions(-) diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi index adadaf97ac01..c697ff01ae8d 100644 --- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi +++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi @@ -54,17 +54,13 @@ status = "okay"; num-slots = <1>; - supports-highspeed; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; + cap-mmc-highspeed; }; watchdog@10060000 { diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts index e925c9fbfb07..de15114fd07c 100644 --- a/arch/arm/boot/dts/exynos4412-origen.dts +++ b/arch/arm/boot/dts/exynos4412-origen.dts @@ -137,17 +137,13 @@ status = "okay"; num-slots = <1>; - supports-highspeed; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; + cap-mmc-highspeed; }; codec@13400000 { diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts index 11967f4561e0..5e066cd87f66 100644 --- a/arch/arm/boot/dts/exynos4412-trats2.dts +++ b/arch/arm/boot/dts/exynos4412-trats2.dts @@ -520,7 +520,6 @@ mmc@12550000 { num-slots = <1>; - supports-highspeed; broken-cd; non-removable; card-detect-delay = <200>; @@ -532,11 +531,8 @@ pinctrl-0 = <&sd4_clk &sd4_cmd &sd4_bus4 &sd4_bus8>; pinctrl-names = "default"; status = "okay"; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; + cap-mmc-highspeed; }; serial@13800000 { diff --git a/arch/arm/boot/dts/exynos5250-arndale.dts b/arch/arm/boot/dts/exynos5250-arndale.dts index d0de1f50d15b..42a3590339fc 100644 --- a/arch/arm/boot/dts/exynos5250-arndale.dts +++ b/arch/arm/boot/dts/exynos5250-arndale.dts @@ -401,7 +401,6 @@ mmc_0: mmc@12200000 { status = "okay"; num-slots = <1>; - supports-highspeed; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -410,17 +409,13 @@ vmmc-supply = <&mmc_reg>; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; + cap-mmc-highspeed; }; mmc_2: mmc@12220000 { status = "okay"; num-slots = <1>; - supports-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -428,12 +423,9 @@ vmmc-supply = <&mmc_reg>; pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - disable-wp; - }; + bus-width = <4>; + disable-wp; + cap-sd-highspeed; }; i2s0: i2s@03830000 { diff --git a/arch/arm/boot/dts/exynos5250-smdk5250.dts b/arch/arm/boot/dts/exynos5250-smdk5250.dts index b4b35adae565..6a0f4c0ff763 100644 --- a/arch/arm/boot/dts/exynos5250-smdk5250.dts +++ b/arch/arm/boot/dts/exynos5250-smdk5250.dts @@ -284,7 +284,6 @@ mmc@12200000 { status = "okay"; num-slots = <1>; - supports-highspeed; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -292,29 +291,22 @@ samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; + cap-mmc-highspeed; }; mmc@12220000 { status = "okay"; num-slots = <1>; - supports-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - disable-wp; - }; + bus-width = <4>; + disable-wp; + cap-sd-highspeed; }; spi_1: spi@12d30000 { diff --git a/arch/arm/boot/dts/exynos5250-snow.dts b/arch/arm/boot/dts/exynos5250-snow.dts index 1c36cd72905f..2a6245934c8d 100644 --- a/arch/arm/boot/dts/exynos5250-snow.dts +++ b/arch/arm/boot/dts/exynos5250-snow.dts @@ -563,7 +563,6 @@ &mmc_0 { status = "okay"; num-slots = <1>; - supports-highspeed; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -571,29 +570,22 @@ samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_cd &sd0_bus4 &sd0_bus8>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; + cap-mmc-highspeed; }; &mmc_2 { status = "okay"; num-slots = <1>; - supports-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - wp-gpios = <&gpc2 1 0>; - }; + bus-width = <4>; + wp-gpios = <&gpc2 1 0>; + cap-sd-highspeed; }; /* @@ -603,7 +595,6 @@ &mmc_3 { status = "okay"; num-slots = <1>; - supports-highspeed; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -611,11 +602,8 @@ samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd3_clk &sd3_cmd &sd3_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - }; + bus-width = <4>; + cap-sd-highspeed; }; &pinctrl_0 { diff --git a/arch/arm/boot/dts/exynos5260-xyref5260.dts b/arch/arm/boot/dts/exynos5260-xyref5260.dts index 8c84ab27c19b..a803b605051b 100644 --- a/arch/arm/boot/dts/exynos5260-xyref5260.dts +++ b/arch/arm/boot/dts/exynos5260-xyref5260.dts @@ -69,7 +69,7 @@ num-slots = <1>; broken-cd; bypass-smu; - supports-highspeed; + cap-mmc-highspeed; supports-hs200-mode; /* 200 Mhz */ card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; @@ -77,27 +77,19 @@ samsung,dw-mshc-ddr-timing = <0 2>; pinctrl-names = "default"; pinctrl-0 = <&sd0_rdqs &sd0_clk &sd0_cmd &sd0_bus1 &sd0_bus4 &sd0_bus8>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; }; &mmc_2 { status = "okay"; num-slots = <1>; - supports-highspeed; + cap-sd-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus1 &sd2_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - disable-wp; - }; + bus-width = <4>; + disable-wp; }; diff --git a/arch/arm/boot/dts/exynos5410-smdk5410.dts b/arch/arm/boot/dts/exynos5410-smdk5410.dts index 7275bbd6fc4b..be3e02530b42 100644 --- a/arch/arm/boot/dts/exynos5410-smdk5410.dts +++ b/arch/arm/boot/dts/exynos5410-smdk5410.dts @@ -40,33 +40,25 @@ &mmc_0 { status = "okay"; num-slots = <1>; - supports-highspeed; + cap-mmc-highspeed; broken-cd; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; }; &mmc_2 { status = "okay"; num-slots = <1>; - supports-highspeed; + cap-sd-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; - - slot@0 { - reg = <0>; - bus-width = <4>; - disable-wp; - }; + bus-width = <4>; + disable-wp; }; &uart0 { diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts index 434fd9d3e09d..70a559cf1a3d 100644 --- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts +++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts @@ -50,7 +50,6 @@ mmc@12200000 { status = "okay"; broken-cd; - supports-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; @@ -58,16 +57,12 @@ pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; vmmc-supply = <&ldo10_reg>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; + cap-mmc-highspeed; }; mmc@12220000 { status = "okay"; - supports-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; @@ -75,11 +70,8 @@ pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; vmmc-supply = <&ldo10_reg>; - - slot@0 { - reg = <0>; - bus-width = <4>; - }; + bus-width = <4>; + cap-sd-highspeed; }; hsi2c_4: i2c@12CA0000 { diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 228a6b1e0aa1..7b1ed2c1baf5 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -187,7 +187,7 @@ num-slots = <1>; broken-cd; caps2-mmc-hs200-1_8v; - supports-highspeed; + cap-mmc-highspeed; non-removable; card-detect-delay = <200>; clock-frequency = <400000000>; @@ -196,17 +196,13 @@ samsung,dw-mshc-ddr-timing = <0 2>; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; }; &mmc_2 { status = "okay"; num-slots = <1>; - supports-highspeed; + cap-sd-highspeed; card-detect-delay = <200>; clock-frequency = <400000000>; samsung,dw-mshc-ciu-div = <3>; @@ -214,11 +210,7 @@ samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - }; + bus-width = <4>; }; diff --git a/arch/arm/boot/dts/exynos5420-smdk5420.dts b/arch/arm/boot/dts/exynos5420-smdk5420.dts index 6052aa9c5659..8be3d7b489ff 100644 --- a/arch/arm/boot/dts/exynos5420-smdk5420.dts +++ b/arch/arm/boot/dts/exynos5420-smdk5420.dts @@ -76,34 +76,26 @@ mmc@12200000 { status = "okay"; broken-cd; - supports-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <0 2>; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; + cap-mmc-highspeed; }; mmc@12220000 { status = "okay"; - supports-highspeed; card-detect-delay = <200>; samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <2 3>; samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - }; + bus-width = <4>; + cap-sd-highspeed; }; dp-controller@145B0000 { diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index f3ee48bbe05f..a587dd6dbcc5 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -185,7 +185,7 @@ num-slots = <1>; broken-cd; caps2-mmc-hs200-1_8v; - supports-highspeed; + cap-mmc-highspeed; non-removable; card-detect-delay = <200>; clock-frequency = <400000000>; @@ -194,17 +194,13 @@ samsung,dw-mshc-ddr-timing = <0 2>; pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_bus4 &sd0_bus8>; - - slot@0 { - reg = <0>; - bus-width = <8>; - }; + bus-width = <8>; }; &mmc_2 { status = "okay"; num-slots = <1>; - supports-highspeed; + cap-sd-highspeed; card-detect-delay = <200>; clock-frequency = <400000000>; samsung,dw-mshc-ciu-div = <3>; @@ -212,11 +208,7 @@ samsung,dw-mshc-ddr-timing = <1 2>; pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_cd &sd2_bus4>; - - slot@0 { - reg = <0>; - bus-width = <4>; - }; + bus-width = <4>; }; -- GitLab From 18c01ab30288d9d0a7d80b08b659531f37ed379d Mon Sep 17 00:00:00 2001 From: Rajesh Ghanekar Date: Fri, 1 Aug 2014 22:17:30 -0400 Subject: [PATCH 0875/9167] nfsd: allow turning off nfsv3 readdir_plus One of our customer's application only needs file names, not file attributes. With directories having 10K+ inodes (assuming buffer cache has directory blocks cached having file names, but inode cache is limited and hence need eviction of older cached inodes), older inodes are evicted periodically. So if they keep on doing readdir(2) from NSF client on multiple directories, some directory's files are periodically removed from inode cache and hence new readdir(2) on same directory requires disk access to bring back inodes again to inode cache. As READDIRPLUS request fetches attributes also, doing getattr on each file on server, it causes unnecessary disk accesses. If READDIRPLUS on NFS client is returned with -ENOTSUPP, NFS client uses READDIR request which just gets the names of the files in a directory, not attributes, hence avoiding disk accesses on server. There's already a corresponding client-side mount option, but an export option reduces the need for configuration across multiple clients. This flag affects NFSv3 only. If it turns out it's needed for NFSv4 as well then we may have to figure out how to extend the behavior to NFSv4, but it's not currently obvious how to do that. Signed-off-by: Rajesh Ghanekar Signed-off-by: J. Bruce Fields --- fs/nfsd/export.c | 1 + fs/nfsd/nfs3proc.c | 8 ++++++++ include/uapi/linux/nfsd/export.h | 5 +++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 72ffd7cce3c3..30a739d896ff 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -1145,6 +1145,7 @@ static struct flags { { NFSEXP_ALLSQUASH, {"all_squash", ""}}, { NFSEXP_ASYNC, {"async", "sync"}}, { NFSEXP_GATHERED_WRITES, {"wdelay", "no_wdelay"}}, + { NFSEXP_NOREADDIRPLUS, {"nordirplus", ""}}, { NFSEXP_NOHIDE, {"nohide", ""}}, { NFSEXP_CROSSMOUNT, {"crossmnt", ""}}, { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index fc51f7f6b36d..12f2aab4f614 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -466,6 +466,14 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, resp->buflen = resp->count; resp->rqstp = rqstp; offset = argp->cookie; + + nfserr = fh_verify(rqstp, &resp->fh, S_IFDIR, NFSD_MAY_NOP); + if (nfserr) + RETURN_STATUS(nfserr); + + if (resp->fh.fh_export->ex_flags & NFSEXP_NOREADDIRPLUS) + RETURN_STATUS(nfserr_notsupp); + nfserr = nfsd_readdir(rqstp, &resp->fh, &offset, &resp->common, diff --git a/include/uapi/linux/nfsd/export.h b/include/uapi/linux/nfsd/export.h index cf47c313794e..584b6ef3a5e8 100644 --- a/include/uapi/linux/nfsd/export.h +++ b/include/uapi/linux/nfsd/export.h @@ -28,7 +28,8 @@ #define NFSEXP_ALLSQUASH 0x0008 #define NFSEXP_ASYNC 0x0010 #define NFSEXP_GATHERED_WRITES 0x0020 -/* 40 80 100 currently unused */ +#define NFSEXP_NOREADDIRPLUS 0x0040 +/* 80 100 currently unused */ #define NFSEXP_NOHIDE 0x0200 #define NFSEXP_NOSUBTREECHECK 0x0400 #define NFSEXP_NOAUTHNLM 0x0800 /* Don't authenticate NLM requests - just trust */ @@ -47,7 +48,7 @@ */ #define NFSEXP_V4ROOT 0x10000 /* All flags that we claim to support. (Note we don't support NOACL.) */ -#define NFSEXP_ALLFLAGS 0x17E3F +#define NFSEXP_ALLFLAGS 0x1FE7F /* The flags that may vary depending on security flavor: */ #define NFSEXP_SECINFO_FLAGS (NFSEXP_READONLY | NFSEXP_ROOTSQUASH \ -- GitLab From a130548d8c06d4fda098f25a6b3dec62beec27cc Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Mon, 18 Aug 2014 13:26:51 -0500 Subject: [PATCH 0876/9167] ARM: dts: Improve Peach Pit and Pi power scheme The DeviceTree files for the Peach Pit and Pi machines have a simplistic model of the connections between the different regulators since not all the tps65090 regulators get their input supply voltage from the VDC. DCDC1-3, LD0-1 and fet7 parent supply is indded VDC but the fet1-6 get their input supply from the DCDC1 and DCDC2 output voltage rails. Update the DeviceTree to better reflect the real connections between tps65090 regulators. Having this information in the DTS is useful since FETs are switches that don't provide an output voltage so the regulator core needs to fetch the FET parent output voltage if the child voltage is queried. Signed-off-by: Javier Martinez Canillas Acked-by: Mark Brown Acked-by: Doug Anderson Signed-off-by: Kukjin Kim --- arch/arm/boot/dts/exynos5420-peach-pit.dts | 12 ++++++------ arch/arm/boot/dts/exynos5800-peach-pi.dts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts index 7b1ed2c1baf5..ab0614841113 100644 --- a/arch/arm/boot/dts/exynos5420-peach-pit.dts +++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts @@ -357,12 +357,12 @@ vsys2-supply = <&vbat>; vsys3-supply = <&vbat>; infet1-supply = <&vbat>; - infet2-supply = <&vbat>; - infet3-supply = <&vbat>; - infet4-supply = <&vbat>; - infet5-supply = <&vbat>; - infet6-supply = <&vbat>; - infet7-supply = <&vbat>; + infet2-supply = <&tps65090_dcdc1>; + infet3-supply = <&tps65090_dcdc2>; + infet4-supply = <&tps65090_dcdc2>; + infet5-supply = <&tps65090_dcdc2>; + infet6-supply = <&tps65090_dcdc2>; + infet7-supply = <&tps65090_dcdc1>; vsys-l1-supply = <&vbat>; vsys-l2-supply = <&vbat>; diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts index a587dd6dbcc5..9ae98aa8b171 100644 --- a/arch/arm/boot/dts/exynos5800-peach-pi.dts +++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts @@ -355,12 +355,12 @@ vsys2-supply = <&vbat>; vsys3-supply = <&vbat>; infet1-supply = <&vbat>; - infet2-supply = <&vbat>; - infet3-supply = <&vbat>; - infet4-supply = <&vbat>; - infet5-supply = <&vbat>; - infet6-supply = <&vbat>; - infet7-supply = <&vbat>; + infet2-supply = <&tps65090_dcdc1>; + infet3-supply = <&tps65090_dcdc2>; + infet4-supply = <&tps65090_dcdc2>; + infet5-supply = <&tps65090_dcdc2>; + infet6-supply = <&tps65090_dcdc2>; + infet7-supply = <&tps65090_dcdc1>; vsys-l1-supply = <&vbat>; vsys-l2-supply = <&vbat>; -- GitLab From e9bd0224c130617d7d6037d3a405571c33b1e097 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 12 Aug 2014 11:54:36 +0200 Subject: [PATCH 0877/9167] ALSA: hda - Remove obsoleted snd_hda_check_board_config() & co The helper functions snd_hda_check_board_config() and snd_hda_check_board_codec_sid_config() are no longer used since the transition to the generic parser and all quirks have been replaced with fixups. Let's kill these dead codes. Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.c | 115 -------------------------------------- sound/pci/hda/hda_local.h | 6 -- 2 files changed, 121 deletions(-) diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index ec6a7d0d1886..0aa2e1ed1dbc 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4816,121 +4816,6 @@ int snd_hda_build_pcms(struct hda_bus *bus) } EXPORT_SYMBOL_GPL(snd_hda_build_pcms); -/** - * snd_hda_check_board_config - compare the current codec with the config table - * @codec: the HDA codec - * @num_configs: number of config enums - * @models: array of model name strings - * @tbl: configuration table, terminated by null entries - * - * Compares the modelname or PCI subsystem id of the current codec with the - * given configuration table. If a matching entry is found, returns its - * config value (supposed to be 0 or positive). - * - * If no entries are matching, the function returns a negative value. - */ -int snd_hda_check_board_config(struct hda_codec *codec, - int num_configs, const char * const *models, - const struct snd_pci_quirk *tbl) -{ - if (codec->modelname && models) { - int i; - for (i = 0; i < num_configs; i++) { - if (models[i] && - !strcmp(codec->modelname, models[i])) { - codec_info(codec, "model '%s' is selected\n", - models[i]); - return i; - } - } - } - - if (!codec->bus->pci || !tbl) - return -1; - - tbl = snd_pci_quirk_lookup(codec->bus->pci, tbl); - if (!tbl) - return -1; - if (tbl->value >= 0 && tbl->value < num_configs) { -#ifdef CONFIG_SND_DEBUG_VERBOSE - char tmp[10]; - const char *model = NULL; - if (models) - model = models[tbl->value]; - if (!model) { - sprintf(tmp, "#%d", tbl->value); - model = tmp; - } - codec_info(codec, "model '%s' is selected for config %x:%x (%s)\n", - model, tbl->subvendor, tbl->subdevice, - (tbl->name ? tbl->name : "Unknown device")); -#endif - return tbl->value; - } - return -1; -} -EXPORT_SYMBOL_GPL(snd_hda_check_board_config); - -/** - * snd_hda_check_board_codec_sid_config - compare the current codec - subsystem ID with the - config table - - This is important for Gateway notebooks with SB450 HDA Audio - where the vendor ID of the PCI device is: - ATI Technologies Inc SB450 HDA Audio [1002:437b] - and the vendor/subvendor are found only at the codec. - - * @codec: the HDA codec - * @num_configs: number of config enums - * @models: array of model name strings - * @tbl: configuration table, terminated by null entries - * - * Compares the modelname or PCI subsystem id of the current codec with the - * given configuration table. If a matching entry is found, returns its - * config value (supposed to be 0 or positive). - * - * If no entries are matching, the function returns a negative value. - */ -int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, - int num_configs, const char * const *models, - const struct snd_pci_quirk *tbl) -{ - const struct snd_pci_quirk *q; - - /* Search for codec ID */ - for (q = tbl; q->subvendor; q++) { - unsigned int mask = 0xffff0000 | q->subdevice_mask; - unsigned int id = (q->subdevice | (q->subvendor << 16)) & mask; - if ((codec->subsystem_id & mask) == id) - break; - } - - if (!q->subvendor) - return -1; - - tbl = q; - - if (tbl->value >= 0 && tbl->value < num_configs) { -#ifdef CONFIG_SND_DEBUG_VERBOSE - char tmp[10]; - const char *model = NULL; - if (models) - model = models[tbl->value]; - if (!model) { - sprintf(tmp, "#%d", tbl->value); - model = tmp; - } - codec_info(codec, "model '%s' is selected for config %x:%x (%s)\n", - model, tbl->subvendor, tbl->subdevice, - (tbl->name ? tbl->name : "Unknown device")); -#endif - return tbl->value; - } - return -1; -} -EXPORT_SYMBOL_GPL(snd_hda_check_board_codec_sid_config); - /** * snd_hda_add_new_ctls - create controls from the array * @codec: the HDA codec diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 364bb413e02a..8a018d4cbe98 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -371,12 +371,6 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen); /* * Misc */ -int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, - const char * const *modelnames, - const struct snd_pci_quirk *pci_list); -int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, - int num_configs, const char * const *models, - const struct snd_pci_quirk *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, const struct snd_kcontrol_new *knew); -- GitLab From e52faba0f3a5520fc766e24520c10cb79fee2fac Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 12 Aug 2014 11:57:05 +0200 Subject: [PATCH 0878/9167] ALSA: hda - Remove obsoleted EXPORT_SYMBOL_HDA() macro Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_codec.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index bbc5a1392c75..9c8820f21f94 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -687,6 +687,4 @@ snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec, struct snd_dma_buffer *dmab) {} #endif -#define EXPORT_SYMBOL_HDA(sym) EXPORT_SYMBOL_GPL(sym) - #endif /* __SOUND_HDA_CODEC_H */ -- GitLab From f2a227cd3891266f1486a21aac86fa39b3abd093 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Aug 2014 13:35:22 +0200 Subject: [PATCH 0879/9167] ALSA: hda/realtek - Optimize alc888_coef_init() Just a refactoring using the existing helper functions. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 91 +++++++++++++++-------------------- 1 file changed, 40 insertions(+), 51 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d71270a3f73f..c9a7a2d237da 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -128,6 +128,43 @@ struct alc_spec { unsigned int coef0; }; +/* + * COEF access helper functions + */ + +static int alc_read_coefex_idx(struct hda_codec *codec, hda_nid_t nid, + unsigned int coef_idx) +{ + unsigned int val; + + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx); + val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0); + return val; +} + +#define alc_read_coef_idx(codec, coef_idx) \ + alc_read_coefex_idx(codec, 0x20, coef_idx) + +static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, + unsigned int coef_idx, unsigned int coef_val) +{ + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, coef_idx); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, coef_val); +} + +#define alc_write_coef_idx(codec, coef_idx, coef_val) \ + alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) + +/* a special bypass for COEF 0; read the cached value at the second time */ +static unsigned int alc_get_coef0(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + if (!spec->coef0) + spec->coef0 = alc_read_coef_idx(codec, 0); + return spec->coef0; +} + /* * Append the given mixer and verb elements for the later use * The mixer array is referred in build_controls(), and init_verbs are @@ -231,19 +268,12 @@ static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) /* additional initialization for ALC888 variants */ static void alc888_coef_init(struct hda_codec *codec) { - unsigned int tmp; - - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); - tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); - if ((tmp & 0xf0) == 0x20) + if (alc_get_coef0(codec) == 0x20) /* alc888S-VC */ - snd_hda_codec_read(codec, 0x20, 0, - AC_VERB_SET_PROC_COEF, 0x830); + alc_write_coef_idx(codec, 7, 0x830); else /* alc888-VB */ - snd_hda_codec_read(codec, 0x20, 0, - AC_VERB_SET_PROC_COEF, 0x3030); + alc_write_coef_idx(codec, 7, 0x3030); } /* additional initialization for ALC889 variants */ @@ -586,47 +616,6 @@ static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) } } -/* - * COEF access helper functions - */ - -static int alc_read_coefex_idx(struct hda_codec *codec, - hda_nid_t nid, - unsigned int coef_idx) -{ - unsigned int val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, - coef_idx); - val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_PROC_COEF, 0); - return val; -} - -#define alc_read_coef_idx(codec, coef_idx) \ - alc_read_coefex_idx(codec, 0x20, coef_idx) - -static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, - unsigned int coef_idx, - unsigned int coef_val) -{ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, - coef_idx); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, - coef_val); -} - -#define alc_write_coef_idx(codec, coef_idx, coef_val) \ - alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) - -/* a special bypass for COEF 0; read the cached value at the second time */ -static unsigned int alc_get_coef0(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - if (!spec->coef0) - spec->coef0 = alc_read_coef_idx(codec, 0); - return spec->coef0; -} - /* */ -- GitLab From 1687ccc8b2229d05c579924086e9b42ada9db888 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Aug 2014 13:49:35 +0200 Subject: [PATCH 0880/9167] ALSA: hda/realtek - Use alc_write_coef_idx() in alc269_quanta_automake() Just a refactoring. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c9a7a2d237da..75614e53e60c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3355,15 +3355,8 @@ static void alc269_quanta_automute(struct hda_codec *codec) { snd_hda_gen_update_outputs(codec); - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_COEF_INDEX, 0x0c); - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_PROC_COEF, 0x680); - - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_COEF_INDEX, 0x0c); - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_PROC_COEF, 0x480); + alc_write_coef_idx(codec, 0x0c, 0x680); + alc_write_coef_idx(codec, 0x0c, 0x480); } static void alc269_fixup_quanta_mute(struct hda_codec *codec, -- GitLab From 98b248839474293481905562ae38dc2d6558ef20 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Aug 2014 13:47:50 +0200 Subject: [PATCH 0881/9167] ALSA: hda/realtek - Add alc_update_coef*_idx() helper ... and rewrite a few open codes with them. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 277 ++++++++++------------------------ 1 file changed, 82 insertions(+), 195 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 75614e53e60c..fe041fa4f2c3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -155,6 +155,20 @@ static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, #define alc_write_coef_idx(codec, coef_idx, coef_val) \ alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) +static void alc_update_coefex_idx(struct hda_codec *codec, hda_nid_t nid, + unsigned int coef_idx, unsigned int mask, + unsigned int bits_set) +{ + unsigned int val = alc_read_coefex_idx(codec, nid, coef_idx); + + if (val != -1) + alc_write_coefex_idx(codec, nid, coef_idx, + (val & ~mask) | bits_set); +} + +#define alc_update_coef_idx(codec, coef_idx, mask, bits_set) \ + alc_update_coefex_idx(codec, 0x20, coef_idx, mask, bits_set) + /* a special bypass for COEF 0; read the cached value at the second time */ static unsigned int alc_get_coef0(struct hda_codec *codec) { @@ -210,20 +224,10 @@ static const struct hda_verb alc_gpio3_init_verbs[] = { static void alc_fix_pll(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int val; - if (!spec->pll_nid) - return; - snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, - spec->pll_coef_idx); - val = snd_hda_codec_read(codec, spec->pll_nid, 0, - AC_VERB_GET_PROC_COEF, 0); - if (val == -1) - return; - snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, - spec->pll_coef_idx); - snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, - val & ~(1 << spec->pll_coef_bit)); + if (spec->pll_nid) + alc_update_coefex_idx(codec, spec->pll_nid, spec->pll_coef_idx, + 1 << spec->pll_coef_bit, 0); } static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, @@ -279,12 +283,7 @@ static void alc888_coef_init(struct hda_codec *codec) /* additional initialization for ALC889 variants */ static void alc889_coef_init(struct hda_codec *codec) { - unsigned int tmp; - - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); - tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); + alc_update_coef_idx(codec, 7, 0, 0x2010); } /* turn on/off EAPD control (only if available) */ @@ -325,8 +324,6 @@ static void alc_eapd_shutup(struct hda_codec *codec) /* generic EAPD initialization */ static void alc_auto_init_amp(struct hda_codec *codec, int type) { - unsigned int tmp; - alc_auto_setup_eapd(codec, true); switch (type) { case ALC_INIT_GPIO1: @@ -341,15 +338,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) case ALC_INIT_DEFAULT: switch (codec->vendor_id) { case 0x10ec0260: - snd_hda_codec_write(codec, 0x1a, 0, - AC_VERB_SET_COEF_INDEX, 7); - tmp = snd_hda_codec_read(codec, 0x1a, 0, - AC_VERB_GET_PROC_COEF, 0); - snd_hda_codec_write(codec, 0x1a, 0, - AC_VERB_SET_COEF_INDEX, 7); - snd_hda_codec_write(codec, 0x1a, 0, - AC_VERB_SET_PROC_COEF, - tmp | 0x2010); + alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x2010); break; case 0x10ec0262: case 0x10ec0880: @@ -366,15 +355,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) #if 0 /* XXX: This may cause the silent output on speaker on some machines */ case 0x10ec0267: case 0x10ec0268: - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_COEF_INDEX, 7); - tmp = snd_hda_codec_read(codec, 0x20, 0, - AC_VERB_GET_PROC_COEF, 0); - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_COEF_INDEX, 7); - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_PROC_COEF, - tmp | 0x3000); + alc_update_coef_idx(codec, 7, 0, 0x3000); break; #endif /* XXX */ } @@ -2504,13 +2485,7 @@ static int patch_alc262(struct hda_codec *codec) /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is * under-run */ - { - int tmp; - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); - tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); - } + alc_update_coefex_idx(codec, 0x1a, 7, 0, 0x80); #endif alc_fix_pll_init(codec, 0x20, 0x0a, 10); @@ -2796,14 +2771,7 @@ static void alc286_shutup(struct hda_codec *codec) static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) { - int val = alc_read_coef_idx(codec, 0x04); - if (val == -1) - return; - if (power_up) - val |= 1 << 11; - else - val &= ~(1 << 11); - alc_write_coef_idx(codec, 0x04, val); + alc_update_coef_idx(codec, 0x04, 1 << 11, power_up ? (1 << 11) : 0); } static void alc269_shutup(struct hda_codec *codec) @@ -2821,8 +2789,6 @@ static void alc269_shutup(struct hda_codec *codec) static void alc282_restore_default_value(struct hda_codec *codec) { - int val; - /* Power Down Control */ alc_write_coef_idx(codec, 0x03, 0x0002); /* FIFO and filter clock */ @@ -2830,11 +2796,9 @@ static void alc282_restore_default_value(struct hda_codec *codec) /* DMIC control */ alc_write_coef_idx(codec, 0x07, 0x0200); /* Analog clock */ - val = alc_read_coef_idx(codec, 0x06); - alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); + alc_update_coef_idx(codec, 0x06, 0x00f0, 0); /* JD */ - val = alc_read_coef_idx(codec, 0x08); - alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); + alc_update_coef_idx(codec, 0x08, 0xfffc, 0x0c2c); /* JD offset1 */ alc_write_coef_idx(codec, 0x0a, 0xcccc); /* JD offset2 */ @@ -2842,27 +2806,21 @@ static void alc282_restore_default_value(struct hda_codec *codec) /* LDO1/2/3, DAC/ADC */ alc_write_coef_idx(codec, 0x0e, 0x6e00); /* JD */ - val = alc_read_coef_idx(codec, 0x0f); - alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); + alc_update_coef_idx(codec, 0x0f, 0xf800, 0x1000); /* Capless */ - val = alc_read_coef_idx(codec, 0x10); - alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); + alc_update_coef_idx(codec, 0x10, 0xfc00, 0x0c00); /* Class D test 4 */ alc_write_coef_idx(codec, 0x6f, 0x0); /* IO power down directly */ - val = alc_read_coef_idx(codec, 0x0c); - alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); + alc_update_coef_idx(codec, 0x0c, 0xfe00, 0); /* ANC */ alc_write_coef_idx(codec, 0x34, 0xa0c0); /* AGC MUX */ - val = alc_read_coef_idx(codec, 0x16); - alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0); + alc_update_coef_idx(codec, 0x16, 0x0008, 0); /* DAC simple content protection */ - val = alc_read_coef_idx(codec, 0x1d); - alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); + alc_update_coef_idx(codec, 0x1d, 0x00e0, 0); /* ADC simple content protection */ - val = alc_read_coef_idx(codec, 0x1f); - alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); + alc_update_coef_idx(codec, 0x1f, 0x00e0, 0); /* DAC ADC Zero Detection */ alc_write_coef_idx(codec, 0x21, 0x8804); /* PLL */ @@ -2876,20 +2834,17 @@ static void alc282_restore_default_value(struct hda_codec *codec) /* capless control 5 */ alc_write_coef_idx(codec, 0x6b, 0x0); /* class D test 2 */ - val = alc_read_coef_idx(codec, 0x6d); - alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900); + alc_update_coef_idx(codec, 0x6d, 0x0fff, 0x0900); /* class D test 3 */ alc_write_coef_idx(codec, 0x6e, 0x110a); /* class D test 5 */ - val = alc_read_coef_idx(codec, 0x70); - alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8); + alc_update_coef_idx(codec, 0x70, 0x00f8, 0x00d8); /* class D test 6 */ alc_write_coef_idx(codec, 0x71, 0x0014); /* classD OCP */ alc_write_coef_idx(codec, 0x72, 0xc2ba); /* classD pure DC test */ - val = alc_read_coef_idx(codec, 0x77); - alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0); + alc_update_coef_idx(codec, 0x77, 0x0f80, 0); /* Class D amp control */ alc_write_coef_idx(codec, 0x6c, 0xfc06); } @@ -2969,8 +2924,6 @@ static void alc282_shutup(struct hda_codec *codec) static void alc283_restore_default_value(struct hda_codec *codec) { - int val; - /* Power Down Control */ alc_write_coef_idx(codec, 0x03, 0x0002); /* FIFO and filter clock */ @@ -2978,11 +2931,9 @@ static void alc283_restore_default_value(struct hda_codec *codec) /* DMIC control */ alc_write_coef_idx(codec, 0x07, 0x0200); /* Analog clock */ - val = alc_read_coef_idx(codec, 0x06); - alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); + alc_update_coef_idx(codec, 0x06, 0x00f0, 0); /* JD */ - val = alc_read_coef_idx(codec, 0x08); - alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); + alc_update_coef_idx(codec, 0x08, 0xfffc, 0x0c2c); /* JD offset1 */ alc_write_coef_idx(codec, 0x0a, 0xcccc); /* JD offset2 */ @@ -2990,27 +2941,21 @@ static void alc283_restore_default_value(struct hda_codec *codec) /* LDO1/2/3, DAC/ADC */ alc_write_coef_idx(codec, 0x0e, 0x6fc0); /* JD */ - val = alc_read_coef_idx(codec, 0x0f); - alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); + alc_update_coef_idx(codec, 0x0f, 0xf800, 0x1000); /* Capless */ - val = alc_read_coef_idx(codec, 0x10); - alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); + alc_update_coef_idx(codec, 0x10, 0xfc00, 0x0c00); /* Class D test 4 */ alc_write_coef_idx(codec, 0x3a, 0x0); /* IO power down directly */ - val = alc_read_coef_idx(codec, 0x0c); - alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); + alc_update_coef_idx(codec, 0x0c, 0xfe00, 0x0); /* ANC */ alc_write_coef_idx(codec, 0x22, 0xa0c0); /* AGC MUX */ - val = alc_read_coefex_idx(codec, 0x53, 0x01); - alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); + alc_update_coefex_idx(codec, 0x53, 0x01, 0x000f, 0x0008); /* DAC simple content protection */ - val = alc_read_coef_idx(codec, 0x1d); - alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); + alc_update_coef_idx(codec, 0x1d, 0x00e0, 0x0); /* ADC simple content protection */ - val = alc_read_coef_idx(codec, 0x1f); - alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); + alc_update_coef_idx(codec, 0x1f, 0x00e0, 0x0); /* DAC ADC Zero Detection */ alc_write_coef_idx(codec, 0x21, 0x8804); /* PLL */ @@ -3024,28 +2969,23 @@ static void alc283_restore_default_value(struct hda_codec *codec) /* capless control 5 */ alc_write_coef_idx(codec, 0x36, 0x0); /* class D test 2 */ - val = alc_read_coef_idx(codec, 0x38); - alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); + alc_update_coef_idx(codec, 0x38, 0x0fff, 0x0900); /* class D test 3 */ alc_write_coef_idx(codec, 0x39, 0x110a); /* class D test 5 */ - val = alc_read_coef_idx(codec, 0x3b); - alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); + alc_update_coef_idx(codec, 0x3b, 0x00f8, 0x00d8); /* class D test 6 */ alc_write_coef_idx(codec, 0x3c, 0x0014); /* classD OCP */ alc_write_coef_idx(codec, 0x3d, 0xc2ba); /* classD pure DC test */ - val = alc_read_coef_idx(codec, 0x42); - alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); + alc_update_coef_idx(codec, 0x42, 0x0f80, 0x0); /* test mode */ alc_write_coef_idx(codec, 0x49, 0x0); /* Class D DC enable */ - val = alc_read_coef_idx(codec, 0x40); - alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); + alc_update_coef_idx(codec, 0x40, 0xf800, 0x9800); /* DC offset */ - val = alc_read_coef_idx(codec, 0x42); - alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); + alc_update_coef_idx(codec, 0x42, 0xf000, 0x2000); /* Class D amp control */ alc_write_coef_idx(codec, 0x37, 0xfc06); } @@ -3055,7 +2995,6 @@ static void alc283_init(struct hda_codec *codec) struct alc_spec *spec = codec->spec; hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; bool hp_pin_sense; - int val; if (!spec->gen.autocfg.hp_outs) { if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) @@ -3085,8 +3024,7 @@ static void alc283_init(struct hda_codec *codec) msleep(85); /* Index 0x46 Combo jack auto switch control 2 */ /* 3k pull low control for Headset jack. */ - val = alc_read_coef_idx(codec, 0x46); - alc_write_coef_idx(codec, 0x46, val & ~(3 << 12)); + alc_update_coef_idx(codec, 0x46, 3 << 12, 0); /* Headphone capless set to normal mode */ alc_write_coef_idx(codec, 0x43, 0x9614); } @@ -3096,7 +3034,6 @@ static void alc283_shutup(struct hda_codec *codec) struct alc_spec *spec = codec->spec; hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; bool hp_pin_sense; - int val; if (!spec->gen.autocfg.hp_outs) { if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) @@ -3121,8 +3058,7 @@ static void alc283_shutup(struct hda_codec *codec) snd_hda_codec_write(codec, hp_pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); - val = alc_read_coef_idx(codec, 0x46); - alc_write_coef_idx(codec, 0x46, val | (3 << 12)); + alc_update_coef_idx(codec, 0x46, 0, 3 << 12); if (hp_pin_sense) msleep(100); @@ -3285,12 +3221,8 @@ static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, static void alc269_fixup_hweq(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - int coef; - - if (action != HDA_FIXUP_ACT_INIT) - return; - coef = alc_read_coef_idx(codec, 0x1e); - alc_write_coef_idx(codec, 0x1e, coef | 0x80); + if (action == HDA_FIXUP_ACT_INIT) + alc_update_coef_idx(codec, 0x1e, 0, 0x80); } static void alc269_fixup_headset_mic(struct hda_codec *codec, @@ -3338,17 +3270,13 @@ static void alc269_fixup_pcm_44k(struct hda_codec *codec, static void alc269_fixup_stereo_dmic(struct hda_codec *codec, const struct hda_fixup *fix, int action) { - int coef; - - if (action != HDA_FIXUP_ACT_INIT) - return; /* The digital-mic unit sends PDM (differential signal) instead of * the standard PCM, thus you can't record a valid mono stream as is. * Below is a workaround specific to ALC269 to control the dmic * signal source as mono. */ - coef = alc_read_coef_idx(codec, 0x07); - alc_write_coef_idx(codec, 0x07, coef | 0x80); + if (action == HDA_FIXUP_ACT_INIT) + alc_update_coef_idx(codec, 0x07, 0, 0x80); } static void alc269_quanta_automute(struct hda_codec *codec) @@ -3602,8 +3530,6 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, static void alc_headset_mode_unplugged(struct hda_codec *codec) { - int val; - switch (codec->vendor_id) { case 0x10ec0255: /* LDO and MISC control */ @@ -3611,8 +3537,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) /* UAJ function set to menual mode */ alc_write_coef_idx(codec, 0x45, 0xd089); /* Direct Drive HP Amp control(Set to verb control)*/ - val = alc_read_coefex_idx(codec, 0x57, 0x05); - alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); + alc_update_coefex_idx(codec, 0x57, 0x05, 1<<14, 0); /* Set MIC2 Vref gate with HP */ alc_write_coef_idx(codec, 0x06, 0x6104); /* Direct Drive HP Amp control */ @@ -3622,8 +3547,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) case 0x10ec0283: alc_write_coef_idx(codec, 0x1b, 0x0c0b); alc_write_coef_idx(codec, 0x45, 0xc429); - val = alc_read_coef_idx(codec, 0x35); - alc_write_coef_idx(codec, 0x35, val & 0xbfff); + alc_update_coef_idx(codec, 0x35, 0x4000, 0); alc_write_coef_idx(codec, 0x06, 0x2104); alc_write_coef_idx(codec, 0x1a, 0x0001); alc_write_coef_idx(codec, 0x26, 0x0004); @@ -3637,22 +3561,17 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) break; case 0x10ec0293: /* SET Line1 JD to 0 */ - val = alc_read_coef_idx(codec, 0x10); - alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 6<<8); + alc_update_coef_idx(codec, 0x10, 7<<8, 6<<8); /* SET charge pump by verb */ - val = alc_read_coefex_idx(codec, 0x57, 0x05); - alc_write_coefex_idx(codec, 0x57, 0x05, (val & ~(1<<15|1<<13)) | 0x0); + alc_update_coefex_idx(codec, 0x57, 0x05, 1<<15|1<<13, 0x0); /* SET EN_OSW to 1 */ - val = alc_read_coefex_idx(codec, 0x57, 0x03); - alc_write_coefex_idx(codec, 0x57, 0x03, (val & ~(1<<10)) | (1<<10) ); + alc_update_coefex_idx(codec, 0x57, 0x03, 1<<10, 1<<10); /* Combo JD gating with LINE1-VREFO */ - val = alc_read_coef_idx(codec, 0x1a); - alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | (1<<3)); + alc_update_coef_idx(codec, 0x1a, 1<<3, 1<<3); /* Set to TRS type */ alc_write_coef_idx(codec, 0x45, 0xc429); /* Combo Jack auto detect */ - val = alc_read_coef_idx(codec, 0x4a); - alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x000e); + alc_update_coef_idx(codec, 0x4a, 0x000f, 0x000e); break; case 0x10ec0668: alc_write_coef_idx(codec, 0x15, 0x0d40); @@ -3666,8 +3585,6 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, hda_nid_t mic_pin) { - int val; - switch (codec->vendor_id) { case 0x10ec0255: alc_write_coef_idx(codec, 0x45, 0xc489); @@ -3681,8 +3598,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, case 0x10ec0283: alc_write_coef_idx(codec, 0x45, 0xc429); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); - val = alc_read_coef_idx(codec, 0x35); - alc_write_coef_idx(codec, 0x35, val | 1<<14); + alc_update_coef_idx(codec, 0x35, 0, 1<<14); alc_write_coef_idx(codec, 0x06, 0x2100); alc_write_coef_idx(codec, 0x1a, 0x0021); alc_write_coef_idx(codec, 0x26, 0x008c); @@ -3698,14 +3614,11 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, alc_write_coef_idx(codec, 0x45, 0xc429); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); /* SET charge pump by verb */ - val = alc_read_coefex_idx(codec, 0x57, 0x05); - alc_write_coefex_idx(codec, 0x57, 0x05, (val & ~(1<<15|1<<13)) | (1<<15|1<<13)); + alc_update_coefex_idx(codec, 0x57, 0x05, 0, 1<<15|1<<13); /* SET EN_OSW to 0 */ - val = alc_read_coefex_idx(codec, 0x57, 0x03); - alc_write_coefex_idx(codec, 0x57, 0x03, (val & ~(1<<10)) | 0x0); + alc_update_coefex_idx(codec, 0x57, 0x03, 1<<10, 0); /* Combo JD gating without LINE1-VREFO */ - val = alc_read_coef_idx(codec, 0x1a); - alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | 0x0); + alc_update_coef_idx(codec, 0x1a, 1<<3, 0); snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); break; case 0x10ec0668: @@ -3713,8 +3626,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); alc_write_coef_idx(codec, 0xb7, 0x802b); alc_write_coef_idx(codec, 0xb5, 0x1040); - val = alc_read_coef_idx(codec, 0xc3); - alc_write_coef_idx(codec, 0xc3, val | 1<<12); + alc_update_coef_idx(codec, 0xc3, 0, 1<<12); snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); break; } @@ -3723,8 +3635,6 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, static void alc_headset_mode_default(struct hda_codec *codec) { - int val; - switch (codec->vendor_id) { case 0x10ec0255: alc_write_coef_idx(codec, 0x45, 0xc089); @@ -3745,13 +3655,11 @@ static void alc_headset_mode_default(struct hda_codec *codec) break; case 0x10ec0293: /* Combo Jack auto detect */ - val = alc_read_coef_idx(codec, 0x4a); - alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x000e); + alc_update_coef_idx(codec, 0x4a, 0x000f, 0x000e); /* Set to TRS type */ alc_write_coef_idx(codec, 0x45, 0xC429); /* Combo JD gating without LINE1-VREFO */ - val = alc_read_coef_idx(codec, 0x1a); - alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | 0x0); + alc_update_coef_idx(codec, 0x1a, 1<<3, 0); break; case 0x10ec0668: alc_write_coef_idx(codec, 0x11, 0x0041); @@ -3765,8 +3673,6 @@ static void alc_headset_mode_default(struct hda_codec *codec) /* Iphone type */ static void alc_headset_mode_ctia(struct hda_codec *codec) { - int val; - switch (codec->vendor_id) { case 0x10ec0255: /* Set to CTIA type */ @@ -3789,8 +3695,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) /* Set to ctia type */ alc_write_coef_idx(codec, 0x45, 0xd429); /* SET Line1 JD to 1 */ - val = alc_read_coef_idx(codec, 0x10); - alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 7<<8); + alc_update_coef_idx(codec, 0x10, 7<<8, 7<<8); break; case 0x10ec0668: alc_write_coef_idx(codec, 0x11, 0x0001); @@ -3804,8 +3709,6 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) /* Nokia type */ static void alc_headset_mode_omtp(struct hda_codec *codec) { - int val; - switch (codec->vendor_id) { case 0x10ec0255: /* Set to OMTP Type */ @@ -3828,8 +3731,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) /* Set to omtp type */ alc_write_coef_idx(codec, 0x45, 0xe429); /* SET Line1 JD to 1 */ - val = alc_read_coef_idx(codec, 0x10); - alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 7<<8); + alc_update_coef_idx(codec, 0x10, 7<<8, 7<<8); break; case 0x10ec0668: alc_write_coef_idx(codec, 0x11, 0x0001); @@ -3871,8 +3773,7 @@ static void alc_determine_headset_type(struct hda_codec *codec) break; case 0x10ec0293: /* Combo Jack auto detect */ - val = alc_read_coef_idx(codec, 0x4a); - alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x0008); + alc_update_coef_idx(codec, 0x4a, 0x000f, 0x0008); /* Set to ctia type */ alc_write_coef_idx(codec, 0x45, 0xD429); msleep(300); @@ -4118,10 +4019,8 @@ static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, const struct hda_fixup *fix, int action) { if (action == HDA_FIXUP_ACT_PRE_PROBE) { - int val; alc_write_coef_idx(codec, 0xc4, 0x8000); - val = alc_read_coef_idx(codec, 0xc2); - alc_write_coef_idx(codec, 0xc2, val & 0xfe); + alc_update_coef_idx(codec, 0xc2, ~0xfe, 0); snd_hda_set_pin_ctl_cache(codec, 0x18, 0); } alc_fixup_headset_mode(codec, fix, action); @@ -4217,7 +4116,6 @@ static void alc283_fixup_chromebook(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct alc_spec *spec = codec->spec; - int val; switch (action) { case HDA_FIXUP_ACT_PRE_PROBE: @@ -4228,11 +4126,9 @@ static void alc283_fixup_chromebook(struct hda_codec *codec, case HDA_FIXUP_ACT_INIT: /* MIC2-VREF control */ /* Set to manual mode */ - val = alc_read_coef_idx(codec, 0x06); - alc_write_coef_idx(codec, 0x06, val & ~0x000c); + alc_update_coef_idx(codec, 0x06, 0x000c, 0); /* Enable Line1 input control by verb */ - val = alc_read_coef_idx(codec, 0x1a); - alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); + alc_update_coef_idx(codec, 0x1a, 0, 1 << 4); break; } } @@ -4241,7 +4137,6 @@ static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, const struct hda_fixup *fix, int action) { struct alc_spec *spec = codec->spec; - int val; switch (action) { case HDA_FIXUP_ACT_PRE_PROBE: @@ -4250,8 +4145,7 @@ static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, case HDA_FIXUP_ACT_INIT: /* MIC2-VREF control */ /* Set to manual mode */ - val = alc_read_coef_idx(codec, 0x06); - alc_write_coef_idx(codec, 0x06, val & ~0x000c); + alc_update_coef_idx(codec, 0x06, 0x000c, 0); break; } } @@ -5304,10 +5198,8 @@ static void alc269_fill_coef(struct hda_codec *codec) } if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { - val = alc_read_coef_idx(codec, 0x04); /* Power up output pin */ - if (val != -1) - alc_write_coef_idx(codec, 0x04, val | (1<<11)); + alc_update_coef_idx(codec, 0x04, 0, 1<<11); } if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { @@ -5323,13 +5215,11 @@ static void alc269_fill_coef(struct hda_codec *codec) } } - val = alc_read_coef_idx(codec, 0xd); /* Class D */ - if (val != -1) - alc_write_coef_idx(codec, 0xd, val | (1<<14)); + /* Class D */ + alc_update_coef_idx(codec, 0xd, 0, 1<<14); - val = alc_read_coef_idx(codec, 0x4); /* HP */ - if (val != -1) - alc_write_coef_idx(codec, 0x4, val | (1<<11)); + /* HP */ + alc_update_coef_idx(codec, 0x4, 0, 1<<11); } /* @@ -6209,16 +6099,14 @@ static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = { static void alc662_fill_coef(struct hda_codec *codec) { - int val, coef; + int coef; coef = alc_get_coef0(codec); switch (codec->vendor_id) { case 0x10ec0662: - if ((coef & 0x00f0) == 0x0030) { - val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ - alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); - } + if ((coef & 0x00f0) == 0x0030) + alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */ break; case 0x10ec0272: case 0x10ec0273: @@ -6227,8 +6115,7 @@ static void alc662_fill_coef(struct hda_codec *codec) case 0x10ec0670: case 0x10ec0671: case 0x10ec0672: - val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ - alc_write_coef_idx(codec, 0xd, val | (1<<14)); + alc_update_coef_idx(codec, 0xd, 0, 1<<14); /* EAPD Ctrl */ break; } } -- GitLab From 54db6c3949359ee35e9addb02506fca431721ef0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Aug 2014 15:11:19 +0200 Subject: [PATCH 0882/9167] ALSA: hda/realtek - Use tables for batch COEF writes/updtes There are many codes doing writes or updates COEF verbs sequentially in a batch. Rewrite such open codes with tables for optimization. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 559 +++++++++++++++++++--------------- 1 file changed, 314 insertions(+), 245 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fe041fa4f2c3..e0fff47b5740 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -179,6 +179,32 @@ static unsigned int alc_get_coef0(struct hda_codec *codec) return spec->coef0; } +/* coef writes/updates batch */ +struct coef_fw { + unsigned char nid; + unsigned char idx; + unsigned short mask; + unsigned short val; +}; + +#define UPDATE_COEFEX(_nid, _idx, _mask, _val) \ + { .nid = (_nid), .idx = (_idx), .mask = (_mask), .val = (_val) } +#define WRITE_COEFEX(_nid, _idx, _val) UPDATE_COEFEX(_nid, _idx, -1, _val) +#define WRITE_COEF(_idx, _val) WRITE_COEFEX(0x20, _idx, _val) +#define UPDATE_COEF(_idx, _mask, _val) UPDATE_COEFEX(0x20, _idx, _mask, _val) + +static void alc_process_coef_fw(struct hda_codec *codec, + const struct coef_fw *fw) +{ + for (; fw->nid; fw++) { + if (fw->mask == (unsigned short)-1) + alc_write_coefex_idx(codec, fw->nid, fw->idx, fw->val); + else + alc_update_coefex_idx(codec, fw->nid, fw->idx, + fw->mask, fw->val); + } +} + /* * Append the given mixer and verb elements for the later use * The mixer array is referred in build_controls(), and init_verbs are @@ -2787,66 +2813,42 @@ static void alc269_shutup(struct hda_codec *codec) snd_hda_shutup_pins(codec); } +static struct coef_fw alc282_coefs[] = { + WRITE_COEF(0x03, 0x0002), /* Power Down Control */ + WRITE_COEF(0x05, 0x0700), /* FIFO and filter clock */ + WRITE_COEF(0x07, 0x0200), /* DMIC control */ + UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */ + UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */ + WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */ + WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */ + WRITE_COEF(0x0e, 0x6e00), /* LDO1/2/3, DAC/ADC */ + UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */ + UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */ + WRITE_COEF(0x6f, 0x0), /* Class D test 4 */ + UPDATE_COEF(0x0c, 0xfe00, 0), /* IO power down directly */ + WRITE_COEF(0x34, 0xa0c0), /* ANC */ + UPDATE_COEF(0x16, 0x0008, 0), /* AGC MUX */ + UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */ + UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */ + WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */ + WRITE_COEF(0x63, 0x2902), /* PLL */ + WRITE_COEF(0x68, 0xa080), /* capless control 2 */ + WRITE_COEF(0x69, 0x3400), /* capless control 3 */ + WRITE_COEF(0x6a, 0x2f3e), /* capless control 4 */ + WRITE_COEF(0x6b, 0x0), /* capless control 5 */ + UPDATE_COEF(0x6d, 0x0fff, 0x0900), /* class D test 2 */ + WRITE_COEF(0x6e, 0x110a), /* class D test 3 */ + UPDATE_COEF(0x70, 0x00f8, 0x00d8), /* class D test 5 */ + WRITE_COEF(0x71, 0x0014), /* class D test 6 */ + WRITE_COEF(0x72, 0xc2ba), /* classD OCP */ + UPDATE_COEF(0x77, 0x0f80, 0), /* classD pure DC test */ + WRITE_COEF(0x6c, 0xfc06), /* Class D amp control */ + {} +}; + static void alc282_restore_default_value(struct hda_codec *codec) { - /* Power Down Control */ - alc_write_coef_idx(codec, 0x03, 0x0002); - /* FIFO and filter clock */ - alc_write_coef_idx(codec, 0x05, 0x0700); - /* DMIC control */ - alc_write_coef_idx(codec, 0x07, 0x0200); - /* Analog clock */ - alc_update_coef_idx(codec, 0x06, 0x00f0, 0); - /* JD */ - alc_update_coef_idx(codec, 0x08, 0xfffc, 0x0c2c); - /* JD offset1 */ - alc_write_coef_idx(codec, 0x0a, 0xcccc); - /* JD offset2 */ - alc_write_coef_idx(codec, 0x0b, 0xcccc); - /* LDO1/2/3, DAC/ADC */ - alc_write_coef_idx(codec, 0x0e, 0x6e00); - /* JD */ - alc_update_coef_idx(codec, 0x0f, 0xf800, 0x1000); - /* Capless */ - alc_update_coef_idx(codec, 0x10, 0xfc00, 0x0c00); - /* Class D test 4 */ - alc_write_coef_idx(codec, 0x6f, 0x0); - /* IO power down directly */ - alc_update_coef_idx(codec, 0x0c, 0xfe00, 0); - /* ANC */ - alc_write_coef_idx(codec, 0x34, 0xa0c0); - /* AGC MUX */ - alc_update_coef_idx(codec, 0x16, 0x0008, 0); - /* DAC simple content protection */ - alc_update_coef_idx(codec, 0x1d, 0x00e0, 0); - /* ADC simple content protection */ - alc_update_coef_idx(codec, 0x1f, 0x00e0, 0); - /* DAC ADC Zero Detection */ - alc_write_coef_idx(codec, 0x21, 0x8804); - /* PLL */ - alc_write_coef_idx(codec, 0x63, 0x2902); - /* capless control 2 */ - alc_write_coef_idx(codec, 0x68, 0xa080); - /* capless control 3 */ - alc_write_coef_idx(codec, 0x69, 0x3400); - /* capless control 4 */ - alc_write_coef_idx(codec, 0x6a, 0x2f3e); - /* capless control 5 */ - alc_write_coef_idx(codec, 0x6b, 0x0); - /* class D test 2 */ - alc_update_coef_idx(codec, 0x6d, 0x0fff, 0x0900); - /* class D test 3 */ - alc_write_coef_idx(codec, 0x6e, 0x110a); - /* class D test 5 */ - alc_update_coef_idx(codec, 0x70, 0x00f8, 0x00d8); - /* class D test 6 */ - alc_write_coef_idx(codec, 0x71, 0x0014); - /* classD OCP */ - alc_write_coef_idx(codec, 0x72, 0xc2ba); - /* classD pure DC test */ - alc_update_coef_idx(codec, 0x77, 0x0f80, 0); - /* Class D amp control */ - alc_write_coef_idx(codec, 0x6c, 0xfc06); + alc_process_coef_fw(codec, alc282_coefs); } static void alc282_init(struct hda_codec *codec) @@ -2922,72 +2924,45 @@ static void alc282_shutup(struct hda_codec *codec) alc_write_coef_idx(codec, 0x78, coef78); } +static struct coef_fw alc283_coefs[] = { + WRITE_COEF(0x03, 0x0002), /* Power Down Control */ + WRITE_COEF(0x05, 0x0700), /* FIFO and filter clock */ + WRITE_COEF(0x07, 0x0200), /* DMIC control */ + UPDATE_COEF(0x06, 0x00f0, 0), /* Analog clock */ + UPDATE_COEF(0x08, 0xfffc, 0x0c2c), /* JD */ + WRITE_COEF(0x0a, 0xcccc), /* JD offset1 */ + WRITE_COEF(0x0b, 0xcccc), /* JD offset2 */ + WRITE_COEF(0x0e, 0x6fc0), /* LDO1/2/3, DAC/ADC */ + UPDATE_COEF(0x0f, 0xf800, 0x1000), /* JD */ + UPDATE_COEF(0x10, 0xfc00, 0x0c00), /* Capless */ + WRITE_COEF(0x3a, 0x0), /* Class D test 4 */ + UPDATE_COEF(0x0c, 0xfe00, 0x0), /* IO power down directly */ + WRITE_COEF(0x22, 0xa0c0), /* ANC */ + UPDATE_COEFEX(0x53, 0x01, 0x000f, 0x0008), /* AGC MUX */ + UPDATE_COEF(0x1d, 0x00e0, 0), /* DAC simple content protection */ + UPDATE_COEF(0x1f, 0x00e0, 0), /* ADC simple content protection */ + WRITE_COEF(0x21, 0x8804), /* DAC ADC Zero Detection */ + WRITE_COEF(0x2e, 0x2902), /* PLL */ + WRITE_COEF(0x33, 0xa080), /* capless control 2 */ + WRITE_COEF(0x34, 0x3400), /* capless control 3 */ + WRITE_COEF(0x35, 0x2f3e), /* capless control 4 */ + WRITE_COEF(0x36, 0x0), /* capless control 5 */ + UPDATE_COEF(0x38, 0x0fff, 0x0900), /* class D test 2 */ + WRITE_COEF(0x39, 0x110a), /* class D test 3 */ + UPDATE_COEF(0x3b, 0x00f8, 0x00d8), /* class D test 5 */ + WRITE_COEF(0x3c, 0x0014), /* class D test 6 */ + WRITE_COEF(0x3d, 0xc2ba), /* classD OCP */ + UPDATE_COEF(0x42, 0x0f80, 0x0), /* classD pure DC test */ + WRITE_COEF(0x49, 0x0), /* test mode */ + UPDATE_COEF(0x40, 0xf800, 0x9800), /* Class D DC enable */ + UPDATE_COEF(0x42, 0xf000, 0x2000), /* DC offset */ + WRITE_COEF(0x37, 0xfc06), /* Class D amp control */ + {} +}; + static void alc283_restore_default_value(struct hda_codec *codec) { - /* Power Down Control */ - alc_write_coef_idx(codec, 0x03, 0x0002); - /* FIFO and filter clock */ - alc_write_coef_idx(codec, 0x05, 0x0700); - /* DMIC control */ - alc_write_coef_idx(codec, 0x07, 0x0200); - /* Analog clock */ - alc_update_coef_idx(codec, 0x06, 0x00f0, 0); - /* JD */ - alc_update_coef_idx(codec, 0x08, 0xfffc, 0x0c2c); - /* JD offset1 */ - alc_write_coef_idx(codec, 0x0a, 0xcccc); - /* JD offset2 */ - alc_write_coef_idx(codec, 0x0b, 0xcccc); - /* LDO1/2/3, DAC/ADC */ - alc_write_coef_idx(codec, 0x0e, 0x6fc0); - /* JD */ - alc_update_coef_idx(codec, 0x0f, 0xf800, 0x1000); - /* Capless */ - alc_update_coef_idx(codec, 0x10, 0xfc00, 0x0c00); - /* Class D test 4 */ - alc_write_coef_idx(codec, 0x3a, 0x0); - /* IO power down directly */ - alc_update_coef_idx(codec, 0x0c, 0xfe00, 0x0); - /* ANC */ - alc_write_coef_idx(codec, 0x22, 0xa0c0); - /* AGC MUX */ - alc_update_coefex_idx(codec, 0x53, 0x01, 0x000f, 0x0008); - /* DAC simple content protection */ - alc_update_coef_idx(codec, 0x1d, 0x00e0, 0x0); - /* ADC simple content protection */ - alc_update_coef_idx(codec, 0x1f, 0x00e0, 0x0); - /* DAC ADC Zero Detection */ - alc_write_coef_idx(codec, 0x21, 0x8804); - /* PLL */ - alc_write_coef_idx(codec, 0x2e, 0x2902); - /* capless control 2 */ - alc_write_coef_idx(codec, 0x33, 0xa080); - /* capless control 3 */ - alc_write_coef_idx(codec, 0x34, 0x3400); - /* capless control 4 */ - alc_write_coef_idx(codec, 0x35, 0x2f3e); - /* capless control 5 */ - alc_write_coef_idx(codec, 0x36, 0x0); - /* class D test 2 */ - alc_update_coef_idx(codec, 0x38, 0x0fff, 0x0900); - /* class D test 3 */ - alc_write_coef_idx(codec, 0x39, 0x110a); - /* class D test 5 */ - alc_update_coef_idx(codec, 0x3b, 0x00f8, 0x00d8); - /* class D test 6 */ - alc_write_coef_idx(codec, 0x3c, 0x0014); - /* classD OCP */ - alc_write_coef_idx(codec, 0x3d, 0xc2ba); - /* classD pure DC test */ - alc_update_coef_idx(codec, 0x42, 0x0f80, 0x0); - /* test mode */ - alc_write_coef_idx(codec, 0x49, 0x0); - /* Class D DC enable */ - alc_update_coef_idx(codec, 0x40, 0xf800, 0x9800); - /* DC offset */ - alc_update_coef_idx(codec, 0x42, 0xf000, 0x2000); - /* Class D amp control */ - alc_write_coef_idx(codec, 0x37, 0xfc06); + alc_process_coef_fw(codec, alc283_coefs); } static void alc283_init(struct hda_codec *codec) @@ -3530,52 +3505,62 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, static void alc_headset_mode_unplugged(struct hda_codec *codec) { + static struct coef_fw coef0255[] = { + WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */ + WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */ + UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/ + WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */ + WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */ + {} + }; + static struct coef_fw coef0233[] = { + WRITE_COEF(0x1b, 0x0c0b), + WRITE_COEF(0x45, 0xc429), + UPDATE_COEF(0x35, 0x4000, 0), + WRITE_COEF(0x06, 0x2104), + WRITE_COEF(0x1a, 0x0001), + WRITE_COEF(0x26, 0x0004), + WRITE_COEF(0x32, 0x42a3), + {} + }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x76, 0x000e), + WRITE_COEF(0x6c, 0x2400), + WRITE_COEF(0x18, 0x7308), + WRITE_COEF(0x6b, 0xc429), + {} + }; + static struct coef_fw coef0293[] = { + UPDATE_COEF(0x10, 7<<8, 6<<8), /* SET Line1 JD to 0 */ + UPDATE_COEFEX(0x57, 0x05, 1<<15|1<<13, 0x0), /* SET charge pump by verb */ + UPDATE_COEFEX(0x57, 0x03, 1<<10, 1<<10), /* SET EN_OSW to 1 */ + UPDATE_COEF(0x1a, 1<<3, 1<<3), /* Combo JD gating with LINE1-VREFO */ + WRITE_COEF(0x45, 0xc429), /* Set to TRS type */ + UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */ + {} + }; + static struct coef_fw coef0668[] = { + WRITE_COEF(0x15, 0x0d40), + WRITE_COEF(0xb7, 0x802b), + {} + }; + switch (codec->vendor_id) { case 0x10ec0255: - /* LDO and MISC control */ - alc_write_coef_idx(codec, 0x1b, 0x0c0b); - /* UAJ function set to menual mode */ - alc_write_coef_idx(codec, 0x45, 0xd089); - /* Direct Drive HP Amp control(Set to verb control)*/ - alc_update_coefex_idx(codec, 0x57, 0x05, 1<<14, 0); - /* Set MIC2 Vref gate with HP */ - alc_write_coef_idx(codec, 0x06, 0x6104); - /* Direct Drive HP Amp control */ - alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); + alc_process_coef_fw(codec, coef0255); break; case 0x10ec0233: case 0x10ec0283: - alc_write_coef_idx(codec, 0x1b, 0x0c0b); - alc_write_coef_idx(codec, 0x45, 0xc429); - alc_update_coef_idx(codec, 0x35, 0x4000, 0); - alc_write_coef_idx(codec, 0x06, 0x2104); - alc_write_coef_idx(codec, 0x1a, 0x0001); - alc_write_coef_idx(codec, 0x26, 0x0004); - alc_write_coef_idx(codec, 0x32, 0x42a3); + alc_process_coef_fw(codec, coef0233); break; case 0x10ec0292: - alc_write_coef_idx(codec, 0x76, 0x000e); - alc_write_coef_idx(codec, 0x6c, 0x2400); - alc_write_coef_idx(codec, 0x18, 0x7308); - alc_write_coef_idx(codec, 0x6b, 0xc429); + alc_process_coef_fw(codec, coef0292); break; case 0x10ec0293: - /* SET Line1 JD to 0 */ - alc_update_coef_idx(codec, 0x10, 7<<8, 6<<8); - /* SET charge pump by verb */ - alc_update_coefex_idx(codec, 0x57, 0x05, 1<<15|1<<13, 0x0); - /* SET EN_OSW to 1 */ - alc_update_coefex_idx(codec, 0x57, 0x03, 1<<10, 1<<10); - /* Combo JD gating with LINE1-VREFO */ - alc_update_coef_idx(codec, 0x1a, 1<<3, 1<<3); - /* Set to TRS type */ - alc_write_coef_idx(codec, 0x45, 0xc429); - /* Combo Jack auto detect */ - alc_update_coef_idx(codec, 0x4a, 0x000f, 0x000e); + alc_process_coef_fw(codec, coef0293); break; case 0x10ec0668: - alc_write_coef_idx(codec, 0x15, 0x0d40); - alc_write_coef_idx(codec, 0xb7, 0x802b); + alc_process_coef_fw(codec, coef0668); break; } codec_dbg(codec, "Headset jack set to unplugged mode.\n"); @@ -3585,48 +3570,65 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, hda_nid_t mic_pin) { + static struct coef_fw coef0255[] = { + WRITE_COEFEX(0x57, 0x03, 0x8aa6), + WRITE_COEF(0x06, 0x6100), /* Set MIC2 Vref gate to normal */ + {} + }; + static struct coef_fw coef0233[] = { + UPDATE_COEF(0x35, 0, 1<<14), + WRITE_COEF(0x06, 0x2100), + WRITE_COEF(0x1a, 0x0021), + WRITE_COEF(0x26, 0x008c), + {} + }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x19, 0xa208), + WRITE_COEF(0x2e, 0xacf0), + {} + }; + static struct coef_fw coef0293[] = { + UPDATE_COEFEX(0x57, 0x05, 0, 1<<15|1<<13), /* SET charge pump by verb */ + UPDATE_COEFEX(0x57, 0x03, 1<<10, 0), /* SET EN_OSW to 0 */ + UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */ + {} + }; + static struct coef_fw coef0688[] = { + WRITE_COEF(0xb7, 0x802b), + WRITE_COEF(0xb5, 0x1040), + UPDATE_COEF(0xc3, 0, 1<<12), + {} + }; + switch (codec->vendor_id) { case 0x10ec0255: alc_write_coef_idx(codec, 0x45, 0xc489); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); - alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); - /* Set MIC2 Vref gate to normal */ - alc_write_coef_idx(codec, 0x06, 0x6100); + alc_process_coef_fw(codec, coef0255); snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); break; case 0x10ec0233: case 0x10ec0283: alc_write_coef_idx(codec, 0x45, 0xc429); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); - alc_update_coef_idx(codec, 0x35, 0, 1<<14); - alc_write_coef_idx(codec, 0x06, 0x2100); - alc_write_coef_idx(codec, 0x1a, 0x0021); - alc_write_coef_idx(codec, 0x26, 0x008c); + alc_process_coef_fw(codec, coef0233); snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); break; case 0x10ec0292: snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); - alc_write_coef_idx(codec, 0x19, 0xa208); - alc_write_coef_idx(codec, 0x2e, 0xacf0); + alc_process_coef_fw(codec, coef0292); break; case 0x10ec0293: /* Set to TRS mode */ alc_write_coef_idx(codec, 0x45, 0xc429); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); - /* SET charge pump by verb */ - alc_update_coefex_idx(codec, 0x57, 0x05, 0, 1<<15|1<<13); - /* SET EN_OSW to 0 */ - alc_update_coefex_idx(codec, 0x57, 0x03, 1<<10, 0); - /* Combo JD gating without LINE1-VREFO */ - alc_update_coef_idx(codec, 0x1a, 1<<3, 0); + alc_process_coef_fw(codec, coef0293); snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); break; case 0x10ec0668: alc_write_coef_idx(codec, 0x11, 0x0001); snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); - alc_write_coef_idx(codec, 0xb7, 0x802b); - alc_write_coef_idx(codec, 0xb5, 0x1040); - alc_update_coef_idx(codec, 0xc3, 0, 1<<12); + alc_process_coef_fw(codec, coef0688); snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); break; } @@ -3635,36 +3637,54 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, static void alc_headset_mode_default(struct hda_codec *codec) { + static struct coef_fw coef0255[] = { + WRITE_COEF(0x45, 0xc089), + WRITE_COEF(0x45, 0xc489), + WRITE_COEFEX(0x57, 0x03, 0x8ea6), + WRITE_COEF(0x49, 0x0049), + {} + }; + static struct coef_fw coef0233[] = { + WRITE_COEF(0x06, 0x2100), + WRITE_COEF(0x32, 0x4ea3), + {} + }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x76, 0x000e), + WRITE_COEF(0x6c, 0x2400), + WRITE_COEF(0x6b, 0xc429), + WRITE_COEF(0x18, 0x7308), + {} + }; + static struct coef_fw coef0293[] = { + UPDATE_COEF(0x4a, 0x000f, 0x000e), /* Combo Jack auto detect */ + WRITE_COEF(0x45, 0xC429), /* Set to TRS type */ + UPDATE_COEF(0x1a, 1<<3, 0), /* Combo JD gating without LINE1-VREFO */ + {} + }; + static struct coef_fw coef0688[] = { + WRITE_COEF(0x11, 0x0041), + WRITE_COEF(0x15, 0x0d40), + WRITE_COEF(0xb7, 0x802b), + {} + }; + switch (codec->vendor_id) { case 0x10ec0255: - alc_write_coef_idx(codec, 0x45, 0xc089); - alc_write_coef_idx(codec, 0x45, 0xc489); - alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); - alc_write_coef_idx(codec, 0x49, 0x0049); + alc_process_coef_fw(codec, coef0255); break; case 0x10ec0233: case 0x10ec0283: - alc_write_coef_idx(codec, 0x06, 0x2100); - alc_write_coef_idx(codec, 0x32, 0x4ea3); + alc_process_coef_fw(codec, coef0233); break; case 0x10ec0292: - alc_write_coef_idx(codec, 0x76, 0x000e); - alc_write_coef_idx(codec, 0x6c, 0x2400); - alc_write_coef_idx(codec, 0x6b, 0xc429); - alc_write_coef_idx(codec, 0x18, 0x7308); + alc_process_coef_fw(codec, coef0292); break; case 0x10ec0293: - /* Combo Jack auto detect */ - alc_update_coef_idx(codec, 0x4a, 0x000f, 0x000e); - /* Set to TRS type */ - alc_write_coef_idx(codec, 0x45, 0xC429); - /* Combo JD gating without LINE1-VREFO */ - alc_update_coef_idx(codec, 0x1a, 1<<3, 0); + alc_process_coef_fw(codec, coef0293); break; case 0x10ec0668: - alc_write_coef_idx(codec, 0x11, 0x0041); - alc_write_coef_idx(codec, 0x15, 0x0d40); - alc_write_coef_idx(codec, 0xb7, 0x802b); + alc_process_coef_fw(codec, coef0688); break; } codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); @@ -3673,34 +3693,52 @@ static void alc_headset_mode_default(struct hda_codec *codec) /* Iphone type */ static void alc_headset_mode_ctia(struct hda_codec *codec) { + static struct coef_fw coef0255[] = { + WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */ + WRITE_COEF(0x1b, 0x0c2b), + WRITE_COEFEX(0x57, 0x03, 0x8ea6), + {} + }; + static struct coef_fw coef0233[] = { + WRITE_COEF(0x45, 0xd429), + WRITE_COEF(0x1b, 0x0c2b), + WRITE_COEF(0x32, 0x4ea3), + {} + }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x6b, 0xd429), + WRITE_COEF(0x76, 0x0008), + WRITE_COEF(0x18, 0x7388), + {} + }; + static struct coef_fw coef0293[] = { + WRITE_COEF(0x45, 0xd429), /* Set to ctia type */ + UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */ + {} + }; + static struct coef_fw coef0688[] = { + WRITE_COEF(0x11, 0x0001), + WRITE_COEF(0x15, 0x0d60), + WRITE_COEF(0xc3, 0x0000), + {} + }; + switch (codec->vendor_id) { case 0x10ec0255: - /* Set to CTIA type */ - alc_write_coef_idx(codec, 0x45, 0xd489); - alc_write_coef_idx(codec, 0x1b, 0x0c2b); - alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); + alc_process_coef_fw(codec, coef0255); break; case 0x10ec0233: case 0x10ec0283: - alc_write_coef_idx(codec, 0x45, 0xd429); - alc_write_coef_idx(codec, 0x1b, 0x0c2b); - alc_write_coef_idx(codec, 0x32, 0x4ea3); + alc_process_coef_fw(codec, coef0233); break; case 0x10ec0292: - alc_write_coef_idx(codec, 0x6b, 0xd429); - alc_write_coef_idx(codec, 0x76, 0x0008); - alc_write_coef_idx(codec, 0x18, 0x7388); + alc_process_coef_fw(codec, coef0292); break; case 0x10ec0293: - /* Set to ctia type */ - alc_write_coef_idx(codec, 0x45, 0xd429); - /* SET Line1 JD to 1 */ - alc_update_coef_idx(codec, 0x10, 7<<8, 7<<8); + alc_process_coef_fw(codec, coef0293); break; case 0x10ec0668: - alc_write_coef_idx(codec, 0x11, 0x0001); - alc_write_coef_idx(codec, 0x15, 0x0d60); - alc_write_coef_idx(codec, 0xc3, 0x0000); + alc_process_coef_fw(codec, coef0688); break; } codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); @@ -3709,34 +3747,52 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) /* Nokia type */ static void alc_headset_mode_omtp(struct hda_codec *codec) { + static struct coef_fw coef0255[] = { + WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */ + WRITE_COEF(0x1b, 0x0c2b), + WRITE_COEFEX(0x57, 0x03, 0x8ea6), + {} + }; + static struct coef_fw coef0233[] = { + WRITE_COEF(0x45, 0xe429), + WRITE_COEF(0x1b, 0x0c2b), + WRITE_COEF(0x32, 0x4ea3), + {} + }; + static struct coef_fw coef0292[] = { + WRITE_COEF(0x6b, 0xe429), + WRITE_COEF(0x76, 0x0008), + WRITE_COEF(0x18, 0x7388), + {} + }; + static struct coef_fw coef0293[] = { + WRITE_COEF(0x45, 0xe429), /* Set to omtp type */ + UPDATE_COEF(0x10, 7<<8, 7<<8), /* SET Line1 JD to 1 */ + {} + }; + static struct coef_fw coef0688[] = { + WRITE_COEF(0x11, 0x0001), + WRITE_COEF(0x15, 0x0d50), + WRITE_COEF(0xc3, 0x0000), + {} + }; + switch (codec->vendor_id) { case 0x10ec0255: - /* Set to OMTP Type */ - alc_write_coef_idx(codec, 0x45, 0xe489); - alc_write_coef_idx(codec, 0x1b, 0x0c2b); - alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); + alc_process_coef_fw(codec, coef0255); break; case 0x10ec0233: case 0x10ec0283: - alc_write_coef_idx(codec, 0x45, 0xe429); - alc_write_coef_idx(codec, 0x1b, 0x0c2b); - alc_write_coef_idx(codec, 0x32, 0x4ea3); + alc_process_coef_fw(codec, coef0233); break; case 0x10ec0292: - alc_write_coef_idx(codec, 0x6b, 0xe429); - alc_write_coef_idx(codec, 0x76, 0x0008); - alc_write_coef_idx(codec, 0x18, 0x7388); + alc_process_coef_fw(codec, coef0292); break; case 0x10ec0293: - /* Set to omtp type */ - alc_write_coef_idx(codec, 0x45, 0xe429); - /* SET Line1 JD to 1 */ - alc_update_coef_idx(codec, 0x10, 7<<8, 7<<8); + alc_process_coef_fw(codec, coef0293); break; case 0x10ec0668: - alc_write_coef_idx(codec, 0x11, 0x0001); - alc_write_coef_idx(codec, 0x15, 0x0d50); - alc_write_coef_idx(codec, 0xc3, 0x0000); + alc_process_coef_fw(codec, coef0688); break; } codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); @@ -3747,13 +3803,28 @@ static void alc_determine_headset_type(struct hda_codec *codec) int val; bool is_ctia = false; struct alc_spec *spec = codec->spec; + static struct coef_fw coef0255[] = { + WRITE_COEF(0x45, 0xd089), /* combo jack auto switch control(Check type)*/ + WRITE_COEF(0x49, 0x0149), /* combo jack auto switch control(Vref + conteol) */ + {} + }; + static struct coef_fw coef0293[] = { + UPDATE_COEF(0x4a, 0x000f, 0x0008), /* Combo Jack auto detect */ + WRITE_COEF(0x45, 0xD429), /* Set to ctia type */ + {} + }; + static struct coef_fw coef0688[] = { + WRITE_COEF(0x11, 0x0001), + WRITE_COEF(0xb7, 0x802b), + WRITE_COEF(0x15, 0x0d60), + WRITE_COEF(0xc3, 0x0c00), + {} + }; switch (codec->vendor_id) { case 0x10ec0255: - /* combo jack auto switch control(Check type)*/ - alc_write_coef_idx(codec, 0x45, 0xd089); - /* combo jack auto switch control(Vref conteol) */ - alc_write_coef_idx(codec, 0x49, 0x0149); + alc_process_coef_fw(codec, coef0255); msleep(300); val = alc_read_coef_idx(codec, 0x46); is_ctia = (val & 0x0070) == 0x0070; @@ -3772,19 +3843,13 @@ static void alc_determine_headset_type(struct hda_codec *codec) is_ctia = (val & 0x001c) == 0x001c; break; case 0x10ec0293: - /* Combo Jack auto detect */ - alc_update_coef_idx(codec, 0x4a, 0x000f, 0x0008); - /* Set to ctia type */ - alc_write_coef_idx(codec, 0x45, 0xD429); + alc_process_coef_fw(codec, coef0293); msleep(300); val = alc_read_coef_idx(codec, 0x46); is_ctia = (val & 0x0070) == 0x0070; break; case 0x10ec0668: - alc_write_coef_idx(codec, 0x11, 0x0001); - alc_write_coef_idx(codec, 0xb7, 0x802b); - alc_write_coef_idx(codec, 0x15, 0x0d60); - alc_write_coef_idx(codec, 0xc3, 0x0c00); + alc_process_coef_fw(codec, coef0688); msleep(300); val = alc_read_coef_idx(codec, 0xbe); is_ctia = (val & 0x1c02) == 0x1c02; @@ -3920,11 +3985,15 @@ static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, static void alc255_set_default_jack_type(struct hda_codec *codec) { /* Set to iphone type */ - alc_write_coef_idx(codec, 0x1b, 0x880b); - alc_write_coef_idx(codec, 0x45, 0xd089); - alc_write_coef_idx(codec, 0x1b, 0x080b); - alc_write_coef_idx(codec, 0x46, 0x0004); - alc_write_coef_idx(codec, 0x1b, 0x0c0b); + static struct coef_fw fw[] = { + WRITE_COEF(0x1b, 0x880b), + WRITE_COEF(0x45, 0xd089), + WRITE_COEF(0x1b, 0x080b), + WRITE_COEF(0x46, 0x0004), + WRITE_COEF(0x1b, 0x0c0b), + {} + }; + alc_process_coef_fw(codec, fw); msleep(30); } -- GitLab From b22ae40ef2e7847ddbd802d1a887188e113675f3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 8 Aug 2014 17:23:07 +0200 Subject: [PATCH 0883/9167] Documentation: kbuild: Remove obsolete include/asm symlink step As of commit f7f16b7799ed68654850ab340ef812895aebcf4c ("kbuild: drop include/asm"), the include/asm symlink is no longer created. Signed-off-by: Geert Uytterhoeven Signed-off-by: Michal Marek --- Documentation/kbuild/makefiles.txt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index 764f5991a3fc..a445e1c8828e 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -818,17 +818,16 @@ a few targets. When kbuild executes, the following steps are followed (roughly): 1) Configuration of the kernel => produce .config 2) Store kernel version in include/linux/version.h -3) Symlink include/asm to include/asm-$(ARCH) -4) Updating all other prerequisites to the target prepare: +3) Updating all other prerequisites to the target prepare: - Additional prerequisites are specified in arch/$(ARCH)/Makefile -5) Recursively descend down in all directories listed in +4) Recursively descend down in all directories listed in init-* core* drivers-* net-* libs-* and build all targets. - The values of the above variables are expanded in arch/$(ARCH)/Makefile. -6) All object files are then linked and the resulting file vmlinux is +5) All object files are then linked and the resulting file vmlinux is located at the root of the obj tree. The very first objects linked are listed in head-y, assigned by arch/$(ARCH)/Makefile. -7) Finally, the architecture-specific part does any required post processing +6) Finally, the architecture-specific part does any required post processing and builds the final bootimage. - This includes building boot records - Preparing initrd images and the like -- GitLab From ef80f0a1e033bcab17257e2155a3c9263a0919c1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 8 Aug 2014 17:23:08 +0200 Subject: [PATCH 0884/9167] Documentation: kbuild: Improve if_changed documentation - These days if_changed is used with many more commands than ld, objcopy, and gzip, hence add an ellipsis, - Any target that utilises if_changed must be listed in $(targets), so it needs an assignment to "targets", not "target". Signed-off-by: Geert Uytterhoeven Signed-off-by: Michal Marek --- Documentation/kbuild/makefiles.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index a445e1c8828e..520b2c75bc56 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -1092,7 +1092,7 @@ When kbuild executes, the following steps are followed (roughly): Usage: target: source(s) FORCE - $(call if_changed,ld/objcopy/gzip) + $(call if_changed,ld/objcopy/gzip/...) When the rule is evaluated, it is checked to see if any files need an update, or the command line has changed since the last @@ -1110,7 +1110,7 @@ When kbuild executes, the following steps are followed (roughly): significant; for instance, the below will fail (note the extra space after the comma): target: source(s) FORCE - #WRONG!# $(call if_changed, ld/objcopy/gzip) + #WRONG!# $(call if_changed, ld/objcopy/gzip/...) ld Link target. Often, LDFLAGS_$@ is used to set specific options to ld. @@ -1142,7 +1142,7 @@ When kbuild executes, the following steps are followed (roughly): The ": %: %.o" part of the prerequisite is a shorthand that free us from listing the setup.o and bootsect.o files. - Note: It is a common mistake to forget the "target :=" assignment, + Note: It is a common mistake to forget the "targets :=" assignment, resulting in the target file being recompiled for no obvious reason. -- GitLab From cf6c53db9525a7f6c5052ccd84a0638128f14632 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 8 Aug 2014 17:23:09 +0200 Subject: [PATCH 0885/9167] Documentation: kbuild: Remove obsolete dtc_cpp section Commit b40b25fff8205dd18124d8fc87b2c9c57f269b5f ("kbuild: always run gcc -E on *.dts, remove cmd_dtc_cpp") improved the functionality of cmd_dtc_cpp and merged it back into cmd_dtc. Signed-off-by: Geert Uytterhoeven Signed-off-by: Michal Marek --- Documentation/kbuild/makefiles.txt | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index 520b2c75bc56..eda00a1073a7 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -1163,29 +1163,6 @@ When kbuild executes, the following steps are followed (roughly): clean-files += *.dtb DTC_FLAGS ?= -p 1024 - dtc_cpp - This is just like dtc as describe above, except that the C pre- - processor is invoked upon the .dtsp file before compiling the result - with dtc. - - In order for build dependencies to work, all files compiled using - dtc_cpp must use the C pre-processor's #include functionality and not - dtc's /include/ functionality. - - Using the C pre-processor allows use of #define to create named - constants. In turn, the #defines will typically appear in a header - file, which may be shared with regular C code. Since the dtc language - represents a data structure rather than code in C syntax, similar - restrictions are placed on a header file included by a device tree - file as for a header file included by an assembly language file. - In particular, the C pre-processor is passed -x assembler-with-cpp, - which sets macro __ASSEMBLY__. __DTS__ is also set. These allow header - files to restrict their content to that compatible with device tree - source. - - A central rule exists to create $(obj)/%.dtb from $(src)/%.dtsp; - architecture Makefiles do no need to explicitly write out that rule. - --- 6.8 Custom kbuild commands When kbuild is executing with KBUILD_VERBOSE=0, then only a shorthand -- GitLab From 39fed7015cd9124b5893fce18d33f49db1c48bea Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 8 Aug 2014 17:23:10 +0200 Subject: [PATCH 0886/9167] Documentation: kbuild: Improve grammar - singular versus plural, - "by" versus "of", - missing "if", "it", "the", - consistent use of "xxx-specific" versus "xxx specific". Signed-off-by: Geert Uytterhoeven Acked-by: Randy Dunlap Signed-off-by: Michal Marek --- Documentation/kbuild/makefiles.txt | 56 +++++++++++++++--------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index eda00a1073a7..a311db829e9b 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -174,7 +174,7 @@ more details, with real examples. --- 3.3 Loadable module goals - obj-m - $(obj-m) specify object files which are built as loadable + $(obj-m) specifies object files which are built as loadable kernel modules. A module may be built from one source file or several source @@ -277,7 +277,7 @@ more details, with real examples. down in the ext2 directory. Kbuild only uses this information to decide that it needs to visit the directory, it is the Makefile in the subdirectory that - specifies what is modules and what is built-in. + specifies what is modular and what is built-in. It is good practice to use a CONFIG_ variable when assigning directory names. This allows kbuild to totally skip the directory if the @@ -403,7 +403,7 @@ more details, with real examples. echoing information to user in a rule is often a good practice but when execution "make -s" one does not expect to see any output except for warnings/errors. - To support this kbuild define $(kecho) which will echo out the + To support this kbuild defines $(kecho) which will echo out the text following $(kecho) to stdout except if "make -s" is used. Example: @@ -417,7 +417,7 @@ more details, with real examples. The kernel may be built with several different versions of $(CC), each supporting a unique set of features and options. - kbuild provide basic support to check for valid options for $(CC). + kbuild provides basic support to check for valid options for $(CC). $(CC) is usually the gcc compiler, but other alternatives are available. @@ -456,8 +456,8 @@ more details, with real examples. Note: as-instr-option uses KBUILD_AFLAGS for $(AS) options cc-option - cc-option is used to check if $(CC) supports a given option, and not - supported to use an optional second option. + cc-option is used to check if $(CC) supports a given option, and if + not supported to use an optional second option. Example: #arch/x86/Makefile @@ -557,8 +557,8 @@ more details, with real examples. false ; \ fi - In this example for a specific GCC version the build will error out explaining - to the user why it stops. + In this example for a specific GCC version the build will error out + explaining to the user why it stops. cc-cross-prefix cc-cross-prefix is used to check if there exists a $(CC) in path with @@ -656,7 +656,7 @@ Both possibilities are described in the following. In the example above the executable is composed of the C++ file qconf.cc - identified by $(qconf-cxxobjs). - If qconf is composed by a mixture of .c and .cc files, then an + If qconf is composed of a mixture of .c and .cc files, then an additional line can be used to identify this. Example: @@ -733,7 +733,7 @@ Both possibilities are described in the following. hostprogs-$(CONFIG_KALLSYMS) += kallsyms Kbuild knows about both 'y' for built-in and 'm' for module. - So if a config symbol evaluate to 'm', kbuild will still build + So if a config symbol evaluates to 'm', kbuild will still build the binary. In other words, Kbuild handles hostprogs-m exactly like hostprogs-y. But only hostprogs-y is recommended to be used when no CONFIG symbols are involved. @@ -754,8 +754,8 @@ Additional files can be specified in kbuild makefiles by use of $(clean-files). #drivers/pci/Makefile clean-files := devlist.h classlist.h -When executing "make clean", the two files "devlist.h classlist.h" will -be deleted. Kbuild will assume files to be in same relative directory as the +When executing "make clean", the two files "devlist.h classlist.h" will be +deleted. Kbuild will assume files to be in the same relative directory as the Makefile except if an absolute path is specified (path starting with '/'). To delete a directory hierarchy use: @@ -786,7 +786,7 @@ is not sufficient this sometimes needs to be explicit. The above assignment instructs kbuild to descend down in the directory compressed/ when "make clean" is executed. -To support the clean infrastructure in the Makefiles that builds the +To support the clean infrastructure in the Makefiles that build the final bootimage there is an optional target named archclean: Example: @@ -926,7 +926,7 @@ When kbuild executes, the following steps are followed (roughly): KBUILD_AFLAGS_MODULE Options for $(AS) when building modules - $(KBUILD_AFLAGS_MODULE) is used to add arch specific options that + $(KBUILD_AFLAGS_MODULE) is used to add arch-specific options that are used for $(AS). From commandline AFLAGS_MODULE shall be used (see kbuild.txt). @@ -937,13 +937,13 @@ When kbuild executes, the following steps are followed (roughly): KBUILD_CFLAGS_MODULE Options for $(CC) when building modules - $(KBUILD_CFLAGS_MODULE) is used to add arch specific options that + $(KBUILD_CFLAGS_MODULE) is used to add arch-specific options that are used for $(CC). From commandline CFLAGS_MODULE shall be used (see kbuild.txt). KBUILD_LDFLAGS_MODULE Options for $(LD) when linking modules - $(KBUILD_LDFLAGS_MODULE) is used to add arch specific options + $(KBUILD_LDFLAGS_MODULE) is used to add arch-specific options used when linking modules. This is often a linker script. From commandline LDFLAGS_MODULE shall be used (see kbuild.txt). @@ -1065,7 +1065,7 @@ When kbuild executes, the following steps are followed (roughly): extra-y - extra-y specify additional targets created in the current + extra-y specifies additional targets created in the current directory, in addition to any targets specified by obj-*. Listing all targets in extra-y is required for two purposes: @@ -1141,7 +1141,7 @@ When kbuild executes, the following steps are followed (roughly): 2) delete target during make clean The ": %: %.o" part of the prerequisite is a shorthand that - free us from listing the setup.o and bootsect.o files. + frees us from listing the setup.o and bootsect.o files. Note: It is a common mistake to forget the "targets :=" assignment, resulting in the target file being recompiled for no obvious reason. @@ -1213,11 +1213,11 @@ When kbuild executes, the following steps are followed (roughly): When building the *.lds target, kbuild uses the variables: KBUILD_CPPFLAGS : Set in top-level Makefile cppflags-y : May be set in the kbuild makefile - CPPFLAGS_$(@F) : Target specific flags. + CPPFLAGS_$(@F) : Target-specific flags. Note that the full filename is used in this assignment. - The kbuild infrastructure for *lds file are used in several + The kbuild infrastructure for *lds files is used in several architecture-specific files. --- 6.10 Generic header files @@ -1230,11 +1230,11 @@ When kbuild executes, the following steps are followed (roughly): === 7 Kbuild syntax for exported headers -The kernel include a set of headers that is exported to userspace. +The kernel includes a set of headers that is exported to userspace. Many headers can be exported as-is but other headers require a minimal pre-processing before they are ready for user-space. The pre-processing does: -- drop kernel specific annotations +- drop kernel-specific annotations - drop include of compiler.h - drop all sections that are kernel internal (guarded by ifdef __KERNEL__) @@ -1244,7 +1244,7 @@ See subsequent chapter for the syntax of the Kbuild file. --- 7.1 header-y - header-y specify header files to be exported. + header-y specifies header files to be exported. Example: #include/linux/Kbuild @@ -1254,7 +1254,7 @@ See subsequent chapter for the syntax of the Kbuild file. The convention is to list one file per line and preferably in alphabetic order. - header-y also specify which subdirectories to visit. + header-y also specifies which subdirectories to visit. A subdirectory is identified by a trailing '/' which can be seen in the example above for the usb subdirectory. @@ -1272,9 +1272,9 @@ See subsequent chapter for the syntax of the Kbuild file. --- 7.3 destination-y - When an architecture have a set of exported headers that needs to be + When an architecture has a set of exported headers that needs to be exported to a different directory destination-y is used. - destination-y specify the destination directory for all exported + destination-y specifies the destination directory for all exported headers in the file where it is present. Example: @@ -1367,9 +1367,9 @@ The top Makefile exports the following variables: INSTALL_MOD_STRIP - If this variable is specified, will cause modules to be stripped + If this variable is specified, it will cause modules to be stripped after they are installed. If INSTALL_MOD_STRIP is '1', then the - default option --strip-debug will be used. Otherwise, + default option --strip-debug will be used. Otherwise, the INSTALL_MOD_STRIP value will be used as the option(s) to the strip command. -- GitLab From c8589d1e9e01debdb4f574afe7c585714353ad79 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 19 Aug 2014 16:34:20 +0900 Subject: [PATCH 0887/9167] kbuild: handle multi-objs dependency appropriately The comment in scripts/Makefile.build says as follows: We would rather have a list of rules like foo.o: $(foo-objs) but that's not so easy, so we rather make all composite objects depend on the set of all their parts This commit makes it possible! For example, assume a Makefile like this obj-m = foo.o bar.o foo-objs := foo1.o foo2.o bar-objs := bar1.o bar2.o Without this patch, foo.o depends on all of foo1.o foo2.o bar1.o bar2.o. It looks funny that foo.o is regenerated when bar1.c is updated. Now we can handle the dependency of foo.o and bar.o separately. Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- scripts/Makefile.build | 10 ++++------ scripts/Makefile.lib | 9 +++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index bf3e6778cd71..5b09d3637855 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -382,16 +382,14 @@ cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalys quiet_cmd_link_multi-m = LD [M] $@ cmd_link_multi-m = $(cmd_link_multi-y) -# We would rather have a list of rules like -# foo.o: $(foo-objs) -# but that's not so easy, so we rather make all composite objects depend -# on the set of all their parts -$(multi-used-y) : %.o: $(multi-objs-y) FORCE +$(multi-used-y): FORCE $(call if_changed,link_multi-y) +$(call multi_depend, $(multi-used-y), .o, -objs -y) -$(multi-used-m) : %.o: $(multi-objs-m) FORCE +$(multi-used-m): FORCE $(call if_changed,link_multi-m) @{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod) +$(call multi_depend, $(multi-used-m), .o, -objs -y) targets += $(multi-used-y) $(multi-used-m) diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 260bf8acfce9..54be19a0fa51 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -159,6 +159,15 @@ dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \ modname-multi = $(sort $(foreach m,$(multi-used),\ $(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=)))) +# Useful for describing the dependency of composite objects +# Usage: +# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add) +define multi_depend +$(foreach m, $(notdir $1), \ + $(eval $(obj)/$m: \ + $(addprefix $(obj)/, $(foreach s, $3, $($(m:%$(strip $2)=%$(s))))))) +endef + ifdef REGENERATE_PARSERS # GPERF -- GitLab From 97e3226e6e984c8cd9bed47010f30827a3ce816a Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 19 Aug 2014 16:34:21 +0900 Subject: [PATCH 0888/9167] kbuild: handle the dependency of multi-objs hostprogs appropriately Assume we have a Makefile like: hostprogs-y := foo bar foo-objs := foo1.o foo2.o bar-objs := bar1.o bar2.o Without this commit, the host program foo depends on all of foo1.o foo2.o bar1.o bar2.o. This commit allows to handle the dependency of each host program separately. Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- scripts/Makefile.host | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.host b/scripts/Makefile.host index ab5980f91714..133edfae5b8a 100644 --- a/scripts/Makefile.host +++ b/scripts/Makefile.host @@ -96,8 +96,9 @@ quiet_cmd_host-cmulti = HOSTLD $@ cmd_host-cmulti = $(HOSTCC) $(HOSTLDFLAGS) -o $@ \ $(addprefix $(obj)/,$($(@F)-objs)) \ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) -$(host-cmulti): $(obj)/%: $(host-cobjs) FORCE +$(host-cmulti): FORCE $(call if_changed,host-cmulti) +$(call multi_depend, $(host-cmulti), , -objs) # Create .o file from a single .c file # host-cobjs -> .o @@ -113,8 +114,9 @@ quiet_cmd_host-cxxmulti = HOSTLD $@ $(foreach o,objs cxxobjs,\ $(addprefix $(obj)/,$($(@F)-$(o)))) \ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F)) -$(host-cxxmulti): $(obj)/%: $(host-cobjs) $(host-cxxobjs) FORCE +$(host-cxxmulti): FORCE $(call if_changed,host-cxxmulti) +$(call multi_depend, $(host-cxxmulti), , -objs -cxxobjs) # Create .o file from a single .cc (C++) file quiet_cmd_host-cxxobjs = HOSTCXX $@ -- GitLab From 022af62d0190e1e3db63c19aeb5f51ae0612cd71 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 19 Aug 2014 16:34:22 +0900 Subject: [PATCH 0889/9167] kbuild: refactor script/kconfig/Makefile Now it is harmless to add all host programs to hostprogs-y. Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 9c4d2412fb72..76f6171768e4 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -157,35 +157,7 @@ qconf-cxxobjs := qconf.o qconf-objs := zconf.tab.o gconf-objs := gconf.o zconf.tab.o -hostprogs-y := conf - -ifeq ($(MAKECMDGOALS),nconfig) - hostprogs-y += nconf -endif - -ifeq ($(MAKECMDGOALS),menuconfig) - hostprogs-y += mconf -endif - -ifeq ($(MAKECMDGOALS),update-po-config) - hostprogs-y += kxgettext -endif - -ifeq ($(MAKECMDGOALS),xconfig) - qconf-target := 1 -endif -ifeq ($(MAKECMDGOALS),gconfig) - gconf-target := 1 -endif - - -ifeq ($(qconf-target),1) - hostprogs-y += qconf -endif - -ifeq ($(gconf-target),1) - hostprogs-y += gconf -endif +hostprogs-y := conf nconf mconf kxgettext qconf gconf clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck clean-files += zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h @@ -224,7 +196,7 @@ HOSTLOADLIBES_nconf = $(shell \ || echo "-lmenu -lpanel -lncurses" ) $(obj)/qconf.o: $(obj)/.tmp_qtcheck -ifeq ($(qconf-target),1) +ifeq ($(MAKECMDGOALS),xconfig) $(obj)/.tmp_qtcheck: $(src)/Makefile -include $(obj)/.tmp_qtcheck @@ -281,7 +253,7 @@ endif $(obj)/gconf.o: $(obj)/.tmp_gtkcheck -ifeq ($(gconf-target),1) +ifeq ($(MAKECMDGOALS),gconfig) -include $(obj)/.tmp_gtkcheck # GTK needs some extra effort, too... -- GitLab From 221ecca6cafefbb5106cfc8bf9f1105233a33745 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 19 Aug 2014 16:34:23 +0900 Subject: [PATCH 0890/9167] kbuild: remove redundant clean-files from scripts/kconfig/Makefile Now mconf, qconf, gconf, nconf are always added to hostprogs-y. Files added to hostprogs-y are removed by "make clean". Signed-off-by: Masahiro Yamada Signed-off-by: Michal Marek --- scripts/kconfig/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 76f6171768e4..e7bf38e92007 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -161,7 +161,6 @@ hostprogs-y := conf nconf mconf kxgettext qconf gconf clean-files := qconf.moc .tmp_qtcheck .tmp_gtkcheck clean-files += zconf.tab.c zconf.lex.c zconf.hash.c gconf.glade.h -clean-files += mconf qconf gconf nconf clean-files += config.pot linux.pot # Check that we have the required ncurses stuff installed for lxdialog (menuconfig) -- GitLab From 8bf4abaddd01aa6c9d13804fa05084cb28135a47 Mon Sep 17 00:00:00 2001 From: Dirk Gouders Date: Sat, 16 Aug 2014 07:56:56 +0200 Subject: [PATCH 0891/9167] scripts/tags.sh: Don't specify kind-spec for emacs' ctags/etags Emacs' ctags/etags don't know about kind-spec in --regex and produce warnings: etags: invalid regexp modifier `v', ignoring etags: invalid regexp modifier `/', ignoring Fix it by removing kind-spec for the emacs case. Signed-off-by: Dirk Gouders Inspired-by: Masatake YAMATO Tested-by: Masatake YAMATO Signed-off-by: Michal Marek --- scripts/tags.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index cbfd269a6011..727989757d59 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -263,7 +263,7 @@ emacs() --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' \ --regex='/PCI_OP_READ(\([a-z]*[a-z]\).*[1-4])/pci_bus_read_config_\1/' \ --regex='/PCI_OP_WRITE(\([a-z]*[a-z]\).*[1-4])/pci_bus_write_config_\1/'\ - --regex='/DEFINE_HASHTABLE\((\w*)/\1/v/' + --regex='/DEFINE_HASHTABLE\((\w*)/\1/' all_kconfigs | xargs $1 -a \ --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' -- GitLab From a60113d6a7fca3320e84d25db84c3c1a5a02b505 Mon Sep 17 00:00:00 2001 From: Dirk Gouders Date: Sat, 16 Aug 2014 07:56:57 +0200 Subject: [PATCH 0892/9167] scripts/tags.sh: remove *PCGFLAGS regular expressions Commit 0a31bc97c80c3fa8 (mm: memcontrol: rewrite uncharge API) removed the macros {TEST,SET,CLEAR,TESTCLEAR}PCFLAG. Remove corresponding entries from tags.sh -- in the emacs case they also produced warnigs because of unmatched '\('. Signed-off-by: Dirk Gouders Inspired-by: Masatake YAMATO Signed-off-by: Michal Marek --- scripts/tags.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index 727989757d59..0f61bd7ee958 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -193,10 +193,6 @@ exuberant() --regex-c++='/TESTCLEARFLAG_FALSE\(([^,)]*).*/TestClearPage\1/' \ --regex-c++='/__TESTCLEARFLAG_FALSE\(([^,)]*).*/__TestClearPage\1/' \ --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/' \ - --regex-c++='/TESTPCGFLAG\(([^,)]*).*/PageCgroup\1/' \ - --regex-c++='/SETPCGFLAG\(([^,)]*).*/SetPageCgroup\1/' \ - --regex-c++='/CLEARPCGFLAG\(([^,)]*).*/ClearPageCgroup\1/' \ - --regex-c++='/TESTCLEARPCGFLAG\(([^,)]*).*/TestClearPageCgroup\1/' \ --regex-c='/PCI_OP_READ\((\w*).*[1-4]\)/pci_bus_read_config_\1/' \ --regex-c='/PCI_OP_WRITE\((\w*).*[1-4]\)/pci_bus_write_config_\1/' \ --regex-c='/DEFINE_(MUTEX|SEMAPHORE|SPINLOCK)\((\w*)/\2/v/' \ @@ -256,10 +252,6 @@ emacs() --regex='/__CLEARPAGEFLAG_NOOP(\([^,)]*\).*/__ClearPage\1/' \ --regex='/TESTCLEARFLAG_FALSE(\([^,)]*\).*/TestClearPage\1/' \ --regex='/__TESTCLEARFLAG_FALSE(\([^,)]*\).*/__TestClearPage\1/' \ - --regex='/TESTPCGFLAG\(([^,)]*).*/PageCgroup\1/' \ - --regex='/SETPCGFLAG\(([^,)]*).*/SetPageCgroup\1/' \ - --regex='/CLEARPCGFLAG\(([^,)]*).*/ClearPageCgroup\1/' \ - --regex='/TESTCLEARPCGFLAG\(([^,)]*).*/TestClearPageCgroup\1/' \ --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' \ --regex='/PCI_OP_READ(\([a-z]*[a-z]\).*[1-4])/pci_bus_read_config_\1/' \ --regex='/PCI_OP_WRITE(\([a-z]*[a-z]\).*[1-4])/pci_bus_write_config_\1/'\ -- GitLab From 8e170655b517ba49bf4d015008474bcc2f425b20 Mon Sep 17 00:00:00 2001 From: Dirk Gouders Date: Sat, 16 Aug 2014 07:56:58 +0200 Subject: [PATCH 0893/9167] scripts/tags.sh: fix DEFINE_HASHTABLE in emacs case The emacs --regex for DEFINE_HASHTABLE produced a warning because of an unmatched '\('. Further, the whole entry did not work, because the regex needs to match from the beginning of a line, including keywords like 'static'. Finally, '\w' should not be used, because it stops at underscores which are often part of variable names in C, resulting in wrong entries in the tags file. Signed-off-by: Dirk Gouders Inspired-by: Masatake YAMATO Signed-off-by: Michal Marek --- scripts/tags.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index 0f61bd7ee958..fd651f90a838 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -255,7 +255,7 @@ emacs() --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/' \ --regex='/PCI_OP_READ(\([a-z]*[a-z]\).*[1-4])/pci_bus_read_config_\1/' \ --regex='/PCI_OP_WRITE(\([a-z]*[a-z]\).*[1-4])/pci_bus_write_config_\1/'\ - --regex='/DEFINE_HASHTABLE\((\w*)/\1/' + --regex='/[^#]*DEFINE_HASHTABLE(\([^,)]*\)/\1/' all_kconfigs | xargs $1 -a \ --regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/' -- GitLab From 7b5bace34fe1ab412fb44ad1aaeaf9081b898d0a Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Tue, 19 Aug 2014 15:33:00 +0800 Subject: [PATCH 0894/9167] ARM: dts: sun7i: Add uart3/4/5, i2c3 and spi2 pinmux This patch add generic dts node for uart3/4/5, i2c3 and spi2. Reviewed-by: Chen-Yu Tsai Signed-off-by: Wills Wang Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/sun7i-a20.dtsi | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi index c658e343ce11..9f16074a4445 100644 --- a/arch/arm/boot/dts/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/sun7i-a20.dtsi @@ -634,6 +634,27 @@ allwinner,pull = <0>; }; + uart3_pins_a: uart3@0 { + allwinner,pins = "PG6", "PG7", "PG8", "PG9"; + allwinner,function = "uart3"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + uart4_pins_a: uart4@0 { + allwinner,pins = "PG10", "PG11"; + allwinner,function = "uart4"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + uart5_pins_a: uart5@0 { + allwinner,pins = "PI10", "PI11"; + allwinner,function = "uart5"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + uart6_pins_a: uart6@0 { allwinner,pins = "PI12", "PI13"; allwinner,function = "uart6"; @@ -669,6 +690,13 @@ allwinner,pull = <0>; }; + i2c3_pins_a: i2c3@0 { + allwinner,pins = "PI0", "PI1"; + allwinner,function = "i2c3"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + emac_pins_a: emac0@0 { allwinner,pins = "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", @@ -734,6 +762,13 @@ allwinner,pull = <0>; }; + spi2_pins_b: spi2@1 { + allwinner,pins = "PB14", "PB15", "PB16", "PB17"; + allwinner,function = "spi2"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + mmc0_pins_a: mmc0@0 { allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; allwinner,function = "mmc0"; -- GitLab From f171abab8f1a75797124be5aae8376e20e4852d9 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Aug 2014 10:06:28 +0530 Subject: [PATCH 0895/9167] iommu/exynos: Fix trivial typos Fixed trivial typos and grammar to improve readability. Changed w/a to workaround. Signed-off-by: Sachin Kamat Acked-by: Randy Dunlap Signed-off-by: Joerg Roedel --- drivers/iommu/exynos-iommu.c | 51 ++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index d037e87a1fe5..74233186f6f7 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -32,7 +32,7 @@ typedef u32 sysmmu_iova_t; typedef u32 sysmmu_pte_t; -/* We does not consider super section mapping (16MB) */ +/* We do not consider super section mapping (16MB) */ #define SECT_ORDER 20 #define LPAGE_ORDER 16 #define SPAGE_ORDER 12 @@ -307,7 +307,7 @@ static void show_fault_information(const char *name, static irqreturn_t exynos_sysmmu_irq(int irq, void *dev_id) { - /* SYSMMU is in blocked when interrupt occurred. */ + /* SYSMMU is in blocked state when interrupt occurred. */ struct sysmmu_drvdata *data = dev_id; enum exynos_sysmmu_inttype itype; sysmmu_iova_t addr = -1; @@ -567,8 +567,8 @@ static void sysmmu_tlb_invalidate_entry(struct device *dev, sysmmu_iova_t iova, /* * L2TLB invalidation required * 4KB page: 1 invalidation - * 64KB page: 16 invalidation - * 1MB page: 64 invalidation + * 64KB page: 16 invalidations + * 1MB page: 64 invalidations * because it is set-associative TLB * with 8-way and 64 sets. * 1MB page can be cached in one of all sets. @@ -714,7 +714,7 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain) if (!priv->lv2entcnt) goto err_counter; - /* w/a of System MMU v3.3 to prevent caching 1MiB mapping */ + /* Workaround for System MMU v3.3 to prevent caching 1MiB mapping */ for (i = 0; i < NUM_LV1ENTRIES; i += 8) { priv->pgtable[i + 0] = ZERO_LV2LINK; priv->pgtable[i + 1] = ZERO_LV2LINK; @@ -861,14 +861,14 @@ static sysmmu_pte_t *alloc_lv2entry(struct exynos_iommu_domain *priv, pgtable_flush(sent, sent + 1); /* - * If pretched SLPD is a fault SLPD in zero_l2_table, FLPD cache - * may caches the address of zero_l2_table. This function - * replaces the zero_l2_table with new L2 page table to write - * valid mappings. + * If pre-fetched SLPD is a faulty SLPD in zero_l2_table, + * FLPD cache may cache the address of zero_l2_table. This + * function replaces the zero_l2_table with new L2 page table + * to write valid mappings. * Accessing the valid area may cause page fault since FLPD - * cache may still caches zero_l2_table for the valid area - * instead of new L2 page table that have the mapping - * information of the valid area + * cache may still cache zero_l2_table for the valid area + * instead of new L2 page table that has the mapping + * information of the valid area. * Thus any replacement of zero_l2_table with other valid L2 * page table must involve FLPD cache invalidation for System * MMU v3.3. @@ -963,27 +963,27 @@ static int lv2set_page(sysmmu_pte_t *pent, phys_addr_t paddr, size_t size, /* * *CAUTION* to the I/O virtual memory managers that support exynos-iommu: * - * System MMU v3.x have an advanced logic to improve address translation + * System MMU v3.x has advanced logic to improve address translation * performance with caching more page table entries by a page table walk. - * However, the logic has a bug that caching fault page table entries and System - * MMU reports page fault if the cached fault entry is hit even though the fault - * entry is updated to a valid entry after the entry is cached. - * To prevent caching fault page table entries which may be updated to valid - * entries later, the virtual memory manager should care about the w/a about the - * problem. The followings describe w/a. + * However, the logic has a bug that while caching faulty page table entries, + * System MMU reports page fault if the cached fault entry is hit even though + * the fault entry is updated to a valid entry after the entry is cached. + * To prevent caching faulty page table entries which may be updated to valid + * entries later, the virtual memory manager should care about the workaround + * for the problem. The following describes the workaround. * * Any two consecutive I/O virtual address regions must have a hole of 128KiB - * in maximum to prevent misbehavior of System MMU 3.x. (w/a of h/w bug) + * at maximum to prevent misbehavior of System MMU 3.x (workaround for h/w bug). * - * Precisely, any start address of I/O virtual region must be aligned by + * Precisely, any start address of I/O virtual region must be aligned with * the following sizes for System MMU v3.1 and v3.2. * System MMU v3.1: 128KiB * System MMU v3.2: 256KiB * * Because System MMU v3.3 caches page table entries more aggressively, it needs - * more w/a. - * - Any two consecutive I/O virtual regions must be have a hole of larger size - * than or equal size to 128KiB. + * more workarounds. + * - Any two consecutive I/O virtual regions must have a hole of size larger + * than or equal to 128KiB. * - Start address of an I/O virtual region must be aligned by 128KiB. */ static int exynos_iommu_map(struct iommu_domain *domain, unsigned long l_iova, @@ -1061,7 +1061,8 @@ static size_t exynos_iommu_unmap(struct iommu_domain *domain, goto err; } - *ent = ZERO_LV2LINK; /* w/a for h/w bug in Sysmem MMU v3.3 */ + /* workaround for h/w bug in System MMU v3.3 */ + *ent = ZERO_LV2LINK; pgtable_flush(ent, ent + 1); size = SECT_SIZE; goto done; -- GitLab From f63ef69028742b09c1c0896177d555a30ff6cf13 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Mon, 11 Aug 2014 13:13:25 +0200 Subject: [PATCH 0896/9167] iommu/vt-d: Don't store SIRTP request Don't store the SIRTP request bit in the register state. It will otherwise become sticky and could request an Interrupt Remap Table Pointer update on each command register write. Found while starting to emulate IR in QEMU, not by observing problems on real hardware. Signed-off-by: Jan Kiszka Signed-off-by: Joerg Roedel --- drivers/iommu/intel_irq_remapping.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index 0df41f6264f5..a872874c2565 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c @@ -438,8 +438,7 @@ static void iommu_set_irq_remapping(struct intel_iommu *iommu, int mode) (addr) | IR_X2APIC_MODE(mode) | INTR_REMAP_TABLE_REG_SIZE); /* Set interrupt-remapping table pointer */ - iommu->gcmd |= DMA_GCMD_SIRTP; - writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG); + writel(iommu->gcmd | DMA_GCMD_SIRTP, iommu->reg + DMAR_GCMD_REG); IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_IRTPS), sts); -- GitLab From d95d6d47138ec1a3ab0a528470f98f8082f389d0 Mon Sep 17 00:00:00 2001 From: Wills Wang Date: Tue, 19 Aug 2014 15:33:01 +0800 Subject: [PATCH 0897/9167] ARM: dts: sun7i: Add Merrii A20 Hummingbird board This adds support for the A20 Hummingbird: http://www.merrii.com/en/pla_d.asp?id=171 This patch enable most on-board peripherals supported on current kernel, such as uart, i2c, spi, pwm, ohci/ehci, gmac and mmc. Reviewed-by: Chen-Yu Tsai Signed-off-by: Wills Wang Signed-off-by: Maxime Ripard --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/sun7i-a20-hummingbird.dts | 236 ++++++++++++++++++++ 2 files changed, 237 insertions(+) create mode 100644 arch/arm/boot/dts/sun7i-a20-hummingbird.dts diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b8c5cd3ddeb9..c72f6537b47a 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -416,6 +416,7 @@ dtb-$(CONFIG_MACH_SUN6I) += \ dtb-$(CONFIG_MACH_SUN7I) += \ sun7i-a20-cubieboard2.dtb \ sun7i-a20-cubietruck.dtb \ + sun7i-a20-hummingbird.dtb \ sun7i-a20-i12-tvbox.dtb \ sun7i-a20-olinuxino-micro.dtb \ sun7i-a20-pcduino3.dtb diff --git a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts new file mode 100644 index 000000000000..0e4bfa3b2b85 --- /dev/null +++ b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts @@ -0,0 +1,236 @@ +/* + * Copyright 2013 Wills Wang + * + * Wills Wang + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +/dts-v1/; +/include/ "sun7i-a20.dtsi" +/include/ "sunxi-common-regulators.dtsi" + +/ { + model = "Merrii A20 Hummingbird"; + compatible = "merrii,a20-hummingbird", "allwinner,sun7i-a20"; + + soc@01c00000 { + mmc0: mmc@01c0f000 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + vmmc-supply = <®_vcc3v0>; + bus-width = <4>; + cd-gpios = <&pio 7 1 0>; /* PH1 */ + cd-inverted; + status = "okay"; + }; + + mmc3: mmc@01c12000 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc3_pins_a>; + vmmc-supply = <®_mmc3_vdd>; + bus-width = <4>; + non-removable; + status = "okay"; + }; + + usbphy: phy@01c13400 { + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; + }; + + ehci0: usb@01c14000 { + status = "okay"; + }; + + ohci0: usb@01c14400 { + status = "okay"; + }; + + ahci: sata@01c18000 { + target-supply = <®_ahci_5v>; + status = "okay"; + }; + + ehci1: usb@01c1c000 { + status = "okay"; + }; + + ohci1: usb@01c1c400 { + status = "okay"; + }; + + pio: pinctrl@01c20800 { + ahci_pwr_pin_a20_hummingbird: ahci_pwr_pin@0 { + allwinner,pins = "PH15"; + allwinner,function = "gpio_out"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + usb1_vbus_pin_a20_hummingbird: usb1_vbus_pin@0 { + allwinner,pins = "PH2"; + allwinner,function = "gpio_out"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + mmc3_vdd_pin_a20_hummingbird: mmc3_vdd_pin@0 { + allwinner,pins = "PH9"; + allwinner,function = "gpio_out"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + + gmac_vdd_pin_a20_hummingbird: gmac_vdd_pin@0 { + allwinner,pins = "PH16"; + allwinner,function = "gpio_out"; + allwinner,drive = <0>; + allwinner,pull = <0>; + }; + }; + + pwm: pwm@01c20e00 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pins_a>; + status = "okay"; + }; + + ir0: ir@01c21800 { + pinctrl-names = "default"; + pinctrl-0 = <&ir0_pins_a>; + status = "okay"; + }; + + uart0: serial@01c28000 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; + }; + + uart2: serial@01c28800 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins_a>; + status = "okay"; + }; + + uart3: serial@01c28c00 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3_pins_a>; + status = "okay"; + }; + + uart4: serial@01c29000 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4_pins_a>; + status = "okay"; + }; + + uart5: serial@01c29400 { + pinctrl-names = "default"; + pinctrl-0 = <&uart5_pins_a>; + status = "okay"; + }; + + i2c0: i2c@01c2ac00 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + axp209: pmic@34 { + compatible = "x-powers,axp209"; + reg = <0x34>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 8>; + interrupt-controller; + #interrupt-cells = <1>; + }; + }; + + i2c1: i2c@01c2b000 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; + }; + + i2c2: i2c@01c2b400 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_pins_a>; + status = "okay"; + }; + + i2c3: i2c@01c2b800 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c3_pins_a>; + status = "okay"; + }; + + spi2: spi@01c17000 { + pinctrl-names = "default"; + pinctrl-0 = <&spi2_pins_b>; + status = "okay"; + }; + + gmac: ethernet@01c50000 { + pinctrl-names = "default"; + pinctrl-0 = <&gmac_pins_rgmii_a>; + phy = <&phy1>; + phy-mode = "rgmii"; + phy-supply = <®_gmac_vdd>; + /* phy reset config */ + snps,reset-gpio = <&pio 0 17 0>; /* PA17 */ + snps,reset-active-low; + /* wait 1s after reset, otherwise fail to read phy id */ + snps,reset-delays-us = <0 10000 1000000>; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; + }; + + reg_ahci_5v: ahci-5v { + pinctrl-0 = <&ahci_pwr_pin_a20_hummingbird>; + gpio = <&pio 7 15 0>; /* PH15 */ + status = "okay"; + }; + + reg_usb1_vbus: usb1-vbus { + pinctrl-0 = <&usb1_vbus_pin_a20_hummingbird>; + gpio = <&pio 7 2 0>; /* PH2 */ + status = "okay"; + }; + + reg_usb2_vbus: usb2-vbus { + status = "okay"; + }; + + reg_mmc3_vdd: mmc3_vdd { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&mmc3_vdd_pin_a20_hummingbird>; + regulator-name = "mmc3_vdd"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + enable-active-high; + gpio = <&pio 7 9 0>; /* PH9 */ + }; + + reg_gmac_vdd: gmac_vdd { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&gmac_vdd_pin_a20_hummingbird>; + regulator-name = "gmac_vdd"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + enable-active-high; + gpio = <&pio 7 16 0>; /* PH16 */ + }; +}; -- GitLab From eecbad7d0306b9ee4f621517052913d1adaea753 Mon Sep 17 00:00:00 2001 From: Andreea-Cristina Bernat Date: Mon, 18 Aug 2014 15:20:56 +0300 Subject: [PATCH 0898/9167] iommu: 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: Joerg Roedel --- drivers/iommu/dmar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index 60ab474bfff3..8ed55b0a1ce4 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -247,7 +247,7 @@ int dmar_remove_dev_scope(struct dmar_pci_notify_info *info, u16 segment, for_each_active_dev_scope(devices, count, index, tmp) if (tmp == &info->dev->dev) { - rcu_assign_pointer(devices[index].dev, NULL); + RCU_INIT_POINTER(devices[index].dev, NULL); synchronize_rcu(); put_device(tmp); return 1; -- GitLab From dc9b2d933a1d5782b70977024f862759c8ebb2f7 Mon Sep 17 00:00:00 2001 From: Wei Huang Date: Wed, 13 Aug 2014 12:06:14 -0400 Subject: [PATCH 0899/9167] KVM: SVM: add rdmsr support for AMD event registers Current KVM only supports RDMSR for K7_EVNTSEL0 and K7_PERFCTR0 MSRs. Reading the rest MSRs will trigger KVM to inject #GP into guest VM. This causes a warning message "Failed to access perfctr msr (MSR c0010001 is ffffffffffffffff)" on AMD host. This patch adds RDMSR support for all K7_EVNTSELn and K7_PERFCTRn registers and thus supresses the warning message. Signed-off-by: Wei Huang Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8f1e22d3b286..5f5edb6ddc83 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2419,7 +2419,13 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_K7_HWCR: case MSR_VM_HSAVE_PA: case MSR_K7_EVNTSEL0: + case MSR_K7_EVNTSEL1: + case MSR_K7_EVNTSEL2: + case MSR_K7_EVNTSEL3: case MSR_K7_PERFCTR0: + case MSR_K7_PERFCTR1: + case MSR_K7_PERFCTR2: + case MSR_K7_PERFCTR3: case MSR_K8_INT_PENDING_MSG: case MSR_AMD64_NB_CFG: case MSR_FAM10H_MMIO_CONF_BASE: -- GitLab From 4473b570a7ebb502f63f292ccfba7df622e5fdd3 Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Mon, 18 Aug 2014 17:50:28 +0800 Subject: [PATCH 0900/9167] KVM: x86: drop fpu_activate hook The only user of the fpu_activate hook was dropped in commit 2d04a05bd7e9 (KVM: x86 emulator: emulate CLTS internally, 2011-04-20). vmx_fpu_activate and svm_fpu_activate are still called on #NM (and for Intel CLTS), but never from common code; hence, there's no need for a hook. Reviewed-by: Yang Zhang Signed-off-by: Wanpeng Li Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 1 - arch/x86/kvm/svm.c | 1 - arch/x86/kvm/vmx.c | 1 - 3 files changed, 3 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 7c492ed9087b..4bda61b582e6 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -710,7 +710,6 @@ struct kvm_x86_ops { void (*cache_reg)(struct kvm_vcpu *vcpu, enum kvm_reg reg); unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); void (*set_rflags)(struct kvm_vcpu *vcpu, unsigned long rflags); - void (*fpu_activate)(struct kvm_vcpu *vcpu); void (*fpu_deactivate)(struct kvm_vcpu *vcpu); void (*tlb_flush)(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ddf742768ecf..1f49c867e72e 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -4349,7 +4349,6 @@ static struct kvm_x86_ops svm_x86_ops = { .cache_reg = svm_cache_reg, .get_rflags = svm_get_rflags, .set_rflags = svm_set_rflags, - .fpu_activate = svm_fpu_activate, .fpu_deactivate = svm_fpu_deactivate, .tlb_flush = svm_flush_tlb, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index bfe11cf124a1..6a216e4762c7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8890,7 +8890,6 @@ static struct kvm_x86_ops vmx_x86_ops = { .cache_reg = vmx_cache_reg, .get_rflags = vmx_get_rflags, .set_rflags = vmx_set_rflags, - .fpu_activate = vmx_fpu_activate, .fpu_deactivate = vmx_fpu_deactivate, .tlb_flush = vmx_flush_tlb, -- GitLab From 15fc075269e42230605343554c5c8001eb819228 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 18 Aug 2014 13:17:00 +0200 Subject: [PATCH 0901/9167] KVM: x86: raise invalid TSS exceptions during a task switch Conditions that would usually trigger a general protection fault should instead raise #TS. 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 03954f7900f5..ef297919a691 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1468,7 +1468,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, return ret; err_code = selector & 0xfffc; - err_vec = GP_VECTOR; + err_vec = in_task_switch ? TS_VECTOR : GP_VECTOR; /* can't load system descriptor into segment selector */ if (seg <= VCPU_SREG_GS && !seg_desc.s) -- GitLab From 3b63a43f1e04b935e1ce0383f78ac0f5c65433d8 Mon Sep 17 00:00:00 2001 From: Monam Agarwal Date: Sat, 22 Mar 2014 12:28:10 +0530 Subject: [PATCH 0902/9167] arch/x86: Use RCU_INIT_POINTER(x, NULL) in kvm/vmx.c Here rcu_assign_pointer() is ensuring that the initialization of a structure is carried out before storing a pointer to that structure. So, rcu_assign_pointer(p, NULL) can always safely be converted to RCU_INIT_POINTER(p, NULL). Signed-off-by: Monam Agarwal 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 6a216e4762c7..cad37d57cc47 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -9097,7 +9097,7 @@ static void __exit vmx_exit(void) free_page((unsigned long)vmx_vmread_bitmap); #ifdef CONFIG_KEXEC - rcu_assign_pointer(crash_vmclear_loaded_vmcss, NULL); + RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); synchronize_rcu(); #endif -- GitLab From adfb5d2746bfbe692324bd26a6de05a3a036b38e Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Tue, 19 Aug 2014 17:04:39 +0800 Subject: [PATCH 0903/9167] KVM: x86: fix check legal type of Variable Range MTRRs The first entry in each pair(IA32_MTRR_PHYSBASEn) defines the base address and memory type for the range; the second entry(IA32_MTRR_PHYSMASKn) contains a mask used to determine the address range. The legal values for the type field of IA32_MTRR_PHYSBASEn are 0,1,4,5, and 6. However, IA32_MTRR_PHYSMASKn don't have type field. This patch avoid check if the type field is legal for IA32_MTRR_PHYSMASKn. Signed-off-by: Wanpeng Li Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 5f5edb6ddc83..fb3ea7aad0c1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1747,7 +1747,13 @@ static bool mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data) } /* variable MTRRs */ - return valid_mtrr_type(data & 0xff); + WARN_ON(!(msr >= 0x200 && msr < 0x200 + 2 * KVM_NR_VAR_MTRR)); + + if ((msr & 1) == 0) + /* MTRR base */ + return valid_mtrr_type(data & 0xff); + /* MTRR mask */ + return true; } static int set_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 data) -- GitLab From d7a2a246a1b5a0b0c803e800019600051e1e6f1a Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Tue, 19 Aug 2014 17:04:40 +0800 Subject: [PATCH 0904/9167] KVM: x86: #GP when attempts to write reserved bits of Variable Range MTRRs Section 11.11.2.3 of the SDM mentions "All other bits in the IA32_MTRR_PHYSBASEn and IA32_MTRR_PHYSMASKn registers are reserved; the processor generates a general-protection exception(#GP) if software attempts to write to them". This patch do it in kvm. Signed-off-by: Wanpeng Li Signed-off-by: Paolo Bonzini --- arch/x86/kvm/x86.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fb3ea7aad0c1..737b4bdac41c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1726,6 +1726,7 @@ static bool valid_mtrr_type(unsigned t) static bool mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data) { int i; + u64 mask = 0; if (!msr_mtrr_valid(msr)) return false; @@ -1749,10 +1750,21 @@ static bool mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data) /* variable MTRRs */ WARN_ON(!(msr >= 0x200 && msr < 0x200 + 2 * KVM_NR_VAR_MTRR)); - if ((msr & 1) == 0) + for (i = 63; i > boot_cpu_data.x86_phys_bits; i--) + mask |= (1ULL << i); + if ((msr & 1) == 0) { /* MTRR base */ - return valid_mtrr_type(data & 0xff); - /* MTRR mask */ + if (!valid_mtrr_type(data & 0xff)) + return false; + mask |= 0xf00; + } else + /* MTRR mask */ + mask |= 0x7ff; + if (data & mask) { + kvm_inject_gp(vcpu, 0); + return false; + } + return true; } -- GitLab From fae0ba2157340635fd99912c0c3b7a28c355c588 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Mon, 18 Aug 2014 22:42:13 +0300 Subject: [PATCH 0905/9167] KVM: x86: Clear apic tsc-deadline after deadline Intel SDM 10.5.4.1 says "When the timer generates an interrupt, it disarms itself and clears the IA32_TSC_DEADLINE MSR". This patch clears the MSR upon timer interrupt delivery which delivered on deadline mode. Since the MSR may be reconfigured while an interrupt is pending, causing the new value to be overriden, pending timer interrupts are checked before setting a new deadline. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 08e8a899e005..666c086c82d4 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -1352,6 +1352,9 @@ 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); } @@ -1639,6 +1642,8 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) if (atomic_read(&apic->lapic_timer.pending) > 0) { kvm_apic_local_deliver(apic, APIC_LVTT); + if (apic_lvtt_tscdeadline(apic)) + apic->lapic_timer.tscdeadline = 0; atomic_set(&apic->lapic_timer.pending, 0); } } -- GitLab From 1e1b6c26443547b05925ae4a4494884c92eb7d95 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Tue, 19 Aug 2014 00:03:00 +0300 Subject: [PATCH 0906/9167] KVM: x86: recalculate_apic_map after enabling apic Currently, recalculate_apic_map ignores vcpus whose lapic is software disabled through the spurious interrupt vector. However, once it is re-enabled, the map is not recalculated. Therefore, if the guest OS configured DFR while lapic is software-disabled, the map may be incorrect. This patch recalculates apic map after software enabling the lapic. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/lapic.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 666c086c82d4..fb919c574e23 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -112,17 +112,6 @@ static inline int __apic_test_and_clear_vector(int vec, void *bitmap) struct static_key_deferred apic_hw_disabled __read_mostly; struct static_key_deferred apic_sw_disabled __read_mostly; -static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) -{ - if ((kvm_apic_get_reg(apic, APIC_SPIV) ^ val) & APIC_SPIV_APIC_ENABLED) { - if (val & APIC_SPIV_APIC_ENABLED) - static_key_slow_dec_deferred(&apic_sw_disabled); - else - static_key_slow_inc(&apic_sw_disabled.key); - } - apic_set_reg(apic, APIC_SPIV, val); -} - static inline int apic_enabled(struct kvm_lapic *apic) { return kvm_apic_sw_enabled(apic) && kvm_apic_hw_enabled(apic); @@ -210,6 +199,20 @@ static void recalculate_apic_map(struct kvm *kvm) kvm_vcpu_request_scan_ioapic(kvm); } +static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) +{ + u32 prev = kvm_apic_get_reg(apic, APIC_SPIV); + + apic_set_reg(apic, APIC_SPIV, val); + if ((prev ^ val) & APIC_SPIV_APIC_ENABLED) { + if (val & APIC_SPIV_APIC_ENABLED) { + static_key_slow_dec_deferred(&apic_sw_disabled); + recalculate_apic_map(apic->vcpu->kvm); + } else + static_key_slow_inc(&apic_sw_disabled.key); + } +} + static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id) { apic_set_reg(apic, APIC_ID, id << 24); -- GitLab From e5f81539f657af7e9f54ea37986fde8f92acef22 Mon Sep 17 00:00:00 2001 From: Feng Kan Date: Wed, 30 Jul 2014 14:56:58 -0700 Subject: [PATCH 0907/9167] irqchip: gic: Replace hex numbers with defines. This is to cleanup some hex numbers used in the code and replace them with defines to make the code cleaner. Signed-off-by: Feng Kan Reviewed-by: Anup Patel Link: https://lkml.kernel.org/r/1406757419-18729-2-git-send-email-fkan@apm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic-common.c | 15 +++++++++------ drivers/irqchip/irq-gic.c | 25 +++++++++++++------------ include/linux/irqchip/arm-gic.h | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c index 60ac704d2090..61541ff24397 100644 --- a/drivers/irqchip/irq-gic-common.c +++ b/drivers/irqchip/irq-gic-common.c @@ -74,20 +74,22 @@ void __init gic_dist_config(void __iomem *base, int gic_irqs, * Set all global interrupts to be level triggered, active low. */ for (i = 32; i < gic_irqs; i += 16) - writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4); + writel_relaxed(GICD_INT_ACTLOW_LVLTRIG, + base + GIC_DIST_CONFIG + i / 4); /* * Set priority on all global interrupts. */ for (i = 32; i < gic_irqs; i += 4) - writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i); + writel_relaxed(GICD_INT_DEF_PRI_X4, base + GIC_DIST_PRI + i); /* * Disable all interrupts. Leave the PPI and SGIs alone * as they are enabled by redistributor registers. */ for (i = 32; i < gic_irqs; i += 32) - writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8); + writel_relaxed(GICD_INT_EN_CLR_X32, + base + GIC_DIST_ENABLE_CLEAR + i / 8); if (sync_access) sync_access(); @@ -101,14 +103,15 @@ void gic_cpu_config(void __iomem *base, void (*sync_access)(void)) * Deal with the banked PPI and SGI interrupts - disable all * PPI interrupts, ensure all SGI interrupts are enabled. */ - writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR); - writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET); + writel_relaxed(GICD_INT_EN_CLR_PPI, base + GIC_DIST_ENABLE_CLEAR); + writel_relaxed(GICD_INT_EN_SET_SGI, base + GIC_DIST_ENABLE_SET); /* * Set priority on PPI and SGI interrupts */ for (i = 0; i < 32; i += 4) - writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); + writel_relaxed(GICD_INT_DEF_PRI_X4, + base + GIC_DIST_PRI + i * 4 / 4); if (sync_access) sync_access(); diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 4b959e606fe8..35847453cecb 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -298,8 +298,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) status = readl_relaxed(gic_data_cpu_base(chip_data) + GIC_CPU_INTACK); raw_spin_unlock(&irq_controller_lock); - gic_irq = (status & 0x3ff); - if (gic_irq == 1023) + gic_irq = (status & GICC_IAR_INT_ID_MASK); + if (gic_irq == GICC_INT_SPURIOUS) goto out; cascade_irq = irq_find_mapping(chip_data->domain, gic_irq); @@ -360,7 +360,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) unsigned int gic_irqs = gic->gic_irqs; void __iomem *base = gic_data_dist_base(gic); - writel_relaxed(0, base + GIC_DIST_CTRL); + writel_relaxed(GICD_DISABLE, base + GIC_DIST_CTRL); /* * Set all global interrupts to this CPU only. @@ -373,7 +373,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) gic_dist_config(base, gic_irqs, NULL); - writel_relaxed(1, base + GIC_DIST_CTRL); + writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL); } static void gic_cpu_init(struct gic_chip_data *gic) @@ -400,8 +400,8 @@ static void gic_cpu_init(struct gic_chip_data *gic) gic_cpu_config(dist_base, NULL); - writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); - writel_relaxed(1, base + GIC_CPU_CTRL); + writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK); + writel_relaxed(GICC_ENABLE, base + GIC_CPU_CTRL); } void gic_cpu_if_down(void) @@ -467,14 +467,14 @@ static void gic_dist_restore(unsigned int gic_nr) if (!dist_base) return; - writel_relaxed(0, dist_base + GIC_DIST_CTRL); + writel_relaxed(GICD_DISABLE, dist_base + GIC_DIST_CTRL); for (i = 0; i < DIV_ROUND_UP(gic_irqs, 16); i++) writel_relaxed(gic_data[gic_nr].saved_spi_conf[i], dist_base + GIC_DIST_CONFIG + i * 4); for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) - writel_relaxed(0xa0a0a0a0, + writel_relaxed(GICD_INT_DEF_PRI_X4, dist_base + GIC_DIST_PRI + i * 4); for (i = 0; i < DIV_ROUND_UP(gic_irqs, 4); i++) @@ -485,7 +485,7 @@ static void gic_dist_restore(unsigned int gic_nr) writel_relaxed(gic_data[gic_nr].saved_spi_enable[i], dist_base + GIC_DIST_ENABLE_SET + i * 4); - writel_relaxed(1, dist_base + GIC_DIST_CTRL); + writel_relaxed(GICD_ENABLE, dist_base + GIC_DIST_CTRL); } static void gic_cpu_save(unsigned int gic_nr) @@ -539,10 +539,11 @@ static void gic_cpu_restore(unsigned int gic_nr) writel_relaxed(ptr[i], dist_base + GIC_DIST_CONFIG + i * 4); for (i = 0; i < DIV_ROUND_UP(32, 4); i++) - writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4); + writel_relaxed(GICD_INT_DEF_PRI_X4, + dist_base + GIC_DIST_PRI + i * 4); - writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK); - writel_relaxed(1, cpu_base + GIC_CPU_CTRL); + writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK); + writel_relaxed(GICC_ENABLE, cpu_base + GIC_CPU_CTRL); } static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 45e2d8c15bd2..5cb9d41af5be 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -21,7 +21,10 @@ #define GIC_CPU_ACTIVEPRIO 0xd0 #define GIC_CPU_IDENT 0xfc +#define GICC_ENABLE 0x1 +#define GICC_INT_PRI_THRESHOLD 0xf0 #define GICC_IAR_INT_ID_MASK 0x3ff +#define GICC_INT_SPURIOUS 1023 #define GIC_DIST_CTRL 0x000 #define GIC_DIST_CTR 0x004 @@ -39,6 +42,18 @@ #define GIC_DIST_SGI_PENDING_CLEAR 0xf10 #define GIC_DIST_SGI_PENDING_SET 0xf20 +#define GICD_ENABLE 0x1 +#define GICD_DISABLE 0x0 +#define GICD_INT_ACTLOW_LVLTRIG 0x0 +#define GICD_INT_EN_CLR_X32 0xffffffff +#define GICD_INT_EN_SET_SGI 0x0000ffff +#define GICD_INT_EN_CLR_PPI 0xffff0000 +#define GICD_INT_DEF_PRI 0xa0 +#define GICD_INT_DEF_PRI_X4 ((GICD_INT_DEF_PRI << 24) |\ + (GICD_INT_DEF_PRI << 16) |\ + (GICD_INT_DEF_PRI << 8) |\ + GICD_INT_DEF_PRI) + #define GICH_HCR 0x0 #define GICH_VTR 0x4 #define GICH_VMCR 0x8 -- GitLab From 3228950621d92f0f212378f95a6998ef3a1be0bb Mon Sep 17 00:00:00 2001 From: Feng Kan Date: Wed, 30 Jul 2014 14:56:59 -0700 Subject: [PATCH 0908/9167] irqchip: gic: Preserve gic V2 bypass bits in cpu ctrl register This change is made to preserve the GIC v2 bypass bits in the GIC_CPU_CTRL register (also known as the GICC_CTLR register in spec). This code will preserve all bits configured by the bootloader regarding v2 bypass group bits. In the X-Gene platform, the bypass functionality is not used and bypass bits should not be changed by the kernel gic code as it could lead to incorrect behavior. Signed-off-by: Feng Kan Reviewed-by: Vinayak Kale Reviewed-by: Anup Patel Link: https://lkml.kernel.org/r/1406757419-18729-3-git-send-email-fkan@apm.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-gic.c | 25 ++++++++++++++++++++++--- include/linux/irqchip/arm-gic.h | 1 + 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 35847453cecb..2500f6ba29e1 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -353,6 +353,21 @@ static u8 gic_get_cpumask(struct gic_chip_data *gic) return mask; } +static void gic_cpu_if_up(void) +{ + void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]); + u32 bypass = 0; + + /* + * Preserve bypass disable bits to be written back later + */ + bypass = readl(cpu_base + GIC_CPU_CTRL); + bypass &= GICC_DIS_BYPASS_MASK; + + writel_relaxed(bypass | GICC_ENABLE, cpu_base + GIC_CPU_CTRL); +} + + static void __init gic_dist_init(struct gic_chip_data *gic) { unsigned int i; @@ -401,13 +416,17 @@ static void gic_cpu_init(struct gic_chip_data *gic) gic_cpu_config(dist_base, NULL); writel_relaxed(GICC_INT_PRI_THRESHOLD, base + GIC_CPU_PRIMASK); - writel_relaxed(GICC_ENABLE, base + GIC_CPU_CTRL); + gic_cpu_if_up(); } void gic_cpu_if_down(void) { void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]); - writel_relaxed(0, cpu_base + GIC_CPU_CTRL); + u32 val = 0; + + val = readl(cpu_base + GIC_CPU_CTRL); + val &= ~GICC_ENABLE; + writel_relaxed(val, cpu_base + GIC_CPU_CTRL); } #ifdef CONFIG_CPU_PM @@ -543,7 +562,7 @@ static void gic_cpu_restore(unsigned int gic_nr) dist_base + GIC_DIST_PRI + i * 4); writel_relaxed(GICC_INT_PRI_THRESHOLD, cpu_base + GIC_CPU_PRIMASK); - writel_relaxed(GICC_ENABLE, cpu_base + GIC_CPU_CTRL); + gic_cpu_if_up(); } static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h index 5cb9d41af5be..13eed92c7d24 100644 --- a/include/linux/irqchip/arm-gic.h +++ b/include/linux/irqchip/arm-gic.h @@ -25,6 +25,7 @@ #define GICC_INT_PRI_THRESHOLD 0xf0 #define GICC_IAR_INT_ID_MASK 0x3ff #define GICC_INT_SPURIOUS 1023 +#define GICC_DIS_BYPASS_MASK 0x1e0 #define GIC_DIST_CTRL 0x000 #define GIC_DIST_CTR 0x004 -- GitLab From 23e11811378259831777e8fdc8b9836faeaa72cd Mon Sep 17 00:00:00 2001 From: Vignesh Raman Date: Tue, 5 Aug 2014 18:39:41 +0530 Subject: [PATCH 0909/9167] dma: imx-sdma: use module_platform_driver for SDMA driver Currently there is no module_exit declared in SDMA driver, so that once sdma module is inserted, it's shown with permanent attribute by lsmod, and it can't be removed. Use module_platform_driver to register/unregister SDMA driver and modify SDMA's remove operation, to make SDMA driver possible to be removed. Signed-off-by: Jiada Wang Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index f7626e37d0b8..40e65a4df94d 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1603,6 +1603,8 @@ static int __init sdma_probe(struct platform_device *pdev) sdma->dma_device.dev->dma_parms = &sdma->dma_parms; dma_set_max_seg_size(sdma->dma_device.dev, 65535); + platform_set_drvdata(pdev, sdma); + ret = dma_async_device_register(&sdma->dma_device); if (ret) { dev_err(&pdev->dev, "unable to register\n"); @@ -1640,7 +1642,20 @@ static int __init sdma_probe(struct platform_device *pdev) static int sdma_remove(struct platform_device *pdev) { - return -EBUSY; + struct sdma_engine *sdma = platform_get_drvdata(pdev); + struct resource *iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); + int irq = platform_get_irq(pdev, 0); + + dma_async_device_unregister(&sdma->dma_device); + kfree(sdma->script_addrs); + free_irq(irq, sdma); + iounmap(sdma->regs); + release_mem_region(iores->start, resource_size(iores)); + kfree(sdma); + + platform_set_drvdata(pdev, NULL); + dev_info(&pdev->dev, "Removed...\n"); + return 0; } static struct platform_driver sdma_driver = { @@ -1650,13 +1665,10 @@ static struct platform_driver sdma_driver = { }, .id_table = sdma_devtypes, .remove = sdma_remove, + .probe = sdma_probe, }; -static int __init sdma_module_init(void) -{ - return platform_driver_probe(&sdma_driver, sdma_probe); -} -module_init(sdma_module_init); +module_platform_driver(sdma_driver); MODULE_AUTHOR("Sascha Hauer, Pengutronix "); MODULE_DESCRIPTION("i.MX SDMA driver"); -- GitLab From c12fe49726cfebacb47dca5f2bb544c38aa09e6d Mon Sep 17 00:00:00 2001 From: Vignesh Raman Date: Tue, 5 Aug 2014 18:39:42 +0530 Subject: [PATCH 0910/9167] dma: imx-sdma: Adding tasklet_kill() in sdma_remove function. Several dma drivers calls tasklet_kill() in remove function. This is done because all running tasklets should be killed on remove. This is missing in imx sdma driver, so adding tasklet_kill() in sdma_remove function. Signed-off-by: Vignesh Raman Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 40e65a4df94d..c615e88c118a 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1645,12 +1645,19 @@ static int sdma_remove(struct platform_device *pdev) struct sdma_engine *sdma = platform_get_drvdata(pdev); struct resource *iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); int irq = platform_get_irq(pdev, 0); + int i; dma_async_device_unregister(&sdma->dma_device); kfree(sdma->script_addrs); free_irq(irq, sdma); iounmap(sdma->regs); release_mem_region(iores->start, resource_size(iores)); + /* Kill the tasklet */ + for (i = 0; i < MAX_DMA_CHANNELS; i++) { + struct sdma_channel *sdmac = &sdma->channel[i]; + + tasklet_kill(&sdmac->tasklet); + } kfree(sdma); platform_set_drvdata(pdev, NULL); -- GitLab From 39f5460d7f9cc57d3dd745301bf60ca5d65a6e7b Mon Sep 17 00:00:00 2001 From: Guodong Xu Date: Tue, 19 Aug 2014 18:07:41 +0800 Subject: [PATCH 0911/9167] regulator: core: add const to regulator_ops and fix build error in mc13892 Commit 272e2315fac3 ("regulator: core: add const qualifier to ops in struct regulator_desc") introduced const qualifier to ops in regulator_desc. This patch adds 'const' to regulator_ops vars in newly added core APIs for v3.17-rc1: - regulator_get_hardware_vsel_register() - regulator_list_hardware_vsel() This patch also fix a build error in mc13892-regulator.c due to const regulator_desc.ops. Modification of regulator_desc.ops' member fields is not allowed. Signed-off-by: Guodong Xu Signed-off-by: Mark Brown --- drivers/regulator/core.c | 8 ++++---- drivers/regulator/mc13892-regulator.c | 11 +++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1e976b6320a2..7bce7158d7e6 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2307,8 +2307,8 @@ int regulator_get_hardware_vsel_register(struct regulator *regulator, unsigned *vsel_reg, unsigned *vsel_mask) { - struct regulator_dev *rdev = regulator->rdev; - struct regulator_ops *ops = rdev->desc->ops; + struct regulator_dev *rdev = regulator->rdev; + const struct regulator_ops *ops = rdev->desc->ops; if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) return -EOPNOTSUPP; @@ -2334,8 +2334,8 @@ EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register); int regulator_list_hardware_vsel(struct regulator *regulator, unsigned selector) { - struct regulator_dev *rdev = regulator->rdev; - struct regulator_ops *ops = rdev->desc->ops; + struct regulator_dev *rdev = regulator->rdev; + const struct regulator_ops *ops = rdev->desc->ops; if (selector >= rdev->desc->n_voltages) return -EINVAL; diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c index f374fa57220f..793b662a1967 100644 --- a/drivers/regulator/mc13892-regulator.c +++ b/drivers/regulator/mc13892-regulator.c @@ -526,6 +526,7 @@ static unsigned int mc13892_vcam_get_mode(struct regulator_dev *rdev) return REGULATOR_MODE_NORMAL; } +static struct regulator_ops mc13892_vcam_ops; static int mc13892_regulator_probe(struct platform_device *pdev) { @@ -582,10 +583,12 @@ static int mc13892_regulator_probe(struct platform_device *pdev) } mc13xxx_unlock(mc13892); - mc13892_regulators[MC13892_VCAM].desc.ops->set_mode - = mc13892_vcam_set_mode; - mc13892_regulators[MC13892_VCAM].desc.ops->get_mode - = mc13892_vcam_get_mode; + /* update mc13892_vcam ops */ + memcpy(&mc13892_vcam_ops, mc13892_regulators[MC13892_VCAM].desc.ops, + sizeof(struct regulator_ops)); + mc13892_vcam_ops.set_mode = mc13892_vcam_set_mode, + mc13892_vcam_ops.get_mode = mc13892_vcam_get_mode, + mc13892_regulators[MC13892_VCAM].desc.ops = &mc13892_vcam_ops; mc13xxx_data = mc13xxx_parse_regulators_dt(pdev, mc13892_regulators, ARRAY_SIZE(mc13892_regulators)); -- GitLab From ea62f4dfe329094cd988a73fe854c6f2e92dd486 Mon Sep 17 00:00:00 2001 From: Guodong Xu Date: Tue, 19 Aug 2014 18:07:42 +0800 Subject: [PATCH 0912/9167] regulator: hi6421: style fix, else with a single return is not required style fix for warnings. 'else' with a single 'return' is usually not required. Signed-off-by: Guodong Xu Signed-off-by: Mark Brown --- drivers/regulator/hi6421-regulator.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index b40851eb5466..b0de92bee4a2 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -435,8 +435,8 @@ static unsigned int hi6421_regulator_ldo_get_mode(struct regulator_dev *rdev) regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); if (reg_val & info->mode_mask) return REGULATOR_MODE_IDLE; - else - return REGULATOR_MODE_NORMAL; + + return REGULATOR_MODE_NORMAL; } static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) @@ -447,8 +447,8 @@ static unsigned int hi6421_regulator_buck_get_mode(struct regulator_dev *rdev) regmap_read(rdev->regmap, rdev->desc->enable_reg, ®_val); if (reg_val & info->mode_mask) return REGULATOR_MODE_STANDBY; - else - return REGULATOR_MODE_NORMAL; + + return REGULATOR_MODE_NORMAL; } static int hi6421_regulator_ldo_set_mode(struct regulator_dev *rdev, @@ -506,8 +506,8 @@ unsigned int hi6421_regulator_ldo_get_optimum_mode(struct regulator_dev *rdev, if (load_uA > info->eco_microamp) return REGULATOR_MODE_NORMAL; - else - return REGULATOR_MODE_IDLE; + + return REGULATOR_MODE_IDLE; } static const struct regulator_ops hi6421_ldo_ops = { -- GitLab From cdec729765659adafba983d6b6760ad52c71d5d8 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Tue, 19 Aug 2014 12:49:34 +0800 Subject: [PATCH 0913/9167] ASoC: fsl: Fix building of imx-es8328 on PPC The imx-es8328 driver fails to build on PPC because it explicitly depends on SND_SOC_IMX_PCM_FIQ, which itself doesn't build on PPC. Instead, rely on the SND_SOC_FSL_SSI config option to pull in the necessary libraries. While we're at it, remove SND_SOC_FSL_UTILS, which also is not needed. Signed-off-by: Sean Cross Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 4698c01af684..3154f43b11ab 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -266,8 +266,6 @@ config SND_SOC_IMX_ES8328 select SND_SOC_IMX_PCM_DMA select SND_SOC_IMX_AUDMUX select SND_SOC_FSL_SSI - select SND_SOC_FSL_UTILS - select SND_SOC_IMX_PCM_FIQ help Say Y if you want to add support for the ES8328 audio codec connected via SSI/I2S over either SPI or I2C. -- GitLab From 4f37b504768c952b64bc9469a2d579c7597590f2 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Tue, 19 Aug 2014 10:51:04 +0400 Subject: [PATCH 0914/9167] libata: Use dev_name() for request_irq() to distinguish devices Use dev_name() instead of driver name for request_irq(). This will help to distinguish between multiple identical devices. Before: CPU0 5: 34425 clps711x-intc 5 pata_of_platform 6: 6778 clps711x-intc 6 pata_of_platform After: CPU0 5: 2182 clps711x-intc 5 20000000.ide 6: 11024 clps711x-intc 6 20100000.ide Signed-off-by: Alexander Shiyan Signed-off-by: Tejun Heo --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index dbdc5d32343f..782d126cf191 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6227,7 +6227,7 @@ int ata_host_activate(struct ata_host *host, int irq, } rc = devm_request_irq(host->dev, irq, irq_handler, irq_flags, - dev_driver_string(host->dev), host); + dev_name(host->dev), host); if (rc) return rc; -- GitLab From 81c7cfd1b22a0ee5e40efef72ec2cd17dbf12e6d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:18 +0200 Subject: [PATCH 0915/9167] ASoC: Move debugfs registration to the component level The debugfs registration is mostly identical between platforms and CODECs. This patches consolidates the two implementations at the component level. Unfortunately there are still a couple of CODEC specific debugfs files that are related to legacy ASoC IO that need to be registered. For this a new callback is added to the component struct that will be initialized when a CODEC is registered and will be used to register the CODEC specific files. Once there are no drivers left using legacy IO this can be removed again. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 20 +++++-- sound/soc/soc-core.c | 122 ++++++++++++++++++------------------------- 2 files changed, 67 insertions(+), 75 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index be6ecae247b0..0ab8b1e4a5d2 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -728,9 +728,24 @@ struct snd_soc_component { struct mutex io_mutex; +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_root; +#endif + + /* + * DO NOT use any of the fields below in drivers, they are temporary and + * are going to be removed again soon. If you use them in driver code the + * driver will be marked as BROKEN when these fields are removed. + */ + /* Don't use these, use snd_soc_component_get_dapm() */ struct snd_soc_dapm_context dapm; struct snd_soc_dapm_context *dapm_ptr; + +#ifdef CONFIG_DEBUG_FS + void (*init_debugfs)(struct snd_soc_component *component); + const char *debugfs_prefix; +#endif }; /* SoC Audio Codec device */ @@ -766,7 +781,6 @@ struct snd_soc_codec { struct snd_soc_dapm_context dapm; #ifdef CONFIG_DEBUG_FS - struct dentry *debugfs_codec_root; struct dentry *debugfs_reg; #endif }; @@ -879,10 +893,6 @@ struct snd_soc_platform { struct list_head list; struct snd_soc_component component; - -#ifdef CONFIG_DEBUG_FS - struct dentry *debugfs_platform_root; -#endif }; struct snd_soc_dai_link { diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d4bfd4a9076f..79371a77f324 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -270,79 +270,56 @@ static const struct file_operations codec_reg_fops = { .llseek = default_llseek, }; -static struct dentry *soc_debugfs_create_dir(struct dentry *parent, - const char *fmt, ...) +static void soc_init_component_debugfs(struct snd_soc_component *component) { - struct dentry *de; - va_list ap; - char *s; + if (component->debugfs_prefix) { + char *name; - va_start(ap, fmt); - s = kvasprintf(GFP_KERNEL, fmt, ap); - va_end(ap); + name = kasprintf(GFP_KERNEL, "%s:%s", + component->debugfs_prefix, component->name); + if (name) { + component->debugfs_root = debugfs_create_dir(name, + component->card->debugfs_card_root); + kfree(name); + } + } else { + component->debugfs_root = debugfs_create_dir(component->name, + component->card->debugfs_card_root); + } - if (!s) - return NULL; + if (!component->debugfs_root) { + dev_warn(component->dev, + "ASoC: Failed to create component debugfs directory\n"); + return; + } - de = debugfs_create_dir(s, parent); - kfree(s); + snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component), + component->debugfs_root); - return de; + if (component->init_debugfs) + component->init_debugfs(component); } -static void soc_init_codec_debugfs(struct snd_soc_codec *codec) +static void soc_cleanup_component_debugfs(struct snd_soc_component *component) { - struct dentry *debugfs_card_root = codec->component.card->debugfs_card_root; + debugfs_remove_recursive(component->debugfs_root); +} - codec->debugfs_codec_root = soc_debugfs_create_dir(debugfs_card_root, - "codec:%s", - codec->component.name); - if (!codec->debugfs_codec_root) { - dev_warn(codec->dev, - "ASoC: Failed to create codec debugfs directory\n"); - return; - } +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->debugfs_codec_root, + debugfs_create_bool("cache_sync", 0444, codec->component.debugfs_root, &codec->cache_sync); - debugfs_create_bool("cache_only", 0444, codec->debugfs_codec_root, + debugfs_create_bool("cache_only", 0444, codec->component.debugfs_root, &codec->cache_only); codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, - codec->debugfs_codec_root, + codec->component.debugfs_root, codec, &codec_reg_fops); if (!codec->debugfs_reg) dev_warn(codec->dev, "ASoC: Failed to create codec register debugfs file\n"); - - snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); -} - -static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) -{ - debugfs_remove_recursive(codec->debugfs_codec_root); -} - -static void soc_init_platform_debugfs(struct snd_soc_platform *platform) -{ - struct dentry *debugfs_card_root = platform->component.card->debugfs_card_root; - - platform->debugfs_platform_root = soc_debugfs_create_dir(debugfs_card_root, - "platform:%s", - platform->component.name); - if (!platform->debugfs_platform_root) { - dev_warn(platform->dev, - "ASoC: Failed to create platform debugfs directory\n"); - return; - } - - snd_soc_dapm_debugfs_init(&platform->component.dapm, - platform->debugfs_platform_root); -} - -static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform) -{ - debugfs_remove_recursive(platform->debugfs_platform_root); } static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, @@ -474,19 +451,15 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card) #else -static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) -{ -} +#define soc_init_codec_debugfs NULL -static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) +static inline void soc_init_component_debugfs( + struct snd_soc_component *component) { } -static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform) -{ -} - -static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform) +static inline void soc_cleanup_component_debugfs( + struct snd_soc_component *component) { } @@ -1026,7 +999,7 @@ static int soc_remove_platform(struct snd_soc_platform *platform) /* Make sure all DAPM widgets are freed */ snd_soc_dapm_free(&platform->component.dapm); - soc_cleanup_platform_debugfs(platform); + soc_cleanup_component_debugfs(&platform->component); platform->probed = 0; module_put(platform->dev->driver->owner); @@ -1046,7 +1019,7 @@ static void soc_remove_codec(struct snd_soc_codec *codec) /* Make sure all DAPM widgets are freed */ snd_soc_dapm_free(&codec->dapm); - soc_cleanup_codec_debugfs(codec); + soc_cleanup_component_debugfs(&codec->component); codec->probed = 0; list_del(&codec->card_list); module_put(codec->dev->driver->owner); @@ -1187,7 +1160,7 @@ static int soc_probe_codec(struct snd_soc_card *card, if (!try_module_get(codec->dev->driver->owner)) return -ENODEV; - soc_init_codec_debugfs(codec); + soc_init_component_debugfs(&codec->component); if (driver->dapm_widgets) { ret = snd_soc_dapm_new_controls(&codec->dapm, @@ -1242,7 +1215,7 @@ static int soc_probe_codec(struct snd_soc_card *card, return 0; err_probe: - soc_cleanup_codec_debugfs(codec); + soc_cleanup_component_debugfs(&codec->component); module_put(codec->dev->driver->owner); return ret; @@ -1262,7 +1235,7 @@ static int soc_probe_platform(struct snd_soc_card *card, if (!try_module_get(platform->dev->driver->owner)) return -ENODEV; - soc_init_platform_debugfs(platform); + soc_init_component_debugfs(&platform->component); if (driver->dapm_widgets) snd_soc_dapm_new_controls(&platform->component.dapm, @@ -1302,7 +1275,7 @@ static int soc_probe_platform(struct snd_soc_card *card, return 0; err_probe: - soc_cleanup_platform_debugfs(platform); + soc_cleanup_component_debugfs(&platform->component); module_put(platform->dev->driver->owner); return ret; @@ -4266,6 +4239,10 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, if (platform_drv->read) platform->component.read = snd_soc_platform_drv_read; +#ifdef CONFIG_DEBUG_FS + platform->component.debugfs_prefix = "platform"; +#endif + mutex_lock(&client_mutex); snd_soc_component_add_unlocked(&platform->component); list_add(&platform->list, &platform_list); @@ -4455,6 +4432,11 @@ int snd_soc_register_codec(struct device *dev, 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; + codec->component.debugfs_prefix = "codec"; +#endif + if (!codec->component.write) { if (codec_drv->get_regmap) regmap = codec_drv->get_regmap(dev); -- GitLab From f1d45cc3ae96a6173129b2c164c216272faa5fc0 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:19 +0200 Subject: [PATCH 0916/9167] ASoC: Consolidate platform and CODEC probe/remove The platform and CODEC probe and remove code is now largely identical. This patch consolidates it at the component level. The resulting code is slightly larger due to all the boiler plate code setting up the indirection for the table based control and DAPM registration. Once all drivers have been update to no longer use the snd_soc_codec_driver and snd_soc_platform_driver specific fields for this the indirection can be removed again. This patch contains two noteworthy hacks that are only meant to be temporary to be able to update drivers and the core in separate incremental patches. The first hack is related to that some DPCM platforms expect that the DAPM widgets for the DAIs of a snd_soc_component are created in the DAPM context of the snd_soc_platform that has the same parent device. For handling this the steal_sibling_dai_widgets attribute is introduced. It gets set for snd_soc_platforms that register DAPM elements. When creating the DAI widgets for a component this flag is checked and if it is found on one of the siblings the component will not create any DAI widgets in its own DAPM context. If the attribute is set on a platform it will look for siblings components and create DAI widgets for them in its own context. The fix for this will be to update the offending drivers to only register a single component rather than two. The second hack deals with the fact that the ASoC card suspend and resume code still needs a list of CODECs that have been registered for the card. To handle this the generic probe and remove path have a check to see if the component is CODEC and if yes add/remove it to the card's CODEC list. While it is possible to clean up the suspend/resume code to not need the CODEC list anymore this is a bit of a chicken and egg problem since it will become easier to clean up the suspend/resume code once there is a unified component layer. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 27 ++- sound/soc/soc-core.c | 335 +++++++++++++------------- sound/soc/soc-generic-dmaengine-pcm.c | 4 +- 3 files changed, 194 insertions(+), 172 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0ab8b1e4a5d2..22543acfae4b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -697,6 +697,10 @@ struct snd_soc_component_driver { void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type, int subseq); int (*stream_event)(struct snd_soc_component *, int event); + + /* probe ordering - for components with runtime dependencies */ + int probe_order; + int remove_order; }; struct snd_soc_component { @@ -710,6 +714,7 @@ struct snd_soc_component { unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ unsigned int registered_as_component:1; + unsigned int probed:1; struct list_head list; @@ -742,6 +747,18 @@ struct snd_soc_component { struct snd_soc_dapm_context dapm; struct snd_soc_dapm_context *dapm_ptr; + const struct snd_kcontrol_new *controls; + unsigned int num_controls; + const struct snd_soc_dapm_widget *dapm_widgets; + unsigned int num_dapm_widgets; + const struct snd_soc_dapm_route *dapm_routes; + unsigned int num_dapm_routes; + bool steal_sibling_dai_widgets; + struct snd_soc_codec *codec; + + int (*probe)(struct snd_soc_component *); + void (*remove)(struct snd_soc_component *); + #ifdef CONFIG_DEBUG_FS void (*init_debugfs)(struct snd_soc_component *component); const char *debugfs_prefix; @@ -761,7 +778,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 probed:1; /* Codec has been probed */ 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 */ @@ -827,10 +843,6 @@ struct snd_soc_codec_driver { enum snd_soc_dapm_type, int); bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */ - - /* probe ordering - for components with runtime dependencies */ - int probe_order; - int remove_order; }; /* SoC platform interface */ @@ -867,10 +879,6 @@ struct snd_soc_platform_driver { /* platform stream compress ops */ const struct snd_compr_ops *compr_ops; - /* probe ordering - for components with runtime dependencies */ - int probe_order; - int remove_order; - /* platform IO - used for platform DAPM */ unsigned int (*read)(struct snd_soc_platform *, unsigned int); int (*write)(struct snd_soc_platform *, unsigned int, unsigned int); @@ -888,7 +896,6 @@ struct snd_soc_platform { const struct snd_soc_platform_driver *driver; unsigned int suspended:1; /* platform is suspended */ - unsigned int probed:1; struct list_head list; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 79371a77f324..b833cc6fd86d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -985,44 +985,20 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) return 0; } -static int soc_remove_platform(struct snd_soc_platform *platform) +static void soc_remove_component(struct snd_soc_component *component) { - int ret; - - if (platform->driver->remove) { - ret = platform->driver->remove(platform); - if (ret < 0) - dev_err(platform->dev, "ASoC: failed to remove %d\n", - ret); - } - - /* Make sure all DAPM widgets are freed */ - snd_soc_dapm_free(&platform->component.dapm); - - soc_cleanup_component_debugfs(&platform->component); - platform->probed = 0; - module_put(platform->dev->driver->owner); - - return 0; -} - -static void soc_remove_codec(struct snd_soc_codec *codec) -{ - int err; + /* This is a HACK and will be removed soon */ + if (component->codec) + list_del(&component->codec->card_list); - if (codec->driver->remove) { - err = codec->driver->remove(codec); - if (err < 0) - dev_err(codec->dev, "ASoC: failed to remove %d\n", err); - } + if (component->remove) + component->remove(component); - /* Make sure all DAPM widgets are freed */ - snd_soc_dapm_free(&codec->dapm); + snd_soc_dapm_free(snd_soc_component_get_dapm(component)); - soc_cleanup_component_debugfs(&codec->component); - codec->probed = 0; - list_del(&codec->card_list); - module_put(codec->dev->driver->owner); + soc_cleanup_component_debugfs(component); + component->probed = 0; + module_put(component->dev->driver->owner); } static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order) @@ -1086,25 +1062,24 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num, int i; /* remove the platform */ - if (platform && platform->probed && - platform->driver->remove_order == order) { - soc_remove_platform(platform); - } + if (platform && platform->component.probed && + platform->component.driver->remove_order == order) + soc_remove_component(&platform->component); /* remove the CODEC-side CODEC */ for (i = 0; i < rtd->num_codecs; i++) { codec = rtd->codec_dais[i]->codec; - if (codec && codec->probed && - codec->driver->remove_order == order) - soc_remove_codec(codec); + if (codec && codec->component.probed && + codec->component.driver->remove_order == order) + soc_remove_component(&codec->component); } /* remove any CPU-side CODEC */ if (cpu_dai) { codec = cpu_dai->codec; - if (codec && codec->probed && - codec->driver->remove_order == order) - soc_remove_codec(codec); + if (codec && codec->component.probed && + codec->component.driver->remove_order == order) + soc_remove_component(&codec->component); } } @@ -1146,137 +1121,108 @@ static void soc_set_name_prefix(struct snd_soc_card *card, } } -static int soc_probe_codec(struct snd_soc_card *card, - struct snd_soc_codec *codec) +static int soc_probe_component(struct snd_soc_card *card, + struct snd_soc_component *component) { - int ret = 0; - const struct snd_soc_codec_driver *driver = codec->driver; + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_component *dai_component, *component2; struct snd_soc_dai *dai; + int ret; - codec->component.card = card; - codec->dapm.card = card; - soc_set_name_prefix(card, &codec->component); + component->card = card; + dapm->card = card; + soc_set_name_prefix(card, component); - if (!try_module_get(codec->dev->driver->owner)) + if (!try_module_get(component->dev->driver->owner)) return -ENODEV; - soc_init_component_debugfs(&codec->component); + soc_init_component_debugfs(component); - if (driver->dapm_widgets) { - ret = snd_soc_dapm_new_controls(&codec->dapm, - driver->dapm_widgets, - driver->num_dapm_widgets); + if (component->dapm_widgets) { + ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets, + component->num_dapm_widgets); if (ret != 0) { - dev_err(codec->dev, + dev_err(component->dev, "Failed to create new controls %d\n", ret); goto err_probe; } } - /* Create DAPM widgets for each DAI stream */ - list_for_each_entry(dai, &codec->component.dai_list, list) { - ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); + /* + * This is rather ugly, but certain platforms expect that the DAPM + * widgets for the DAIs for components with the same parent device are + * created in the platforms DAPM context. Until that is fixed we need to + * keep this. + */ + if (component->steal_sibling_dai_widgets) { + dai_component = NULL; + list_for_each_entry(component2, &component_list, list) { + if (component == component2) + continue; - if (ret != 0) { - dev_err(codec->dev, - "Failed to create DAI widgets %d\n", ret); - goto err_probe; + if (component2->dev == component->dev && + !list_empty(&component2->dai_list)) { + dai_component = component2; + break; + } } - } - - codec->dapm.idle_bias_off = driver->idle_bias_off; - - if (driver->probe) { - ret = driver->probe(codec); - if (ret < 0) { - dev_err(codec->dev, - "ASoC: failed to probe CODEC %d\n", ret); - goto err_probe; + } else { + dai_component = component; + list_for_each_entry(component2, &component_list, list) { + if (component2->dev == component->dev && + component2->steal_sibling_dai_widgets) { + dai_component = NULL; + break; + } } - WARN(codec->dapm.idle_bias_off && - codec->dapm.bias_level != SND_SOC_BIAS_OFF, - "codec %s can not start from non-off bias with idle_bias_off==1\n", - codec->component.name); } - if (driver->controls) - snd_soc_add_codec_controls(codec, driver->controls, - driver->num_controls); - if (driver->dapm_routes) - snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, - driver->num_dapm_routes); - - /* mark codec as probed and add to card codec list */ - codec->probed = 1; - list_add(&codec->card_list, &card->codec_dev_list); - list_add(&codec->dapm.list, &card->dapm_list); - - return 0; - -err_probe: - soc_cleanup_component_debugfs(&codec->component); - module_put(codec->dev->driver->owner); - - return ret; -} - -static int soc_probe_platform(struct snd_soc_card *card, - struct snd_soc_platform *platform) -{ - int ret = 0; - const struct snd_soc_platform_driver *driver = platform->driver; - struct snd_soc_component *component; - struct snd_soc_dai *dai; - - platform->component.card = card; - platform->component.dapm.card = card; - - if (!try_module_get(platform->dev->driver->owner)) - return -ENODEV; - - soc_init_component_debugfs(&platform->component); - - if (driver->dapm_widgets) - snd_soc_dapm_new_controls(&platform->component.dapm, - driver->dapm_widgets, driver->num_dapm_widgets); - - /* Create DAPM widgets for each DAI stream */ - list_for_each_entry(component, &component_list, list) { - if (component->dev != platform->dev) - continue; - list_for_each_entry(dai, &component->dai_list, list) - snd_soc_dapm_new_dai_widgets(&platform->component.dapm, - dai); + if (dai_component) { + list_for_each_entry(dai, &dai_component->dai_list, list) { + snd_soc_dapm_new_dai_widgets(dapm, dai); + if (ret != 0) { + dev_err(component->dev, + "Failed to create DAI widgets %d\n", + ret); + goto err_probe; + } + } } - platform->component.dapm.idle_bias_off = 1; - - if (driver->probe) { - ret = driver->probe(platform); + if (component->probe) { + ret = component->probe(component); if (ret < 0) { - dev_err(platform->dev, - "ASoC: failed to probe platform %d\n", ret); + dev_err(component->dev, + "ASoC: failed to probe component %d\n", ret); goto err_probe; } + + WARN(dapm->idle_bias_off && + dapm->bias_level != SND_SOC_BIAS_OFF, + "codec %s can not start from non-off bias with idle_bias_off==1\n", + component->name); } - if (driver->controls) - snd_soc_add_platform_controls(platform, driver->controls, - driver->num_controls); - if (driver->dapm_routes) - snd_soc_dapm_add_routes(&platform->component.dapm, - driver->dapm_routes, driver->num_dapm_routes); + if (component->controls) + snd_soc_add_component_controls(component, component->controls, + component->num_controls); + if (component->dapm_routes) + snd_soc_dapm_add_routes(dapm, component->dapm_routes, + component->num_dapm_routes); - /* mark platform as probed and add to card platform list */ - platform->probed = 1; - list_add(&platform->component.dapm.list, &card->dapm_list); + component->probed = 1; + list_add(&dapm->list, &card->dapm_list); + + /* This is a HACK and will be removed soon */ + if (component->codec) + list_add(&component->codec->card_list, &card->codec_dev_list); return 0; err_probe: - soc_cleanup_component_debugfs(&platform->component); - module_put(platform->dev->driver->owner); + soc_cleanup_component_debugfs(component); + module_put(component->dev->driver->owner); return ret; } @@ -1334,33 +1280,36 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, int order) { struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_platform *platform = rtd->platform; + struct snd_soc_component *component; int i, ret; /* probe the CPU-side component, if it is a CODEC */ - if (cpu_dai->codec && - !cpu_dai->codec->probed && - cpu_dai->codec->driver->probe_order == order) { - ret = soc_probe_codec(card, cpu_dai->codec); - if (ret < 0) - return ret; + if (rtd->cpu_dai->codec) { + component = &rtd->cpu_dai->codec->component; + if (!component->probed && + component->driver->probe_order == order) { + ret = soc_probe_component(card, component); + if (ret < 0) + return ret; + } } /* probe the CODEC-side components */ for (i = 0; i < rtd->num_codecs; i++) { - if (!rtd->codec_dais[i]->codec->probed && - rtd->codec_dais[i]->codec->driver->probe_order == order) { - ret = soc_probe_codec(card, rtd->codec_dais[i]->codec); + component = &rtd->codec_dais[i]->codec->component; + if (!component->probed && + component->driver->probe_order == order) { + ret = soc_probe_component(card, component); if (ret < 0) return ret; } } /* probe the platform */ - if (!platform->probed && - platform->driver->probe_order == order) { - ret = soc_probe_platform(card, platform); + if (!platform->component.probed && + platform->component.driver->probe_order == order) { + ret = soc_probe_component(card, &platform->component); if (ret < 0) return ret; } @@ -1647,12 +1596,12 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; int ret; - if (rtd->codec->probed) { + if (rtd->codec->component.probed) { dev_err(rtd->codec->dev, "ASoC: codec already probed\n"); return -EBUSY; } - ret = soc_probe_codec(card, rtd->codec); + ret = soc_probe_component(card, &rtd->codec->component); if (ret < 0) return ret; @@ -1681,8 +1630,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) rtd->dev_registered = 0; } - if (codec && codec->probed) - soc_remove_codec(codec); + if (codec && codec->component.probed) + soc_remove_component(&codec->component); } static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) @@ -4198,6 +4147,20 @@ void snd_soc_unregister_component(struct device *dev) } EXPORT_SYMBOL_GPL(snd_soc_unregister_component); +static int snd_soc_platform_drv_probe(struct snd_soc_component *component) +{ + struct snd_soc_platform *platform = snd_soc_component_to_platform(component); + + return platform->driver->probe(platform); +} + +static void snd_soc_platform_drv_remove(struct snd_soc_component *component) +{ + struct snd_soc_platform *platform = snd_soc_component_to_platform(component); + + platform->driver->remove(platform); +} + static int snd_soc_platform_drv_write(struct snd_soc_component *component, unsigned int reg, unsigned int val) { @@ -4234,6 +4197,24 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, platform->dev = dev; platform->driver = platform_drv; + if (platform_drv->controls) { + platform->component.controls = platform_drv->controls; + platform->component.num_controls = platform_drv->num_controls; + } + if (platform_drv->dapm_widgets) { + platform->component.dapm_widgets = platform_drv->dapm_widgets; + platform->component.num_dapm_widgets = platform_drv->num_dapm_widgets; + platform->component.steal_sibling_dai_widgets = true; + } + if (platform_drv->dapm_routes) { + platform->component.dapm_routes = platform_drv->dapm_routes; + platform->component.num_dapm_routes = platform_drv->num_dapm_routes; + } + + if (platform_drv->probe) + platform->component.probe = snd_soc_platform_drv_probe; + if (platform_drv->remove) + platform->component.remove = snd_soc_platform_drv_remove; if (platform_drv->write) platform->component.write = snd_soc_platform_drv_write; if (platform_drv->read) @@ -4363,6 +4344,20 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream) stream->formats |= codec_format_map[i]; } +static int snd_soc_codec_drv_probe(struct snd_soc_component *component) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + return codec->driver->probe(codec); +} + +static void snd_soc_codec_drv_remove(struct snd_soc_component *component) +{ + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + + codec->driver->remove(codec); +} + static int snd_soc_codec_drv_write(struct snd_soc_component *component, unsigned int reg, unsigned int val) { @@ -4411,12 +4406,30 @@ int snd_soc_register_codec(struct device *dev, return -ENOMEM; codec->component.dapm_ptr = &codec->dapm; + codec->component.codec = codec; ret = snd_soc_component_initialize(&codec->component, &codec_drv->component_driver, dev); if (ret) goto err_free; + if (codec_drv->controls) { + codec->component.controls = codec_drv->controls; + codec->component.num_controls = codec_drv->num_controls; + } + if (codec_drv->dapm_widgets) { + codec->component.dapm_widgets = codec_drv->dapm_widgets; + codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets; + } + if (codec_drv->dapm_routes) { + codec->component.dapm_routes = codec_drv->dapm_routes; + codec->component.num_dapm_routes = codec_drv->num_dapm_routes; + } + + if (codec_drv->probe) + codec->component.probe = snd_soc_codec_drv_probe; + if (codec_drv->remove) + codec->component.remove = snd_soc_codec_drv_remove; if (codec_drv->write) codec->component.write = snd_soc_codec_drv_write; if (codec_drv->read) diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index 6307f85e871b..b329b84bc5af 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -336,10 +336,12 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = { }; static const struct snd_soc_platform_driver dmaengine_pcm_platform = { + .component_driver = { + .probe_order = SND_SOC_COMP_ORDER_LATE, + }, .ops = &dmaengine_pcm_ops, .pcm_new = dmaengine_pcm_new, .pcm_free = dmaengine_pcm_free, - .probe_order = SND_SOC_COMP_ORDER_LATE, }; static const char * const dmaengine_pcm_dma_channel_names[] = { -- GitLab From 93c3ce76ccced3a8718149e8734ccaa931e9a1f1 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:20 +0200 Subject: [PATCH 0917/9167] ASoC: Make rtd->codec optional There are some place in the ASoC core that expect rtd->codec to be non NULL (mainly CODEC specific sysfs files). With componentization going forward rtd->codec might be NULL in some cases. This patch prepares the core for this by not registering CODEC specific sysfs files if rtd->codec is NULL. sysfs file removal does not need to be conditionalized as it handles the removal of non-existing files just fine. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b833cc6fd86d..1c705c28389c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1261,17 +1261,21 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd, } rtd->dev_registered = 1; - /* add DAPM sysfs entries for this codec */ - ret = snd_soc_dapm_sys_add(rtd->dev); - if (ret < 0) - dev_err(rtd->dev, - "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); + if (rtd->codec) { + /* add DAPM sysfs entries for this codec */ + ret = snd_soc_dapm_sys_add(rtd->dev); + if (ret < 0) + dev_err(rtd->dev, + "ASoC: failed to add codec dapm sysfs entries: %d\n", + ret); - /* add codec sysfs entries */ - ret = device_create_file(rtd->dev, &dev_attr_codec_reg); - if (ret < 0) - dev_err(rtd->dev, - "ASoC: failed to add codec sysfs files: %d\n", ret); + /* add codec sysfs entries */ + ret = device_create_file(rtd->dev, &dev_attr_codec_reg); + if (ret < 0) + dev_err(rtd->dev, + "ASoC: failed to add codec sysfs files: %d\n", + ret); + } return 0; } -- GitLab From 61aca5646b736a794d40de29a197144db3f0c5ba Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:21 +0200 Subject: [PATCH 0918/9167] ASoC: Add component level probe/remove support Now that we have a unified probe and remove path make sure to call them for all components. soc_{probe,remove}_component are responsible for setting up the DAPM context for the component, initialize the component prefix, manage the debugfs entries as well as do the registration of table based controls and DAPM elements. They also call the component drivers probe and remove callbacks. This patch makes these things available for generic snd_soc_component drivers rather than only having them for snd_soc_codec and snd_soc_platform drivers. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 11 +++++++++++ sound/soc/soc-core.c | 42 ++++++++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 22543acfae4b..4a223a895f00 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -690,6 +690,17 @@ struct snd_soc_compr_ops { struct snd_soc_component_driver { const char *name; + /* Default control and setup, added after probe() is run */ + const struct snd_kcontrol_new *controls; + unsigned int num_controls; + const struct snd_soc_dapm_widget *dapm_widgets; + unsigned int num_dapm_widgets; + const struct snd_soc_dapm_route *dapm_routes; + unsigned int num_dapm_routes; + + int (*probe)(struct snd_soc_component *); + void (*remove)(struct snd_soc_component *); + /* DT */ int (*of_xlate_dai_name)(struct snd_soc_component *component, struct of_phandle_args *args, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1c705c28389c..08fd85e8c751 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1058,7 +1058,7 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num, struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_platform *platform = rtd->platform; - struct snd_soc_codec *codec; + struct snd_soc_component *component; int i; /* remove the platform */ @@ -1068,18 +1068,17 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num, /* remove the CODEC-side CODEC */ for (i = 0; i < rtd->num_codecs; i++) { - codec = rtd->codec_dais[i]->codec; - if (codec && codec->component.probed && - codec->component.driver->remove_order == order) - soc_remove_component(&codec->component); + component = rtd->codec_dais[i]->component; + if (component->probed && + component->driver->remove_order == order) + soc_remove_component(component); } /* remove any CPU-side CODEC */ if (cpu_dai) { - codec = cpu_dai->codec; - if (codec && codec->component.probed && - codec->component.driver->remove_order == order) - soc_remove_component(&codec->component); + if (cpu_dai->component->probed && + cpu_dai->component->driver->remove_order == order) + soc_remove_component(cpu_dai->component); } } @@ -1289,19 +1288,17 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, int i, ret; /* probe the CPU-side component, if it is a CODEC */ - if (rtd->cpu_dai->codec) { - component = &rtd->cpu_dai->codec->component; - if (!component->probed && - component->driver->probe_order == order) { - ret = soc_probe_component(card, component); - if (ret < 0) - return ret; - } + component = rtd->cpu_dai->component; + if (!component->probed && + component->driver->probe_order == order) { + ret = soc_probe_component(card, component); + if (ret < 0) + return ret; } /* probe the CODEC-side components */ for (i = 0; i < rtd->num_codecs; i++) { - component = &rtd->codec_dais[i]->codec->component; + component = rtd->codec_dais[i]->component; if (!component->probed && component->driver->probe_order == order) { ret = soc_probe_component(card, component); @@ -4042,6 +4039,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, component->dev = dev; component->driver = driver; + component->probe = component->driver->probe; + component->remove = component->driver->remove; if (!component->dapm_ptr) component->dapm_ptr = &component->dapm; @@ -4055,6 +4054,13 @@ static int snd_soc_component_initialize(struct snd_soc_component *component, if (driver->stream_event) dapm->stream_event = snd_soc_component_stream_event; + component->controls = driver->controls; + component->num_controls = driver->num_controls; + component->dapm_widgets = driver->dapm_widgets; + component->num_dapm_widgets = driver->num_dapm_widgets; + component->dapm_routes = driver->dapm_routes; + component->num_dapm_routes = driver->num_dapm_routes; + INIT_LIST_HEAD(&component->dai_list); mutex_init(&component->io_mutex); -- GitLab From 65d9361f0cb50a20641802ee3075145d72e4409c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:22 +0200 Subject: [PATCH 0919/9167] ASoC: Move AUX dev support to the component level This patch makes it possible to register arbitrary components as a AUX dev for a card. This was previously only possible for CODEC components. With componentization having made it possible for components to have DAPM contexts and controls there is no reason why AUX devs should be artificially limited to snd_soc_codec devices. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-core.c | 48 +++++++++++++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 4a223a895f00..fbc2ad840244 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1140,6 +1140,7 @@ struct snd_soc_pcm_runtime { struct snd_soc_platform *platform; struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; + struct snd_soc_component *component; /* Only valid for AUX dev rtds */ struct snd_soc_dai **codec_dais; unsigned int num_codecs; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 08fd85e8c751..08c04f4c7e62 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -860,6 +860,23 @@ EXPORT_SYMBOL_GPL(snd_soc_resume); static const struct snd_soc_dai_ops null_dai_ops = { }; +static struct snd_soc_component *soc_find_component( + const struct device_node *of_node, const char *name) +{ + struct snd_soc_component *component; + + list_for_each_entry(component, &component_list, list) { + if (of_node) { + if (component->dev->of_node == of_node) + return component; + } else if (strcmp(component->name, name) == 0) { + return component; + } + } + + return NULL; +} + static struct snd_soc_codec *soc_find_codec( const struct device_node *codec_of_node, const char *codec_name) @@ -1577,17 +1594,24 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num) { struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; - const char *codecname = aux_dev->codec_name; + const char *name = aux_dev->codec_name; - rtd->codec = soc_find_codec(aux_dev->codec_of_node, codecname); - if (!rtd->codec) { + rtd->component = soc_find_component(aux_dev->codec_of_node, name); + if (!rtd->component) { if (aux_dev->codec_of_node) - codecname = of_node_full_name(aux_dev->codec_of_node); + name = of_node_full_name(aux_dev->codec_of_node); - dev_err(card->dev, "ASoC: %s not registered\n", codecname); + dev_err(card->dev, "ASoC: %s not registered\n", name); return -EPROBE_DEFER; } + /* + * Some places still reference rtd->codec, so we have to keep that + * initialized if the component is a CODEC. Once all those references + * have been removed, this code can be removed as well. + */ + rtd->codec = rtd->component->codec; + return 0; } @@ -1597,18 +1621,18 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; int ret; - if (rtd->codec->component.probed) { - dev_err(rtd->codec->dev, "ASoC: codec already probed\n"); + if (rtd->component->probed) { + dev_err(rtd->dev, "ASoC: codec already probed\n"); return -EBUSY; } - ret = soc_probe_component(card, &rtd->codec->component); + ret = soc_probe_component(card, rtd->component); if (ret < 0) return ret; /* do machine specific initialization */ if (aux_dev->init) { - ret = aux_dev->init(&rtd->codec->dapm); + ret = aux_dev->init(snd_soc_component_get_dapm(rtd->component)); if (ret < 0) { dev_err(card->dev, "ASoC: failed to init %s: %d\n", aux_dev->name, ret); @@ -1622,7 +1646,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) static void soc_remove_aux_dev(struct snd_soc_card *card, int num) { struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; - struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_component *component = rtd->component; /* unregister the rtd device */ if (rtd->dev_registered) { @@ -1631,8 +1655,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) rtd->dev_registered = 0; } - if (codec && codec->component.probed) - soc_remove_component(&codec->component); + if (component && component->probed) + soc_remove_component(component); } static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) -- GitLab From 57bf772687700e206c760ba2e4097f78bde97887 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:23 +0200 Subject: [PATCH 0920/9167] ASoC: Pass component instead of DAPM context to AUX dev init callback Given that the component is the containing structure it makes more sense to pass the component rather than the DAPM context to the AUX dev init callback. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 2 +- sound/soc/samsung/speyside.c | 6 ++++-- sound/soc/soc-core.c | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index fbc2ad840244..3a0031e1f9b4 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1022,7 +1022,7 @@ struct snd_soc_aux_dev { const struct device_node *codec_of_node; /* codec/machine specific init - e.g. add machine controls */ - int (*init)(struct snd_soc_dapm_context *dapm); + int (*init)(struct snd_soc_component *component); }; /* SoC card */ diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 9902efcb8ea1..a05482651aae 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -228,10 +228,12 @@ static struct snd_soc_dai_link speyside_dai[] = { }, }; -static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm) +static int speyside_wm9081_init(struct snd_soc_component *component) { + struct snd_soc_codec *codec = snd_soc_component_to_codec(component); + /* At any time the WM9081 is active it will have this clock */ - return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0, + return snd_soc_codec_set_sysclk(codec, WM9081_SYSCLK_MCLK, 0, MCLK_AUDIO_RATE, 0); } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 08c04f4c7e62..4393bc33d3af 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1632,7 +1632,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) /* do machine specific initialization */ if (aux_dev->init) { - ret = aux_dev->init(snd_soc_component_get_dapm(rtd->component)); + ret = aux_dev->init(rtd->component); if (ret < 0) { dev_err(card->dev, "ASoC: failed to init %s: %d\n", aux_dev->name, ret); -- GitLab From 70090bbb8b7d7da7a6f64969b43a61c493c560ff Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:24 +0200 Subject: [PATCH 0921/9167] ASoC: Move component->probed check into soc_{remove,probe}_component() Having the check in a centralized place makes the code a bit cleaner and shorter. Note: There is a slight semantic change in this patch. soc_probe_aux_dev() will no longer return -EBUSY if the AUX dev has already been probed before. This is fine though since it will simply do nothing in that case and return success. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4393bc33d3af..2fbfbfca48dc 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1004,6 +1004,9 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) static void soc_remove_component(struct snd_soc_component *component) { + if (!component->probed) + return; + /* This is a HACK and will be removed soon */ if (component->codec) list_del(&component->codec->card_list); @@ -1079,22 +1082,19 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num, int i; /* remove the platform */ - if (platform && platform->component.probed && - platform->component.driver->remove_order == order) + if (platform && platform->component.driver->remove_order == order) soc_remove_component(&platform->component); /* remove the CODEC-side CODEC */ for (i = 0; i < rtd->num_codecs; i++) { component = rtd->codec_dais[i]->component; - if (component->probed && - component->driver->remove_order == order) + if (component->driver->remove_order == order) soc_remove_component(component); } /* remove any CPU-side CODEC */ if (cpu_dai) { - if (cpu_dai->component->probed && - cpu_dai->component->driver->remove_order == order) + if (cpu_dai->component->driver->remove_order == order) soc_remove_component(cpu_dai->component); } } @@ -1145,6 +1145,9 @@ static int soc_probe_component(struct snd_soc_card *card, struct snd_soc_dai *dai; int ret; + if (component->probed) + return 0; + component->card = card; dapm->card = card; soc_set_name_prefix(card, component); @@ -1306,8 +1309,7 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, /* probe the CPU-side component, if it is a CODEC */ component = rtd->cpu_dai->component; - if (!component->probed && - component->driver->probe_order == order) { + if (component->driver->probe_order == order) { ret = soc_probe_component(card, component); if (ret < 0) return ret; @@ -1316,8 +1318,7 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, /* probe the CODEC-side components */ for (i = 0; i < rtd->num_codecs; i++) { component = rtd->codec_dais[i]->component; - if (!component->probed && - component->driver->probe_order == order) { + if (component->driver->probe_order == order) { ret = soc_probe_component(card, component); if (ret < 0) return ret; @@ -1325,8 +1326,7 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, } /* probe the platform */ - if (!platform->component.probed && - platform->component.driver->probe_order == order) { + if (platform->component.driver->probe_order == order) { ret = soc_probe_component(card, &platform->component); if (ret < 0) return ret; @@ -1621,11 +1621,6 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; int ret; - if (rtd->component->probed) { - dev_err(rtd->dev, "ASoC: codec already probed\n"); - return -EBUSY; - } - ret = soc_probe_component(card, rtd->component); if (ret < 0) return ret; -- GitLab From ffbd7dd72bd3ad9bcae9190788c858e57f1e8e4e Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:25 +0200 Subject: [PATCH 0922/9167] ASoC: Cleanup DAI module reference counting Currently when a DAI has no CODEC associated to it the reference on the module containing the DAI driver is increased when the DAI is probed and decrease when the DAI is removed. For DAIs with CODECs the module reference count was already incremented when the CODEC is probed. Now that all components have their module reference count incremented when they are probed and all DAIs do have a component it is possible to remove the module reference counting on DAI probe and removal. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2fbfbfca48dc..4dc2876c06de 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1067,8 +1067,6 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) cpu_dai->name, err); } cpu_dai->probed = 0; - if (!cpu_dai->codec) - module_put(cpu_dai->dev->driver->owner); } } @@ -1422,18 +1420,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) /* probe the cpu_dai */ if (!cpu_dai->probed && cpu_dai->driver->probe_order == order) { - if (!cpu_dai->codec) { - if (!try_module_get(cpu_dai->dev->driver->owner)) - return -ENODEV; - } - 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); - module_put(cpu_dai->dev->driver->owner); return ret; } } -- GitLab From e60cd14f0bf6c004cd7032a24a036ba32d56e08a Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:26 +0200 Subject: [PATCH 0923/9167] ASoC: Consolidate CPU and CODEC DAI removal CPU and CODEC DAI works exactly the same way. There is already a helper function for CODEC DAI removal, use that one as well for CPU DAI removal. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4dc2876c06de..5f6f97874ca2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1021,28 +1021,27 @@ static void soc_remove_component(struct snd_soc_component *component) module_put(component->dev->driver->owner); } -static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order) +static void soc_remove_dai(struct snd_soc_dai *dai, int order) { int err; - if (codec_dai && codec_dai->probed && - codec_dai->driver->remove_order == order) { - if (codec_dai->driver->remove) { - err = codec_dai->driver->remove(codec_dai); + if (dai && dai->probed && + dai->driver->remove_order == order) { + if (dai->driver->remove) { + err = dai->driver->remove(dai); if (err < 0) - dev_err(codec_dai->dev, + dev_err(dai->dev, "ASoC: failed to remove %s: %d\n", - codec_dai->name, err); + dai->name, err); } - codec_dai->probed = 0; + dai->probed = 0; } } static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) { struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int i, err; + int i; /* unregister the rtd device */ if (rtd->dev_registered) { @@ -1054,20 +1053,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) /* remove the CODEC DAI */ for (i = 0; i < rtd->num_codecs; i++) - soc_remove_codec_dai(rtd->codec_dais[i], order); + soc_remove_dai(rtd->codec_dais[i], order); - /* remove the cpu_dai */ - if (cpu_dai && cpu_dai->probed && - cpu_dai->driver->remove_order == order) { - if (cpu_dai->driver->remove) { - err = cpu_dai->driver->remove(cpu_dai); - if (err < 0) - dev_err(cpu_dai->dev, - "ASoC: failed to remove %s: %d\n", - cpu_dai->name, err); - } - cpu_dai->probed = 0; - } + soc_remove_dai(rtd->cpu_dai, order); } static void soc_remove_link_components(struct snd_soc_card *card, int num, -- GitLab From 14621c7e5e72200ec021a7580121130ce7f2ff22 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:27 +0200 Subject: [PATCH 0924/9167] ASoC: Consolidate CPU and CODEC DAI lookup The lookup of CPU and CODEC DAIs is fairly similar and can easily be consolidated into a single helper function. There are two main differences in the current implementation of the CPU and CODEC DAI lookup: 1) CPU DAIs can be looked up by the DAI name alone and do not necessarily require a component name/of_node. 2) The CODEC DAI search only considers DAIs from CODEC components. For 1) the new helper function will allow to lookup DAIs without providing a component name or of_node, but since snd_soc_register_card() already rejects CODEC DAI link components without neither a of_node or a name we'll never get into the situation where we try to lookup a CODEC DAI without a name/of_node. For 2) the new helper function just always considers all components. Componentization is now at a point where it is possible to register a CODEC as a snd_soc_component rather than a snd_soc_codec, by considering DAIs from all components it is possible to use such a CODEC in a DAI link. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 72 ++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 53 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 5f6f97874ca2..140f43f91635 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -877,35 +877,23 @@ static struct snd_soc_component *soc_find_component( return NULL; } -static struct snd_soc_codec *soc_find_codec( - const struct device_node *codec_of_node, - const char *codec_name) +static struct snd_soc_dai *snd_soc_find_dai( + const struct snd_soc_dai_link_component *dlc) { - struct snd_soc_codec *codec; + struct snd_soc_component *component; + struct snd_soc_dai *dai; - list_for_each_entry(codec, &codec_list, list) { - if (codec_of_node) { - if (codec->dev->of_node != codec_of_node) - continue; - } else { - if (strcmp(codec->component.name, codec_name)) + /* Find CPU DAI from registered DAIs*/ + list_for_each_entry(component, &component_list, list) { + if (dlc->of_node && component->dev->of_node != dlc->of_node) + continue; + if (dlc->name && strcmp(dev_name(component->dev), dlc->name)) + continue; + list_for_each_entry(dai, &component->dai_list, list) { + if (dlc->dai_name && strcmp(dai->name, dlc->dai_name)) continue; - } - - return codec; - } - - return NULL; -} - -static struct snd_soc_dai *soc_find_codec_dai(struct snd_soc_codec *codec, - const char *codec_dai_name) -{ - struct snd_soc_dai *codec_dai; - list_for_each_entry(codec_dai, &codec->component.dai_list, list) { - if (!strcmp(codec_dai->name, codec_dai_name)) { - return codec_dai; + return dai; } } @@ -916,33 +904,19 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; - struct snd_soc_component *component; struct snd_soc_dai_link_component *codecs = dai_link->codecs; + struct snd_soc_dai_link_component cpu_dai_component; struct snd_soc_dai **codec_dais = rtd->codec_dais; struct snd_soc_platform *platform; - struct snd_soc_dai *cpu_dai; const char *platform_name; int i; dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); - /* Find CPU DAI from registered DAIs*/ - list_for_each_entry(component, &component_list, list) { - if (dai_link->cpu_of_node && - component->dev->of_node != dai_link->cpu_of_node) - continue; - if (dai_link->cpu_name && - strcmp(dev_name(component->dev), dai_link->cpu_name)) - continue; - list_for_each_entry(cpu_dai, &component->dai_list, list) { - if (dai_link->cpu_dai_name && - strcmp(cpu_dai->name, dai_link->cpu_dai_name)) - continue; - - rtd->cpu_dai = cpu_dai; - } - } - + cpu_dai_component.name = dai_link->cpu_name; + cpu_dai_component.of_node = dai_link->cpu_of_node; + cpu_dai_component.dai_name = dai_link->cpu_dai_name; + rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component); if (!rtd->cpu_dai) { dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", dai_link->cpu_dai_name); @@ -953,15 +927,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) /* Find CODEC from registered CODECs */ for (i = 0; i < rtd->num_codecs; i++) { - struct snd_soc_codec *codec; - codec = soc_find_codec(codecs[i].of_node, codecs[i].name); - if (!codec) { - dev_err(card->dev, "ASoC: CODEC %s not registered\n", - codecs[i].name); - return -EPROBE_DEFER; - } - - codec_dais[i] = soc_find_codec_dai(codec, codecs[i].dai_name); + codec_dais[i] = snd_soc_find_dai(&codecs[i]); if (!codec_dais[i]) { dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", codecs[i].dai_name); -- GitLab From 886f5692253de1a9509f5cb708432b2157afb57c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:28 +0200 Subject: [PATCH 0925/9167] ASoC: Automatically initialize regmap for all components So far regmap is only automatically initialized for CODECs. Now that we have the infrastructure in place to let components have DAPM widgets and controls that want to use the generic regmap based IO also make sure to automatically initialize regmap for all components. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 3 --- sound/soc/soc-core.c | 35 +++++++++++++++++------------------ sound/soc/soc-io.c | 28 ---------------------------- 3 files changed, 17 insertions(+), 49 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 3a0031e1f9b4..8ebee30311e3 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1289,9 +1289,6 @@ 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); -int snd_soc_component_init_io(struct snd_soc_component *component, - struct regmap *regmap); - /* 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 140f43f91635..96f286643ca1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4032,8 +4032,23 @@ 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) +{ + 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; + } +} + static void snd_soc_component_add_unlocked(struct snd_soc_component *component) { + if (!component->write && !component->read) + snd_soc_component_init_regmap(component); + list_add(&component->list, &component_list); } @@ -4371,7 +4386,6 @@ int snd_soc_register_codec(struct device *dev, { struct snd_soc_codec *codec; struct snd_soc_dai *dai; - struct regmap *regmap; int ret, i; dev_dbg(dev, "codec register %s\n", dev_name(dev)); @@ -4425,23 +4439,8 @@ int snd_soc_register_codec(struct device *dev, codec->component.debugfs_prefix = "codec"; #endif - if (!codec->component.write) { - if (codec_drv->get_regmap) - regmap = codec_drv->get_regmap(dev); - else - regmap = dev_get_regmap(dev, NULL); - - if (regmap) { - ret = snd_soc_component_init_io(&codec->component, - regmap); - if (ret) { - dev_err(codec->dev, - "Failed to set cache I/O:%d\n", - ret); - goto err_cleanup; - } - } - } + if (codec_drv->get_regmap) + codec->component.regmap = codec_drv->get_regmap(dev); for (i = 0; i < num_dai; i++) { fixup_codec_formats(&dai_drv[i].playback); diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 7767fbd73eb7..9b3939049cef 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c @@ -271,31 +271,3 @@ int snd_soc_platform_write(struct snd_soc_platform *platform, return snd_soc_component_write(&platform->component, reg, val); } EXPORT_SYMBOL_GPL(snd_soc_platform_write); - -/** - * snd_soc_component_init_io() - Initialize regmap IO - * - * @component: component to initialize - * @regmap: regmap instance to use for IO operations - * - * Return: 0 on success, a negative error code otherwise - */ -int snd_soc_component_init_io(struct snd_soc_component *component, - struct regmap *regmap) -{ - int ret; - - if (!regmap) - return -EINVAL; - - ret = regmap_get_val_bytes(regmap); - /* Errors are legitimate for non-integer byte - * multiples */ - if (ret > 0) - component->val_bytes = ret; - - component->regmap = regmap; - - return 0; -} -EXPORT_SYMBOL_GPL(snd_soc_component_init_io); -- GitLab From 75af7c081982d76cef0daf26e96b5d1e8cb9d631 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:29 +0200 Subject: [PATCH 0926/9167] ASoC: Remove support for legacy snd_soc_platform IO There were never any actual users of this in upstream and by we have with regmap a replacement in place, which should be used by new drivers. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- include/sound/soc.h | 3 --- sound/soc/soc-core.c | 22 ---------------------- 2 files changed, 25 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 8ebee30311e3..edbb0d72ab38 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -890,9 +890,6 @@ struct snd_soc_platform_driver { /* platform stream compress ops */ const struct snd_compr_ops *compr_ops; - /* platform IO - used for platform DAPM */ - unsigned int (*read)(struct snd_soc_platform *, unsigned int); - int (*write)(struct snd_soc_platform *, unsigned int, unsigned int); int (*bespoke_trigger)(struct snd_pcm_substream *, int); }; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 96f286643ca1..2d7a9ecbb0e3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4151,24 +4151,6 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component) platform->driver->remove(platform); } -static int snd_soc_platform_drv_write(struct snd_soc_component *component, - unsigned int reg, unsigned int val) -{ - struct snd_soc_platform *platform = snd_soc_component_to_platform(component); - - return platform->driver->write(platform, reg, val); -} - -static int snd_soc_platform_drv_read(struct snd_soc_component *component, - unsigned int reg, unsigned int *val) -{ - struct snd_soc_platform *platform = snd_soc_component_to_platform(component); - - *val = platform->driver->read(platform, reg); - - return 0; -} - /** * snd_soc_add_platform - Add a platform to the ASoC core * @dev: The parent device for the platform @@ -4205,10 +4187,6 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, platform->component.probe = snd_soc_platform_drv_probe; if (platform_drv->remove) platform->component.remove = snd_soc_platform_drv_remove; - if (platform_drv->write) - platform->component.write = snd_soc_platform_drv_write; - if (platform_drv->read) - platform->component.read = snd_soc_platform_drv_read; #ifdef CONFIG_DEBUG_FS platform->component.debugfs_prefix = "platform"; -- GitLab From c5599b87a8317738a541d8893cb327df5d04b007 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 15:51:30 +0200 Subject: [PATCH 0927/9167] ASoC: Replace list_empty(&card->codec_dev_list) with !card->instantiated With componentization we no longer necessarily need a snd_soc_codec struct for a card. Instead of checking if the card's CODEC list is empty just use card->instantiated to check if the card has been instantiated yet. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2d7a9ecbb0e3..c36983a133fa 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -552,10 +552,8 @@ int snd_soc_suspend(struct device *dev) struct snd_soc_codec *codec; int i, j; - /* If the initialization of this soc device failed, there is no codec - * associated with it. Just bail out in this case. - */ - if (list_empty(&card->codec_dev_list)) + /* If the card is not initialized yet there is nothing to do */ + if (!card->instantiated) return 0; /* Due to the resume being scheduled into a workqueue we could @@ -808,10 +806,8 @@ int snd_soc_resume(struct device *dev) struct snd_soc_card *card = dev_get_drvdata(dev); int i, ac97_control = 0; - /* If the initialization of this soc device failed, there is no codec - * associated with it. Just bail out in this case. - */ - if (list_empty(&card->codec_dev_list)) + /* If the card is not initialized yet there is nothing to do */ + if (!card->instantiated) return 0; /* activate pins from sleep state */ -- GitLab From 38c6e4bb67760db1392b9c5ee0082af07c0db20d Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Tue, 19 Aug 2014 17:36:41 +0800 Subject: [PATCH 0928/9167] ASoC: fsl-asoc-card: move 'config SND_SOC_FSL_ASOC_CARD' to 'if SND_IMX_SOC' Build kernel with SND_SOC_FSL_ASOC_CARD=m && SND_SOC_FSL_{SSI,SAI,ESAI}=y leads the following error: sound/built-in.o: In function `fsl_sai_probe': >> fsl_sai.c:(.text+0x5f662): undefined reference to `imx_pcm_dma_init' sound/built-in.o: In function `fsl_esai_probe': >> fsl_esai.c:(.text+0x6044b): undefined reference to `imx_pcm_dma_init' The config SND_SOC_FSL_ASOC_CARD is for IMX SOC, So move it under condition of 'if SND_IMX_SOC'. Reported-by: kbuild test robot Signed-off-by: Shengjiu Wang Signed-off-by: Mark Brown --- sound/soc/fsl/Kconfig | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 3154f43b11ab..7c1da8ede975 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig @@ -59,23 +59,6 @@ config SND_SOC_FSL_ESAI config SND_SOC_FSL_UTILS tristate -config SND_SOC_FSL_ASOC_CARD - tristate "Generic ASoC Sound Card with ASRC support" - depends on OF && I2C - select SND_SOC_IMX_AUDMUX - select SND_SOC_IMX_PCM_DMA - select SND_SOC_FSL_ESAI - select SND_SOC_FSL_SAI - select SND_SOC_FSL_SSI - select SND_SOC_CS42XX8_I2C - select SND_SOC_SGTL5000 - select SND_SOC_WM8962 - help - ALSA SoC Audio support with ASRC feature for Freescale SoCs that have - ESAI/SAI/SSI and connect with external CODECs such as WM8962, CS42888 - and SGTL5000. - Say Y if you want to add support for Freescale Generic ASoC Sound Card. - config SND_SOC_IMX_PCM_DMA tristate select SND_SOC_GENERIC_DMAENGINE_PCM @@ -298,6 +281,23 @@ config SND_SOC_IMX_MC13783 select SND_SOC_MC13783 select SND_SOC_IMX_PCM_DMA +config SND_SOC_FSL_ASOC_CARD + tristate "Generic ASoC Sound Card with ASRC support" + depends on OF && I2C + select SND_SOC_IMX_AUDMUX + select SND_SOC_IMX_PCM_DMA + select SND_SOC_FSL_ESAI + select SND_SOC_FSL_SAI + select SND_SOC_FSL_SSI + select SND_SOC_CS42XX8_I2C + select SND_SOC_SGTL5000 + select SND_SOC_WM8962 + help + ALSA SoC Audio support with ASRC feature for Freescale SoCs that have + ESAI/SAI/SSI and connect with external CODECs such as WM8962, CS42888 + and SGTL5000. + Say Y if you want to add support for Freescale Generic ASoC Sound Card. + endif # SND_IMX_SOC endmenu -- GitLab From 0fc6a323e19173fc89e17940bb1e19447aa0224e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Sun, 17 Aug 2014 18:33:38 +0200 Subject: [PATCH 0929/9167] spi: bcm53xx: driver for SPI controller on Broadcom bcma SoC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Broadcom 53xx ARM SoCs use bcma bus that contains various cores (AKA devices). If board has a serial flash, it's connected over SPI and the bcma bus includes a SPI controller. Example log from such a board: bus0: Found chip with id 53010, rev 0x00 and package 0x02 (...) bus0: Core 18 found: SPI flash controller (manuf 0x4BF, id 0x50A, rev 0x01, class 0x0) This patch adds a bcma driver for SPI core, it registers SPI master controller and "bcm53xxspiflash" SPI device. Signed-off-by: Rafał Miłecki Signed-off-by: Mark Brown --- drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi-bcm53xx.c | 295 ++++++++++++++++++++++++++++++++++++++ drivers/spi/spi-bcm53xx.h | 72 ++++++++++ 4 files changed, 374 insertions(+) create mode 100644 drivers/spi/spi-bcm53xx.c create mode 100644 drivers/spi/spi-bcm53xx.h diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 62e2242ad7e0..b14b829fb45c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -112,6 +112,12 @@ config SPI_AU1550 If you say yes to this option, support will be included for the PSC SPI controller found on Au1550, Au1200 and Au1300 series. +config SPI_BCM53XX + tristate "Broadcom BCM53xx SPI controller" + depends on ARCH_BCM_5301X + help + Enable support for the SPI controller on Broadcom BCM53xx ARM SoCs. + config SPI_BCM63XX tristate "Broadcom BCM63xx SPI controller" depends on BCM63XX diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 762da0741148..78f24ca36fcf 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o obj-$(CONFIG_SPI_ATH79) += spi-ath79.o obj-$(CONFIG_SPI_AU1550) += spi-au1550.o obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o +obj-$(CONFIG_SPI_BCM53XX) += spi-bcm53xx.o obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o obj-$(CONFIG_SPI_BFIN5XX) += spi-bfin5xx.o diff --git a/drivers/spi/spi-bcm53xx.c b/drivers/spi/spi-bcm53xx.c new file mode 100644 index 000000000000..48f13dfe7cf0 --- /dev/null +++ b/drivers/spi/spi-bcm53xx.c @@ -0,0 +1,295 @@ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +#include "spi-bcm53xx.h" + +#define BCM53XXSPI_MAX_SPI_BAUD 13500000 /* 216 MHz? */ + +/* The longest observed required wait was 19 ms */ +#define BCM53XXSPI_SPE_TIMEOUT_MS 80 + +struct bcm53xxspi { + struct bcma_device *core; + struct spi_master *master; + + size_t read_offset; +}; + +static inline u32 bcm53xxspi_read(struct bcm53xxspi *b53spi, u16 offset) +{ + return bcma_read32(b53spi->core, offset); +} + +static inline void bcm53xxspi_write(struct bcm53xxspi *b53spi, u16 offset, + u32 value) +{ + bcma_write32(b53spi->core, offset, value); +} + +static inline unsigned int bcm53xxspi_calc_timeout(size_t len) +{ + /* Do some magic calculation based on length and buad. Add 10% and 1. */ + return (len * 9000 / BCM53XXSPI_MAX_SPI_BAUD * 110 / 100) + 1; +} + +static int bcm53xxspi_wait(struct bcm53xxspi *b53spi, unsigned int timeout_ms) +{ + unsigned long deadline; + u32 tmp; + + /* SPE bit has to be 0 before we read MSPI STATUS */ + deadline = jiffies + BCM53XXSPI_SPE_TIMEOUT_MS * HZ / 1000; + do { + tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2); + if (!(tmp & B53SPI_MSPI_SPCR2_SPE)) + break; + udelay(5); + } while (!time_after_eq(jiffies, deadline)); + + if (tmp & B53SPI_MSPI_SPCR2_SPE) + goto spi_timeout; + + /* Check status */ + deadline = jiffies + timeout_ms * HZ / 1000; + do { + tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_MSPI_STATUS); + if (tmp & B53SPI_MSPI_MSPI_STATUS_SPIF) { + bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0); + return 0; + } + + cpu_relax(); + udelay(100); + } while (!time_after_eq(jiffies, deadline)); + +spi_timeout: + bcm53xxspi_write(b53spi, B53SPI_MSPI_MSPI_STATUS, 0); + + pr_err("Timeout waiting for SPI to be ready!\n"); + + return -EBUSY; +} + +static void bcm53xxspi_buf_write(struct bcm53xxspi *b53spi, u8 *w_buf, + size_t len, bool cont) +{ + u32 tmp; + int i; + + for (i = 0; i < len; i++) { + /* Transmit Register File MSB */ + bcm53xxspi_write(b53spi, B53SPI_MSPI_TXRAM + 4 * (i * 2), + (unsigned int)w_buf[i]); + } + + for (i = 0; i < len; i++) { + tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL | + B53SPI_CDRAM_PCS_DSCK; + if (!cont && i == len - 1) + tmp &= ~B53SPI_CDRAM_CONT; + tmp &= ~0x1; + /* Command Register File */ + bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp); + } + + /* Set queue pointers */ + bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0); + bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP, len - 1); + + if (cont) + bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1); + + /* Start SPI transfer */ + tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2); + tmp |= B53SPI_MSPI_SPCR2_SPE; + if (cont) + tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD; + bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp); + + /* Wait for SPI to finish */ + bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len)); + + if (!cont) + bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0); + + b53spi->read_offset = len; +} + +static void bcm53xxspi_buf_read(struct bcm53xxspi *b53spi, u8 *r_buf, + size_t len, bool cont) +{ + u32 tmp; + int i; + + for (i = 0; i < b53spi->read_offset + len; i++) { + tmp = B53SPI_CDRAM_CONT | B53SPI_CDRAM_PCS_DISABLE_ALL | + B53SPI_CDRAM_PCS_DSCK; + if (!cont && i == b53spi->read_offset + len - 1) + tmp &= ~B53SPI_CDRAM_CONT; + tmp &= ~0x1; + /* Command Register File */ + bcm53xxspi_write(b53spi, B53SPI_MSPI_CDRAM + 4 * i, tmp); + } + + /* Set queue pointers */ + bcm53xxspi_write(b53spi, B53SPI_MSPI_NEWQP, 0); + bcm53xxspi_write(b53spi, B53SPI_MSPI_ENDQP, + b53spi->read_offset + len - 1); + + if (cont) + bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 1); + + /* Start SPI transfer */ + tmp = bcm53xxspi_read(b53spi, B53SPI_MSPI_SPCR2); + tmp |= B53SPI_MSPI_SPCR2_SPE; + if (cont) + tmp |= B53SPI_MSPI_SPCR2_CONT_AFTER_CMD; + bcm53xxspi_write(b53spi, B53SPI_MSPI_SPCR2, tmp); + + /* Wait for SPI to finish */ + bcm53xxspi_wait(b53spi, bcm53xxspi_calc_timeout(len)); + + if (!cont) + bcm53xxspi_write(b53spi, B53SPI_MSPI_WRITE_LOCK, 0); + + for (i = 0; i < len; ++i) { + int offset = b53spi->read_offset + i; + + /* Data stored in the transmit register file LSB */ + r_buf[i] = (u8)bcm53xxspi_read(b53spi, B53SPI_MSPI_RXRAM + 4 * (1 + offset * 2)); + } + + b53spi->read_offset = 0; +} + +static int bcm53xxspi_transfer_one(struct spi_master *master, + struct spi_device *spi, + struct spi_transfer *t) +{ + struct bcm53xxspi *b53spi = spi_master_get_devdata(master); + u8 *buf; + size_t left; + + if (t->tx_buf) { + buf = (u8 *)t->tx_buf; + left = t->len; + while (left) { + size_t to_write = min_t(size_t, 16, left); + bool cont = left - to_write > 0; + + bcm53xxspi_buf_write(b53spi, buf, to_write, cont); + left -= to_write; + buf += to_write; + } + } + + if (t->rx_buf) { + buf = (u8 *)t->rx_buf; + left = t->len; + while (left) { + size_t to_read = min_t(size_t, 16 - b53spi->read_offset, + left); + bool cont = left - to_read > 0; + + bcm53xxspi_buf_read(b53spi, buf, to_read, cont); + left -= to_read; + buf += to_read; + } + } + + return 0; +} + +/************************************************** + * BCMA + **************************************************/ + +struct spi_board_info bcm53xx_info = { + .modalias = "bcm53xxspiflash", +}; + +static const struct bcma_device_id bcm53xxspi_bcma_tbl[] = { + BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_NS_QSPI, BCMA_ANY_REV, BCMA_ANY_CLASS), + BCMA_CORETABLE_END +}; +MODULE_DEVICE_TABLE(bcma, bcm53xxspi_bcma_tbl); + +static int bcm53xxspi_bcma_probe(struct bcma_device *core) +{ + struct bcm53xxspi *b53spi; + struct spi_master *master; + int err; + + if (core->bus->drv_cc.core->id.rev != 42) { + pr_err("SPI on SoC with unsupported ChipCommon rev\n"); + return -ENOTSUPP; + } + + master = spi_alloc_master(&core->dev, sizeof(*b53spi)); + if (!master) + return -ENOMEM; + + b53spi = spi_master_get_devdata(master); + b53spi->master = master; + b53spi->core = core; + + master->transfer_one = bcm53xxspi_transfer_one; + + bcma_set_drvdata(core, b53spi); + + err = devm_spi_register_master(&core->dev, master); + if (err) { + spi_master_put(master); + bcma_set_drvdata(core, NULL); + goto out; + } + + /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */ + spi_new_device(master, &bcm53xx_info); + +out: + return err; +} + +static void bcm53xxspi_bcma_remove(struct bcma_device *core) +{ + struct bcm53xxspi *b53spi = bcma_get_drvdata(core); + + spi_unregister_master(b53spi->master); +} + +static struct bcma_driver bcm53xxspi_bcma_driver = { + .name = KBUILD_MODNAME, + .id_table = bcm53xxspi_bcma_tbl, + .probe = bcm53xxspi_bcma_probe, + .remove = bcm53xxspi_bcma_remove, +}; + +/************************************************** + * Init & exit + **************************************************/ + +static int __init bcm53xxspi_module_init(void) +{ + int err = 0; + + err = bcma_driver_register(&bcm53xxspi_bcma_driver); + if (err) + pr_err("Failed to register bcma driver: %d\n", err); + + return err; +} + +static void __exit bcm53xxspi_module_exit(void) +{ + bcma_driver_unregister(&bcm53xxspi_bcma_driver); +} + +module_init(bcm53xxspi_module_init); +module_exit(bcm53xxspi_module_exit); diff --git a/drivers/spi/spi-bcm53xx.h b/drivers/spi/spi-bcm53xx.h new file mode 100644 index 000000000000..73575dfe6916 --- /dev/null +++ b/drivers/spi/spi-bcm53xx.h @@ -0,0 +1,72 @@ +#ifndef SPI_BCM53XX_H +#define SPI_BCM53XX_H + +#define B53SPI_BSPI_REVISION_ID 0x000 +#define B53SPI_BSPI_SCRATCH 0x004 +#define B53SPI_BSPI_MAST_N_BOOT_CTRL 0x008 +#define B53SPI_BSPI_BUSY_STATUS 0x00c +#define B53SPI_BSPI_INTR_STATUS 0x010 +#define B53SPI_BSPI_B0_STATUS 0x014 +#define B53SPI_BSPI_B0_CTRL 0x018 +#define B53SPI_BSPI_B1_STATUS 0x01c +#define B53SPI_BSPI_B1_CTRL 0x020 +#define B53SPI_BSPI_STRAP_OVERRIDE_CTRL 0x024 +#define B53SPI_BSPI_FLEX_MODE_ENABLE 0x028 +#define B53SPI_BSPI_BITS_PER_CYCLE 0x02c +#define B53SPI_BSPI_BITS_PER_PHASE 0x030 +#define B53SPI_BSPI_CMD_AND_MODE_BYTE 0x034 +#define B53SPI_BSPI_BSPI_FLASH_UPPER_ADDR_BYTE 0x038 +#define B53SPI_BSPI_BSPI_XOR_VALUE 0x03c +#define B53SPI_BSPI_BSPI_XOR_ENABLE 0x040 +#define B53SPI_BSPI_BSPI_PIO_MODE_ENABLE 0x044 +#define B53SPI_BSPI_BSPI_PIO_IODIR 0x048 +#define B53SPI_BSPI_BSPI_PIO_DATA 0x04c + +/* RAF */ +#define B53SPI_RAF_START_ADDR 0x100 +#define B53SPI_RAF_NUM_WORDS 0x104 +#define B53SPI_RAF_CTRL 0x108 +#define B53SPI_RAF_FULLNESS 0x10c +#define B53SPI_RAF_WATERMARK 0x110 +#define B53SPI_RAF_STATUS 0x114 +#define B53SPI_RAF_READ_DATA 0x118 +#define B53SPI_RAF_WORD_CNT 0x11c +#define B53SPI_RAF_CURR_ADDR 0x120 + +/* MSPI */ +#define B53SPI_MSPI_SPCR0_LSB 0x200 +#define B53SPI_MSPI_SPCR0_MSB 0x204 +#define B53SPI_MSPI_SPCR1_LSB 0x208 +#define B53SPI_MSPI_SPCR1_MSB 0x20c +#define B53SPI_MSPI_NEWQP 0x210 +#define B53SPI_MSPI_ENDQP 0x214 +#define B53SPI_MSPI_SPCR2 0x218 +#define B53SPI_MSPI_SPCR2_SPE 0x00000040 +#define B53SPI_MSPI_SPCR2_CONT_AFTER_CMD 0x00000080 +#define B53SPI_MSPI_MSPI_STATUS 0x220 +#define B53SPI_MSPI_MSPI_STATUS_SPIF 0x00000001 +#define B53SPI_MSPI_CPTQP 0x224 +#define B53SPI_MSPI_TXRAM 0x240 /* 32 registers, up to 0x2b8 */ +#define B53SPI_MSPI_RXRAM 0x2c0 /* 32 registers, up to 0x33c */ +#define B53SPI_MSPI_CDRAM 0x340 /* 16 registers, up to 0x37c */ +#define B53SPI_CDRAM_PCS_PCS0 0x00000001 +#define B53SPI_CDRAM_PCS_PCS1 0x00000002 +#define B53SPI_CDRAM_PCS_PCS2 0x00000004 +#define B53SPI_CDRAM_PCS_PCS3 0x00000008 +#define B53SPI_CDRAM_PCS_DISABLE_ALL 0x0000000f +#define B53SPI_CDRAM_PCS_DSCK 0x00000010 +#define B53SPI_CDRAM_BITSE 0x00000040 +#define B53SPI_CDRAM_CONT 0x00000080 +#define B53SPI_MSPI_WRITE_LOCK 0x380 +#define B53SPI_MSPI_DISABLE_FLUSH_GEN 0x384 + +/* Interrupt */ +#define B53SPI_INTR_RAF_LR_FULLNESS_REACHED 0x3a0 +#define B53SPI_INTR_RAF_LR_TRUNCATED 0x3a4 +#define B53SPI_INTR_RAF_LR_IMPATIENT 0x3a8 +#define B53SPI_INTR_RAF_LR_SESSION_DONE 0x3ac +#define B53SPI_INTR_RAF_LR_OVERREAD 0x3b0 +#define B53SPI_INTR_MSPI_DONE 0x3b4 +#define B53SPI_INTR_MSPI_HALT_SET_TRANSACTION_DONE 0x3b8 + +#endif /* SPI_BCM53XX_H */ -- GitLab From 5d0ecb0e7dd53e61e034bac8508d7601b04e679d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 17:48:06 +0200 Subject: [PATCH 0930/9167] ASoC: sh: Don't opencode DMAengine API calls Use the proper wrapper functions instead of directly calling the DMAengine callback functions. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/sh/siu_pcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index 488f9becb44f..32eb6da2d2bd 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -139,7 +139,7 @@ static int siu_pcm_wr_set(struct siu_port *port_info, desc->callback = siu_dma_tx_complete; desc->callback_param = siu_stream; - cookie = desc->tx_submit(desc); + cookie = dmaengine_submit(desc); if (cookie < 0) { dev_err(dev, "Failed to submit a dma transfer\n"); return cookie; @@ -189,7 +189,7 @@ static int siu_pcm_rd_set(struct siu_port *port_info, desc->callback = siu_dma_tx_complete; desc->callback_param = siu_stream; - cookie = desc->tx_submit(desc); + cookie = dmaengine_submit(desc); if (cookie < 0) { dev_err(dev, "Failed to submit dma descriptor\n"); return cookie; -- GitLab From ff495d3a8ea4d46d237096e6521b24b7ba612e53 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 19 Aug 2014 17:48:07 +0200 Subject: [PATCH 0931/9167] ASoC: txx9: Don't opencode DMAengine API calls Use the proper wrapper functions instead of directly calling the DMAengine callback functions. Also add the missing include to linux/dmaengine.h. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/txx9/txx9aclc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c index f0829de28708..cd71fd889d8b 100644 --- a/sound/soc/txx9/txx9aclc.c +++ b/sound/soc/txx9/txx9aclc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -137,7 +138,7 @@ txx9aclc_dma_submit(struct txx9aclc_dmadata *dmadata, dma_addr_t buf_dma_addr) } desc->callback = txx9aclc_dma_complete; desc->callback_param = dmadata; - desc->tx_submit(desc); + dmaengine_submit(desc); return desc; } @@ -160,7 +161,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) void __iomem *base = drvdata->base; spin_unlock_irqrestore(&dmadata->dma_lock, flags); - chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(chan); /* first time */ for (i = 0; i < NR_DMA_CHAIN; i++) { desc = txx9aclc_dma_submit(dmadata, @@ -169,7 +170,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) return; } dmadata->dmacount = NR_DMA_CHAIN; - chan->device->device_issue_pending(chan); + dma_async_issue_pending(chan); spin_lock_irqsave(&dmadata->dma_lock, flags); __raw_writel(ctlbit, base + ACCTLEN); dmadata->frag_count = NR_DMA_CHAIN % dmadata->frags; @@ -188,7 +189,7 @@ static void txx9aclc_dma_tasklet(unsigned long data) dmadata->frag_count * dmadata->frag_bytes); if (!desc) return; - chan->device->device_issue_pending(chan); + dma_async_issue_pending(chan); spin_lock_irqsave(&dmadata->dma_lock, flags); dmadata->frag_count++; @@ -266,7 +267,7 @@ static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) struct dma_chan *chan = dmadata->dma_chan; dmadata->frag_count = -1; - chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(chan); return 0; } @@ -398,8 +399,7 @@ static int txx9aclc_pcm_remove(struct snd_soc_platform *platform) struct dma_chan *chan = dmadata->dma_chan; if (chan) { dmadata->frag_count = -1; - chan->device->device_control(chan, - DMA_TERMINATE_ALL, 0); + dmaengine_terminate_all(chan); dma_release_channel(chan); } dev->dmadata[i].dma_chan = NULL; -- GitLab From ddc643630f5deb1995d191719086b64873c67a44 Mon Sep 17 00:00:00 2001 From: Srikanth Thokala Date: Mon, 28 Jul 2014 17:47:48 +0530 Subject: [PATCH 0932/9167] dma: Add Xilinx AXI DMA DT Binding Documentation Device-tree binding documentation of Xilinx DMA Engine Signed-off-by: Srikanth Thokala Acked-by: Arnd Bergmann Signed-off-by: Vinod Koul --- .../bindings/dma/xilinx/xilinx_dma.txt | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt diff --git a/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt new file mode 100644 index 000000000000..2291c4098730 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/xilinx/xilinx_dma.txt @@ -0,0 +1,65 @@ +Xilinx AXI DMA engine, it does transfers between memory and AXI4 stream +target devices. It can be configured to have one channel or two channels. +If configured as two channels, one is to transmit to the device and another +is to receive from the device. + +Required properties: +- compatible: Should be "xlnx,axi-dma-1.00.a" +- #dma-cells: Should be <1>, see "dmas" property below +- reg: Should contain DMA registers location and length. +- dma-channel child node: Should have atleast one channel and can have upto + two channels per device. This node specifies the properties of each + DMA channel (see child node properties below). + +Optional properties: +- xlnx,include-sg: Tells whether configured for Scatter-mode in + the hardware. + +Required child node properties: +- compatible: It should be either "xlnx,axi-dma-mm2s-channel" or + "xlnx,axi-dma-s2mm-channel". +- interrupts: Should contain per channel DMA interrupts. +- xlnx,datawidth: Should contain the stream data width, take values + {32,64...1024}. + +Option child node properties: +- xlnx,include-dre: Tells whether hardware is configured for Data + Realignment Engine. + +Example: +++++++++ + +axi_dma_0: axidma@40400000 { + compatible = "xlnx,axi-dma-1.00.a"; + #dma_cells = <1>; + reg = < 0x40400000 0x10000 >; + dma-channel@40400000 { + compatible = "xlnx,axi-dma-mm2s-channel"; + interrupts = < 0 59 4 >; + xlnx,datawidth = <0x40>; + } ; + dma-channel@40400030 { + compatible = "xlnx,axi-dma-s2mm-channel"; + interrupts = < 0 58 4 >; + xlnx,datawidth = <0x40>; + } ; +} ; + + +* DMA client + +Required properties: +- dmas: a list of <[DMA device phandle] [Channel ID]> pairs, + where Channel ID is '0' for write/tx and '1' for read/rx + channel. +- dma-names: a list of DMA channel names, one per "dmas" entry + +Example: +++++++++ + +dmatest_0: dmatest@0 { + compatible ="xlnx,axi-dma-test-1.00.a"; + dmas = <&axi_dma_0 0 + &axi_dma_0 1>; + dma-names = "dma0", "dma1"; +} ; -- GitLab From 29a4bb1431035560b4be3fc5917c5ab8b8141204 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 13 Aug 2014 13:57:42 +0200 Subject: [PATCH 0933/9167] dma: xilinx: Remove .owner field for driver There is no need to init .owner field. Based on the patch from Peter Griffin "mmc: remove .owner field for drivers using module_platform_driver" This patch removes the superflous .owner field for drivers which use the module_platform_driver API, as this is overriden in platform_driver_register anyway." Signed-off-by: Michal Simek Reviewed-by: Levente Kurusa Signed-off-by: Vinod Koul --- drivers/dma/xilinx/xilinx_vdma.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_vdma.c index 42a13e8d4607..a6e64767186e 100644 --- a/drivers/dma/xilinx/xilinx_vdma.c +++ b/drivers/dma/xilinx/xilinx_vdma.c @@ -1365,7 +1365,6 @@ static const struct of_device_id xilinx_vdma_of_ids[] = { static struct platform_driver xilinx_vdma_driver = { .driver = { .name = "xilinx-vdma", - .owner = THIS_MODULE, .of_match_table = xilinx_vdma_of_ids, }, .probe = xilinx_vdma_probe, -- GitLab From 684284b64aae96c8d5de0dc0d6e4b72f8b3502ce Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 22 Jan 2014 14:21:28 +0100 Subject: [PATCH 0934/9167] ARM: integrator: add MMCI device to IM-PD1 The IM-PD1 logic module daughterboard holds an MMCI block, which we can now provide using platform resources such as proper GPIO lines etc. We add the GPIO table dynamically and using the new GPIO descriptor mechanism. Tested and hey, it works: root@integrator:/ mount /dev/mmcblk0p1 /mnt/ root@integrator:/ ls /mnt/ ARM U-BOOT.EXE u-boot.bin u-boot.srec u-pad.bin Reviewed-by: Alexandre Courbot Signed-off-by: Linus Walleij --- arch/arm/mach-integrator/impd1.c | 48 ++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c index 3ce880729cff..38b0da300dd5 100644 --- a/arch/arm/mach-integrator/impd1.c +++ b/arch/arm/mach-integrator/impd1.c @@ -20,10 +20,13 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include "lm.h" @@ -51,6 +54,13 @@ void impd1_tweak_control(struct device *dev, u32 mask, u32 val) EXPORT_SYMBOL(impd1_tweak_control); +/* + * MMC support + */ +static struct mmci_platform_data mmc_data = { + .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, +}; + /* * CLCD support */ @@ -291,6 +301,7 @@ static struct impd1_device impd1_devs[] = { .offset = 0x00700000, .irq = { 7, 8 }, .id = 0x00041181, + .platform_data = &mmc_data, }, { .offset = 0x00800000, .irq = { 9 }, @@ -372,6 +383,43 @@ static int __init_refok impd1_probe(struct lm_device *dev) pc_base = dev->resource.start + idev->offset; snprintf(devname, 32, "lm%x:%5.5lx", dev->id, idev->offset >> 12); + + /* Add GPIO descriptor lookup table for the PL061 block */ + if (idev->offset == 0x00400000) { + struct gpiod_lookup_table *lookup; + char *chipname; + char *mmciname; + + lookup = devm_kzalloc(&dev->dev, + sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup), + GFP_KERNEL); + chipname = devm_kstrdup(&dev->dev, devname, GFP_KERNEL); + mmciname = kasprintf(GFP_KERNEL, "lm%x:00700", dev->id); + lookup->dev_id = mmciname; + /* + * Offsets on GPIO block 1: + * 3 = MMC WP (write protect) + * 4 = MMC CD (card detect) + * + * Offsets on GPIO block 2: + * 0 = Up key + * 1 = Down key + * 2 = Left key + * 3 = Right key + * 4 = Key lower left + * 5 = Key lower right + */ + /* We need the two MMCI GPIO entries */ + lookup->table[0].chip_label = chipname; + lookup->table[0].chip_hwnum = 3; + lookup->table[0].con_id = "wp"; + lookup->table[1].chip_label = chipname; + lookup->table[1].chip_hwnum = 4; + lookup->table[1].con_id = "cd"; + lookup->table[1].flags = GPIO_ACTIVE_LOW; + gpiod_add_lookup_table(lookup); + } + d = amba_ahb_device_add_res(&dev->dev, devname, pc_base, SZ_4K, irq1, irq2, idev->platform_data, idev->id, -- GitLab From 91a55d4f690066a249d5cdeca86f0c3164301861 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Jul 2014 19:14:19 +0200 Subject: [PATCH 0935/9167] ARM: at91: introduce OLD_IRQ_AT91 Kconfig option Introduce the OLD_IRQ_AT91 Kconfig option to prepare migration to the new AIC driver. Select this option for all at91 SoCs and all available boards so that we can later move DT enabled boards to the new irq driver and keep the old implementation when legacy boards are selected. Signed-off-by: Boris BREZILLON Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/Kconfig | 17 +++++++++-------- arch/arm/mach-at91/Kconfig.non_dt | 6 ++++++ arch/arm/mach-at91/Makefile | 3 ++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 6cc6f7aebdae..3dc3a69b8430 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -28,6 +28,11 @@ config OLD_CLK_AT91 bool default AT91_PMC_UNIT && AT91_USE_OLD_CLK +config OLD_IRQ_AT91 + bool + select MULTI_IRQ_HANDLER + select SPARSE_IRQ + config AT91_SAM9_ALT_RESET bool default !ARCH_AT91X40 @@ -47,16 +52,12 @@ config SOC_AT91SAM9 select AT91_SAM9_TIME select CPU_ARM926T select GENERIC_CLOCKEVENTS - select MULTI_IRQ_HANDLER - select SPARSE_IRQ config SOC_SAMA5 bool select AT91_SAM9_TIME select CPU_V7 select GENERIC_CLOCKEVENTS - select MULTI_IRQ_HANDLER - select SPARSE_IRQ select USE_OF menu "Atmel AT91 System-on-Chip" @@ -70,8 +71,7 @@ config ARCH_AT91X40 depends on !MMU select CPU_ARM7TDMI select ARCH_USES_GETTIMEOFFSET - select MULTI_IRQ_HANDLER - select SPARSE_IRQ + select OLD_IRQ_AT91 help Select this if you are using one of Atmel's AT91X40 SoC. @@ -111,8 +111,6 @@ config SOC_AT91RM9200 select CPU_ARM920T select GENERIC_CLOCKEVENTS select HAVE_AT91_DBGU0 - select MULTI_IRQ_HANDLER - select SPARSE_IRQ select HAVE_AT91_USB_CLK config SOC_AT91SAM9260 @@ -195,6 +193,7 @@ comment "Generic Board Type" config MACH_AT91RM9200_DT bool "Atmel AT91RM9200 Evaluation Kits with device-tree support" depends on SOC_AT91RM9200 + select OLD_IRQ_AT91 select USE_OF help Select this if you want to experiment device-tree with @@ -203,6 +202,7 @@ config MACH_AT91RM9200_DT config MACH_AT91SAM9_DT bool "Atmel AT91SAM Evaluation Kits with device-tree support" depends on SOC_AT91SAM9 + select OLD_IRQ_AT91 select USE_OF help Select this if you want to experiment device-tree with @@ -211,6 +211,7 @@ config MACH_AT91SAM9_DT config MACH_SAMA5_DT bool "Atmel SAMA5 Evaluation Kits with device-tree support" depends on SOC_SAMA5 + select OLD_IRQ_AT91 select USE_OF select PHYLIB if NETDEVICES help diff --git a/arch/arm/mach-at91/Kconfig.non_dt b/arch/arm/mach-at91/Kconfig.non_dt index 44ace320d2e1..b774c3d3c632 100644 --- a/arch/arm/mach-at91/Kconfig.non_dt +++ b/arch/arm/mach-at91/Kconfig.non_dt @@ -14,31 +14,37 @@ config ARCH_AT91RM9200 bool "AT91RM9200" select SOC_AT91RM9200 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9260 bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20" select SOC_AT91SAM9260 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9261 bool "AT91SAM9261 or AT91SAM9G10" select SOC_AT91SAM9261 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9263 bool "AT91SAM9263" select SOC_AT91SAM9263 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9RL bool "AT91SAM9RL" select SOC_AT91SAM9RL select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 config ARCH_AT91SAM9G45 bool "AT91SAM9G45" select SOC_AT91SAM9G45 select AT91_USE_OLD_CLK + select OLD_IRQ_AT91 endchoice diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 78e9cec282f4..d972fd67de83 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -2,11 +2,12 @@ # Makefile for the linux kernel. # -obj-y := irq.o gpio.o setup.o sysirq_mask.o +obj-y := gpio.o setup.o sysirq_mask.o obj-m := obj-n := obj- := +obj-$(CONFIG_OLD_IRQ_AT91) += irq.o obj-$(CONFIG_OLD_CLK_AT91) += clock.o obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o -- GitLab From 071926041e5b38f84f2aaac2122c57e398e535b5 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Jul 2014 19:14:20 +0200 Subject: [PATCH 0936/9167] ARM: at91: enclose at91_aic_xx calls in IS_ENABLED(CONFIG_OLD_IRQ_AT91) blocks Enclose at91_aic_xx calls in IS_ENABLED(CONFIG_OLD_IRQ_AT91) blocks in order to prepare migration to the new AIC driver. In the new AIC driver the suspend/resume functions are called by the generic irq framework and are no longer needed in the PM specific code. Moreover, the new AIC driver no longer exposes the at91_aic_base variable which is used by the at91_aic_read functions. Signed-off-by: Boris BREZILLON Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/pm.c | 32 ++++++++++++++++++++------------ arch/arm/mach-at91/setup.c | 3 ++- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index e95554532987..5920373809c5 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -206,16 +206,19 @@ static int at91_pm_enter(suspend_state_t state) at91_pinctrl_gpio_suspend(); else at91_gpio_suspend(); - at91_irq_suspend(); - pr_debug("AT91: PM - wake mask %08x, pm state %d\n", - /* remember all the always-wake irqs */ - (at91_pmc_read(AT91_PMC_PCSR) - | (1 << AT91_ID_FIQ) - | (1 << AT91_ID_SYS) - | (at91_get_extern_irq())) - & at91_aic_read(AT91_AIC_IMR), - state); + if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) { + at91_irq_suspend(); + + pr_debug("AT91: PM - wake mask %08x, pm state %d\n", + /* remember all the always-wake irqs */ + (at91_pmc_read(AT91_PMC_PCSR) + | (1 << AT91_ID_FIQ) + | (1 << AT91_ID_SYS) + | (at91_get_extern_irq())) + & at91_aic_read(AT91_AIC_IMR), + state); + } switch (state) { /* @@ -280,12 +283,17 @@ static int at91_pm_enter(suspend_state_t state) goto error; } - pr_debug("AT91: PM - wakeup %08x\n", - at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR)); + if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) + pr_debug("AT91: PM - wakeup %08x\n", + at91_aic_read(AT91_AIC_IPR) & + at91_aic_read(AT91_AIC_IMR)); error: target_state = PM_SUSPEND_ON; - at91_irq_resume(); + + if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) + at91_irq_resume(); + if (of_have_populated_dt()) at91_pinctrl_gpio_resume(); else diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index f7a07a58ebb6..0bf893a574f9 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -49,7 +49,8 @@ void __init at91_init_irq_default(void) void __init at91_init_interrupts(unsigned int *priority) { /* Initialize the AIC interrupt controller */ - at91_aic_init(priority, at91_boot_soc.extern_irq); + if (IS_ENABLED(CONFIG_OLD_IRQ_AT91)) + at91_aic_init(priority, at91_boot_soc.extern_irq); /* Enable GPIO interrupts */ at91_gpio_irq_setup(); -- GitLab From 3b26f39b0ab1f390365701981e831aa128e3e4ac Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Jul 2014 19:14:21 +0200 Subject: [PATCH 0937/9167] ARM: at91: make use of the new AIC driver for dt enabled boards Remove selection of OLD_IRQ_AT91 when selecting dt boards. Select ATMEL_AIC_IRQ for sama5 SoCs (a kernel compiled for this SoC will always use ATMEL_AIC_IRQ driver). Select ATMEL_AIC_IRQ for at91rm9200 and at91sam9 SoCs only if OLD_IRQ_AT91 is not selected (which means we are compiling a pure DT kernel, without any legacy board support). Remove specific irq init code in all dt board files: this init procedure is automatically handled in of_irq_init which is called by the arm irq core code and is in charge of calling the appropriate aic init functions. Signed-off-by: Boris BREZILLON Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/Kconfig | 6 +++--- arch/arm/mach-at91/board-dt-rm9200.c | 13 ------------- arch/arm/mach-at91/board-dt-sam9.c | 13 ------------- arch/arm/mach-at91/board-dt-sama5.c | 13 ------------- 4 files changed, 3 insertions(+), 42 deletions(-) diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 3dc3a69b8430..dd28e1fedbdc 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -50,12 +50,14 @@ config HAVE_AT91_SMD config SOC_AT91SAM9 bool select AT91_SAM9_TIME + select ATMEL_AIC_IRQ if !OLD_IRQ_AT91 select CPU_ARM926T select GENERIC_CLOCKEVENTS config SOC_SAMA5 bool select AT91_SAM9_TIME + select ATMEL_AIC5_IRQ select CPU_V7 select GENERIC_CLOCKEVENTS select USE_OF @@ -108,6 +110,7 @@ endif if SOC_SAM_V4_V5 config SOC_AT91RM9200 bool "AT91RM9200" + select ATMEL_AIC_IRQ if !OLD_IRQ_AT91 select CPU_ARM920T select GENERIC_CLOCKEVENTS select HAVE_AT91_DBGU0 @@ -193,7 +196,6 @@ comment "Generic Board Type" config MACH_AT91RM9200_DT bool "Atmel AT91RM9200 Evaluation Kits with device-tree support" depends on SOC_AT91RM9200 - select OLD_IRQ_AT91 select USE_OF help Select this if you want to experiment device-tree with @@ -202,7 +204,6 @@ config MACH_AT91RM9200_DT config MACH_AT91SAM9_DT bool "Atmel AT91SAM Evaluation Kits with device-tree support" depends on SOC_AT91SAM9 - select OLD_IRQ_AT91 select USE_OF help Select this if you want to experiment device-tree with @@ -211,7 +212,6 @@ config MACH_AT91SAM9_DT config MACH_SAMA5_DT bool "Atmel SAMA5 Evaluation Kits with device-tree support" depends on SOC_SAMA5 - select OLD_IRQ_AT91 select USE_OF select PHYLIB if NETDEVICES help diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c index 3a185faee795..61ea21445664 100644 --- a/arch/arm/mach-at91/board-dt-rm9200.c +++ b/arch/arm/mach-at91/board-dt-rm9200.c @@ -24,17 +24,6 @@ #include "at91_aic.h" #include "generic.h" - -static const struct of_device_id irq_of_match[] __initconst = { - { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, - { /*sentinel*/ } -}; - -static void __init at91rm9200_dt_init_irq(void) -{ - of_irq_init(irq_of_match); -} - static const char *at91rm9200_dt_board_compat[] __initdata = { "atmel,at91rm9200", NULL @@ -43,8 +32,6 @@ static const char *at91rm9200_dt_board_compat[] __initdata = { DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)") .init_time = at91rm9200_timer_init, .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, .init_early = at91rm9200_dt_initialize, - .init_irq = at91rm9200_dt_init_irq, .dt_compat = at91rm9200_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-at91/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c index 575b0be66ca8..dfa8d48146fe 100644 --- a/arch/arm/mach-at91/board-dt-sam9.c +++ b/arch/arm/mach-at91/board-dt-sam9.c @@ -34,17 +34,6 @@ static void __init sam9_dt_timer_init(void) at91sam926x_pit_init(); } -static const struct of_device_id irq_of_match[] __initconst = { - - { .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init }, - { /*sentinel*/ } -}; - -static void __init at91_dt_init_irq(void) -{ - of_irq_init(irq_of_match); -} - static const char *at91_dt_board_compat[] __initdata = { "atmel,at91sam9", NULL @@ -54,8 +43,6 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)") /* Maintainer: Atmel */ .init_time = sam9_dt_timer_init, .map_io = at91_map_io, - .handle_irq = at91_aic_handle_irq, .init_early = at91_dt_initialize, - .init_irq = at91_dt_init_irq, .dt_compat = at91_dt_board_compat, MACHINE_END diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c index 075ec0576ada..d6fe04bcaabd 100644 --- a/arch/arm/mach-at91/board-dt-sama5.c +++ b/arch/arm/mach-at91/board-dt-sama5.c @@ -35,17 +35,6 @@ static void __init sama5_dt_timer_init(void) at91sam926x_pit_init(); } -static const struct of_device_id irq_of_match[] __initconst = { - - { .compatible = "atmel,sama5d3-aic", .data = at91_aic5_of_init }, - { /*sentinel*/ } -}; - -static void __init at91_dt_init_irq(void) -{ - of_irq_init(irq_of_match); -} - static int ksz9021rn_phy_fixup(struct phy_device *phy) { int value; @@ -82,9 +71,7 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)") /* Maintainer: Atmel */ .init_time = sama5_dt_timer_init, .map_io = at91_map_io, - .handle_irq = at91_aic5_handle_irq, .init_early = at91_dt_initialize, - .init_irq = at91_dt_init_irq, .init_machine = sama5_dt_device_init, .dt_compat = sama5_dt_board_compat, MACHINE_END -- GitLab From 2626063f86cdce500153e8550334b9331421dc6f Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Thu, 10 Jul 2014 19:14:22 +0200 Subject: [PATCH 0938/9167] ARM: at91: remove old irq material Remove all the material related to AIC5 support: this interrupt controller driver is now implemented in drivers/irqchip/atmel-aic.c. Signed-off-by: Boris BREZILLON Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/irq.c | 270 +-------------------------------------- 1 file changed, 6 insertions(+), 264 deletions(-) diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c index 3d192c5aee66..cdb3ec9efd2b 100644 --- a/arch/arm/mach-at91/irq.c +++ b/arch/arm/mach-at91/irq.c @@ -48,11 +48,6 @@ void __iomem *at91_aic_base; static struct irq_domain *at91_aic_domain; static struct device_node *at91_aic_np; static unsigned int n_irqs = NR_AIC_IRQS; -static unsigned long at91_aic_caps = 0; - -/* AIC5 introduces a Source Select Register */ -#define AT91_AIC_CAP_AIC5 (1 << 0) -#define has_aic5() (at91_aic_caps & AT91_AIC_CAP_AIC5) #ifdef CONFIG_PM @@ -92,50 +87,14 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value) void at91_irq_suspend(void) { - int bit = -1; - - if (has_aic5()) { - /* disable enabled irqs */ - while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) { - at91_aic_write(AT91_AIC5_SSR, - bit & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IDCR, 1); - } - /* enable wakeup irqs */ - bit = -1; - while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) { - at91_aic_write(AT91_AIC5_SSR, - bit & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IECR, 1); - } - } else { - at91_aic_write(AT91_AIC_IDCR, *backups); - at91_aic_write(AT91_AIC_IECR, *wakeups); - } + at91_aic_write(AT91_AIC_IDCR, *backups); + at91_aic_write(AT91_AIC_IECR, *wakeups); } void at91_irq_resume(void) { - int bit = -1; - - if (has_aic5()) { - /* disable wakeup irqs */ - while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) { - at91_aic_write(AT91_AIC5_SSR, - bit & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IDCR, 1); - } - /* enable irqs disabled for suspend */ - bit = -1; - while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) { - at91_aic_write(AT91_AIC5_SSR, - bit & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IECR, 1); - } - } else { - at91_aic_write(AT91_AIC_IDCR, *wakeups); - at91_aic_write(AT91_AIC_IECR, *backups); - } + at91_aic_write(AT91_AIC_IDCR, *wakeups); + at91_aic_write(AT91_AIC_IECR, *backups); } #else @@ -169,21 +128,6 @@ at91_aic_handle_irq(struct pt_regs *regs) handle_IRQ(irqnr, regs); } -asmlinkage void __exception_irq_entry -at91_aic5_handle_irq(struct pt_regs *regs) -{ - u32 irqnr; - u32 irqstat; - - irqnr = at91_aic_read(AT91_AIC5_IVR); - irqstat = at91_aic_read(AT91_AIC5_ISR); - - if (!irqstat) - at91_aic_write(AT91_AIC5_EOICR, 0); - else - handle_IRQ(irqnr, regs); -} - static void at91_aic_mask_irq(struct irq_data *d) { /* Disable interrupt on AIC */ @@ -192,15 +136,6 @@ static void at91_aic_mask_irq(struct irq_data *d) clear_backup(d->hwirq); } -static void __maybe_unused at91_aic5_mask_irq(struct irq_data *d) -{ - /* Disable interrupt on AIC5 */ - at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IDCR, 1); - /* Update ISR cache */ - clear_backup(d->hwirq); -} - static void at91_aic_unmask_irq(struct irq_data *d) { /* Enable interrupt on AIC */ @@ -209,15 +144,6 @@ static void at91_aic_unmask_irq(struct irq_data *d) set_backup(d->hwirq); } -static void __maybe_unused at91_aic5_unmask_irq(struct irq_data *d) -{ - /* Enable interrupt on AIC5 */ - at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IECR, 1); - /* Update ISR cache */ - set_backup(d->hwirq); -} - static void at91_aic_eoi(struct irq_data *d) { /* @@ -227,11 +153,6 @@ static void at91_aic_eoi(struct irq_data *d) at91_aic_write(AT91_AIC_EOICR, 0); } -static void __maybe_unused at91_aic5_eoi(struct irq_data *d) -{ - at91_aic_write(AT91_AIC5_EOICR, 0); -} - static unsigned long *at91_extern_irq; u32 at91_get_extern_irq(void) @@ -282,16 +203,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type) if (srctype < 0) return srctype; - if (has_aic5()) { - at91_aic_write(AT91_AIC5_SSR, - d->hwirq & AT91_AIC5_INTSEL_MSK); - smr = at91_aic_read(AT91_AIC5_SMR) & ~AT91_AIC_SRCTYPE; - at91_aic_write(AT91_AIC5_SMR, smr | srctype); - } else { - smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) - & ~AT91_AIC_SRCTYPE; - at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype); - } + smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE; + at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype); return 0; } @@ -331,177 +244,6 @@ static void __init at91_aic_hw_init(unsigned int spu_vector) at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF); } -static void __init __maybe_unused at91_aic5_hw_init(unsigned int spu_vector) -{ - int i; - - /* - * Perform 8 End Of Interrupt Command to make sure AIC - * will not Lock out nIRQ - */ - for (i = 0; i < 8; i++) - at91_aic_write(AT91_AIC5_EOICR, 0); - - /* - * Spurious Interrupt ID in Spurious Vector Register. - * When there is no current interrupt, the IRQ Vector Register - * reads the value stored in AIC_SPU - */ - at91_aic_write(AT91_AIC5_SPU, spu_vector); - - /* No debugging in AIC: Debug (Protect) Control Register */ - at91_aic_write(AT91_AIC5_DCR, 0); - - /* Disable and clear all interrupts initially */ - for (i = 0; i < n_irqs; i++) { - at91_aic_write(AT91_AIC5_SSR, i & AT91_AIC5_INTSEL_MSK); - at91_aic_write(AT91_AIC5_IDCR, 1); - at91_aic_write(AT91_AIC5_ICCR, 1); - } -} - -#if defined(CONFIG_OF) -static unsigned int *at91_aic_irq_priorities; - -static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - /* Put virq number in Source Vector Register */ - at91_aic_write(AT91_AIC_SVR(hw), virq); - - /* Active Low interrupt, with priority */ - at91_aic_write(AT91_AIC_SMR(hw), - AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]); - - irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq); - set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); - - return 0; -} - -static int at91_aic5_irq_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - at91_aic_write(AT91_AIC5_SSR, hw & AT91_AIC5_INTSEL_MSK); - - /* Put virq number in Source Vector Register */ - at91_aic_write(AT91_AIC5_SVR, virq); - - /* Active Low interrupt, with priority */ - at91_aic_write(AT91_AIC5_SMR, - AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]); - - irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq); - set_irq_flags(virq, IRQF_VALID | IRQF_PROBE); - - return 0; -} - -static int at91_aic_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 (WARN_ON(intsize < 3)) - return -EINVAL; - if (WARN_ON(intspec[0] >= n_irqs)) - return -EINVAL; - if (WARN_ON((intspec[2] < AT91_AIC_IRQ_MIN_PRIORITY) - || (intspec[2] > AT91_AIC_IRQ_MAX_PRIORITY))) - return -EINVAL; - - *out_hwirq = intspec[0]; - *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK; - at91_aic_irq_priorities[*out_hwirq] = intspec[2]; - - return 0; -} - -static struct irq_domain_ops at91_aic_irq_ops = { - .map = at91_aic_irq_map, - .xlate = at91_aic_irq_domain_xlate, -}; - -int __init at91_aic_of_common_init(struct device_node *node, - struct device_node *parent) -{ - struct property *prop; - const __be32 *p; - u32 val; - - at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs) - * sizeof(*at91_extern_irq), GFP_KERNEL); - if (!at91_extern_irq) - return -ENOMEM; - - if (at91_aic_pm_init()) { - kfree(at91_extern_irq); - return -ENOMEM; - } - - at91_aic_irq_priorities = kzalloc(n_irqs - * sizeof(*at91_aic_irq_priorities), - GFP_KERNEL); - if (!at91_aic_irq_priorities) - return -ENOMEM; - - at91_aic_base = of_iomap(node, 0); - at91_aic_np = node; - - at91_aic_domain = irq_domain_add_linear(at91_aic_np, n_irqs, - &at91_aic_irq_ops, NULL); - if (!at91_aic_domain) - panic("Unable to add AIC irq domain (DT)\n"); - - of_property_for_each_u32(node, "atmel,external-irqs", prop, p, val) { - if (val >= n_irqs) - pr_warn("AIC: external irq %d >= %d skip it\n", - val, n_irqs); - else - set_bit(val, at91_extern_irq); - } - - irq_set_default_host(at91_aic_domain); - - return 0; -} - -int __init at91_aic_of_init(struct device_node *node, - struct device_node *parent) -{ - int err; - - err = at91_aic_of_common_init(node, parent); - if (err) - return err; - - at91_aic_hw_init(n_irqs); - - return 0; -} - -int __init at91_aic5_of_init(struct device_node *node, - struct device_node *parent) -{ - int err; - - at91_aic_caps |= AT91_AIC_CAP_AIC5; - n_irqs = NR_AIC5_IRQS; - at91_aic_chip.irq_ack = at91_aic5_mask_irq; - at91_aic_chip.irq_mask = at91_aic5_mask_irq; - at91_aic_chip.irq_unmask = at91_aic5_unmask_irq; - at91_aic_chip.irq_eoi = at91_aic5_eoi; - at91_aic_irq_ops.map = at91_aic5_irq_map; - - err = at91_aic_of_common_init(node, parent); - if (err) - return err; - - at91_aic5_hw_init(n_irqs); - - return 0; -} -#endif - /* * Initialize the AIC interrupt controller. */ -- GitLab From 5828c60826e9422169b3711aa58a583242864cc8 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 31 Jul 2014 18:36:20 +0300 Subject: [PATCH 0939/9167] mtd: ndfc: silence an array underflow static checker warning We check "cs" for array overflows but we don't check for underflows and it upsets the static checkers. Signed-off-by: Dan Carpenter Signed-off-by: Brian Norris --- drivers/mtd/nand/ndfc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 69eaba690a99..253a644da76a 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c @@ -203,7 +203,8 @@ static int ndfc_probe(struct platform_device *ofdev) struct ndfc_controller *ndfc; const __be32 *reg; u32 ccr; - int err, len, cs; + u32 cs; + int err, len; /* Read the reg property to get the chip select */ reg = of_get_property(ofdev->dev.of_node, "reg", &len); -- GitLab From 9b6e5172e363b0c35a6be4d3197f3bcdc789292e Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Thu, 31 Jul 2014 16:31:16 +0200 Subject: [PATCH 0940/9167] mtd: use NULL instead of 0 for an address Use NULL instead of 0 when returning an address. This fixes a sparse warning. Signed-off-by: Martin Kepplinger Signed-off-by: Brian Norris --- drivers/mtd/maps/pcmciamtd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index a3cfad392ed6..af747af5eee9 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -89,7 +89,7 @@ static caddr_t remap_window(struct map_info *map, unsigned long to) if (!pcmcia_dev_present(dev->p_dev)) { pr_debug("device removed\n"); - return 0; + return NULL; } offset = to & ~(dev->win_size-1); -- GitLab From 796fe3648a13b311f5b9a125e2d2532a2ce7c78a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Poggi?= Date: Tue, 29 Jul 2014 15:27:27 +0200 Subject: [PATCH 0941/9167] mtd: atmel_nand: increase chip_delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some nand with 8k page size like Micron MT29F32G08ABAAAWP need more than 20us. Signed-off-by: Raphaël Poggi Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index e321c564ff05..77bd877d8f28 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -2099,7 +2099,7 @@ static int atmel_nand_probe(struct platform_device *pdev) } nand_chip->ecc.mode = host->board.ecc_mode; - nand_chip->chip_delay = 20; /* 20us command delay time */ + nand_chip->chip_delay = 40; /* 40us command delay time */ if (host->board.bus_width_16) /* 16-bit bus width */ nand_chip->options |= NAND_BUSWIDTH_16; -- GitLab From a35571058ec8e7c82dceea90cdecead51674f963 Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Tue, 22 Jul 2014 17:24:18 +0800 Subject: [PATCH 0942/9167] mtd: atmel_nand: add pmecc support for 512, 1k, 4k, 8k page size PMECC can support 512, 1k, 2k, 4k, 8k page size. The driver currently only support 2k page size nand flash. So this patch add support to 512, 1k, 4k and 8k page size nand flash. Signed-off-by: Josh Wu Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 77bd877d8f28..e4d57ffef07e 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1174,7 +1174,17 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, /* set ECC page size and oob layout */ switch (mtd->writesize) { + case 512: + case 1024: case 2048: + case 4096: + case 8192: + if (sector_size > mtd->writesize) { + dev_err(host->dev, "pmecc sector size is bigger than the page size!\n"); + err_no = -EINVAL; + goto err; + } + host->pmecc_degree = (sector_size == 512) ? PMECC_GF_DIMENSION_13 : PMECC_GF_DIMENSION_14; host->pmecc_cw_len = (1 << host->pmecc_degree) - 1; @@ -1201,13 +1211,9 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, nand_chip->ecc.layout = &atmel_pmecc_oobinfo; break; - case 512: - case 1024: - case 4096: - /* TODO */ + default: dev_warn(host->dev, "Unsupported page size for PMECC, use Software ECC\n"); - default: /* page size not handled by HW ECC */ /* switching back to soft ECC */ nand_chip->ecc.mode = NAND_ECC_SOFT; -- GitLab From 7b7d8982f0169d5ac67c6c2877449fb7f6968cac Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 27 Jul 2014 14:31:53 -0700 Subject: [PATCH 0943/9167] mtd: fix linux/mtd/nand.h kernel-doc warning Fix kernel-doc warning in : Warning(..//include/linux/mtd/nand.h:795): No description found for parameter 'ecc' Signed-off-by: Randy Dunlap Cc: David Woodhouse Cc: Brian Norris Cc: linux-mtd@lists.infradead.org Signed-off-by: Brian Norris --- include/linux/mtd/nand.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 3083c53e0270..b7c11991cb09 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -766,6 +766,7 @@ struct nand_chip { * @options: stores various chip bit options * @id_len: The valid length of the @id. * @oobsize: OOB size + * @ecc: ECC correctability and step information from the datasheet. * @ecc.strength_ds: The ECC correctability from the datasheet, same as the * @ecc_strength_ds in nand_chip{}. * @ecc.step_ds: The ECC step required by the @ecc.strength_ds, same as the -- GitLab From f2fabe16b819cdead86fb38c8ab88a0d9c308293 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Sun, 27 Jul 2014 23:56:08 +0200 Subject: [PATCH 0944/9167] mtd: spi-nor: add support for Micron M25PX80 This commit adds the support in the spi-nor driver of the Micron M25PX80 flash, a 8 Mbit SPI flash from Micron. Signed-off-by: Thomas Petazzoni Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index b5ad6bebf5e7..4dc0c8662265 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -611,6 +611,7 @@ const struct spi_device_id spi_nor_ids[] = { { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, { "m25px64", INFO(0x207117, 0, 64 * 1024, 128, 0) }, + { "m25px80", INFO(0x207114, 0, 64 * 1024, 16, 0) }, /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) }, -- GitLab From 8fb7b9309c41407801958138db978eb38fd80c01 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Mon, 28 Jul 2014 21:19:55 +0800 Subject: [PATCH 0945/9167] mtd: atmel_nand: remove redundant dev_err call There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Signed-off-by: Wei Yongjun Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index e4d57ffef07e..0abc965caedf 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1148,7 +1148,6 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, host->ecc = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(host->ecc)) { - dev_err(host->dev, "ioremap failed\n"); err_no = PTR_ERR(host->ecc); goto err; } @@ -1156,8 +1155,6 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, regs_pmerr = platform_get_resource(pdev, IORESOURCE_MEM, 2); host->pmerrloc_base = devm_ioremap_resource(&pdev->dev, regs_pmerr); if (IS_ERR(host->pmerrloc_base)) { - dev_err(host->dev, - "Can not get I/O resource for PMECC ERRLOC controller!\n"); err_no = PTR_ERR(host->pmerrloc_base); goto err; } @@ -1165,7 +1162,6 @@ static int atmel_pmecc_nand_init_params(struct platform_device *pdev, regs_rom = platform_get_resource(pdev, IORESOURCE_MEM, 3); host->pmecc_rom_base = devm_ioremap_resource(&pdev->dev, regs_rom); if (IS_ERR(host->pmecc_rom_base)) { - dev_err(host->dev, "Can not get I/O resource for ROM!\n"); err_no = PTR_ERR(host->pmecc_rom_base); goto err; } @@ -1536,10 +1532,8 @@ static int atmel_hw_nand_init_params(struct platform_device *pdev, } host->ecc = devm_ioremap_resource(&pdev->dev, regs); - if (IS_ERR(host->ecc)) { - dev_err(host->dev, "ioremap failed\n"); + if (IS_ERR(host->ecc)) return PTR_ERR(host->ecc); - } /* ECC is calculated for the whole page (1 step) */ nand_chip->ecc.size = mtd->writesize; @@ -2046,7 +2040,6 @@ static int atmel_nand_probe(struct platform_device *pdev) mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); host->io_base = devm_ioremap_resource(&pdev->dev, mem); if (IS_ERR(host->io_base)) { - dev_err(&pdev->dev, "atmel_nand: ioremap resource failed\n"); res = PTR_ERR(host->io_base); goto err_nand_ioremap; } -- GitLab From 2902330e7ac16d5962f114d92bb17631e9cb49e9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 11 Jul 2014 11:14:05 +0900 Subject: [PATCH 0946/9167] mtd: denali: avoid using a magic number MAP10 command with '0x2000' data sets up a read-ahead/write access. Signed-off-by: Masahiro Yamada Signed-off-by: Brian Norris --- drivers/mtd/nand/denali.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 0b071a3136a2..da0fcc224739 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -74,6 +74,7 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting." #define SPARE_ACCESS 0x41 #define MAIN_ACCESS 0x42 #define MAIN_SPARE_ACCESS 0x43 +#define PIPELINE_ACCESS 0x2000 #define DENALI_READ 0 #define DENALI_WRITE 0x100 @@ -765,7 +766,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali, iowrite32(cmd, denali->flash_mem); } else { index_addr(denali, (uint32_t)cmd, - 0x2000 | op | page_count); + PIPELINE_ACCESS | op | page_count); /* wait for command to be accepted * can always use status0 bit as the -- GitLab From 6f3c0f163103fb225c77b73ca17fc4ecea308103 Mon Sep 17 00:00:00 2001 From: Samarth Parikh Date: Wed, 16 Jul 2014 16:14:37 +0530 Subject: [PATCH 0947/9167] mtd: Fixed checkpatch seq_printf warnings Fixed checkpatch warnings: "WARNING: Prefer seq_puts to seq_printf" This patch is created with reference to the ongoing lkml thread https://lkml.org/lkml/2014/7/15/646 where Andrew Morton wrote: " - puts is presumably faster - puts doesn't go rogue if you accidentally pass it a "%". - this patch would actually make compiled object files few bytes smaller. Perhaps because seq_printf() is a varargs function, forcing the caller to pass args on the stack instead of in registers. " Signed-off-by: Samarth Parikh Signed-off-by: Brian Norris --- drivers/mtd/devices/docg3.c | 26 +++++++++++++------------- drivers/mtd/mtdswap.c | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 91a169c44b39..21cc4b66feaa 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1697,16 +1697,16 @@ static int dbg_asicmode_show(struct seq_file *s, void *p) switch (mode) { case DOC_ASICMODE_RESET: - pos += seq_printf(s, "reset"); + pos += seq_puts(s, "reset"); break; case DOC_ASICMODE_NORMAL: - pos += seq_printf(s, "normal"); + pos += seq_puts(s, "normal"); break; case DOC_ASICMODE_POWERDOWN: - pos += seq_printf(s, "powerdown"); + pos += seq_puts(s, "powerdown"); break; } - pos += seq_printf(s, ")\n"); + pos += seq_puts(s, ")\n"); return pos; } DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show); @@ -1745,22 +1745,22 @@ static int dbg_protection_show(struct seq_file *s, void *p) pos += seq_printf(s, "Protection = 0x%02x (", protect); if (protect & DOC_PROTECT_FOUNDRY_OTP_LOCK) - pos += seq_printf(s, "FOUNDRY_OTP_LOCK,"); + pos += seq_puts(s, "FOUNDRY_OTP_LOCK,"); if (protect & DOC_PROTECT_CUSTOMER_OTP_LOCK) - pos += seq_printf(s, "CUSTOMER_OTP_LOCK,"); + pos += seq_puts(s, "CUSTOMER_OTP_LOCK,"); if (protect & DOC_PROTECT_LOCK_INPUT) - pos += seq_printf(s, "LOCK_INPUT,"); + pos += seq_puts(s, "LOCK_INPUT,"); if (protect & DOC_PROTECT_STICKY_LOCK) - pos += seq_printf(s, "STICKY_LOCK,"); + pos += seq_puts(s, "STICKY_LOCK,"); if (protect & DOC_PROTECT_PROTECTION_ENABLED) - pos += seq_printf(s, "PROTECTION ON,"); + pos += seq_puts(s, "PROTECTION ON,"); if (protect & DOC_PROTECT_IPL_DOWNLOAD_LOCK) - pos += seq_printf(s, "IPL_DOWNLOAD_LOCK,"); + pos += seq_puts(s, "IPL_DOWNLOAD_LOCK,"); if (protect & DOC_PROTECT_PROTECTION_ERROR) - pos += seq_printf(s, "PROTECT_ERR,"); + pos += seq_puts(s, "PROTECT_ERR,"); else - pos += seq_printf(s, "NO_PROTECT_ERR"); - pos += seq_printf(s, ")\n"); + 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, " diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index 8b33b26eb12b..0ec96cd5dc78 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c @@ -1287,7 +1287,7 @@ static int mtdswap_show(struct seq_file *s, void *data) seq_printf(s, "total erasures: %lu\n", sum); - seq_printf(s, "\n"); + seq_puts(s, "\n"); seq_printf(s, "mtdswap_readsect count: %llu\n", d->sect_read_count); seq_printf(s, "mtdswap_writesect count: %llu\n", d->sect_write_count); @@ -1296,7 +1296,7 @@ static int mtdswap_show(struct seq_file *s, void *data) seq_printf(s, "mtd write count: %llu\n", d->mtd_write_count); seq_printf(s, "discarded pages count: %llu\n", d->discard_page_count); - seq_printf(s, "\n"); + seq_puts(s, "\n"); seq_printf(s, "total pages: %u\n", pages); seq_printf(s, "pages mapped: %u\n", mapped); -- GitLab From 57d3a9a89a0645f3597561e214f8d6852a2c56b4 Mon Sep 17 00:00:00 2001 From: White Ding Date: Thu, 24 Jul 2014 00:10:45 +0800 Subject: [PATCH 0948/9167] mtd: nand: fix nand_lock/unlock() function Do nand reset before write protect check. If we want to check the WP# low or high through STATUS READ and check bit 7, we must reset the device, other operation (eg.erase/program a locked block) can also clear the bit 7 of status register. As we know the status register can be refreshed, if we do some operation to trigger it, for example if we do erase/program operation to one block that is locked, then READ STATUS, the bit 7 of READ STATUS will be 0 indicate the device in write protect, then if we do erase/program operation to another block that is unlocked, the bit 7 of READ STATUS will be 1 indicate the device is not write protect. Suppose we checked the bit 7 of READ STATUS is 0 then judge the WP# is low (write protect), but in this case the WP# maybe high if we do erase/program operation to a locked block, so we must reset the device if we want to check the WP# low or high through STATUS READ and check bit 7. Signed-off-by: White Ding Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_base.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index d8cdf06343fb..1a27c2da29ff 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -982,6 +982,15 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) chip->select_chip(mtd, chipnr); + /* + * Reset the chip. + * If we want to check the WP through READ STATUS and check the bit 7 + * we must reset the chip + * some operation can also clear the bit 7 of status register + * eg. erase/program a locked block + */ + chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + /* Check, if it is write protected */ if (nand_check_wp(mtd)) { pr_debug("%s: device is write protected!\n", @@ -1032,6 +1041,15 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) chip->select_chip(mtd, chipnr); + /* + * Reset the chip. + * If we want to check the WP through READ STATUS and check the bit 7 + * we must reset the chip + * some operation can also clear the bit 7 of status register + * eg. erase/program a locked block + */ + chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); + /* Check, if it is write protected */ if (nand_check_wp(mtd)) { pr_debug("%s: device is write protected!\n", -- GitLab From 36c6a7ac74044b8025488c018279115bb3c32eb0 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:06:19 -0700 Subject: [PATCH 0949/9167] mtd: cfi_cmdset_0002: allow retry/timeout loop to exit The variable 'retries' is never modified, so if the reset operation never is going to complete, we'll get stuck in an infinite loop. It looks like the intention was to decrement 'retries' on every loop. Untested. Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/chips/cfi_cmdset_0002.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 5a4bfe33112a..6da141af9cba 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -2029,6 +2029,8 @@ static int cfi_amdstd_panic_wait(struct map_info *map, struct flchip *chip, udelay(1); } + + retries--; } /* the chip never became ready */ -- GitLab From 0c2b4e21444d0e274e91fc7db85caddb30988853 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:06:27 -0700 Subject: [PATCH 0950/9167] mtd: correct upper bounds check for mtd_*() APIs When checking the upper boundary (i.e., whether an address is higher than the maximum size of the MTD), we should be doing an inclusive check (greater or equal). For instance, an address of 16MB (0x1000000) on a 16MB device is invalid. The strengthening of this bounds check is redundant for those which already have a address+length check and ensure that the length is non-zero, but let's just fix them all, for completeness. Signed-off-by: Brian Norris --- drivers/mtd/mtdcore.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index e4831b4159db..c1015173f2d9 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -778,7 +778,7 @@ EXPORT_SYMBOL_GPL(__put_mtd_device); */ int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) { - if (instr->addr > mtd->size || instr->len > mtd->size - instr->addr) + if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr) return -EINVAL; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; @@ -804,7 +804,7 @@ int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, *phys = 0; if (!mtd->_point) return -EOPNOTSUPP; - if (from < 0 || from > mtd->size || len > mtd->size - from) + if (from < 0 || from >= mtd->size || len > mtd->size - from) return -EINVAL; if (!len) return 0; @@ -817,7 +817,7 @@ int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) { if (!mtd->_point) return -EOPNOTSUPP; - if (from < 0 || from > mtd->size || len > mtd->size - from) + if (from < 0 || from >= mtd->size || len > mtd->size - from) return -EINVAL; if (!len) return 0; @@ -835,7 +835,7 @@ unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len, { if (!mtd->_get_unmapped_area) return -EOPNOTSUPP; - if (offset > mtd->size || len > mtd->size - offset) + if (offset >= mtd->size || len > mtd->size - offset) return -EINVAL; return mtd->_get_unmapped_area(mtd, len, offset, flags); } @@ -846,7 +846,7 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, { int ret_code; *retlen = 0; - if (from < 0 || from > mtd->size || len > mtd->size - from) + if (from < 0 || from >= mtd->size || len > mtd->size - from) return -EINVAL; if (!len) return 0; @@ -869,7 +869,7 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) { *retlen = 0; - if (to < 0 || to > mtd->size || len > mtd->size - to) + if (to < 0 || to >= mtd->size || len > mtd->size - to) return -EINVAL; if (!mtd->_write || !(mtd->flags & MTD_WRITEABLE)) return -EROFS; @@ -892,7 +892,7 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, *retlen = 0; if (!mtd->_panic_write) return -EOPNOTSUPP; - if (to < 0 || to > mtd->size || len > mtd->size - to) + if (to < 0 || to >= mtd->size || len > mtd->size - to) return -EINVAL; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; @@ -1011,7 +1011,7 @@ int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { if (!mtd->_lock) return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) return -EINVAL; if (!len) return 0; @@ -1023,7 +1023,7 @@ int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) { if (!mtd->_unlock) return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) return -EINVAL; if (!len) return 0; @@ -1035,7 +1035,7 @@ int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) { if (!mtd->_is_locked) return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size || len > mtd->size - ofs) + if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) return -EINVAL; if (!len) return 0; @@ -1045,7 +1045,7 @@ EXPORT_SYMBOL_GPL(mtd_is_locked); int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs) { - if (ofs < 0 || ofs > mtd->size) + if (ofs < 0 || ofs >= mtd->size) return -EINVAL; if (!mtd->_block_isreserved) return 0; @@ -1055,7 +1055,7 @@ EXPORT_SYMBOL_GPL(mtd_block_isreserved); int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) { - if (ofs < 0 || ofs > mtd->size) + if (ofs < 0 || ofs >= mtd->size) return -EINVAL; if (!mtd->_block_isbad) return 0; @@ -1067,7 +1067,7 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) { if (!mtd->_block_markbad) return -EOPNOTSUPP; - if (ofs < 0 || ofs > mtd->size) + if (ofs < 0 || ofs >= mtd->size) return -EINVAL; if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; -- GitLab From f7f0d358f5f2f1133b5a14337028ddab848cd74e Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:06:39 -0700 Subject: [PATCH 0951/9167] mtd: sm_ftl: initialize error code There is one theoretical case that could fall through to using an uninitialized value as the return code. Let's give it a value of 0. Untested. Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/sm_ftl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index cf49c22673b9..c23184a47fc4 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -1058,7 +1058,7 @@ static int sm_write(struct mtd_blktrans_dev *dev, { struct sm_ftl *ftl = dev->priv; struct ftl_zone *zone; - int error, zone_num, block, boffset; + int error = 0, zone_num, block, boffset; BUG_ON(ftl->readonly); sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset); -- GitLab From 5e47212831ac565993d21ebd36216d98f2b58f30 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:06:47 -0700 Subject: [PATCH 0952/9167] mtd: remove dead non-char logic MTD used to allow compiling out character device support. This was dropped in the following commit, but some of the accompanying logic was never dropped: commit 660685d9d1b4730f0b5ca97fa95f272f99c63bce Author: Artem Bityutskiy Date: Thu Mar 14 13:27:40 2013 +0200 mtd: merge mtdchar module with mtdcore The weird logic was flagged by Coverity. Signed-off-by: Brian Norris Cc: Artem Bityutskiy --- drivers/mtd/mtdcore.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index c1015173f2d9..4c611871d7e6 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -105,12 +105,11 @@ static LIST_HEAD(mtd_notifiers); */ static void mtd_release(struct device *dev) { - struct mtd_info __maybe_unused *mtd = dev_get_drvdata(dev); + struct mtd_info *mtd = dev_get_drvdata(dev); dev_t index = MTD_DEVT(mtd->index); - /* remove /dev/mtdXro node if needed */ - if (index) - device_destroy(&mtd_class, index + 1); + /* remove /dev/mtdXro node */ + device_destroy(&mtd_class, index + 1); } static int mtd_cls_suspend(struct device *dev, pm_message_t state) @@ -442,10 +441,8 @@ int add_mtd_device(struct mtd_info *mtd) if (device_register(&mtd->dev) != 0) goto fail_added; - if (MTD_DEVT(i)) - device_create(&mtd_class, mtd->dev.parent, - MTD_DEVT(i) + 1, - NULL, "mtd%dro", i); + device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL, + "mtd%dro", i); pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name); /* No need to get a refcount on the module containing -- GitLab From 8c3f3f1d7941bcb25590b784f84accd7dcb44ba3 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:02 -0700 Subject: [PATCH 0953/9167] mtd: mtdswap: fix integer overflow Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/mtdswap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index 0ec96cd5dc78..48cf6f98df44 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c @@ -1474,7 +1474,7 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) } eblocks = mtd_div_by_eb(use_size, mtd); - use_size = eblocks * mtd->erasesize; + use_size = (uint64_t)eblocks * mtd->erasesize; bad_blocks = mtdswap_badblocks(mtd, use_size); eavailable = eblocks - bad_blocks; -- GitLab From 1001ff7a4f64f3f4264e69d3ed70ff428f627e01 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:12 -0700 Subject: [PATCH 0954/9167] mtd: tests: fix integer overflow issues These multiplications are done with 32-bit arithmetic, then converted to 64-bit. We should widen the integers first to prevent overflow. This could be a problem for large (>4GB) MTD's. Detected by Coverity. Signed-off-by: Brian Norris Cc: Akinobu Mita --- drivers/mtd/tests/mtd_test.c | 4 ++-- drivers/mtd/tests/nandbiterrs.c | 2 +- drivers/mtd/tests/oobtest.c | 8 ++++---- drivers/mtd/tests/pagetest.c | 4 ++-- drivers/mtd/tests/readtest.c | 2 +- drivers/mtd/tests/speedtest.c | 14 +++++++------- drivers/mtd/tests/subpagetest.c | 10 +++++----- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/tests/mtd_test.c b/drivers/mtd/tests/mtd_test.c index 111ee46a7428..34736bbcc07b 100644 --- a/drivers/mtd/tests/mtd_test.c +++ b/drivers/mtd/tests/mtd_test.c @@ -10,7 +10,7 @@ int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum) { int err; struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; memset(&ei, 0, sizeof(struct erase_info)); ei.mtd = mtd; @@ -33,7 +33,7 @@ int mtdtest_erase_eraseblock(struct mtd_info *mtd, unsigned int ebnum) static int is_block_bad(struct mtd_info *mtd, unsigned int ebnum) { int ret; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; ret = mtd_block_isbad(mtd, addr); if (ret) diff --git a/drivers/mtd/tests/nandbiterrs.c b/drivers/mtd/tests/nandbiterrs.c index 6f976159611f..273f7e553954 100644 --- a/drivers/mtd/tests/nandbiterrs.c +++ b/drivers/mtd/tests/nandbiterrs.c @@ -364,7 +364,7 @@ static int __init mtd_nandbiterrs_init(void) pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize); - offset = page_offset * mtd->writesize; + offset = (loff_t)page_offset * mtd->writesize; eraseblock = mtd_div_by_eb(offset, mtd); pr_info("Using page=%u, offset=%llu, eraseblock=%u\n", diff --git a/drivers/mtd/tests/oobtest.c b/drivers/mtd/tests/oobtest.c index f19ab1acde1f..dc4f9602b97e 100644 --- a/drivers/mtd/tests/oobtest.c +++ b/drivers/mtd/tests/oobtest.c @@ -120,7 +120,7 @@ static int verify_eraseblock(int ebnum) int i; struct mtd_oob_ops ops; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, use_len_max * pgcnt); for (i = 0; i < pgcnt; ++i, addr += mtd->writesize) { @@ -214,7 +214,7 @@ static int verify_eraseblock_in_one_go(int ebnum) { struct mtd_oob_ops ops; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; size_t len = mtd->ecclayout->oobavail * pgcnt; prandom_bytes_state(&rnd_state, writebuf, len); @@ -568,7 +568,7 @@ static int __init mtd_oobtest_init(void) size_t sz = mtd->ecclayout->oobavail; if (bbt[i] || bbt[i + 1]) continue; - addr = (i + 1) * mtd->erasesize - mtd->writesize; + addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize; prandom_bytes_state(&rnd_state, writebuf, sz * cnt); for (pg = 0; pg < cnt; ++pg) { ops.mode = MTD_OPS_AUTO_OOB; @@ -598,7 +598,7 @@ static int __init mtd_oobtest_init(void) continue; prandom_bytes_state(&rnd_state, writebuf, mtd->ecclayout->oobavail * 2); - addr = (i + 1) * mtd->erasesize - mtd->writesize; + addr = (loff_t)(i + 1) * mtd->erasesize - mtd->writesize; ops.mode = MTD_OPS_AUTO_OOB; ops.len = 0; ops.retlen = 0; diff --git a/drivers/mtd/tests/pagetest.c b/drivers/mtd/tests/pagetest.c index ed2d3f656fd2..88296e888e9d 100644 --- a/drivers/mtd/tests/pagetest.c +++ b/drivers/mtd/tests/pagetest.c @@ -52,7 +52,7 @@ static struct rnd_state rnd_state; static int write_eraseblock(int ebnum) { - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, mtd->erasesize); cond_resched(); @@ -64,7 +64,7 @@ static int verify_eraseblock(int ebnum) uint32_t j; int err = 0, i; loff_t addr0, addrn; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; addr0 = 0; for (i = 0; i < ebcnt && bbt[i]; ++i) diff --git a/drivers/mtd/tests/readtest.c b/drivers/mtd/tests/readtest.c index 626e66d0f7e7..a54cf1511114 100644 --- a/drivers/mtd/tests/readtest.c +++ b/drivers/mtd/tests/readtest.c @@ -47,7 +47,7 @@ static int pgcnt; static int read_eraseblock_by_page(int ebnum) { int i, ret, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; void *oobbuf = iobuf1; diff --git a/drivers/mtd/tests/speedtest.c b/drivers/mtd/tests/speedtest.c index 87ff6a29f84e..5ee9f7021020 100644 --- a/drivers/mtd/tests/speedtest.c +++ b/drivers/mtd/tests/speedtest.c @@ -55,7 +55,7 @@ static int multiblock_erase(int ebnum, int blocks) { int err; struct erase_info ei; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; memset(&ei, 0, sizeof(struct erase_info)); ei.mtd = mtd; @@ -80,7 +80,7 @@ static int multiblock_erase(int ebnum, int blocks) static int write_eraseblock(int ebnum) { - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; return mtdtest_write(mtd, addr, mtd->erasesize, iobuf); } @@ -88,7 +88,7 @@ static int write_eraseblock(int ebnum) static int write_eraseblock_by_page(int ebnum) { int i, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < pgcnt; i++) { @@ -106,7 +106,7 @@ static int write_eraseblock_by_2pages(int ebnum) { size_t sz = pgsize * 2; int i, n = pgcnt / 2, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < n; i++) { @@ -124,7 +124,7 @@ static int write_eraseblock_by_2pages(int ebnum) static int read_eraseblock(int ebnum) { - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; return mtdtest_read(mtd, addr, mtd->erasesize, iobuf); } @@ -132,7 +132,7 @@ static int read_eraseblock(int ebnum) static int read_eraseblock_by_page(int ebnum) { int i, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < pgcnt; i++) { @@ -150,7 +150,7 @@ static int read_eraseblock_by_2pages(int ebnum) { size_t sz = pgsize * 2; int i, n = pgcnt / 2, err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; void *buf = iobuf; for (i = 0; i < n; i++) { diff --git a/drivers/mtd/tests/subpagetest.c b/drivers/mtd/tests/subpagetest.c index a876371ad410..7b59ef522d5e 100644 --- a/drivers/mtd/tests/subpagetest.c +++ b/drivers/mtd/tests/subpagetest.c @@ -57,7 +57,7 @@ static int write_eraseblock(int ebnum) { size_t written; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, subpgsize); err = mtd_write(mtd, addr, subpgsize, &written, writebuf); @@ -92,7 +92,7 @@ static int write_eraseblock2(int ebnum) { size_t written; int err = 0, k; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; for (k = 1; k < 33; ++k) { if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize) @@ -131,7 +131,7 @@ static int verify_eraseblock(int ebnum) { size_t read; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; prandom_bytes_state(&rnd_state, writebuf, subpgsize); clear_data(readbuf, subpgsize); @@ -192,7 +192,7 @@ static int verify_eraseblock2(int ebnum) { size_t read; int err = 0, k; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; for (k = 1; k < 33; ++k) { if (addr + (subpgsize * k) > (ebnum + 1) * mtd->erasesize) @@ -227,7 +227,7 @@ static int verify_eraseblock_ff(int ebnum) uint32_t j; size_t read; int err = 0; - loff_t addr = ebnum * mtd->erasesize; + loff_t addr = (loff_t)ebnum * mtd->erasesize; memset(writebuf, 0xff, subpgsize); for (j = 0; j < mtd->erasesize / subpgsize; ++j) { -- GitLab From 31f754628cbb12c983600f22d9f0fed50dfe2134 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:22 -0700 Subject: [PATCH 0955/9167] mtd: use __packed shorthand Signed-off-by: Brian Norris --- drivers/mtd/mtdswap.c | 2 +- drivers/mtd/nand/sm_common.h | 2 +- include/linux/mtd/cfi.h | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index 48cf6f98df44..fc8b3d16cce7 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c @@ -145,7 +145,7 @@ struct mtdswap_dev { struct mtdswap_oobdata { __le16 magic; __le32 count; -} __attribute__((packed)); +} __packed; #define MTDSWAP_MAGIC_CLEAN 0x2095 #define MTDSWAP_MAGIC_DIRTY (MTDSWAP_MAGIC_CLEAN + 1) diff --git a/drivers/mtd/nand/sm_common.h b/drivers/mtd/nand/sm_common.h index 00f4a83359b2..d3e028e58b0f 100644 --- a/drivers/mtd/nand/sm_common.h +++ b/drivers/mtd/nand/sm_common.h @@ -18,7 +18,7 @@ struct sm_oob { uint8_t ecc2[3]; uint8_t lba_copy2[2]; uint8_t ecc1[3]; -} __attribute__((packed)); +} __packed; /* one sector is always 512 bytes, but it can consist of two nand pages */ diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 37ef6b194089..299d7d31fe53 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -153,7 +153,7 @@ struct cfi_ident { uint16_t MaxBufWriteSize; uint8_t NumEraseRegions; uint32_t EraseRegionInfo[0]; /* Not host ordered */ -} __attribute__((packed)); +} __packed; /* Extended Query Structure for both PRI and ALT */ @@ -161,7 +161,7 @@ struct cfi_extquery { uint8_t pri[3]; uint8_t MajorVersion; uint8_t MinorVersion; -} __attribute__((packed)); +} __packed; /* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */ @@ -180,7 +180,7 @@ struct cfi_pri_intelext { uint8_t FactProtRegSize; uint8_t UserProtRegSize; uint8_t extra[0]; -} __attribute__((packed)); +} __packed; struct cfi_intelext_otpinfo { uint32_t ProtRegAddr; @@ -188,7 +188,7 @@ struct cfi_intelext_otpinfo { uint8_t FactProtRegSize; uint16_t UserGroups; uint8_t UserProtRegSize; -} __attribute__((packed)); +} __packed; struct cfi_intelext_blockinfo { uint16_t NumIdentBlocks; @@ -196,7 +196,7 @@ struct cfi_intelext_blockinfo { uint16_t MinBlockEraseCycles; uint8_t BitsPerCell; uint8_t BlockCap; -} __attribute__((packed)); +} __packed; struct cfi_intelext_regioninfo { uint16_t NumIdentPartitions; @@ -205,7 +205,7 @@ struct cfi_intelext_regioninfo { uint8_t NumOpAllowedSimEraMode; uint8_t NumBlockTypes; struct cfi_intelext_blockinfo BlockTypes[1]; -} __attribute__((packed)); +} __packed; struct cfi_intelext_programming_regioninfo { uint8_t ProgRegShift; @@ -214,7 +214,7 @@ struct cfi_intelext_programming_regioninfo { uint8_t Reserved2; uint8_t ControlInvalid; uint8_t Reserved3; -} __attribute__((packed)); +} __packed; /* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ @@ -233,7 +233,7 @@ struct cfi_pri_amdstd { uint8_t VppMin; uint8_t VppMax; uint8_t TopBottom; -} __attribute__((packed)); +} __packed; /* Vendor-Specific PRI for Atmel chips (command set 0x0002) */ @@ -245,18 +245,18 @@ struct cfi_pri_atmel { uint8_t BottomBoot; uint8_t BurstMode; uint8_t PageMode; -} __attribute__((packed)); +} __packed; struct cfi_pri_query { uint8_t NumFields; uint32_t ProtField[1]; /* Not host ordered */ -} __attribute__((packed)); +} __packed; struct cfi_bri_query { uint8_t PageModeReadCap; uint8_t NumFields; uint32_t ConfField[1]; /* Not host ordered */ -} __attribute__((packed)); +} __packed; #define P_ID_NONE 0x0000 #define P_ID_INTEL_EXT 0x0001 -- GitLab From c115add9d073752d38f6517882dfeafe76fc4458 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:31 -0700 Subject: [PATCH 0956/9167] mtd: nand: denali: set proper error code on timeout The condition "if (irq_status == 0)" already ensures that one half of the ternary ?: is dead. I think this should probably actually be a FAIL, not a PASS. Caught by Coverity. Signed-off-by: Brian Norris Cc: Jamie Iles --- drivers/mtd/nand/denali.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index da0fcc224739..4885a0f573cd 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -1062,9 +1062,7 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, dev_err(denali->dev, "timeout on write_page (type = %d)\n", raw_xfer); - denali->status = - (irq_status & INTR_STATUS__PROGRAM_FAIL) ? - NAND_STATUS_FAIL : PASS; + denali->status = NAND_STATUS_FAIL; } denali_enable_dma(denali, false); -- GitLab From b033e1aac9afd314add799b6cd2a5489f892757f Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:44 -0700 Subject: [PATCH 0957/9167] mtd: nandsim: fix integer widening This multiplication should be done in 64-bit, not 32-bit. Caught by Coverity. Signed-off-by: Brian Norris --- drivers/mtd/nand/nandsim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 4f0d83648e5a..7dc1dd28d896 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -827,7 +827,7 @@ static int parse_badblocks(struct nandsim *ns, struct mtd_info *mtd) NS_ERR("invalid badblocks.\n"); return -EINVAL; } - offset = erase_block_no * ns->geom.secsz; + offset = (loff_t)erase_block_no * ns->geom.secsz; if (mtd_block_markbad(mtd, offset)) { NS_ERR("invalid badblocks.\n"); return -EINVAL; -- GitLab From 7a6f43958a53020f85818ff5c895623e88781fd6 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:07:56 -0700 Subject: [PATCH 0958/9167] mtd: maps: solutionengine: drop excess dependency Already depends on SOLUTION_ENGINE, so we don't need the SUPERH dependency too. Signed-off-by: Brian Norris --- drivers/mtd/maps/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 21b2874a303b..ba801d2c6dcc 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -249,7 +249,7 @@ config MTD_CFI_FLAGADM config MTD_SOLUTIONENGINE tristate "CFI Flash device mapped on Hitachi SolutionEngine" - depends on SUPERH && SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS + depends on SOLUTION_ENGINE && MTD_CFI && MTD_REDBOOT_PARTS help This enables access to the flash chips on the Hitachi SolutionEngine and similar boards. Say 'Y' if you are building a kernel for such a board. -- GitLab From 537ab1bd47d6518e8a40207a80dd0c2c4bc43aed Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:08:03 -0700 Subject: [PATCH 0959/9167] mtd: nand: fix integer widening problems chip->pagebuf is a 32-bit type (int), so the shift will only be applied as 32-bit. Fix this for 64-bit safety. Caught by Coverity. 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 1a27c2da29ff..ae6e7c47f8e2 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2409,8 +2409,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; /* Invalidate the page cache, when we write to the cached page */ - if (to <= (chip->pagebuf << chip->page_shift) && - (chip->pagebuf << chip->page_shift) < (to + ops->len)) + if (to <= ((loff_t)chip->pagebuf << chip->page_shift) && + ((loff_t)chip->pagebuf << chip->page_shift) < (to + ops->len)) chip->pagebuf = -1; /* Don't allow multipage oob writes with offset */ -- GitLab From 1cc8d8413327a684cd5e93cd52ececb0223bb40b Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Mon, 21 Jul 2014 19:08:13 -0700 Subject: [PATCH 0960/9167] mtd: terminate user-provided string Noticed by Coverity as a potential security issue. Signed-off-by: Brian Norris --- drivers/mtd/mtdchar.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index a0f54e80670c..53563955931b 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -549,6 +549,9 @@ static int mtdchar_blkpg_ioctl(struct mtd_info *mtd, if (mtd_is_partition(mtd)) return -EINVAL; + /* Sanitize user input */ + p.devname[BLKPG_DEVNAMELTH - 1] = '\0'; + return mtd_add_partition(mtd, p.devname, p.start, p.length); case BLKPG_DEL_PARTITION: -- GitLab From ff0a215438cf7be0a652cb3457f562539bd40b22 Mon Sep 17 00:00:00 2001 From: "Wu, Josh" Date: Tue, 5 Aug 2014 18:38:52 +0800 Subject: [PATCH 0961/9167] mtd: atmel_nand: NFC: fix mtd_nandbiterrs.ko test fail when using sram write When enable NFC sram write, it will failed the mtd_nandbiterrs.ko test. As in driver's nfc_sram_write_page(), if ops->mode equal to MTD_OSP_RAW, driver assumes the data buffer contains one page data and one oob data followed. And driver will write the page data and oob data to nand. But this is wrong implementation. Since the data buffer don't contains the oob data to write. We should write the chip->oob_poi to nand's oob. So this patch fix it by writing the oob data from chip->oob_poi. Signed-off-by: Josh Wu Signed-off-by: Brian Norris --- drivers/mtd/nand/atmel_nand.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 0abc965caedf..9c5f717bda54 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -1907,15 +1907,7 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, if (offset || (data_len < mtd->writesize)) return -EINVAL; - cfg = nfc_readl(host->nfc->hsmc_regs, CFG); len = mtd->writesize; - - if (unlikely(raw)) { - len += mtd->oobsize; - nfc_writel(host->nfc->hsmc_regs, CFG, cfg | NFC_CFG_WSPARE); - } else - nfc_writel(host->nfc->hsmc_regs, CFG, cfg & ~NFC_CFG_WSPARE); - /* Copy page data to sram that will write to nand via NFC */ if (use_dma) { if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) != 0) @@ -1925,6 +1917,15 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, memcpy32_toio(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); + len += mtd->oobsize; + nfc_writel(host->nfc->hsmc_regs, CFG, cfg | NFC_CFG_WSPARE); + } else { + nfc_writel(host->nfc->hsmc_regs, CFG, cfg & ~NFC_CFG_WSPARE); + } + if (chip->ecc.mode == NAND_ECC_HW && host->has_pmecc) /* * When use NFC sram, need set up PMECC before send -- GitLab From bd8898db3e03147d9d7ddd48876fb3f3bcbab6c1 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Sat, 9 Aug 2014 19:07:53 +0200 Subject: [PATCH 0962/9167] mtd: nand: Use ULL-suffix for big u64 constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/mtd/nand/nand_timings.c:45: warning: integer constant is too large for ‘long’ type [ Editorial note: This is a false warning. Looking at ISO draft N1124 (this is approximately C11, the first PDF I had lying around), section 6.4.4.1 (statement 5): "The type of an integer constant is the first of the corresponding list in which its value can be represented." So this should not be an overflow, and any toolchain that says so (e.g., GCC 4.4) is buggy. -Brian ] Signed-off-by: Geert Uytterhoeven Signed-off-by: Brian Norris --- drivers/mtd/nand/nand_timings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/nand_timings.c index 8b36253420fa..e81470a8ac67 100644 --- a/drivers/mtd/nand/nand_timings.c +++ b/drivers/mtd/nand/nand_timings.c @@ -42,7 +42,7 @@ static const struct nand_sdr_timings onfi_sdr_timings[] = { .tRHZ_max = 200000, .tRLOH_min = 0, .tRP_min = 50000, - .tRST_max = 250000000000, + .tRST_max = 250000000000ULL, .tWB_max = 200000, .tRR_min = 40000, .tWC_min = 100000, -- GitLab From 02f8a24e7b1c253ee37edc684200c11300de23f9 Mon Sep 17 00:00:00 2001 From: Aaron Wu Date: Thu, 7 Aug 2014 11:43:49 +0800 Subject: [PATCH 0963/9167] mtd: gpio_flash: handle case where offset + len exceeds the window size Fix the bug in handling gpio flash read/write when offset + len from MTD exceeds the window size Signed-off-by: Aaron Wu [Brian: made some commentary edits. Also note that the BUG_ON() was provably false for all non-negative inputs (since x % y <= x), so we dropped it.] Signed-off-by: Brian Norris --- drivers/mtd/maps/gpio-addr-flash.c | 42 ++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index a4c477b9fdd6..2fb346091af2 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c @@ -99,22 +99,28 @@ static map_word gf_read(struct map_info *map, unsigned long ofs) * @from: flash offset to copy from * @len: how much to copy * - * We rely on the MTD layer to chunk up copies such that a single request here - * will not cross a window size. This allows us to only wiggle the GPIOs once - * before falling back to a normal memcpy. Reading the higher layer code shows - * that this is indeed the case, but add a BUG_ON() to future proof. + * The "from" region may straddle more than one window, so toggle the GPIOs for + * each window region before reading its data. */ static void gf_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { struct async_state *state = gf_map_info_to_state(map); - gf_set_gpios(state, from); + int this_len; - /* BUG if operation crosses the win_size */ - BUG_ON(!((from + len) % state->win_size <= (from + len))); + while (len) { + if ((from % state->win_size) + len > state->win_size) + this_len = state->win_size - (from % state->win_size); + else + this_len = len; - /* operation does not cross the win_size, so one shot it */ - memcpy_fromio(to, map->virt + (from % state->win_size), len); + gf_set_gpios(state, from); + memcpy_fromio(to, map->virt + (from % state->win_size), + this_len); + len -= this_len; + from += this_len; + to += this_len; + } } /** @@ -147,13 +153,21 @@ static void gf_copy_to(struct map_info *map, unsigned long to, { struct async_state *state = gf_map_info_to_state(map); - gf_set_gpios(state, to); + int this_len; + + while (len) { + if ((to % state->win_size) + len > state->win_size) + this_len = state->win_size - (to % state->win_size); + else + this_len = len; - /* BUG if operation crosses the win_size */ - BUG_ON(!((to + len) % state->win_size <= (to + len))); + gf_set_gpios(state, to); + memcpy_toio(map->virt + (to % state->win_size), from, len); - /* operation does not cross the win_size, so one shot it */ - memcpy_toio(map->virt + (to % state->win_size), from, len); + len -= this_len; + to += this_len; + from += this_len; + } } static const char * const part_probe_types[] = { -- GitLab From ab75e89c013d8fff8bd8a6e520d184c3da1a4583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 7 Aug 2014 09:47:01 +0200 Subject: [PATCH 0964/9167] mtd: spi-nor: remove duplicated w25q128 entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Acked-by: Huang Shijie Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 4dc0c8662265..2fea172dd530 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -624,7 +624,6 @@ const struct spi_device_id spi_nor_ids[] = { { "w25q32dw", INFO(0xef6016, 0, 64 * 1024, 64, SECT_4K) }, { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) }, -- GitLab From 54ea17a597b00e46b3720e75dd7595cd5dfa5670 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Thu, 7 Aug 2014 09:47:02 +0200 Subject: [PATCH 0965/9167] mtd: spi-nor: drop jedec_probe /helper/ function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's a one-liner doing no magic and its name may be confusing because it does not have to use JEDEC (e.g. when using alternative read_id). Signed-off-by: Rafał Miłecki Acked-by: Huang Shijie Signed-off-by: Brian Norris --- drivers/mtd/spi-nor/spi-nor.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 2fea172dd530..03e0ab8b2086 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -671,11 +671,6 @@ static const struct spi_device_id *spi_nor_read_id(struct spi_nor *nor) return ERR_PTR(-ENODEV); } -static const struct spi_device_id *jedec_probe(struct spi_nor *nor) -{ - return nor->read_id(nor); -} - static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { @@ -958,7 +953,7 @@ int spi_nor_scan(struct spi_nor *nor, const struct spi_device_id *id, if (info->jedec_id) { const struct spi_device_id *jid; - jid = jedec_probe(nor); + jid = nor->read_id(nor); if (IS_ERR(jid)) { return PTR_ERR(jid); } else if (jid != id) { -- GitLab From f0d61161620019599868a5840df16a9d483a96cf Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Aug 2014 09:29:00 +0100 Subject: [PATCH 0966/9167] MAINTAINERS: Add designated reviewers for IIO subsystem Add those persons who generally tend to review new IIO patches to the list of designated reviewers to make sure that they are Cc'ed on new patches. Signed-off-by: Lars-Peter Clausen Acked-by: Peter Meerwald Acked-by: Hartmut Knaack Signed-off-by: Jonathan Cameron --- MAINTAINERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6d2c52ea407d..23aee9f6ec47 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4537,6 +4537,9 @@ F: drivers/media/rc/iguanair.c IIO SUBSYSTEM AND DRIVERS M: Jonathan Cameron +R: Hartmut Knaack +R: Lars-Peter Clausen +R: Peter Meerwald L: linux-iio@vger.kernel.org S: Maintained F: drivers/iio/ -- GitLab From 4ce72abc6ea768d6f214456adcd7e0a293cbc065 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Aug 2014 09:08:00 +0100 Subject: [PATCH 0967/9167] MAINTAINERS: Add entry for Analog Devices IIO drivers Add Michael and myself as the maintainer for the Analog Devices IIO drivers. The entry matches on all files in drivers/staging/iio and drivers/iio/ starting with the 'ad' prefix, except for 'adjd' as that one is used by Avago Technologies. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- MAINTAINERS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 23aee9f6ec47..316218cd9d1f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -666,6 +666,17 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers) W: http://blackfin.uclinux.org/ S: Supported F: sound/soc/blackfin/* + +ANALOG DEVICES INC IIO DRIVERS +M: Lars-Peter Clausen +M: Michael Hennerich +W: http://wiki.analog.com/ +W: http://ez.analog.com/community/linux-device-drivers +S: Supported +F: drivers/iio/*/ad* +X: drivers/iio/*/adjd* +F: drivers/staging/iio/*/ad* +F: staging/iio/trigger/iio-trig-bfin-timer.c AOA (Apple Onboard Audio) ALSA DRIVER M: Johannes Berg -- GitLab From c83441e0a7f45f19e8955ce45febaefa66e9e1af Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 18 Aug 2014 08:57:00 +0100 Subject: [PATCH 0968/9167] staging:iio: Remove ad5930/ad9850/ad9852/ad9910/ad9951 dummy drivers All what these 'drivers' do is expose a single (non standard ABI) sysfs attribute that when written to does a direct pass-through to spi_write(). This is rather ugly and does not justify the existence of a driver as the same can easily done by using the spidev interface. The drivers will eventually be rewritten as proper IIO ABI compliant drivers which do have the proper abstraction layers between userspace and the device. But in the meantime these driver do not add any extra value and just clutter up the staging area. So just remove them. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/staging/iio/frequency/Kconfig | 35 --- drivers/staging/iio/frequency/Makefile | 5 - drivers/staging/iio/frequency/ad5930.c | 140 ---------- drivers/staging/iio/frequency/ad9850.c | 120 -------- drivers/staging/iio/frequency/ad9852.c | 245 ---------------- drivers/staging/iio/frequency/ad9910.c | 371 ------------------------- drivers/staging/iio/frequency/ad9951.c | 201 -------------- 7 files changed, 1117 deletions(-) delete mode 100644 drivers/staging/iio/frequency/ad5930.c delete mode 100644 drivers/staging/iio/frequency/ad9850.c delete mode 100644 drivers/staging/iio/frequency/ad9852.c delete mode 100644 drivers/staging/iio/frequency/ad9910.c delete mode 100644 drivers/staging/iio/frequency/ad9951.c diff --git a/drivers/staging/iio/frequency/Kconfig b/drivers/staging/iio/frequency/Kconfig index 93b7141b2c1f..fc726d3c64a6 100644 --- a/drivers/staging/iio/frequency/Kconfig +++ b/drivers/staging/iio/frequency/Kconfig @@ -3,13 +3,6 @@ # menu "Direct Digital Synthesis" -config AD5930 - tristate "Analog Devices ad5930/5932 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad5930/ad5932, provides direct access via sysfs. - config AD9832 tristate "Analog Devices ad9832/5 driver" depends on SPI @@ -30,32 +23,4 @@ config AD9834 To compile this driver as a module, choose M here: the module will be called ad9834. -config AD9850 - tristate "Analog Devices ad9850/1 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad9850/1, provides direct access via sysfs. - -config AD9852 - tristate "Analog Devices ad9852/4 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad9852/4, provides direct access via sysfs. - -config AD9910 - tristate "Analog Devices ad9910 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad9910, provides direct access via sysfs. - -config AD9951 - tristate "Analog Devices ad9951 driver" - depends on SPI - help - Say yes here to build support for Analog Devices DDS chip - ad9951, provides direct access via sysfs. - endmenu diff --git a/drivers/staging/iio/frequency/Makefile b/drivers/staging/iio/frequency/Makefile index 147746176b9b..e5dbcfce44f9 100644 --- a/drivers/staging/iio/frequency/Makefile +++ b/drivers/staging/iio/frequency/Makefile @@ -2,10 +2,5 @@ # Makefile for Direct Digital Synthesis drivers # -obj-$(CONFIG_AD5930) += ad5930.o obj-$(CONFIG_AD9832) += ad9832.o obj-$(CONFIG_AD9834) += ad9834.o -obj-$(CONFIG_AD9850) += ad9850.o -obj-$(CONFIG_AD9852) += ad9852.o -obj-$(CONFIG_AD9910) += ad9910.o -obj-$(CONFIG_AD9951) += ad9951.o diff --git a/drivers/staging/iio/frequency/ad5930.c b/drivers/staging/iio/frequency/ad5930.c deleted file mode 100644 index a4aeee6ffdf2..000000000000 --- a/drivers/staging/iio/frequency/ad5930.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad5930 - * - * Copyright (c) 2010-2010 Analog Devices 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 - -#define DRV_NAME "ad5930" - -#define value_mask (u16)0xf000 -#define addr_shift 12 - -/* Register format: 4 bits addr + 12 bits value */ -struct ad5903_config { - u16 control; - u16 incnum; - u16 frqdelt[2]; - u16 incitvl; - u16 buritvl; - u16 strtfrq[2]; -}; - -struct ad5930_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad5930_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_transfer xfer; - int ret; - struct ad5903_config *config = (struct ad5903_config *)buf; - struct iio_dev *idev = dev_to_iio_dev(dev); - struct ad5930_state *st = iio_priv(idev); - - config->control = (config->control & ~value_mask); - config->incnum = (config->control & ~value_mask) | (1 << addr_shift); - config->frqdelt[0] = (config->control & ~value_mask) | (2 << addr_shift); - config->frqdelt[1] = (config->control & ~value_mask) | 3 << addr_shift; - config->incitvl = (config->control & ~value_mask) | 4 << addr_shift; - config->buritvl = (config->control & ~value_mask) | 8 << addr_shift; - config->strtfrq[0] = (config->control & ~value_mask) | 0xc << addr_shift; - config->strtfrq[1] = (config->control & ~value_mask) | 0xd << addr_shift; - - xfer.len = len; - xfer.tx_buf = config; - mutex_lock(&st->lock); - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad5930_set_parameter, 0); - -static struct attribute *ad5930_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad5930_attribute_group = { - .attrs = ad5930_attributes, -}; - -static const struct iio_info ad5930_info = { - .attrs = &ad5930_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int ad5930_probe(struct spi_device *spi) -{ - struct ad5930_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!idev) - return -ENOMEM; - spi_set_drvdata(spi, idev); - st = iio_priv(idev); - - mutex_init(&st->lock); - st->sdev = spi; - idev->dev.parent = &spi->dev; - idev->info = &ad5930_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(idev); - if (ret) - return ret; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 16; - spi_setup(spi); - - return 0; -} - -static int ad5930_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad5930_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad5930_probe, - .remove = ad5930_remove, -}; -module_spi_driver(ad5930_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad5930 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/ad9850.c b/drivers/staging/iio/frequency/ad9850.c deleted file mode 100644 index 8727933cafcf..000000000000 --- a/drivers/staging/iio/frequency/ad9850.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad9850 - * - * Copyright (c) 2010-2010 Analog Devices 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 - -#define DRV_NAME "ad9850" - -/* Register format: 4 bits addr + 12 bits value */ -struct ad9850_config { - u8 control[5]; -}; - -struct ad9850_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad9850_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_transfer xfer; - int ret; - struct ad9850_config *config = (struct ad9850_config *)buf; - struct iio_dev *idev = dev_to_iio_dev(dev); - struct ad9850_state *st = iio_priv(idev); - - xfer.len = len; - xfer.tx_buf = config; - mutex_lock(&st->lock); - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9850_set_parameter, 0); - -static struct attribute *ad9850_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9850_attribute_group = { - .attrs = ad9850_attributes, -}; - -static const struct iio_info ad9850_info = { - .attrs = &ad9850_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int ad9850_probe(struct spi_device *spi) -{ - struct ad9850_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!idev) - return -ENOMEM; - spi_set_drvdata(spi, idev); - st = iio_priv(idev); - mutex_init(&st->lock); - st->sdev = spi; - - idev->dev.parent = &spi->dev; - idev->info = &ad9850_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(idev); - if (ret) - return ret; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 16; - spi_setup(spi); - - return 0; -} - -static int ad9850_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad9850_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad9850_probe, - .remove = ad9850_remove, -}; -module_spi_driver(ad9850_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9850 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/ad9852.c b/drivers/staging/iio/frequency/ad9852.c deleted file mode 100644 index af2f2cc7a2f1..000000000000 --- a/drivers/staging/iio/frequency/ad9852.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad9852 - * - * Copyright (c) 2010 Analog Devices 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 - -#define DRV_NAME "ad9852" - -#define addr_phaad1 0x0 -#define addr_phaad2 0x1 -#define addr_fretu1 0x2 -#define addr_fretu2 0x3 -#define addr_delfre 0x4 -#define addr_updclk 0x5 -#define addr_ramclk 0x6 -#define addr_contrl 0x7 -#define addr_optskm 0x8 -#define addr_optskr 0xa -#define addr_dacctl 0xb - -#define COMPPD (1 << 4) -#define REFMULT2 (1 << 2) -#define BYPPLL (1 << 5) -#define PLLRANG (1 << 6) -#define IEUPCLK (1) -#define OSKEN (1 << 5) - -#define read_bit (1 << 7) - -/* Register format: 1 byte addr + value */ -struct ad9852_config { - u8 phajst0[3]; - u8 phajst1[3]; - u8 fretun1[6]; - u8 fretun2[6]; - u8 dltafre[6]; - u8 updtclk[5]; - u8 ramprat[4]; - u8 control[5]; - u8 outpskm[3]; - u8 outpskr[2]; - u8 daccntl[3]; -}; - -struct ad9852_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad9852_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_transfer xfer; - int ret; - struct ad9852_config *config = (struct ad9852_config *)buf; - struct iio_dev *idev = dev_to_iio_dev(dev); - struct ad9852_state *st = iio_priv(idev); - - xfer.len = 3; - xfer.tx_buf = &config->phajst0[0]; - mutex_lock(&st->lock); - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->phajst1[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 6; - xfer.tx_buf = &config->fretun1[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 6; - xfer.tx_buf = &config->fretun2[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 6; - xfer.tx_buf = &config->dltafre[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->updtclk[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 4; - xfer.tx_buf = &config->ramprat[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->control[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->outpskm[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 2; - xfer.tx_buf = &config->outpskr[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->daccntl[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0); - -static void ad9852_init(struct ad9852_state *st) -{ - struct spi_transfer xfer; - int ret; - u8 config[5]; - - config[0] = addr_contrl; - config[1] = COMPPD; - config[2] = REFMULT2 | BYPPLL | PLLRANG; - config[3] = IEUPCLK; - config[4] = OSKEN; - - mutex_lock(&st->lock); - - xfer.len = 5; - xfer.tx_buf = &config; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - -error_ret: - mutex_unlock(&st->lock); - - - -} - -static struct attribute *ad9852_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9852_attribute_group = { - .attrs = ad9852_attributes, -}; - -static const struct iio_info ad9852_info = { - .attrs = &ad9852_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int ad9852_probe(struct spi_device *spi) -{ - struct ad9852_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!idev) - return -ENOMEM; - st = iio_priv(idev); - spi_set_drvdata(spi, idev); - mutex_init(&st->lock); - st->sdev = spi; - - idev->dev.parent = &spi->dev; - idev->info = &ad9852_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = devm_iio_device_register(&spi->dev, idev); - if (ret) - return ret; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 8; - spi_setup(spi); - ad9852_init(st); - - return 0; -} - -static struct spi_driver ad9852_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad9852_probe, -}; -module_spi_driver(ad9852_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9852 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/ad9910.c b/drivers/staging/iio/frequency/ad9910.c deleted file mode 100644 index 755e0482681a..000000000000 --- a/drivers/staging/iio/frequency/ad9910.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad9910 - * - * Copyright (c) 2010 Analog Devices 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 - -#define DRV_NAME "ad9910" - -#define CFR1 0x0 -#define CFR2 0x1 -#define CFR3 0x2 - -#define AUXDAC 0x3 -#define IOUPD 0x4 -#define FTW 0x7 -#define POW 0x8 -#define ASF 0x9 -#define MULTC 0x0A -#define DIG_RAMPL 0x0B -#define DIG_RAMPS 0x0C -#define DIG_RAMPR 0x0D -#define SIN_TONEP0 0x0E -#define SIN_TONEP1 0x0F -#define SIN_TONEP2 0x10 -#define SIN_TONEP3 0x11 -#define SIN_TONEP4 0x12 -#define SIN_TONEP5 0x13 -#define SIN_TONEP6 0x14 -#define SIN_TONEP7 0x15 - -#define RAM_ENABLE (1 << 7) - -#define MANUAL_OSK (1 << 7) -#define INVSIC (1 << 6) -#define DDS_SINEOP (1) - -#define AUTO_OSK (1) -#define OSKEN (1 << 1) -#define LOAD_ARR (1 << 2) -#define CLR_PHA (1 << 3) -#define CLR_DIG (1 << 4) -#define ACLR_PHA (1 << 5) -#define ACLR_DIG (1 << 6) -#define LOAD_LRR (1 << 7) - -#define LSB_FST (1) -#define SDIO_IPT (1 << 1) -#define EXT_PWD (1 << 3) -#define ADAC_PWD (1 << 4) -#define REFCLK_PWD (1 << 5) -#define DAC_PWD (1 << 6) -#define DIG_PWD (1 << 7) - -#define ENA_AMP (1) -#define READ_FTW (1) -#define DIGR_LOW (1 << 1) -#define DIGR_HIGH (1 << 2) -#define DIGR_ENA (1 << 3) -#define SYNCCLK_ENA (1 << 6) -#define ITER_IOUPD (1 << 7) - -#define TX_ENA (1 << 1) -#define PDCLK_INV (1 << 2) -#define PDCLK_ENB (1 << 3) - -#define PARA_ENA (1 << 4) -#define SYNC_DIS (1 << 5) -#define DATA_ASS (1 << 6) -#define MATCH_ENA (1 << 7) - -#define PLL_ENA (1) -#define PFD_RST (1 << 2) -#define REFCLK_RST (1 << 6) -#define REFCLK_BYP (1 << 7) - -/* Register format: 1 byte addr + value */ -struct ad9910_config { - u8 auxdac[5]; - u8 ioupd[5]; - u8 ftw[5]; - u8 pow[3]; - u8 asf[5]; - u8 multc[5]; - u8 dig_rampl[9]; - u8 dig_ramps[9]; - u8 dig_rampr[5]; - u8 sin_tonep0[9]; - u8 sin_tonep1[9]; - u8 sin_tonep2[9]; - u8 sin_tonep3[9]; - u8 sin_tonep4[9]; - u8 sin_tonep5[9]; - u8 sin_tonep6[9]; - u8 sin_tonep7[9]; -}; - -struct ad9910_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad9910_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_transfer xfer; - int ret; - struct ad9910_config *config = (struct ad9910_config *)buf; - struct iio_dev *idev = dev_to_iio_dev(dev); - struct ad9910_state *st = iio_priv(idev); - - xfer.len = 5; - xfer.tx_buf = &config->auxdac[0]; - mutex_lock(&st->lock); - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->ioupd[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->ftw[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->pow[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->asf[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->multc[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->dig_rampl[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->dig_ramps[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->dig_rampr[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep0[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep1[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep2[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep3[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep4[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep5[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep6[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 9; - xfer.tx_buf = &config->sin_tonep7[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0); - -static void ad9910_init(struct ad9910_state *st) -{ - struct spi_transfer xfer; - int ret; - u8 cfr[5]; - - cfr[0] = CFR1; - cfr[1] = 0; - cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP; - cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR; - cfr[4] = 0; - - mutex_lock(&st->lock); - - xfer.len = 5; - xfer.tx_buf = 𝔠 - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - cfr[0] = CFR2; - cfr[1] = ENA_AMP; - cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD; - cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB; - cfr[4] = PARA_ENA; - - xfer.len = 5; - xfer.tx_buf = 𝔠 - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - cfr[0] = CFR3; - cfr[1] = PLL_ENA; - cfr[2] = 0; - cfr[3] = REFCLK_RST | REFCLK_BYP; - cfr[4] = 0; - - xfer.len = 5; - xfer.tx_buf = 𝔠 - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - -error_ret: - mutex_unlock(&st->lock); - - - -} - -static struct attribute *ad9910_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9910_attribute_group = { - .attrs = ad9910_attributes, -}; - -static const struct iio_info ad9910_info = { - .attrs = &ad9910_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int ad9910_probe(struct spi_device *spi) -{ - struct ad9910_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!idev) - return -ENOMEM; - spi_set_drvdata(spi, idev); - st = iio_priv(idev); - mutex_init(&st->lock); - st->sdev = spi; - - idev->dev.parent = &spi->dev; - idev->info = &ad9910_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = iio_device_register(idev); - if (ret) - return ret; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 8; - spi_setup(spi); - ad9910_init(st); - return 0; -} - -static int ad9910_remove(struct spi_device *spi) -{ - iio_device_unregister(spi_get_drvdata(spi)); - - return 0; -} - -static struct spi_driver ad9910_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad9910_probe, - .remove = ad9910_remove, -}; -module_spi_driver(ad9910_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9910 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); diff --git a/drivers/staging/iio/frequency/ad9951.c b/drivers/staging/iio/frequency/ad9951.c deleted file mode 100644 index d465db0e9c0b..000000000000 --- a/drivers/staging/iio/frequency/ad9951.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Driver for ADI Direct Digital Synthesis ad9951 - * - * Copyright (c) 2010 Analog Devices 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 - -#define DRV_NAME "ad9951" - -#define CFR1 0x0 -#define CFR2 0x1 - -#define AUTO_OSK (1) -#define OSKEN (1 << 1) -#define LOAD_ARR (1 << 2) - -#define AUTO_SYNC (1 << 7) - -#define LSB_FST (1) -#define SDIO_IPT (1 << 1) -#define CLR_PHA (1 << 2) -#define SINE_OPT (1 << 4) -#define ACLR_PHA (1 << 5) - -#define VCO_RANGE (1 << 2) - -#define CRS_OPT (1 << 1) -#define HMANU_SYNC (1 << 2) -#define HSPD_SYNC (1 << 3) - -/* Register format: 1 byte addr + value */ -struct ad9951_config { - u8 asf[3]; - u8 arr[2]; - u8 ftw0[5]; - u8 ftw1[3]; -}; - -struct ad9951_state { - struct mutex lock; - struct spi_device *sdev; -}; - -static ssize_t ad9951_set_parameter(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct spi_transfer xfer; - int ret; - struct ad9951_config *config = (struct ad9951_config *)buf; - struct iio_dev *idev = dev_to_iio_dev(dev); - struct ad9951_state *st = iio_priv(idev); - - xfer.len = 3; - xfer.tx_buf = &config->asf[0]; - mutex_lock(&st->lock); - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 2; - xfer.tx_buf = &config->arr[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 5; - xfer.tx_buf = &config->ftw0[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - xfer.len = 3; - xfer.tx_buf = &config->ftw1[0]; - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0); - -static void ad9951_init(struct ad9951_state *st) -{ - struct spi_transfer xfer; - int ret; - u8 cfr[5]; - - cfr[0] = CFR1; - cfr[1] = 0; - cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA; - cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR; - cfr[4] = 0; - - mutex_lock(&st->lock); - - xfer.len = 5; - xfer.tx_buf = 𝔠 - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - - cfr[0] = CFR2; - cfr[1] = VCO_RANGE; - cfr[2] = HSPD_SYNC; - cfr[3] = 0; - - xfer.len = 4; - xfer.tx_buf = 𝔠 - - ret = spi_sync_transfer(st->sdev, &xfer, 1); - if (ret) - goto error_ret; - -error_ret: - mutex_unlock(&st->lock); - - - -} - -static struct attribute *ad9951_attributes[] = { - &iio_dev_attr_dds.dev_attr.attr, - NULL, -}; - -static const struct attribute_group ad9951_attribute_group = { - .attrs = ad9951_attributes, -}; - -static const struct iio_info ad9951_info = { - .attrs = &ad9951_attribute_group, - .driver_module = THIS_MODULE, -}; - -static int ad9951_probe(struct spi_device *spi) -{ - struct ad9951_state *st; - struct iio_dev *idev; - int ret = 0; - - idev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); - if (!idev) - return -ENOMEM; - spi_set_drvdata(spi, idev); - st = iio_priv(idev); - mutex_init(&st->lock); - st->sdev = spi; - - idev->dev.parent = &spi->dev; - - idev->info = &ad9951_info; - idev->modes = INDIO_DIRECT_MODE; - - ret = devm_iio_device_register(&spi->dev, idev); - if (ret) - return ret; - spi->max_speed_hz = 2000000; - spi->mode = SPI_MODE_3; - spi->bits_per_word = 8; - spi_setup(spi); - ad9951_init(st); - return 0; -} - -static struct spi_driver ad9951_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .probe = ad9951_probe, -}; -module_spi_driver(ad9951_driver); - -MODULE_AUTHOR("Cliff Cai"); -MODULE_DESCRIPTION("Analog Devices ad9951 driver"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("spi:" DRV_NAME); -- GitLab From ff9e7621586ff8b86a18cfbb7c437c277ebc1970 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 13 Aug 2014 13:00:00 +0100 Subject: [PATCH 0969/9167] iio: adc: xilinx: Remove .owner field for driver There is no need to init .owner field. Based on the patch from Peter Griffin "mmc: remove .owner field for drivers using module_platform_driver" This patch removes the superflous .owner field for drivers which use the module_platform_driver API, as this is overriden in platform_driver_register anyway." Signed-off-by: Michal Simek Signed-off-by: Jonathan Cameron --- drivers/iio/adc/xilinx-xadc-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index 196e269e48d1..5d52a3106fac 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -1326,7 +1326,6 @@ static struct platform_driver xadc_driver = { .remove = xadc_remove, .driver = { .name = "xadc", - .owner = THIS_MODULE, .of_match_table = xadc_of_match_table, }, }; -- GitLab From 38ec10f60d9ca3a7eb3a5b52500a67479296b86f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 16 Aug 2014 16:27:41 +0100 Subject: [PATCH 0970/9167] spi: Only call transfer_one() if we have buffers to transfer Client drivers such as the ChomeOS EC driver sometimes use transfers with no buffers and only a delay specified in order to allow a delay after the assertion of /CS. Rather than require controller drivers handle this noop case gracefully put checks in the core to ensure that we don't call into the controller for such transfers. Reported-by: Addy Ke Tested-by: Doug Anderson Reviewed-by: Doug Anderson Signed-off-by: Mark Brown --- drivers/spi/spi.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index e0531baf2782..0edccc82ece5 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -789,27 +789,35 @@ static int spi_transfer_one_message(struct spi_master *master, list_for_each_entry(xfer, &msg->transfers, transfer_list) { trace_spi_transfer_start(msg, xfer); - reinit_completion(&master->xfer_completion); - - ret = master->transfer_one(master, msg->spi, xfer); - if (ret < 0) { - dev_err(&msg->spi->dev, - "SPI transfer failed: %d\n", ret); - goto out; - } + if (xfer->tx_buf || xfer->rx_buf) { + reinit_completion(&master->xfer_completion); + + ret = master->transfer_one(master, msg->spi, xfer); + if (ret < 0) { + dev_err(&msg->spi->dev, + "SPI transfer failed: %d\n", ret); + goto out; + } - if (ret > 0) { - ret = 0; - ms = xfer->len * 8 * 1000 / xfer->speed_hz; - ms += ms + 100; /* some tolerance */ + if (ret > 0) { + ret = 0; + ms = xfer->len * 8 * 1000 / xfer->speed_hz; + ms += ms + 100; /* some tolerance */ - ms = wait_for_completion_timeout(&master->xfer_completion, - msecs_to_jiffies(ms)); - } + ms = wait_for_completion_timeout(&master->xfer_completion, + msecs_to_jiffies(ms)); + } - if (ms == 0) { - dev_err(&msg->spi->dev, "SPI transfer timed out\n"); - msg->status = -ETIMEDOUT; + if (ms == 0) { + dev_err(&msg->spi->dev, + "SPI transfer timed out\n"); + msg->status = -ETIMEDOUT; + } + } else { + if (xfer->len) + dev_err(&msg->spi->dev, + "Bufferless transfer has length %u\n", + xfer->len); } trace_spi_transfer_stop(msg, xfer); -- GitLab From 468e0f47ed87350408ddac0e942fbf9a723408f9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 19 Aug 2014 20:29:20 +0300 Subject: [PATCH 0971/9167] spi/pxa2xx-pci: remove unnecessary assignment There is no need to unset driver data pointer at removal stage. Signed-off-by: Andy Shevchenko Signed-off-by: Mark Brown --- drivers/spi/spi-pxa2xx-pci.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c index 20ebbc764693..536c863bebf1 100644 --- a/drivers/spi/spi-pxa2xx-pci.c +++ b/drivers/spi/spi-pxa2xx-pci.c @@ -123,7 +123,6 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev) platform_device_unregister(pdev); clk_unregister(spi_pdata->ssp.clk); - pci_set_drvdata(dev, NULL); } static const struct pci_device_id pxa2xx_spi_pci_devices[] = { -- GitLab From 45e1a279ce1d2ff9b2b2fedf4cdced10c7ca3ab5 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 19 Aug 2014 10:49:07 -0600 Subject: [PATCH 0972/9167] regmap: of_regmap_get_endian() cleanup Commit d647c199510c ("regmap: add DT endianness binding support") had some issues. Commit ba1b53feb8ca ("regmap: Fix DT endianess parsing logic") fixed the main problem. This patch fixes the other. Specifically, restore the overall default of REGMAP_ENDIAN_BIG if none of the config, DT, or the bus specify any endianness. Without this, of_regmap_get_endian() could return REGMAP_ENDIAN_DEFAULT, which the calling code can't handle. Since all busses do specify an endianness in the current code, this makes no difference right now, but I saw no justification in the patch description for removing this final default. Also, clean up the code a bit: * s/of_regmap_get_endian/regmap_get_endian/ since the function isn't DT- specific, even if the reason it was originally added was to add some DT-specific features. * After potentially reading an endianess specification from DT, the code checks whether DT did specify an endianness, and if so, returns it. Move this test outside the whole switch statement so that if the REGMAP_ENDIAN_REG case ever modifies *endian, this check will pick that up. This partially reverts part of commit ba1b53feb8ca ("regmap: Fix DT endianess parsing logic"), while maintaining the bug-fix that commit made to this code. * Make the comments briefer, and only refer to the specific action taken at their location. This makes most of the comments independent of DT, and easier to follow. Cc: Xiubo Li Cc: Javier Martinez Canillas Cc: Thierry Reding Fixes: d647c199510c ("regmap: add DT endianness binding support") Signed-off-by: Stephen Warren Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 54 +++++++++++++----------------------- 1 file changed, 20 insertions(+), 34 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 055a9c3a3b12..bb4502a48be5 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -454,7 +454,7 @@ enum regmap_endian_type { REGMAP_ENDIAN_VAL, }; -static int of_regmap_get_endian(struct device *dev, +static int regmap_get_endian(struct device *dev, const struct regmap_bus *bus, const struct regmap_config *config, enum regmap_endian_type type, @@ -465,15 +465,7 @@ static int of_regmap_get_endian(struct device *dev, if (!endian || !config) return -EINVAL; - /* - * Firstly, try to parse the endianness from driver's config, - * this is to be compatible with the none DT or the old drivers. - * From the driver's config the endianness value maybe: - * REGMAP_ENDIAN_BIG, - * REGMAP_ENDIAN_LITTLE, - * REGMAP_ENDIAN_NATIVE, - * REGMAP_ENDIAN_DEFAULT. - */ + /* Retrieve the endianness specification from the regmap config */ switch (type) { case REGMAP_ENDIAN_REG: *endian = config->reg_format_endian; @@ -485,31 +477,17 @@ static int of_regmap_get_endian(struct device *dev, return -EINVAL; } - /* - * If the endianness parsed from driver config is - * REGMAP_ENDIAN_DEFAULT, that means maybe we are using the DT - * node to specify the endianness information. - */ + /* If the regmap config specified a non-default value, use that */ if (*endian != REGMAP_ENDIAN_DEFAULT) return 0; - /* - * Secondly, try to parse the endianness from DT node if the - * driver config does not specify it. - * From the DT node the endianness value maybe: - * REGMAP_ENDIAN_BIG, - * REGMAP_ENDIAN_LITTLE, - */ + /* Parse the device's DT node for an endianness specification */ switch (type) { case REGMAP_ENDIAN_VAL: if (of_property_read_bool(np, "big-endian")) *endian = REGMAP_ENDIAN_BIG; else if (of_property_read_bool(np, "little-endian")) *endian = REGMAP_ENDIAN_LITTLE; - - if (*endian != REGMAP_ENDIAN_DEFAULT) - return 0; - break; case REGMAP_ENDIAN_REG: break; @@ -517,10 +495,11 @@ static int of_regmap_get_endian(struct device *dev, return -EINVAL; } - /* - * Finally, try to parse the endianness from regmap bus config - * if in device's DT node the endianness property is absent. - */ + /* If the endianness was specified in DT, use that */ + if (*endian != REGMAP_ENDIAN_DEFAULT) + return 0; + + /* Retrieve the endianness specification from the bus config */ switch (type) { case REGMAP_ENDIAN_REG: if (bus && bus->reg_format_endian_default) @@ -534,6 +513,13 @@ static int of_regmap_get_endian(struct device *dev, return -EINVAL; } + /* If the bus specified a non-default value, use that */ + if (*endian != REGMAP_ENDIAN_DEFAULT) + return 0; + + /* Use this if no other value was found */ + *endian = REGMAP_ENDIAN_BIG; + return 0; } @@ -640,13 +626,13 @@ struct regmap *regmap_init(struct device *dev, map->reg_read = _regmap_bus_read; } - ret = of_regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_REG, - ®_endian); + ret = regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_REG, + ®_endian); if (ret) return ERR_PTR(ret); - ret = of_regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_VAL, - &val_endian); + ret = regmap_get_endian(dev, bus, config, REGMAP_ENDIAN_VAL, + &val_endian); if (ret) return ERR_PTR(ret); -- GitLab From eeed09e8116f9932b55aa284d109bdea1e2ddc46 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:32:24 +0900 Subject: [PATCH 0973/9167] ARM: shmobile: kzm9g: Add shmobile_init_late() Extend board specific KZM9D DT reference machine vector to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-kzm9g-reference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c index 5d2621f202d1..9ec98871e292 100644 --- a/arch/arm/mach-shmobile/board-kzm9g-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c @@ -54,5 +54,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g-reference") .init_early = sh73a0_init_delay, .nr_irqs = NR_IRQS_LEGACY, .init_machine = kzm_init, + .init_late = shmobile_init_late, .dt_compat = kzm9g_boards_compat_dt, MACHINE_END -- GitLab From b9c9281339376521d0feb78c9051fedfbb3cf111 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:32:41 +0900 Subject: [PATCH 0974/9167] ARM: shmobile: marzen: Add shmobile_init_late() Extend board specific Marzen DT reference machine vector to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-marzen-reference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c index 21b3e1ca2261..9194bce1812c 100644 --- a/arch/arm/mach-shmobile/board-marzen-reference.c +++ b/arch/arm/mach-shmobile/board-marzen-reference.c @@ -67,5 +67,6 @@ DT_MACHINE_START(MARZEN, "marzen") .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, .init_machine = marzen_init, + .init_late = shmobile_init_late, .dt_compat = marzen_boards_compat_dt, MACHINE_END -- GitLab From 6e15a3873aa9b4ab2980f781b05bfc5c99bf4b99 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:32:59 +0900 Subject: [PATCH 0975/9167] ARM: shmobile: bockw: Add shmobile_init_late() Extend board specific Bock-W DT reference machine vector to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-bockw-reference.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/board-bockw-reference.c b/arch/arm/mach-shmobile/board-bockw-reference.c index ba840cd333b9..9202f1641a16 100644 --- a/arch/arm/mach-shmobile/board-bockw-reference.c +++ b/arch/arm/mach-shmobile/board-bockw-reference.c @@ -83,5 +83,6 @@ DT_MACHINE_START(BOCKW_DT, "bockw") .init_early = r8a7778_init_delay, .init_irq = r8a7778_init_irq_dt, .init_machine = bockw_init, + .init_late = shmobile_init_late, .dt_compat = bockw_boards_compat_dt, MACHINE_END -- GitLab From 509c42a5fce00f8769f68847580ba3c4dc884218 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:33:17 +0900 Subject: [PATCH 0976/9167] ARM: shmobile: ape6evm: Add shmobile_init_late() Extend board specific APE6EVM reference machine vectors to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-ape6evm-reference.c | 1 + arch/arm/mach-shmobile/board-ape6evm.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/mach-shmobile/board-ape6evm-reference.c b/arch/arm/mach-shmobile/board-ape6evm-reference.c index 2f7723e5fe91..1ecda4b58828 100644 --- a/arch/arm/mach-shmobile/board-ape6evm-reference.c +++ b/arch/arm/mach-shmobile/board-ape6evm-reference.c @@ -61,5 +61,6 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { DT_MACHINE_START(APE6EVM_DT, "ape6evm") .init_early = r8a73a4_init_early, .init_machine = ape6evm_add_standard_devices, + .init_late = shmobile_init_late, .dt_compat = ape6evm_boards_compat_dt, MACHINE_END diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c index 1585b8830b13..befbae03a1ec 100644 --- a/arch/arm/mach-shmobile/board-ape6evm.c +++ b/arch/arm/mach-shmobile/board-ape6evm.c @@ -285,5 +285,6 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { DT_MACHINE_START(APE6EVM_DT, "ape6evm") .init_early = r8a73a4_init_early, .init_machine = ape6evm_add_standard_devices, + .init_late = shmobile_init_late, .dt_compat = ape6evm_boards_compat_dt, MACHINE_END -- GitLab From 911f7cec78af1445d4b0f5f79907cb5bd4522ce5 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:45:00 +0900 Subject: [PATCH 0977/9167] ARM: shmobile: ape6evm: Use shmobile_init_delay() The r8a73a4 DTS includes CPU Frequency information so adjust the APE6EVM board code to use shmobile_init_delay() instead of relying on CPU Frequency information included in r8a73a4_init_delay() that is specified in C. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-ape6evm-reference.c | 2 +- arch/arm/mach-shmobile/board-ape6evm.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-shmobile/board-ape6evm-reference.c b/arch/arm/mach-shmobile/board-ape6evm-reference.c index 1ecda4b58828..9e99b1511a90 100644 --- a/arch/arm/mach-shmobile/board-ape6evm-reference.c +++ b/arch/arm/mach-shmobile/board-ape6evm-reference.c @@ -59,7 +59,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_early = r8a73a4_init_early, + .init_early = shmobile_init_delay, .init_machine = ape6evm_add_standard_devices, .init_late = shmobile_init_late, .dt_compat = ape6evm_boards_compat_dt, diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c index befbae03a1ec..b222f68d55b7 100644 --- a/arch/arm/mach-shmobile/board-ape6evm.c +++ b/arch/arm/mach-shmobile/board-ape6evm.c @@ -283,7 +283,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(APE6EVM_DT, "ape6evm") - .init_early = r8a73a4_init_early, + .init_early = shmobile_init_delay, .init_machine = ape6evm_add_standard_devices, .init_late = shmobile_init_late, .dt_compat = ape6evm_boards_compat_dt, -- GitLab From 322163c437b200b70ecb87ab102dfedce0ba0e91 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 8 Aug 2014 20:49:13 +0900 Subject: [PATCH 0978/9167] ARM: shmobile: marzen: Remove NR_IRQS_LEGACY Remove NR_IRQS_LEGACY from the Marzen Reference code. The Marzen Reference machine vector requires use of Multiplatform, and in such case SPARSE_IRQ is enabled by default. This in turns means that the default value of .nr_irqs equals NR_IRQS and NR_IRQS_LEGACY. Because of this we can simply remove NR_IRQS_LEGACY and move one step closer to a cruft-free environment. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-marzen-reference.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c index 9194bce1812c..c3dfa6c89a9e 100644 --- a/arch/arm/mach-shmobile/board-marzen-reference.c +++ b/arch/arm/mach-shmobile/board-marzen-reference.c @@ -64,7 +64,6 @@ DT_MACHINE_START(MARZEN, "marzen") .map_io = r8a7779_map_io, .init_early = shmobile_init_delay, .init_time = marzen_init_timer, - .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, .init_machine = marzen_init, .init_late = shmobile_init_late, -- GitLab From f185a01b3877880135ea73ddfcec52bd9a4d4864 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 13 Aug 2014 13:56:59 +0200 Subject: [PATCH 0979/9167] ARM: shmobile: kzm9g: Remove unneeded nr_irqs initialization As per arch_probe_nr_irqs(), the default value is NR_IRQS, which maps to NR_IRQS_LEGACY if CONFIG_SPARSE_IRQ=y. Since SPARSE_IRQ is selected by both ARCH_MULTIPLATFORM and ARCH_SHMOBILE_LEGACY, it's always enabled on shmobile. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-kzm9g.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index f8bc7f8f86ad..36593cb20e57 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -910,7 +910,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g") .smp = smp_ops(sh73a0_smp_ops), .map_io = sh73a0_map_io, .init_early = sh73a0_add_early_devices, - .nr_irqs = NR_IRQS_LEGACY, .init_irq = sh73a0_init_irq, .init_machine = kzm_init, .init_late = shmobile_init_late, -- GitLab From 3969d6490ba35b01f84bb12472c29c6029f7298b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 13 Aug 2014 13:56:58 +0200 Subject: [PATCH 0980/9167] ARM: shmobile: kzm9g-reference: Remove unneeded nr_irqs initialization As per arch_probe_nr_irqs(), the default value is NR_IRQS, which maps to NR_IRQS_LEGACY if CONFIG_SPARSE_IRQ=y. Since SPARSE_IRQ is selected by both ARCH_MULTIPLATFORM and ARCH_SHMOBILE_LEGACY, it's always enabled on shmobile. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-kzm9g-reference.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c index 9ec98871e292..1694a1609296 100644 --- a/arch/arm/mach-shmobile/board-kzm9g-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c @@ -52,7 +52,6 @@ DT_MACHINE_START(KZM9G_DT, "kzm9g-reference") .smp = smp_ops(sh73a0_smp_ops), .map_io = sh73a0_map_io, .init_early = sh73a0_init_delay, - .nr_irqs = NR_IRQS_LEGACY, .init_machine = kzm_init, .init_late = shmobile_init_late, .dt_compat = kzm9g_boards_compat_dt, -- GitLab From e604d80971e65c7ae895a4b38caed3838cf07554 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:32:15 +0900 Subject: [PATCH 0981/9167] ARM: shmobile: sh73a0: Add shmobile_init_late() Extend sh73a0 SoC machine vector to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh73a0.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 2c802ae9b241..002291881eb3 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -799,6 +799,7 @@ DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") .init_early = sh73a0_init_delay, .nr_irqs = NR_IRQS_LEGACY, .init_machine = sh73a0_add_standard_devices_dt, + .init_late = shmobile_init_late, .dt_compat = sh73a0_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ -- GitLab From d5b00b90705d5fff53f611ba4746d79fedbb52be Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:32:33 +0900 Subject: [PATCH 0982/9167] ARM: shmobile: r8a7779: Fix shmobile_init_late() Fix r8a7779 SoC machine vector to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup and platform devices are omitted as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7779.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 236c1befb9e3..6875a9fe28c2 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -774,7 +774,7 @@ DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, .init_machine = r8a7779_add_standard_devices_dt, - .init_late = r8a7779_init_late, + .init_late = shmobile_init_late, .dt_compat = r8a7779_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ -- GitLab From 7759a7a8e9b07a9046c1bdb2cd4c9ce197280392 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:32:50 +0900 Subject: [PATCH 0983/9167] ARM: shmobile: r8a7778: Fix shmobile_init_late() Fix r8a7778 SoC machine vector to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup and platform devices are omitted as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7778.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index 383e43bf1cb6..e1a477bce447 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -610,8 +610,8 @@ static const char *r8a7778_compat_dt[] __initdata = { DT_MACHINE_START(R8A7778_DT, "Generic R8A7778 (Flattened Device Tree)") .init_early = r8a7778_init_delay, .init_irq = r8a7778_init_irq_dt, + .init_late = shmobile_init_late, .dt_compat = r8a7778_compat_dt, - .init_late = r8a7778_init_late, MACHINE_END #endif /* CONFIG_USE_OF */ -- GitLab From 0592d1b5d296b0b6a24b7e48b7b48662164d3117 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:33:08 +0900 Subject: [PATCH 0984/9167] ARM: shmobile: r8a73a4: Add shmobile_init_late() Extend r8a73a4 SoC machine vector to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a73a4.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c index 6683072a9d98..6fbcdcc39d53 100644 --- a/arch/arm/mach-shmobile/setup-r8a73a4.c +++ b/arch/arm/mach-shmobile/setup-r8a73a4.c @@ -311,6 +311,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = { DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") .init_early = r8a73a4_init_early, + .init_late = shmobile_init_late, .dt_compat = r8a73a4_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ -- GitLab From 9b0fd79af38cb1d68f5faf4fb528713116480e9f Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 08:33:26 +0900 Subject: [PATCH 0985/9167] ARM: shmobile: r7s72100: Add shmobile_init_late() Extend r7s72100 SoC machine vector to include shmobile_init_late() so Suspend-to-RAM and CPUIdle are setup as expected. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r7s72100.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c index f3b3b14ba972..8cdc25d146a9 100644 --- a/arch/arm/mach-shmobile/setup-r7s72100.c +++ b/arch/arm/mach-shmobile/setup-r7s72100.c @@ -53,6 +53,7 @@ static const char *r7s72100_boards_compat_dt[] __initdata = { DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)") .init_early = shmobile_init_delay, + .init_late = shmobile_init_late, .dt_compat = r7s72100_boards_compat_dt, MACHINE_END #endif /* CONFIG_USE_OF */ -- GitLab From f2acab52e77650044b0772a6d7abbfef1eb4cede Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 31 Jul 2014 09:25:15 +0900 Subject: [PATCH 0986/9167] ARM: shmobile: Rework multiplatform include workaround Now when the majority of the include files have moved from arch/arm/mach-shmobile/include/mach/ to arch/arm/mach-shmobile/ remove the header include file workaround in the Makefile... ... and add another workaround in irqs.h to cope with the fact that needs to be where it is until the PFC code has been updated to remove legacy non-DT interfaces. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/Makefile | 2 -- arch/arm/mach-shmobile/irqs.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index fe3878a1a69a..a6a1dc0335ae 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -2,8 +2,6 @@ # Makefile for the linux kernel. # -ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/arch/arm/mach-shmobile/include - # Common objects obj-y := timer.o console.o diff --git a/arch/arm/mach-shmobile/irqs.h b/arch/arm/mach-shmobile/irqs.h index 4ff2d2aa94f0..8e28223f1b3c 100644 --- a/arch/arm/mach-shmobile/irqs.h +++ b/arch/arm/mach-shmobile/irqs.h @@ -2,7 +2,7 @@ #define __SHMOBILE_IRQS_H #include -#include +#include "include/mach/irqs.h" /* GIC */ #define gic_spi(nr) ((nr) + 32) -- GitLab From fe8abe0bc2afb20b126e7e0759081dc0df2cd60d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 5 Aug 2014 15:21:29 +0200 Subject: [PATCH 0987/9167] ARM: shmobile: dma: Use defines instead of hardcoded numbers Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/dma-register.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-shmobile/dma-register.h b/arch/arm/mach-shmobile/dma-register.h index 97c40bd9b94f..52a2f66e600f 100644 --- a/arch/arm/mach-shmobile/dma-register.h +++ b/arch/arm/mach-shmobile/dma-register.h @@ -52,8 +52,8 @@ static const unsigned int dma_ts_shift[] = { ((((i) & TS_LOW_BIT) << TS_LOW_SHIFT) |\ (((i) & TS_HI_BIT) << TS_HI_SHIFT)) -#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz))) -#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz))) +#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | RS_ERS | TS_INDEX2VAL((xmit_sz))) +#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | RS_ERS | TS_INDEX2VAL((xmit_sz))) /* -- GitLab From 93f05252514a8c7b6bf5a132f6b20f10215cb59c Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Fri, 8 Aug 2014 20:49:04 +0900 Subject: [PATCH 0988/9167] ARM: shmobile: r8a7779: Remove NR_IRQS_LEGACY Remove NR_IRQS_LEGACY from the r8a7779 generic machine vector. The generic r8a7779 machine vector requires use of Multiplatform, and in such case SPARSE_IRQ is enabled by default. This in turns means that the default value of .nr_irqs equals NR_IRQS and NR_IRQS_LEGACY. Because of this we can simply remove NR_IRQS_LEGACY and move one step closer to a cruft-free environment. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7779.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c index 6875a9fe28c2..6829cd19ea72 100644 --- a/arch/arm/mach-shmobile/setup-r8a7779.c +++ b/arch/arm/mach-shmobile/setup-r8a7779.c @@ -771,7 +771,6 @@ static const char *r8a7779_compat_dt[] __initdata = { DT_MACHINE_START(R8A7779_DT, "Generic R8A7779 (Flattened Device Tree)") .map_io = r8a7779_map_io, .init_early = shmobile_init_delay, - .nr_irqs = NR_IRQS_LEGACY, .init_irq = r8a7779_init_irq_dt, .init_machine = r8a7779_add_standard_devices_dt, .init_late = shmobile_init_late, -- GitLab From ea2e46086969e11b759a8f2c111c9b007d1b35c9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 13 Aug 2014 13:56:56 +0200 Subject: [PATCH 0989/9167] ARM: shmobile: sh7372: Remove unneeded nr_irqs initialization As per arch_probe_nr_irqs(), the default value is NR_IRQS, which maps to NR_IRQS_LEGACY if CONFIG_SPARSE_IRQ=y. Since SPARSE_IRQ is selected by both ARCH_MULTIPLATFORM and ARCH_SHMOBILE_LEGACY, it's always enabled on shmobile. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh7372.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 9cdfcdfd38fc..3731eccccef4 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -1008,7 +1008,6 @@ static const char *sh7372_boards_compat_dt[] __initdata = { DT_MACHINE_START(SH7372_DT, "Generic SH7372 (Flattened Device Tree)") .map_io = sh7372_map_io, .init_early = sh7372_add_early_devices_dt, - .nr_irqs = NR_IRQS_LEGACY, .init_irq = sh7372_init_irq, .handle_irq = shmobile_handle_irq_intc, .init_machine = sh7372_add_standard_devices_dt, -- GitLab From 5ac9e7f35db00e630c9f95a1f73ac329371cdbbf Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 13 Aug 2014 13:56:57 +0200 Subject: [PATCH 0990/9167] ARM: shmobile: sh73a0: Remove unneeded nr_irqs initialization As per arch_probe_nr_irqs(), the default value is NR_IRQS, which maps to NR_IRQS_LEGACY if CONFIG_SPARSE_IRQ=y. Since SPARSE_IRQ is selected by both ARCH_MULTIPLATFORM and ARCH_SHMOBILE_LEGACY, it's always enabled on shmobile. Signed-off-by: Geert Uytterhoeven Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh73a0.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index 002291881eb3..e7a0296b81b1 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -797,7 +797,6 @@ DT_MACHINE_START(SH73A0_DT, "Generic SH73A0 (Flattened Device Tree)") .smp = smp_ops(sh73a0_smp_ops), .map_io = sh73a0_map_io, .init_early = sh73a0_init_delay, - .nr_irqs = NR_IRQS_LEGACY, .init_machine = sh73a0_add_standard_devices_dt, .init_late = shmobile_init_late, .dt_compat = sh73a0_boards_compat_dt, -- GitLab From 7132fe4f568721cbd5d9bce5a8a71556e9bc45b4 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Sun, 17 Aug 2014 09:24:26 -0700 Subject: [PATCH 0991/9167] Input: drv260x - add TI drv260x haptics driver Add the TI drv260x haptics/vibrator driver. This device uses the input force feedback to produce a wave form to driver an ERM or LRA actuator device. The initial driver supports the devices real time playback mode. But the device has additional wave patterns in ROM. This functionality will be added in future patchsets. Product data sheet is located here: http://www.ti.com/product/drv2605 Signed-off-by: Dan Murphy Signed-off-by: Dmitry Torokhov --- .../devicetree/bindings/input/ti,drv260x.txt | 51 ++ drivers/input/misc/Kconfig | 11 + drivers/input/misc/Makefile | 1 + drivers/input/misc/drv260x.c | 738 ++++++++++++++++++ include/dt-bindings/input/ti-drv260x.h | 36 + include/linux/platform_data/drv260x-pdata.h | 28 + 6 files changed, 865 insertions(+) create mode 100644 Documentation/devicetree/bindings/input/ti,drv260x.txt create mode 100644 drivers/input/misc/drv260x.c create mode 100644 include/dt-bindings/input/ti-drv260x.h create mode 100644 include/linux/platform_data/drv260x-pdata.h diff --git a/Documentation/devicetree/bindings/input/ti,drv260x.txt b/Documentation/devicetree/bindings/input/ti,drv260x.txt new file mode 100644 index 000000000000..a9c8519eb9de --- /dev/null +++ b/Documentation/devicetree/bindings/input/ti,drv260x.txt @@ -0,0 +1,51 @@ +Texas Instruments - drv260x Haptics driver family + +The drv260x family serial control bus communicates through I2C protocols + +Required properties: + - compatible - One of: + "ti,drv2604" - DRV2604 + "ti,drv2605" - DRV2605 + "ti,drv2605l" - DRV2605L + - reg - I2C slave address + - vbat-supply - Required supply regulator + - mode - Power up mode of the chip (defined in include/dt-bindings/input/ti-drv260x.h) + DRV260X_LRA_MODE - Linear Resonance Actuator mode (Piezoelectric) + DRV260X_LRA_NO_CAL_MODE - This is a LRA Mode but there is no calibration + sequence during init. And the device is configured for real + time playback mode (RTP mode). + DRV260X_ERM_MODE - Eccentric Rotating Mass mode (Rotary vibrator) + - library-sel - These are ROM based waveforms pre-programmed into the IC. + This should be set to set the library to use at power up. + (defined in include/dt-bindings/input/ti-drv260x.h) + DRV260X_LIB_EMPTY - Do not use a pre-programmed library + DRV260X_ERM_LIB_A - Pre-programmed Library + DRV260X_ERM_LIB_B - Pre-programmed Library + DRV260X_ERM_LIB_C - Pre-programmed Library + DRV260X_ERM_LIB_D - Pre-programmed Library + DRV260X_ERM_LIB_E - Pre-programmed Library + DRV260X_ERM_LIB_F - Pre-programmed Library + DRV260X_LIB_LRA - Pre-programmed LRA Library + +Optional properties: + - enable-gpio - gpio pin to enable/disable the device. + - vib-rated-mv - The rated voltage of the actuator in millivolts. + If this is not set then the value will be defaulted to + 3.2 v. + - vib-overdrive-mv - The overdrive voltage of the actuator in millivolts. + If this is not set then the value will be defaulted to + 3.2 v. +Example: + +drv2605l: drv2605l@5a { + compatible = "ti,drv2605l"; + reg = <0x5a>; + enable-gpio = <&gpio1 28 GPIO_ACTIVE_HIGH>; + mode = ; + library-sel = ; + vib-rated-mv = <3200>; + vib-overdriver-mv = <3200>; +}; + +For more product information please see the link below: +http://www.ti.com/product/drv2605 diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 2ff4425a893b..41d0ae62ba05 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -676,4 +676,15 @@ config INPUT_SOC_BUTTON_ARRAY To compile this driver as a module, choose M here: the module will be called soc_button_array. +config INPUT_DRV260X_HAPTICS + tristate "TI DRV260X haptics support" + depends on INPUT && I2C && GPIOLIB + select INPUT_FF_MEMLESS + select REGMAP_I2C + help + Say Y to enable support for the TI DRV260X haptics driver. + + To compile this driver as a module, choose M here: the + module will be called drv260x-haptics. + endif diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 4955ad322a01..cd4bc2d3474f 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o obj-$(CONFIG_INPUT_DA9052_ONKEY) += da9052_onkey.o obj-$(CONFIG_INPUT_DA9055_ONKEY) += da9055_onkey.o obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o +obj-$(CONFIG_INPUT_DRV260X_HAPTICS) += drv260x.o obj-$(CONFIG_INPUT_GP2A) += gp2ap002a00f.o obj-$(CONFIG_INPUT_GPIO_BEEPER) += gpio-beeper.o obj-$(CONFIG_INPUT_GPIO_TILT_POLLED) += gpio_tilt_polled.o diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c new file mode 100644 index 000000000000..e90e3b8189f7 --- /dev/null +++ b/drivers/input/misc/drv260x.c @@ -0,0 +1,738 @@ +/* + * DRV260X haptics driver family + * + * Author: Dan Murphy + * + * Copyright: (C) 2014 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. + * + * 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 DRV260X_STATUS 0x0 +#define DRV260X_MODE 0x1 +#define DRV260X_RT_PB_IN 0x2 +#define DRV260X_LIB_SEL 0x3 +#define DRV260X_WV_SEQ_1 0x4 +#define DRV260X_WV_SEQ_2 0x5 +#define DRV260X_WV_SEQ_3 0x6 +#define DRV260X_WV_SEQ_4 0x7 +#define DRV260X_WV_SEQ_5 0x8 +#define DRV260X_WV_SEQ_6 0x9 +#define DRV260X_WV_SEQ_7 0xa +#define DRV260X_WV_SEQ_8 0xb +#define DRV260X_GO 0xc +#define DRV260X_OVERDRIVE_OFF 0xd +#define DRV260X_SUSTAIN_P_OFF 0xe +#define DRV260X_SUSTAIN_N_OFF 0xf +#define DRV260X_BRAKE_OFF 0x10 +#define DRV260X_A_TO_V_CTRL 0x11 +#define DRV260X_A_TO_V_MIN_INPUT 0x12 +#define DRV260X_A_TO_V_MAX_INPUT 0x13 +#define DRV260X_A_TO_V_MIN_OUT 0x14 +#define DRV260X_A_TO_V_MAX_OUT 0x15 +#define DRV260X_RATED_VOLT 0x16 +#define DRV260X_OD_CLAMP_VOLT 0x17 +#define DRV260X_CAL_COMP 0x18 +#define DRV260X_CAL_BACK_EMF 0x19 +#define DRV260X_FEEDBACK_CTRL 0x1a +#define DRV260X_CTRL1 0x1b +#define DRV260X_CTRL2 0x1c +#define DRV260X_CTRL3 0x1d +#define DRV260X_CTRL4 0x1e +#define DRV260X_CTRL5 0x1f +#define DRV260X_LRA_LOOP_PERIOD 0x20 +#define DRV260X_VBAT_MON 0x21 +#define DRV260X_LRA_RES_PERIOD 0x22 +#define DRV260X_MAX_REG 0x23 + +#define DRV260X_ALLOWED_R_BYTES 25 +#define DRV260X_ALLOWED_W_BYTES 2 +#define DRV260X_MAX_RW_RETRIES 5 +#define DRV260X_I2C_RETRY_DELAY 10 + +#define DRV260X_GO_BIT 0x01 + +/* Library Selection */ +#define DRV260X_LIB_SEL_MASK 0x07 +#define DRV260X_LIB_SEL_RAM 0x0 +#define DRV260X_LIB_SEL_OD 0x1 +#define DRV260X_LIB_SEL_40_60 0x2 +#define DRV260X_LIB_SEL_60_80 0x3 +#define DRV260X_LIB_SEL_100_140 0x4 +#define DRV260X_LIB_SEL_140_PLUS 0x5 + +#define DRV260X_LIB_SEL_HIZ_MASK 0x10 +#define DRV260X_LIB_SEL_HIZ_EN 0x01 +#define DRV260X_LIB_SEL_HIZ_DIS 0 + +/* Mode register */ +#define DRV260X_STANDBY (1 << 6) +#define DRV260X_STANDBY_MASK 0x40 +#define DRV260X_INTERNAL_TRIGGER 0x00 +#define DRV260X_EXT_TRIGGER_EDGE 0x01 +#define DRV260X_EXT_TRIGGER_LEVEL 0x02 +#define DRV260X_PWM_ANALOG_IN 0x03 +#define DRV260X_AUDIOHAPTIC 0x04 +#define DRV260X_RT_PLAYBACK 0x05 +#define DRV260X_DIAGNOSTICS 0x06 +#define DRV260X_AUTO_CAL 0x07 + +/* Audio to Haptics Control */ +#define DRV260X_AUDIO_HAPTICS_PEAK_10MS (0 << 2) +#define DRV260X_AUDIO_HAPTICS_PEAK_20MS (1 << 2) +#define DRV260X_AUDIO_HAPTICS_PEAK_30MS (2 << 2) +#define DRV260X_AUDIO_HAPTICS_PEAK_40MS (3 << 2) + +#define DRV260X_AUDIO_HAPTICS_FILTER_100HZ 0x00 +#define DRV260X_AUDIO_HAPTICS_FILTER_125HZ 0x01 +#define DRV260X_AUDIO_HAPTICS_FILTER_150HZ 0x02 +#define DRV260X_AUDIO_HAPTICS_FILTER_200HZ 0x03 + +/* Min/Max Input/Output Voltages */ +#define DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT 0x19 +#define DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT 0x64 +#define DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT 0x19 +#define DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT 0xFF + +/* Feedback register */ +#define DRV260X_FB_REG_ERM_MODE 0x7f +#define DRV260X_FB_REG_LRA_MODE (1 << 7) + +#define DRV260X_BRAKE_FACTOR_MASK 0x1f +#define DRV260X_BRAKE_FACTOR_2X (1 << 0) +#define DRV260X_BRAKE_FACTOR_3X (2 << 4) +#define DRV260X_BRAKE_FACTOR_4X (3 << 4) +#define DRV260X_BRAKE_FACTOR_6X (4 << 4) +#define DRV260X_BRAKE_FACTOR_8X (5 << 4) +#define DRV260X_BRAKE_FACTOR_16 (6 << 4) +#define DRV260X_BRAKE_FACTOR_DIS (7 << 4) + +#define DRV260X_LOOP_GAIN_LOW 0xf3 +#define DRV260X_LOOP_GAIN_MED (1 << 2) +#define DRV260X_LOOP_GAIN_HIGH (2 << 2) +#define DRV260X_LOOP_GAIN_VERY_HIGH (3 << 2) + +#define DRV260X_BEMF_GAIN_0 0xfc +#define DRV260X_BEMF_GAIN_1 (1 << 0) +#define DRV260X_BEMF_GAIN_2 (2 << 0) +#define DRV260X_BEMF_GAIN_3 (3 << 0) + +/* Control 1 register */ +#define DRV260X_AC_CPLE_EN (1 << 5) +#define DRV260X_STARTUP_BOOST (1 << 7) + +/* Control 2 register */ + +#define DRV260X_IDISS_TIME_45 0 +#define DRV260X_IDISS_TIME_75 (1 << 0) +#define DRV260X_IDISS_TIME_150 (1 << 1) +#define DRV260X_IDISS_TIME_225 0x03 + +#define DRV260X_BLANK_TIME_45 (0 << 2) +#define DRV260X_BLANK_TIME_75 (1 << 2) +#define DRV260X_BLANK_TIME_150 (2 << 2) +#define DRV260X_BLANK_TIME_225 (3 << 2) + +#define DRV260X_SAMP_TIME_150 (0 << 4) +#define DRV260X_SAMP_TIME_200 (1 << 4) +#define DRV260X_SAMP_TIME_250 (2 << 4) +#define DRV260X_SAMP_TIME_300 (3 << 4) + +#define DRV260X_BRAKE_STABILIZER (1 << 6) +#define DRV260X_UNIDIR_IN (0 << 7) +#define DRV260X_BIDIR_IN (1 << 7) + +/* Control 3 Register */ +#define DRV260X_LRA_OPEN_LOOP (1 << 0) +#define DRV260X_ANANLOG_IN (1 << 1) +#define DRV260X_LRA_DRV_MODE (1 << 2) +#define DRV260X_RTP_UNSIGNED_DATA (1 << 3) +#define DRV260X_SUPPLY_COMP_DIS (1 << 4) +#define DRV260X_ERM_OPEN_LOOP (1 << 5) +#define DRV260X_NG_THRESH_0 (0 << 6) +#define DRV260X_NG_THRESH_2 (1 << 6) +#define DRV260X_NG_THRESH_4 (2 << 6) +#define DRV260X_NG_THRESH_8 (3 << 6) + +/* Control 4 Register */ +#define DRV260X_AUTOCAL_TIME_150MS (0 << 4) +#define DRV260X_AUTOCAL_TIME_250MS (1 << 4) +#define DRV260X_AUTOCAL_TIME_500MS (2 << 4) +#define DRV260X_AUTOCAL_TIME_1000MS (3 << 4) + +/** + * struct drv260x_data - + * @input_dev - Pointer to the input device + * @client - Pointer to the I2C client + * @regmap - Register map of the device + * @work - Work item used to off load the enable/disable of the vibration + * @enable_gpio - Pointer to the gpio used for enable/disabling + * @regulator - Pointer to the regulator for the IC + * @magnitude - Magnitude of the vibration event + * @mode - The operating mode of the IC (LRA_NO_CAL, ERM or LRA) + * @library - The vibration library to be used + * @rated_voltage - The rated_voltage of the actuator + * @overdriver_voltage - The over drive voltage of the actuator +**/ +struct drv260x_data { + struct input_dev *input_dev; + struct i2c_client *client; + struct regmap *regmap; + struct work_struct work; + struct gpio_desc *enable_gpio; + struct regulator *regulator; + u32 magnitude; + u32 mode; + u32 library; + int rated_voltage; + int overdrive_voltage; +}; + +static struct reg_default drv260x_reg_defs[] = { + { DRV260X_STATUS, 0xe0 }, + { DRV260X_MODE, 0x40 }, + { DRV260X_RT_PB_IN, 0x00 }, + { DRV260X_LIB_SEL, 0x00 }, + { DRV260X_WV_SEQ_1, 0x01 }, + { DRV260X_WV_SEQ_2, 0x00 }, + { DRV260X_WV_SEQ_3, 0x00 }, + { DRV260X_WV_SEQ_4, 0x00 }, + { DRV260X_WV_SEQ_5, 0x00 }, + { DRV260X_WV_SEQ_6, 0x00 }, + { DRV260X_WV_SEQ_7, 0x00 }, + { DRV260X_WV_SEQ_8, 0x00 }, + { DRV260X_GO, 0x00 }, + { DRV260X_OVERDRIVE_OFF, 0x00 }, + { DRV260X_SUSTAIN_P_OFF, 0x00 }, + { DRV260X_SUSTAIN_N_OFF, 0x00 }, + { DRV260X_BRAKE_OFF, 0x00 }, + { DRV260X_A_TO_V_CTRL, 0x05 }, + { DRV260X_A_TO_V_MIN_INPUT, 0x19 }, + { DRV260X_A_TO_V_MAX_INPUT, 0xff }, + { DRV260X_A_TO_V_MIN_OUT, 0x19 }, + { DRV260X_A_TO_V_MAX_OUT, 0xff }, + { DRV260X_RATED_VOLT, 0x3e }, + { DRV260X_OD_CLAMP_VOLT, 0x8c }, + { DRV260X_CAL_COMP, 0x0c }, + { DRV260X_CAL_BACK_EMF, 0x6c }, + { DRV260X_FEEDBACK_CTRL, 0x36 }, + { DRV260X_CTRL1, 0x93 }, + { DRV260X_CTRL2, 0xfa }, + { DRV260X_CTRL3, 0xa0 }, + { DRV260X_CTRL4, 0x20 }, + { DRV260X_CTRL5, 0x80 }, + { DRV260X_LRA_LOOP_PERIOD, 0x33 }, + { DRV260X_VBAT_MON, 0x00 }, + { DRV260X_LRA_RES_PERIOD, 0x00 }, +}; + +#define DRV260X_DEF_RATED_VOLT 0x90 +#define DRV260X_DEF_OD_CLAMP_VOLT 0x90 + +/** + * Rated and Overdriver Voltages: + * Calculated using the formula r = v * 255 / 5.6 + * where r is what will be written to the register + * and v is the rated or overdriver voltage of the actuator + **/ +static int drv260x_calculate_voltage(unsigned int voltage) +{ + return (voltage * 255 / 5600); +} + +static void drv260x_worker(struct work_struct *work) +{ + struct drv260x_data *haptics = container_of(work, struct drv260x_data, work); + int error; + + gpiod_set_value(haptics->enable_gpio, 1); + /* Data sheet says to wait 250us before trying to communicate */ + udelay(250); + + error = regmap_write(haptics->regmap, + DRV260X_MODE, DRV260X_RT_PLAYBACK); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write set mode: %d\n", error); + } else { + error = regmap_write(haptics->regmap, + DRV260X_RT_PB_IN, haptics->magnitude); + if (error) + dev_err(&haptics->client->dev, + "Failed to set magnitude: %d\n", error); + } +} + +static int drv260x_haptics_play(struct input_dev *input, void *data, + struct ff_effect *effect) +{ + struct drv260x_data *haptics = input_get_drvdata(input); + + haptics->mode = DRV260X_LRA_NO_CAL_MODE; + + if (effect->u.rumble.strong_magnitude > 0) + haptics->magnitude = effect->u.rumble.strong_magnitude; + else if (effect->u.rumble.weak_magnitude > 0) + haptics->magnitude = effect->u.rumble.weak_magnitude; + else + haptics->magnitude = 0; + + schedule_work(&haptics->work); + + return 0; +} + +static void drv260x_close(struct input_dev *input) +{ + struct drv260x_data *haptics = input_get_drvdata(input); + int error; + + cancel_work_sync(&haptics->work); + + error = regmap_write(haptics->regmap, DRV260X_MODE, DRV260X_STANDBY); + if (error) + dev_err(&haptics->client->dev, + "Failed to enter standby mode: %d\n", error); + + gpiod_set_value(haptics->enable_gpio, 0); +} + +static const struct reg_default drv260x_lra_cal_regs[] = { + { DRV260X_MODE, DRV260X_AUTO_CAL }, + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 }, + { DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE | + DRV260X_BRAKE_FACTOR_4X | DRV260X_LOOP_GAIN_HIGH }, +}; + +static const struct reg_default drv260x_lra_init_regs[] = { + { DRV260X_MODE, DRV260X_RT_PLAYBACK }, + { DRV260X_A_TO_V_CTRL, DRV260X_AUDIO_HAPTICS_PEAK_20MS | + DRV260X_AUDIO_HAPTICS_FILTER_125HZ }, + { DRV260X_A_TO_V_MIN_INPUT, DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT }, + { DRV260X_A_TO_V_MAX_INPUT, DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT }, + { DRV260X_A_TO_V_MIN_OUT, DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT }, + { DRV260X_A_TO_V_MAX_OUT, DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT }, + { DRV260X_FEEDBACK_CTRL, DRV260X_FB_REG_LRA_MODE | + DRV260X_BRAKE_FACTOR_2X | DRV260X_LOOP_GAIN_MED | + DRV260X_BEMF_GAIN_3 }, + { DRV260X_CTRL1, DRV260X_STARTUP_BOOST }, + { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 }, + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ANANLOG_IN }, + { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS }, +}; + +static const struct reg_default drv260x_erm_cal_regs[] = { + { DRV260X_MODE, DRV260X_AUTO_CAL }, + { DRV260X_A_TO_V_MIN_INPUT, DRV260X_AUDIO_HAPTICS_MIN_IN_VOLT }, + { DRV260X_A_TO_V_MAX_INPUT, DRV260X_AUDIO_HAPTICS_MAX_IN_VOLT }, + { DRV260X_A_TO_V_MIN_OUT, DRV260X_AUDIO_HAPTICS_MIN_OUT_VOLT }, + { DRV260X_A_TO_V_MAX_OUT, DRV260X_AUDIO_HAPTICS_MAX_OUT_VOLT }, + { DRV260X_FEEDBACK_CTRL, DRV260X_BRAKE_FACTOR_3X | + DRV260X_LOOP_GAIN_MED | DRV260X_BEMF_GAIN_2 }, + { DRV260X_CTRL1, DRV260X_STARTUP_BOOST }, + { DRV260X_CTRL2, DRV260X_SAMP_TIME_250 | DRV260X_BLANK_TIME_75 | + DRV260X_IDISS_TIME_75 }, + { DRV260X_CTRL3, DRV260X_NG_THRESH_2 | DRV260X_ERM_OPEN_LOOP }, + { DRV260X_CTRL4, DRV260X_AUTOCAL_TIME_500MS }, +}; + +static int drv260x_init(struct drv260x_data *haptics) +{ + int error; + unsigned int cal_buf; + + error = regmap_write(haptics->regmap, + DRV260X_RATED_VOLT, haptics->rated_voltage); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write DRV260X_RATED_VOLT register: %d\n", + error); + return error; + } + + error = regmap_write(haptics->regmap, + DRV260X_OD_CLAMP_VOLT, haptics->overdrive_voltage); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write DRV260X_OD_CLAMP_VOLT register: %d\n", + error); + return error; + } + + switch (haptics->mode) { + case DRV260X_LRA_MODE: + error = regmap_register_patch(haptics->regmap, + drv260x_lra_cal_regs, + ARRAY_SIZE(drv260x_lra_cal_regs)); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write LRA calibration registers: %d\n", + error); + return error; + } + + break; + + case DRV260X_ERM_MODE: + error = regmap_register_patch(haptics->regmap, + drv260x_erm_cal_regs, + ARRAY_SIZE(drv260x_erm_cal_regs)); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write ERM calibration registers: %d\n", + error); + return error; + } + + error = regmap_update_bits(haptics->regmap, DRV260X_LIB_SEL, + DRV260X_LIB_SEL_MASK, + haptics->library); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write DRV260X_LIB_SEL register: %d\n", + error); + return error; + } + + break; + + default: + error = regmap_register_patch(haptics->regmap, + drv260x_lra_init_regs, + ARRAY_SIZE(drv260x_lra_init_regs)); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write LRA init registers: %d\n", + error); + return error; + } + + error = regmap_update_bits(haptics->regmap, DRV260X_LIB_SEL, + DRV260X_LIB_SEL_MASK, + haptics->library); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write DRV260X_LIB_SEL register: %d\n", + error); + return error; + } + + /* No need to set GO bit here */ + return 0; + } + + error = regmap_write(haptics->regmap, DRV260X_GO, DRV260X_GO_BIT); + if (error) { + dev_err(&haptics->client->dev, + "Failed to write GO register: %d\n", + error); + return error; + } + + do { + error = regmap_read(haptics->regmap, DRV260X_GO, &cal_buf); + if (error) { + dev_err(&haptics->client->dev, + "Failed to read GO register: %d\n", + error); + return error; + } + } while (cal_buf == DRV260X_GO_BIT); + + return 0; +} + +static const struct regmap_config drv260x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + + .max_register = DRV260X_MAX_REG, + .reg_defaults = drv260x_reg_defs, + .num_reg_defaults = ARRAY_SIZE(drv260x_reg_defs), + .cache_type = REGCACHE_NONE, +}; + +#ifdef CONFIG_OF +static int drv260x_parse_dt(struct device *dev, + struct drv260x_data *haptics) +{ + struct device_node *np = dev->of_node; + unsigned int voltage; + int error; + + error = of_property_read_u32(np, "mode", &haptics->mode); + if (error) { + dev_err(dev, "%s: No entry for mode\n", __func__); + return error; + } + + error = of_property_read_u32(np, "library-sel", &haptics->library); + if (error) { + dev_err(dev, "%s: No entry for library selection\n", + __func__); + return error; + } + + error = of_property_read_u32(np, "vib-rated-mv", &voltage); + if (!error) + haptics->rated_voltage = drv260x_calculate_voltage(voltage); + + + error = of_property_read_u32(np, "vib-overdrive-mv", &voltage); + if (!error) + haptics->overdrive_voltage = drv260x_calculate_voltage(voltage); + + return 0; +} +#else +static inline int drv260x_parse_dt(struct device *dev, + struct drv260x_data *haptics) +{ + dev_err(dev, "no platform data defined\n"); + + return -EINVAL; +} +#endif + +static int drv260x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + const struct drv260x_platform_data *pdata = dev_get_platdata(&client->dev); + struct drv260x_data *haptics; + int error; + + haptics = devm_kzalloc(&client->dev, sizeof(*haptics), GFP_KERNEL); + if (!haptics) + return -ENOMEM; + + haptics->rated_voltage = DRV260X_DEF_OD_CLAMP_VOLT; + haptics->rated_voltage = DRV260X_DEF_RATED_VOLT; + + if (pdata) { + haptics->mode = pdata->mode; + haptics->library = pdata->library_selection; + if (pdata->vib_overdrive_voltage) + haptics->overdrive_voltage = drv260x_calculate_voltage(pdata->vib_overdrive_voltage); + if (pdata->vib_rated_voltage) + haptics->rated_voltage = drv260x_calculate_voltage(pdata->vib_rated_voltage); + } else if (client->dev.of_node) { + error = drv260x_parse_dt(&client->dev, haptics); + if (error) + return error; + } else { + dev_err(&client->dev, "Platform data not set\n"); + return -ENODEV; + } + + + if (haptics->mode < DRV260X_LRA_MODE || + haptics->mode > DRV260X_ERM_MODE) { + dev_err(&client->dev, + "Vibrator mode is invalid: %i\n", + haptics->mode); + return -EINVAL; + } + + if (haptics->library < DRV260X_LIB_EMPTY || + haptics->library > DRV260X_ERM_LIB_F) { + dev_err(&client->dev, + "Library value is invalid: %i\n", haptics->library); + return -EINVAL; + } + + if (haptics->mode == DRV260X_LRA_MODE && + haptics->library != DRV260X_LIB_EMPTY && + haptics->library != DRV260X_LIB_LRA) { + dev_err(&client->dev, + "LRA Mode with ERM Library mismatch\n"); + return -EINVAL; + } + + haptics->regulator = devm_regulator_get(&client->dev, "vbat"); + if (IS_ERR(haptics->regulator)) { + error = PTR_ERR(haptics->regulator); + dev_err(&client->dev, + "unable to get regulator, error: %d\n", error); + return error; + } + + haptics->enable_gpio = devm_gpiod_get(&client->dev, "enable"); + if (IS_ERR(haptics->enable_gpio)) { + error = PTR_ERR(haptics->enable_gpio); + if (error != -ENOENT && error != -ENOSYS) + return error; + haptics->enable_gpio = NULL; + } else { + gpiod_direction_output(haptics->enable_gpio, 1); + } + + haptics->input_dev = devm_input_allocate_device(&client->dev); + if (!haptics->input_dev) { + dev_err(&client->dev, "Failed to allocate input device\n"); + return -ENOMEM; + } + + haptics->input_dev->name = "drv260x:haptics"; + haptics->input_dev->dev.parent = client->dev.parent; + haptics->input_dev->close = drv260x_close; + input_set_drvdata(haptics->input_dev, haptics); + input_set_capability(haptics->input_dev, EV_FF, FF_RUMBLE); + + error = input_ff_create_memless(haptics->input_dev, NULL, + drv260x_haptics_play); + if (error) { + dev_err(&client->dev, "input_ff_create() failed: %d\n", + error); + return error; + } + + INIT_WORK(&haptics->work, drv260x_worker); + + haptics->client = client; + i2c_set_clientdata(client, haptics); + + haptics->regmap = devm_regmap_init_i2c(client, &drv260x_regmap_config); + if (IS_ERR(haptics->regmap)) { + error = PTR_ERR(haptics->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + error); + return error; + } + + error = drv260x_init(haptics); + if (error) { + dev_err(&client->dev, "Device init failed: %d\n", error); + return error; + } + + error = input_register_device(haptics->input_dev); + if (error) { + dev_err(&client->dev, "couldn't register input device: %d\n", + error); + return error; + } + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int drv260x_suspend(struct device *dev) +{ + struct drv260x_data *haptics = dev_get_drvdata(dev); + int ret = 0; + + mutex_lock(&haptics->input_dev->mutex); + + if (haptics->input_dev->users) { + ret = regmap_update_bits(haptics->regmap, + DRV260X_MODE, + DRV260X_STANDBY_MASK, + DRV260X_STANDBY); + if (ret) { + dev_err(dev, "Failed to set standby mode\n"); + goto out; + } + + gpiod_set_value(haptics->enable_gpio, 0); + + ret = regulator_disable(haptics->regulator); + if (ret) { + dev_err(dev, "Failed to disable regulator\n"); + regmap_update_bits(haptics->regmap, + DRV260X_MODE, + DRV260X_STANDBY_MASK, 0); + } + } +out: + mutex_unlock(&haptics->input_dev->mutex); + return ret; +} + +static int drv260x_resume(struct device *dev) +{ + struct drv260x_data *haptics = dev_get_drvdata(dev); + int ret = 0; + + mutex_lock(&haptics->input_dev->mutex); + + if (haptics->input_dev->users) { + ret = regulator_enable(haptics->regulator); + if (ret) { + dev_err(dev, "Failed to enable regulator\n"); + goto out; + } + + ret = regmap_update_bits(haptics->regmap, + DRV260X_MODE, + DRV260X_STANDBY_MASK, 0); + if (ret) { + dev_err(dev, "Failed to unset standby mode\n"); + regulator_disable(haptics->regulator); + goto out; + } + + gpiod_set_value(haptics->enable_gpio, 1); + } + +out: + mutex_unlock(&haptics->input_dev->mutex); + return ret; +} +#endif + +static SIMPLE_DEV_PM_OPS(drv260x_pm_ops, drv260x_suspend, drv260x_resume); + +static const struct i2c_device_id drv260x_id[] = { + { "drv2605l", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, drv260x_id); + +#ifdef CONFIG_OF +static const struct of_device_id drv260x_of_match[] = { + { .compatible = "ti,drv2604", }, + { .compatible = "ti,drv2604l", }, + { .compatible = "ti,drv2605", }, + { .compatible = "ti,drv2605l", }, + { } +}; +MODULE_DEVICE_TABLE(of, drv260x_of_match); +#endif + +static struct i2c_driver drv260x_driver = { + .probe = drv260x_probe, + .driver = { + .name = "drv260x-haptics", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(drv260x_of_match), + .pm = &drv260x_pm_ops, + }, + .id_table = drv260x_id, +}; +module_i2c_driver(drv260x_driver); + +MODULE_ALIAS("platform:drv260x-haptics"); +MODULE_DESCRIPTION("TI DRV260x haptics driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Dan Murphy "); diff --git a/include/dt-bindings/input/ti-drv260x.h b/include/dt-bindings/input/ti-drv260x.h new file mode 100644 index 000000000000..2626e6d9f707 --- /dev/null +++ b/include/dt-bindings/input/ti-drv260x.h @@ -0,0 +1,36 @@ +/* + * DRV260X haptics driver family + * + * Author: Dan Murphy + * + * Copyright: (C) 2014 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. + * + * 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 _DT_BINDINGS_TI_DRV260X_H +#define _DT_BINDINGS_TI_DRV260X_H + +/* Calibration Types */ +#define DRV260X_LRA_MODE 0x00 +#define DRV260X_LRA_NO_CAL_MODE 0x01 +#define DRV260X_ERM_MODE 0x02 + +/* Library Selection */ +#define DRV260X_LIB_EMPTY 0x00 +#define DRV260X_ERM_LIB_A 0x01 +#define DRV260X_ERM_LIB_B 0x02 +#define DRV260X_ERM_LIB_C 0x03 +#define DRV260X_ERM_LIB_D 0x04 +#define DRV260X_ERM_LIB_E 0x05 +#define DRV260X_LIB_LRA 0x06 +#define DRV260X_ERM_LIB_F 0x07 + +#endif diff --git a/include/linux/platform_data/drv260x-pdata.h b/include/linux/platform_data/drv260x-pdata.h new file mode 100644 index 000000000000..0a03b0944411 --- /dev/null +++ b/include/linux/platform_data/drv260x-pdata.h @@ -0,0 +1,28 @@ +/* + * Platform data for DRV260X haptics driver family + * + * Author: Dan Murphy + * + * Copyright: (C) 2014 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. + * + * 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_DRV260X_PDATA_H +#define _LINUX_DRV260X_PDATA_H + +struct drv260x_platform_data { + u32 library_selection; + u32 mode; + u32 vib_rated_voltage; + u32 vib_overdrive_voltage; +}; + +#endif -- GitLab From 5d07f4202c5d63b73ba1734ed38e08461a689313 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 13 Aug 2014 21:19:53 +0200 Subject: [PATCH 0992/9167] sched: s/do_each_thread/for_each_process_thread/ in core.c Change kernel/sched/core.c to use for_each_process_thread(). Signed-off-by: Oleg Nesterov Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Hidetoshi Seto Cc: Frank Mayhar Cc: Frederic Weisbecker Cc: Andrew Morton Cc: Sanjay Rao Cc: Larry Woodman Cc: Rik van Riel Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20140813191953.GA19315@redhat.com Signed-off-by: Ingo Molnar --- kernel/sched/core.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 7d1ec6e60535..4f2826f46e95 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4505,7 +4505,7 @@ void show_state_filter(unsigned long state_filter) " task PC stack pid father\n"); #endif rcu_read_lock(); - do_each_thread(g, p) { + for_each_process_thread(g, p) { /* * reset the NMI-timeout, listing all files on a slow * console might take a lot of time: @@ -4513,7 +4513,7 @@ void show_state_filter(unsigned long state_filter) touch_nmi_watchdog(); if (!state_filter || (p->state & state_filter)) sched_show_task(p); - } while_each_thread(g, p); + } touch_all_softlockup_watchdogs(); @@ -7137,7 +7137,7 @@ void normalize_rt_tasks(void) struct rq *rq; read_lock_irqsave(&tasklist_lock, flags); - do_each_thread(g, p) { + for_each_process_thread(g, p) { /* * Only normalize user tasks: */ @@ -7168,8 +7168,7 @@ void normalize_rt_tasks(void) __task_rq_unlock(rq); raw_spin_unlock(&p->pi_lock); - } while_each_thread(g, p); - + } read_unlock_irqrestore(&tasklist_lock, flags); } @@ -7357,10 +7356,10 @@ static inline int tg_has_rt_tasks(struct task_group *tg) { struct task_struct *g, *p; - do_each_thread(g, p) { + for_each_process_thread(g, p) { if (rt_task(p) && task_rq(p)->rt.tg == tg) return 1; - } while_each_thread(g, p); + } return 0; } -- GitLab From d38e83c715270cc2e137bbf6f25206c8c023896b Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 13 Aug 2014 21:19:56 +0200 Subject: [PATCH 0993/9167] sched: s/do_each_thread/for_each_process_thread/ in debug.c Change kernel/sched/debug.c to use for_each_process_thread(). Signed-off-by: Oleg Nesterov Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Hidetoshi Seto Cc: Frank Mayhar Cc: Frederic Weisbecker Cc: Andrew Morton Cc: Sanjay Rao Cc: Larry Woodman Cc: Rik van Riel Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20140813191956.GA19324@redhat.com Signed-off-by: Ingo Molnar --- kernel/sched/debug.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 627b3c34b821..c7fe1ea0e8ab 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -160,14 +160,12 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu) "----------------------------------------------------\n"); read_lock_irqsave(&tasklist_lock, flags); - - do_each_thread(g, p) { + for_each_process_thread(g, p) { if (task_cpu(p) != rq_cpu) continue; print_task(m, rq, p); - } while_each_thread(g, p); - + } read_unlock_irqrestore(&tasklist_lock, flags); } -- GitLab From 1e4dda08b4c39b3d8f4a3ee7269d49e0200c8af8 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 13 Aug 2014 21:20:00 +0200 Subject: [PATCH 0994/9167] sched: Change thread_group_cputime() to use for_each_thread() Change thread_group_cputime() to use for_each_thread() instead of buggy while_each_thread(). This also makes the pid_alive() check unnecessary. Signed-off-by: Oleg Nesterov Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Hidetoshi Seto Cc: Frank Mayhar Cc: Frederic Weisbecker Cc: Andrew Morton Cc: Sanjay Rao Cc: Larry Woodman Cc: Rik van Riel Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20140813192000.GA19327@redhat.com Signed-off-by: Ingo Molnar --- kernel/sched/cputime.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c index 72fdf06ef865..3e52836359ba 100644 --- a/kernel/sched/cputime.c +++ b/kernel/sched/cputime.c @@ -294,18 +294,12 @@ void thread_group_cputime(struct task_struct *tsk, struct task_cputime *times) times->sum_exec_runtime = sig->sum_sched_runtime; rcu_read_lock(); - /* make sure we can trust tsk->thread_group list */ - if (!likely(pid_alive(tsk))) - goto out; - - t = tsk; - do { + for_each_thread(tsk, t) { task_cputime(t, &utime, &stime); times->utime += utime; times->stime += stime; times->sum_exec_runtime += task_sched_runtime(t); - } while_each_thread(tsk, t); -out: + } rcu_read_unlock(); } -- GitLab From 5aface53d1a0ef7823215c4078fca8445995d006 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 13 Aug 2014 21:20:03 +0200 Subject: [PATCH 0995/9167] sched: Change autogroup_move_group() to use for_each_thread() Change autogroup_move_group() to use for_each_thread() instead of buggy while_each_thread(). Signed-off-by: Oleg Nesterov Signed-off-by: Peter Zijlstra Cc: Mike Galbraith Cc: Hidetoshi Seto Cc: Frank Mayhar Cc: Frederic Weisbecker Cc: Andrew Morton Cc: Sanjay Rao Cc: Larry Woodman Cc: Rik van Riel Cc: Linus Torvalds Link: http://lkml.kernel.org/r/20140813192003.GA19334@redhat.com Signed-off-by: Ingo Molnar --- kernel/sched/auto_group.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kernel/sched/auto_group.c b/kernel/sched/auto_group.c index e73efba98301..8a2e230fb86a 100644 --- a/kernel/sched/auto_group.c +++ b/kernel/sched/auto_group.c @@ -148,11 +148,8 @@ autogroup_move_group(struct task_struct *p, struct autogroup *ag) if (!ACCESS_ONCE(sysctl_sched_autogroup_enabled)) goto out; - t = p; - do { + for_each_thread(p, t) sched_move_task(t); - } while_each_thread(p, t); - out: unlock_task_sighand(p, &flags); autogroup_kref_put(prev); -- GitLab From 8b06c55bdb8b402cb4814e83dc4b1cb245fcc9f5 Mon Sep 17 00:00:00 2001 From: Pranith Kumar Date: Wed, 13 Aug 2014 13:28:12 -0400 Subject: [PATCH 0996/9167] sched: Match declaration with definition Match the declaration of runqueues with the definition. Signed-off-by: Pranith Kumar Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1407950893-32731-1-git-send-email-bobby.prani@gmail.com Signed-off-by: Ingo Molnar --- kernel/sched/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 579712f4e9d5..4c2b87fd5f52 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -647,7 +647,7 @@ static inline int cpu_of(struct rq *rq) #endif } -DECLARE_PER_CPU(struct rq, runqueues); +DECLARE_PER_CPU_SHARED_ALIGNED(struct rq, runqueues); #define cpu_rq(cpu) (&per_cpu(runqueues, (cpu))) #define this_rq() (&__get_cpu_var(runqueues)) -- GitLab From f36c019c79edb3a89920afae1b2b45987af1a112 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Wed, 6 Aug 2014 12:06:01 +0400 Subject: [PATCH 0997/9167] sched/fair: Fix reschedule which is generated on throttled cfs_rq (sched_entity::on_rq == 1) does not guarantee the task is pickable; changes on throttled cfs_rq must not lead to reschedule. Check for task_struct::on_rq instead. Signed-off-by: Kirill Tkhai Signed-off-by: Peter Zijlstra Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1407312361.8424.35.camel@tkhai Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 1413c44ce8a1..bc37bb97159f 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7494,7 +7494,7 @@ static void task_fork_fair(struct task_struct *p) static void prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio) { - if (!p->se.on_rq) + if (!p->on_rq) return; /* @@ -7550,15 +7550,15 @@ static void switched_from_fair(struct rq *rq, struct task_struct *p) */ static void switched_to_fair(struct rq *rq, struct task_struct *p) { - struct sched_entity *se = &p->se; #ifdef CONFIG_FAIR_GROUP_SCHED + struct sched_entity *se = &p->se; /* * Since the real-depth could have been changed (only FAIR * class maintain depth value), reset depth properly. */ se->depth = se->parent ? se->parent->depth + 1 : 0; #endif - if (!se->on_rq) + if (!p->on_rq) return; /* -- GitLab From a32e84594ddf018cc618a8781298804c3e6131ce Mon Sep 17 00:00:00 2001 From: Wanpeng Li Date: Wed, 20 Aug 2014 15:31:53 +0800 Subject: [PATCH 0998/9167] KVM: vmx: fix ept reserved bits for 1-GByte page EPT misconfig handler in kvm will check which reason lead to EPT misconfiguration after vmexit. One of the reasons is that an EPT paging-structure entry is configured with settings reserved for future functionality. However, the handler can't identify if paging-structure entry of reserved bits for 1-GByte page are configured, since PDPTE which point to 1-GByte page will reserve bits 29:12 instead of bits 7:3 which are reserved for PDPTE that references an EPT Page Directory. This patch fix it by reserve bits 29:12 for 1-GByte page. Signed-off-by: Wanpeng Li Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index cad37d57cc47..286c2835e25c 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5521,17 +5521,18 @@ static u64 ept_rsvd_mask(u64 spte, int level) for (i = 51; i > boot_cpu_data.x86_phys_bits; i--) mask |= (1ULL << i); - if (level > 2) + if (level == 4) /* bits 7:3 reserved */ mask |= 0xf8; - else if (level == 2) { - if (spte & (1ULL << 7)) - /* 2MB ref, bits 20:12 reserved */ - mask |= 0x1ff000; - else - /* bits 6:3 reserved */ - mask |= 0x78; - } + else if (spte & (1ULL << 7)) + /* + * 1GB/2MB page, bits 29:12 or 20:12 reserved respectively, + * level == 1 if the hypervisor is using the ignored bit 7. + */ + mask |= (PAGE_SIZE << ((level - 1) * 9)) - PAGE_SIZE; + else if (level > 1) + /* bits 6:3 reserved */ + mask |= 0x78; return mask; } @@ -5561,7 +5562,8 @@ static void ept_misconfig_inspect_spte(struct kvm_vcpu *vcpu, u64 spte, WARN_ON(1); } - if (level == 1 || (level == 2 && (spte & (1ULL << 7)))) { + /* bits 5:3 are _not_ reserved for large page or leaf page */ + if ((rsvd_bits & 0x38) == 0) { u64 ept_mem_type = (spte & 0x38) >> 3; if (ept_mem_type == 2 || ept_mem_type == 3 || -- GitLab From d27aa7f15c3b1105c8cd8c2d190ab354f877cac5 Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 20 Aug 2014 13:25:52 +0300 Subject: [PATCH 0999/9167] KVM: x86: Clarify PMU related features bit manipulation kvm_pmu_cpuid_update makes a lot of bit manuiplation operations, when in fact there are already unions that can be used instead. Changing the bit manipulation to the union for clarity. This patch does not change the functionality. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/pmu.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c index 3dd6accb64ec..8e6b7d869d2f 100644 --- a/arch/x86/kvm/pmu.c +++ b/arch/x86/kvm/pmu.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "x86.h" #include "cpuid.h" #include "lapic.h" @@ -463,7 +464,8 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) { struct kvm_pmu *pmu = &vcpu->arch.pmu; struct kvm_cpuid_entry2 *entry; - unsigned bitmap_len; + union cpuid10_eax eax; + union cpuid10_edx edx; pmu->nr_arch_gp_counters = 0; pmu->nr_arch_fixed_counters = 0; @@ -475,25 +477,27 @@ void kvm_pmu_cpuid_update(struct kvm_vcpu *vcpu) entry = kvm_find_cpuid_entry(vcpu, 0xa, 0); if (!entry) return; + eax.full = entry->eax; + edx.full = entry->edx; - pmu->version = entry->eax & 0xff; + pmu->version = eax.split.version_id; if (!pmu->version) return; - pmu->nr_arch_gp_counters = min((int)(entry->eax >> 8) & 0xff, - INTEL_PMC_MAX_GENERIC); - pmu->counter_bitmask[KVM_PMC_GP] = - ((u64)1 << ((entry->eax >> 16) & 0xff)) - 1; - bitmap_len = (entry->eax >> 24) & 0xff; - pmu->available_event_types = ~entry->ebx & ((1ull << bitmap_len) - 1); + pmu->nr_arch_gp_counters = min_t(int, eax.split.num_counters, + INTEL_PMC_MAX_GENERIC); + pmu->counter_bitmask[KVM_PMC_GP] = ((u64)1 << eax.split.bit_width) - 1; + pmu->available_event_types = ~entry->ebx & + ((1ull << eax.split.mask_length) - 1); if (pmu->version == 1) { pmu->nr_arch_fixed_counters = 0; } else { - pmu->nr_arch_fixed_counters = min((int)(entry->edx & 0x1f), + pmu->nr_arch_fixed_counters = + min_t(int, edx.split.num_counters_fixed, INTEL_PMC_MAX_FIXED); pmu->counter_bitmask[KVM_PMC_FIXED] = - ((u64)1 << ((entry->edx >> 5) & 0xff)) - 1; + ((u64)1 << edx.split.bit_width_fixed) - 1; } pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) | -- GitLab From 592f085847f4ea753586dfe6ce75ba37d5992a45 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 Aug 2014 10:05:08 +0200 Subject: [PATCH 1000/9167] KVM: emulate: do not return X86EMUL_PROPAGATE_FAULT explicitly Always get it through emulate_exception or emulate_ts. This ensures that the ctxt->exception fields have been populated. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index ef297919a691..4fbf4b598f92 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1549,8 +1549,7 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg); return X86EMUL_CONTINUE; exception: - emulate_exception(ctxt, err_vec, err_code, true); - return X86EMUL_PROPAGATE_FAULT; + return emulate_exception(ctxt, err_vec, err_code, true); } static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt, @@ -2723,8 +2722,7 @@ static int emulator_do_task_switch(struct x86_emulate_ctxt *ctxt, if (!next_tss_desc.p || ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || desc_limit < 0x2b)) { - emulate_ts(ctxt, tss_selector & 0xfffc); - return X86EMUL_PROPAGATE_FAULT; + return emulate_ts(ctxt, tss_selector & 0xfffc); } if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) { @@ -3016,7 +3014,7 @@ static int em_movbe(struct x86_emulate_ctxt *ctxt) ctxt->dst.val = swab64(ctxt->src.val); break; default: - return X86EMUL_PROPAGATE_FAULT; + BUG(); } return X86EMUL_CONTINUE; } -- GitLab From e0ad0b477c36fde6b0923670647495d07bf42f94 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 20 Aug 2014 10:08:23 +0200 Subject: [PATCH 1001/9167] KVM: emulate: warn on invalid or uninitialized exception numbers These were reported when running Jailhouse on AMD processors. Initialize ctxt->exception.vector with an invalid exception number, and warn if it remained invalid even though the emulator got an X86EMUL_PROPAGATE_FAULT return code. Signed-off-by: Paolo Bonzini --- arch/x86/kvm/emulate.c | 5 ++++- arch/x86/kvm/x86.c | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 4fbf4b598f92..e5bf13003cd2 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -527,6 +527,7 @@ static unsigned long seg_base(struct x86_emulate_ctxt *ctxt, int seg) static int emulate_exception(struct x86_emulate_ctxt *ctxt, int vec, u32 error, bool valid) { + WARN_ON(vec > 0x1f); ctxt->exception.vector = vec; ctxt->exception.error_code = error; ctxt->exception.error_code_valid = valid; @@ -4827,8 +4828,10 @@ int x86_emulate_insn(struct x86_emulate_ctxt *ctxt) ctxt->eip = ctxt->_eip; done: - if (rc == X86EMUL_PROPAGATE_FAULT) + if (rc == X86EMUL_PROPAGATE_FAULT) { + WARN_ON(ctxt->exception.vector > 0x1f); ctxt->have_exception = true; + } if (rc == X86EMUL_INTERCEPTED) return EMULATION_INTERCEPTED; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 737b4bdac41c..cd718c01cdf1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5248,6 +5248,7 @@ int x86_emulate_instruction(struct kvm_vcpu *vcpu, ctxt->interruptibility = 0; ctxt->have_exception = false; + ctxt->exception.vector = -1; ctxt->perm_ok = false; ctxt->ud = emulation_type & EMULTYPE_TRAP_UD; -- GitLab From 700be564308bcfc217bd3515d634b56f0c3c1bbb Mon Sep 17 00:00:00 2001 From: Don Zickus Date: Tue, 19 Aug 2014 22:31:14 -0400 Subject: [PATCH 1002/9167] perf symbols: Don't try to find DSOs in SYSV maps We are seeing a lot of the following with regards to SYSV memory Failed to open /SYSV0000279c, continuing without symbols We don't believe this memory will have DSO info, so treat it like the heap and stack for now and skip it to prevent the warning. Signed-off-by: Don Zickus Signed-off-by: Joe Mario Cc: Jiri Olsa Cc: Joe Mario Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1408501874-244377-1-git-send-email-dzickus@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/map.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 31b8905dd863..b7090596ac50 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c @@ -31,6 +31,7 @@ static inline int is_anon_memory(const char *filename) static inline int is_no_dso_memory(const char *filename) { return !strncmp(filename, "[stack", 6) || + !strncmp(filename, "/SYSV",5) || !strcmp(filename, "[heap]"); } -- GitLab From ad7e767a726dd7dffad45d7fcbf371094e7f2288 Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Thu, 7 Aug 2014 00:27:00 -0700 Subject: [PATCH 1003/9167] perf tools powerpc: Explicitly include util/debug.h Looks like util/debug.h was indirectly included before and is no longer included now. pr_debug is left undefined and the build of perf tool fails on Powerpc. Explicitly include util/debug.h. Signed-off-by: Sukadev Bhattiprolu Acked-by: Jiri Olsa Cc: Jiri Olsa Cc: Michael Ellerman Link: http://lkml.kernel.org/r/20140807072700.GA17623@us.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/arch/powerpc/util/skip-callchain-idx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index a7c23a4b3778..d73ef8bb08c7 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c @@ -15,6 +15,7 @@ #include "util/thread.h" #include "util/callchain.h" +#include "util/debug.h" /* * When saving the callchain on Power, the kernel conservatively saves -- GitLab From 8e4bebe0952af357e099147023af756baa466ede Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Thu, 7 Aug 2014 18:51:34 +0800 Subject: [PATCH 1004/9167] irqchip: hip04: Enable Hisilicon HiP04 interrupt controller HiP04 GIC is the variate of ARM GICv2. ARM GICv2 supports 8 cores. HiP04 GIC extends to support 16 cores. It results that bit fields in GIC_DIST_TARGET & GIC_DIST_SOFTINT are different from ARM GICv2. And the maximium IRQ is downgrade from 1020 to 510. Since different register offset & bitfields definitation breaks compartible with ARM GICv2, create a new hip04 irq driver. And this driver is derived from irq-gic.c to support the Hisilicon HiP04 interrupt controller, which is similar to the GIC, but deviates at some points. Support for power management, non-banked registers, cascaded GICs (and multiple controllers in general) and bigLittle support has been removed from the GIC driver. Affinity related functions have been adjusted to match the Hisilicon hardware implementation. Signed-off-by: Haojian Zhuang Link: https://lkml.kernel.org/r/1407408695-19626-9-git-send-email-haojian.zhuang@linaro.org Signed-off-by: Jason Cooper --- drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-hip04.c | 424 ++++++++++++++++++++++++++++++++++++ 2 files changed, 425 insertions(+) create mode 100644 drivers/irqchip/irq-hip04.c diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index 73052ba9ca62..1dca5bc2cc43 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_IRQCHIP) += irqchip.o obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o obj-$(CONFIG_ARCH_EXYNOS) += exynos-combiner.o +obj-$(CONFIG_ARCH_HIP04) += irq-hip04.o obj-$(CONFIG_ARCH_MMP) += irq-mmp.o obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o obj-$(CONFIG_ARCH_MXS) += irq-mxs.o diff --git a/drivers/irqchip/irq-hip04.c b/drivers/irqchip/irq-hip04.c new file mode 100644 index 000000000000..9c8f833522e6 --- /dev/null +++ b/drivers/irqchip/irq-hip04.c @@ -0,0 +1,424 @@ +/* + * Hisilicon HiP04 INTC + * + * Copyright (C) 2002-2014 ARM Limited. + * Copyright (c) 2013-2014 Hisilicon Ltd. + * Copyright (c) 2013-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. + * + * Interrupt architecture for the HIP04 INTC: + * + * o There is one Interrupt Distributor, which receives interrupts + * from system devices and sends them to the Interrupt Controllers. + * + * o There is one CPU Interface per CPU, which sends interrupts sent + * by the Distributor, and interrupts generated locally, to the + * associated CPU. The base address of the CPU interface is usually + * aliased so that the same address points to different chips depending + * on the CPU it is accessed from. + * + * Note that IRQs 0-31 are special - they are local to each CPU. + * As such, the enable set/clear, pending set/clear and active bit + * registers are banked per-cpu for these sources. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "irq-gic-common.h" +#include "irqchip.h" + +#define HIP04_MAX_IRQS 510 + +struct hip04_irq_data { + void __iomem *dist_base; + void __iomem *cpu_base; + struct irq_domain *domain; + unsigned int nr_irqs; +}; + +static DEFINE_RAW_SPINLOCK(irq_controller_lock); + +/* + * The GIC mapping of CPU interfaces does not necessarily match + * the logical CPU numbering. Let's use a mapping as returned + * by the GIC itself. + */ +#define NR_HIP04_CPU_IF 16 +static u16 hip04_cpu_map[NR_HIP04_CPU_IF] __read_mostly; + +static struct hip04_irq_data hip04_data __read_mostly; + +static inline void __iomem *hip04_dist_base(struct irq_data *d) +{ + struct hip04_irq_data *hip04_data = irq_data_get_irq_chip_data(d); + return hip04_data->dist_base; +} + +static inline void __iomem *hip04_cpu_base(struct irq_data *d) +{ + struct hip04_irq_data *hip04_data = irq_data_get_irq_chip_data(d); + return hip04_data->cpu_base; +} + +static inline unsigned int hip04_irq(struct irq_data *d) +{ + return d->hwirq; +} + +/* + * Routines to acknowledge, disable and enable interrupts + */ +static void hip04_mask_irq(struct irq_data *d) +{ + u32 mask = 1 << (hip04_irq(d) % 32); + + raw_spin_lock(&irq_controller_lock); + writel_relaxed(mask, hip04_dist_base(d) + GIC_DIST_ENABLE_CLEAR + + (hip04_irq(d) / 32) * 4); + raw_spin_unlock(&irq_controller_lock); +} + +static void hip04_unmask_irq(struct irq_data *d) +{ + u32 mask = 1 << (hip04_irq(d) % 32); + + raw_spin_lock(&irq_controller_lock); + writel_relaxed(mask, hip04_dist_base(d) + GIC_DIST_ENABLE_SET + + (hip04_irq(d) / 32) * 4); + raw_spin_unlock(&irq_controller_lock); +} + +static void hip04_eoi_irq(struct irq_data *d) +{ + writel_relaxed(hip04_irq(d), hip04_cpu_base(d) + GIC_CPU_EOI); +} + +static int hip04_irq_set_type(struct irq_data *d, unsigned int type) +{ + void __iomem *base = hip04_dist_base(d); + unsigned int irq = hip04_irq(d); + + /* Interrupt configuration for SGIs can't be changed */ + if (irq < 16) + return -EINVAL; + + if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING) + return -EINVAL; + + raw_spin_lock(&irq_controller_lock); + + gic_configure_irq(irq, type, base, NULL); + + raw_spin_unlock(&irq_controller_lock); + + return 0; +} + +#ifdef CONFIG_SMP +static int hip04_irq_set_affinity(struct irq_data *d, + const struct cpumask *mask_val, + bool force) +{ + void __iomem *reg; + unsigned int cpu, shift = (hip04_irq(d) % 2) * 16; + u32 val, mask, bit; + + if (!force) + cpu = cpumask_any_and(mask_val, cpu_online_mask); + else + cpu = cpumask_first(mask_val); + + if (cpu >= NR_HIP04_CPU_IF || cpu >= nr_cpu_ids) + return -EINVAL; + + raw_spin_lock(&irq_controller_lock); + reg = hip04_dist_base(d) + GIC_DIST_TARGET + ((hip04_irq(d) * 2) & ~3); + mask = 0xffff << shift; + bit = hip04_cpu_map[cpu] << shift; + val = readl_relaxed(reg) & ~mask; + writel_relaxed(val | bit, reg); + raw_spin_unlock(&irq_controller_lock); + + return IRQ_SET_MASK_OK; +} +#endif + +static void __exception_irq_entry hip04_handle_irq(struct pt_regs *regs) +{ + u32 irqstat, irqnr; + void __iomem *cpu_base = hip04_data.cpu_base; + + do { + irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK); + irqnr = irqstat & GICC_IAR_INT_ID_MASK; + + if (likely(irqnr > 15 && irqnr <= HIP04_MAX_IRQS)) { + irqnr = irq_find_mapping(hip04_data.domain, irqnr); + handle_IRQ(irqnr, regs); + continue; + } + if (irqnr < 16) { + writel_relaxed(irqstat, cpu_base + GIC_CPU_EOI); +#ifdef CONFIG_SMP + handle_IPI(irqnr, regs); +#endif + continue; + } + break; + } while (1); +} + +static struct irq_chip hip04_irq_chip = { + .name = "HIP04 INTC", + .irq_mask = hip04_mask_irq, + .irq_unmask = hip04_unmask_irq, + .irq_eoi = hip04_eoi_irq, + .irq_set_type = hip04_irq_set_type, +#ifdef CONFIG_SMP + .irq_set_affinity = hip04_irq_set_affinity, +#endif +}; + +static u16 hip04_get_cpumask(struct hip04_irq_data *intc) +{ + void __iomem *base = intc->dist_base; + u32 mask, i; + + for (i = mask = 0; i < 32; i += 2) { + mask = readl_relaxed(base + GIC_DIST_TARGET + i * 2); + mask |= mask >> 16; + if (mask) + break; + } + + if (!mask) + pr_crit("GIC CPU mask not found - kernel will fail to boot.\n"); + + return mask; +} + +static void __init hip04_irq_dist_init(struct hip04_irq_data *intc) +{ + unsigned int i; + u32 cpumask; + unsigned int nr_irqs = intc->nr_irqs; + void __iomem *base = intc->dist_base; + + writel_relaxed(0, base + GIC_DIST_CTRL); + + /* + * Set all global interrupts to this CPU only. + */ + cpumask = hip04_get_cpumask(intc); + cpumask |= cpumask << 16; + for (i = 32; i < nr_irqs; i += 2) + writel_relaxed(cpumask, base + GIC_DIST_TARGET + ((i * 2) & ~3)); + + gic_dist_config(base, nr_irqs, NULL); + + writel_relaxed(1, base + GIC_DIST_CTRL); +} + +static void hip04_irq_cpu_init(struct hip04_irq_data *intc) +{ + void __iomem *dist_base = intc->dist_base; + void __iomem *base = intc->cpu_base; + unsigned int cpu_mask, cpu = smp_processor_id(); + int i; + + /* + * Get what the GIC says our CPU mask is. + */ + BUG_ON(cpu >= NR_HIP04_CPU_IF); + cpu_mask = hip04_get_cpumask(intc); + hip04_cpu_map[cpu] = cpu_mask; + + /* + * Clear our mask from the other map entries in case they're + * still undefined. + */ + for (i = 0; i < NR_HIP04_CPU_IF; i++) + if (i != cpu) + hip04_cpu_map[i] &= ~cpu_mask; + + gic_cpu_config(dist_base, NULL); + + writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); + writel_relaxed(1, base + GIC_CPU_CTRL); +} + +#ifdef CONFIG_SMP +static void hip04_raise_softirq(const struct cpumask *mask, unsigned int irq) +{ + int cpu; + unsigned long flags, map = 0; + + raw_spin_lock_irqsave(&irq_controller_lock, flags); + + /* Convert our logical CPU mask into a physical one. */ + for_each_cpu(cpu, mask) + map |= hip04_cpu_map[cpu]; + + /* + * Ensure that stores to Normal memory are visible to the + * other CPUs before they observe us issuing the IPI. + */ + dmb(ishst); + + /* this always happens on GIC0 */ + writel_relaxed(map << 8 | irq, hip04_data.dist_base + GIC_DIST_SOFTINT); + + raw_spin_unlock_irqrestore(&irq_controller_lock, flags); +} +#endif + +static int hip04_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) +{ + if (hw < 32) { + irq_set_percpu_devid(irq); + irq_set_chip_and_handler(irq, &hip04_irq_chip, + handle_percpu_devid_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); + } else { + irq_set_chip_and_handler(irq, &hip04_irq_chip, + handle_fasteoi_irq); + set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); + } + irq_set_chip_data(irq, d->host_data); + return 0; +} + +static int hip04_irq_domain_xlate(struct irq_domain *d, + struct device_node *controller, + const u32 *intspec, unsigned int intsize, + unsigned long *out_hwirq, + unsigned int *out_type) +{ + unsigned long ret = 0; + + if (d->of_node != controller) + return -EINVAL; + if (intsize < 3) + return -EINVAL; + + /* Get the interrupt number and add 16 to skip over SGIs */ + *out_hwirq = intspec[1] + 16; + + /* For SPIs, we need to add 16 more to get the irq ID number */ + if (!intspec[0]) + *out_hwirq += 16; + + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; + + return ret; +} + +#ifdef CONFIG_SMP +static int hip04_irq_secondary_init(struct notifier_block *nfb, + unsigned long action, + void *hcpu) +{ + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) + hip04_irq_cpu_init(&hip04_data); + return NOTIFY_OK; +} + +/* + * Notifier for enabling the INTC CPU interface. Set an arbitrarily high + * priority because the GIC needs to be up before the ARM generic timers. + */ +static struct notifier_block hip04_irq_cpu_notifier = { + .notifier_call = hip04_irq_secondary_init, + .priority = 100, +}; +#endif + +static const struct irq_domain_ops hip04_irq_domain_ops = { + .map = hip04_irq_domain_map, + .xlate = hip04_irq_domain_xlate, +}; + +static int __init +hip04_of_init(struct device_node *node, struct device_node *parent) +{ + irq_hw_number_t hwirq_base = 16; + int nr_irqs, irq_base, i; + + if (WARN_ON(!node)) + return -ENODEV; + + hip04_data.dist_base = of_iomap(node, 0); + WARN(!hip04_data.dist_base, "fail to map hip04 intc dist registers\n"); + + hip04_data.cpu_base = of_iomap(node, 1); + WARN(!hip04_data.cpu_base, "unable to map hip04 intc cpu registers\n"); + + /* + * Initialize the CPU interface map to all CPUs. + * It will be refined as each CPU probes its ID. + */ + for (i = 0; i < NR_HIP04_CPU_IF; i++) + hip04_cpu_map[i] = 0xff; + + /* + * Find out how many interrupts are supported. + * The HIP04 INTC only supports up to 510 interrupt sources. + */ + nr_irqs = readl_relaxed(hip04_data.dist_base + GIC_DIST_CTR) & 0x1f; + nr_irqs = (nr_irqs + 1) * 32; + if (nr_irqs > HIP04_MAX_IRQS) + nr_irqs = HIP04_MAX_IRQS; + hip04_data.nr_irqs = nr_irqs; + + nr_irqs -= hwirq_base; /* calculate # of irqs to allocate */ + + irq_base = irq_alloc_descs(-1, hwirq_base, nr_irqs, numa_node_id()); + if (IS_ERR_VALUE(irq_base)) { + pr_err("failed to allocate IRQ numbers\n"); + return -EINVAL; + } + + hip04_data.domain = irq_domain_add_legacy(node, nr_irqs, irq_base, + hwirq_base, + &hip04_irq_domain_ops, + &hip04_data); + + if (WARN_ON(!hip04_data.domain)) + return -EINVAL; + +#ifdef CONFIG_SMP + set_smp_cross_call(hip04_raise_softirq); + register_cpu_notifier(&hip04_irq_cpu_notifier); +#endif + set_handle_irq(hip04_handle_irq); + + hip04_irq_dist_init(&hip04_data); + hip04_irq_cpu_init(&hip04_data); + + return 0; +} +IRQCHIP_DECLARE(hip04_intc, "hisilicon,hip04-intc", hip04_of_init); -- GitLab From da0c1e65b51a289540159663aa4b90ba2366bc21 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Wed, 20 Aug 2014 13:47:32 +0400 Subject: [PATCH 1005/9167] sched: Add wrapper for checking task_struct::on_rq Implement task_on_rq_queued() and use it everywhere instead of on_rq check. No functional changes. The only exception is we do not use the wrapper in check_for_tasks(), because it requires to export task_on_rq_queued() in global header files. Next patch in series would return it back, so we do not twist it from here to there. Signed-off-by: Kirill Tkhai Cc: Peter Zijlstra Cc: Paul Turner Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Mike Galbraith Cc: Kirill Tkhai Cc: Tim Chen Cc: Nicolas Pitre Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1408528052.23412.87.camel@tkhai Signed-off-by: Ingo Molnar --- kernel/sched/core.c | 82 ++++++++++++++++++++-------------------- kernel/sched/deadline.c | 15 ++++---- kernel/sched/fair.c | 22 +++++------ kernel/sched/rt.c | 16 ++++---- kernel/sched/sched.h | 7 ++++ kernel/sched/stop_task.c | 2 +- 6 files changed, 76 insertions(+), 68 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4f2826f46e95..a02b624fee6c 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -1043,7 +1043,7 @@ void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags) * A queue event has occurred, and we're going to schedule. In * this case, we can save a useless back to back clock update. */ - if (rq->curr->on_rq && test_tsk_need_resched(rq->curr)) + if (task_on_rq_queued(rq->curr) && test_tsk_need_resched(rq->curr)) rq->skip_clock_update = 1; } @@ -1088,7 +1088,7 @@ void set_task_cpu(struct task_struct *p, unsigned int new_cpu) static void __migrate_swap_task(struct task_struct *p, int cpu) { - if (p->on_rq) { + if (task_on_rq_queued(p)) { struct rq *src_rq, *dst_rq; src_rq = task_rq(p); @@ -1214,7 +1214,7 @@ static int migration_cpu_stop(void *data); unsigned long wait_task_inactive(struct task_struct *p, long match_state) { unsigned long flags; - int running, on_rq; + int running, queued; unsigned long ncsw; struct rq *rq; @@ -1252,7 +1252,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) rq = task_rq_lock(p, &flags); trace_sched_wait_task(p); running = task_running(rq, p); - on_rq = p->on_rq; + queued = task_on_rq_queued(p); ncsw = 0; if (!match_state || p->state == match_state) ncsw = p->nvcsw | LONG_MIN; /* sets MSB */ @@ -1284,7 +1284,7 @@ unsigned long wait_task_inactive(struct task_struct *p, long match_state) * running right now), it's preempted, and we should * yield - it could be a while. */ - if (unlikely(on_rq)) { + if (unlikely(queued)) { ktime_t to = ktime_set(0, NSEC_PER_SEC/HZ); set_current_state(TASK_UNINTERRUPTIBLE); @@ -1478,7 +1478,7 @@ ttwu_stat(struct task_struct *p, int cpu, int wake_flags) static void ttwu_activate(struct rq *rq, struct task_struct *p, int en_flags) { activate_task(rq, p, en_flags); - p->on_rq = 1; + p->on_rq = TASK_ON_RQ_QUEUED; /* if a worker is waking up, notify workqueue */ if (p->flags & PF_WQ_WORKER) @@ -1537,7 +1537,7 @@ static int ttwu_remote(struct task_struct *p, int wake_flags) int ret = 0; rq = __task_rq_lock(p); - if (p->on_rq) { + if (task_on_rq_queued(p)) { /* check_preempt_curr() may use rq clock */ update_rq_clock(rq); ttwu_do_wakeup(rq, p, wake_flags); @@ -1678,7 +1678,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) success = 1; /* we're going to change ->state */ cpu = task_cpu(p); - if (p->on_rq && ttwu_remote(p, wake_flags)) + if (task_on_rq_queued(p) && ttwu_remote(p, wake_flags)) goto stat; #ifdef CONFIG_SMP @@ -1742,7 +1742,7 @@ static void try_to_wake_up_local(struct task_struct *p) if (!(p->state & TASK_NORMAL)) goto out; - if (!p->on_rq) + if (!task_on_rq_queued(p)) ttwu_activate(rq, p, ENQUEUE_WAKEUP); ttwu_do_wakeup(rq, p, 0); @@ -2095,7 +2095,7 @@ void wake_up_new_task(struct task_struct *p) init_task_runnable_average(p); rq = __task_rq_lock(p); activate_task(rq, p, 0); - p->on_rq = 1; + p->on_rq = TASK_ON_RQ_QUEUED; trace_sched_wakeup_new(p, true); check_preempt_curr(rq, p, WF_FORK); #ifdef CONFIG_SMP @@ -2444,7 +2444,7 @@ static u64 do_task_delta_exec(struct task_struct *p, struct rq *rq) * project cycles that may never be accounted to this * thread, breaking clock_gettime(). */ - if (task_current(rq, p) && p->on_rq) { + if (task_current(rq, p) && task_on_rq_queued(p)) { update_rq_clock(rq); ns = rq_clock_task(rq) - p->se.exec_start; if ((s64)ns < 0) @@ -2490,7 +2490,7 @@ unsigned long long task_sched_runtime(struct task_struct *p) * If we see ->on_cpu without ->on_rq, the task is leaving, and has * been accounted, so we're correct here as well. */ - if (!p->on_cpu || !p->on_rq) + if (!p->on_cpu || !task_on_rq_queued(p)) return p->se.sum_exec_runtime; #endif @@ -2794,7 +2794,7 @@ static void __sched __schedule(void) switch_count = &prev->nvcsw; } - if (prev->on_rq || rq->skip_clock_update < 0) + if (task_on_rq_queued(prev) || rq->skip_clock_update < 0) update_rq_clock(rq); next = pick_next_task(rq, prev); @@ -2959,7 +2959,7 @@ EXPORT_SYMBOL(default_wake_function); */ void rt_mutex_setprio(struct task_struct *p, int prio) { - int oldprio, on_rq, running, enqueue_flag = 0; + int oldprio, queued, running, enqueue_flag = 0; struct rq *rq; const struct sched_class *prev_class; @@ -2988,9 +2988,9 @@ void rt_mutex_setprio(struct task_struct *p, int prio) trace_sched_pi_setprio(p, prio); oldprio = p->prio; prev_class = p->sched_class; - on_rq = p->on_rq; + queued = task_on_rq_queued(p); running = task_current(rq, p); - if (on_rq) + if (queued) dequeue_task(rq, p, 0); if (running) p->sched_class->put_prev_task(rq, p); @@ -3030,7 +3030,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) if (running) p->sched_class->set_curr_task(rq); - if (on_rq) + if (queued) enqueue_task(rq, p, enqueue_flag); check_class_changed(rq, p, prev_class, oldprio); @@ -3041,7 +3041,7 @@ void rt_mutex_setprio(struct task_struct *p, int prio) void set_user_nice(struct task_struct *p, long nice) { - int old_prio, delta, on_rq; + int old_prio, delta, queued; unsigned long flags; struct rq *rq; @@ -3062,8 +3062,8 @@ void set_user_nice(struct task_struct *p, long nice) p->static_prio = NICE_TO_PRIO(nice); goto out_unlock; } - on_rq = p->on_rq; - if (on_rq) + queued = task_on_rq_queued(p); + if (queued) dequeue_task(rq, p, 0); p->static_prio = NICE_TO_PRIO(nice); @@ -3072,7 +3072,7 @@ void set_user_nice(struct task_struct *p, long nice) p->prio = effective_prio(p); delta = p->prio - old_prio; - if (on_rq) { + if (queued) { enqueue_task(rq, p, 0); /* * If the task increased its priority or is running and @@ -3344,7 +3344,7 @@ static int __sched_setscheduler(struct task_struct *p, { int newprio = dl_policy(attr->sched_policy) ? MAX_DL_PRIO - 1 : MAX_RT_PRIO - 1 - attr->sched_priority; - int retval, oldprio, oldpolicy = -1, on_rq, running; + int retval, oldprio, oldpolicy = -1, queued, running; int policy = attr->sched_policy; unsigned long flags; const struct sched_class *prev_class; @@ -3541,9 +3541,9 @@ static int __sched_setscheduler(struct task_struct *p, return 0; } - on_rq = p->on_rq; + queued = task_on_rq_queued(p); running = task_current(rq, p); - if (on_rq) + if (queued) dequeue_task(rq, p, 0); if (running) p->sched_class->put_prev_task(rq, p); @@ -3553,7 +3553,7 @@ static int __sched_setscheduler(struct task_struct *p, if (running) p->sched_class->set_curr_task(rq); - if (on_rq) { + if (queued) { /* * We enqueue to tail when the priority of a task is * increased (user space view). @@ -4568,7 +4568,7 @@ void init_idle(struct task_struct *idle, int cpu) rcu_read_unlock(); rq->curr = rq->idle = idle; - idle->on_rq = 1; + idle->on_rq = TASK_ON_RQ_QUEUED; #if defined(CONFIG_SMP) idle->on_cpu = 1; #endif @@ -4645,7 +4645,7 @@ int set_cpus_allowed_ptr(struct task_struct *p, const struct cpumask *new_mask) goto out; dest_cpu = cpumask_any_and(cpu_active_mask, new_mask); - if (p->on_rq) { + if (task_on_rq_queued(p)) { struct migration_arg arg = { p, dest_cpu }; /* Need help from migration thread: drop lock and wait. */ task_rq_unlock(rq, p, &flags); @@ -4695,7 +4695,7 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) * If we're not on a rq, the next wake-up will ensure we're * placed properly. */ - if (p->on_rq) { + if (task_on_rq_queued(p)) { dequeue_task(rq_src, p, 0); set_task_cpu(p, dest_cpu); enqueue_task(rq_dest, p, 0); @@ -4736,13 +4736,13 @@ void sched_setnuma(struct task_struct *p, int nid) { struct rq *rq; unsigned long flags; - bool on_rq, running; + bool queued, running; rq = task_rq_lock(p, &flags); - on_rq = p->on_rq; + queued = task_on_rq_queued(p); running = task_current(rq, p); - if (on_rq) + if (queued) dequeue_task(rq, p, 0); if (running) p->sched_class->put_prev_task(rq, p); @@ -4751,7 +4751,7 @@ void sched_setnuma(struct task_struct *p, int nid) if (running) p->sched_class->set_curr_task(rq); - if (on_rq) + if (queued) enqueue_task(rq, p, 0); task_rq_unlock(rq, p, &flags); } @@ -7116,13 +7116,13 @@ static void normalize_task(struct rq *rq, struct task_struct *p) .sched_policy = SCHED_NORMAL, }; int old_prio = p->prio; - int on_rq; + int queued; - on_rq = p->on_rq; - if (on_rq) + queued = task_on_rq_queued(p); + if (queued) dequeue_task(rq, p, 0); __setscheduler(rq, p, &attr); - if (on_rq) { + if (queued) { enqueue_task(rq, p, 0); resched_curr(rq); } @@ -7309,16 +7309,16 @@ void sched_offline_group(struct task_group *tg) void sched_move_task(struct task_struct *tsk) { struct task_group *tg; - int on_rq, running; + int queued, running; unsigned long flags; struct rq *rq; rq = task_rq_lock(tsk, &flags); running = task_current(rq, tsk); - on_rq = tsk->on_rq; + queued = task_on_rq_queued(tsk); - if (on_rq) + if (queued) dequeue_task(rq, tsk, 0); if (unlikely(running)) tsk->sched_class->put_prev_task(rq, tsk); @@ -7331,14 +7331,14 @@ void sched_move_task(struct task_struct *tsk) #ifdef CONFIG_FAIR_GROUP_SCHED if (tsk->sched_class->task_move_group) - tsk->sched_class->task_move_group(tsk, on_rq); + tsk->sched_class->task_move_group(tsk, queued); else #endif set_task_rq(tsk, task_cpu(tsk)); if (unlikely(running)) tsk->sched_class->set_curr_task(rq); - if (on_rq) + if (queued) enqueue_task(rq, tsk, 0); task_rq_unlock(rq, tsk, &flags); diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 255ce138b652..d21a8e0259d2 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c @@ -530,7 +530,7 @@ static enum hrtimer_restart dl_task_timer(struct hrtimer *timer) update_rq_clock(rq); dl_se->dl_throttled = 0; dl_se->dl_yielded = 0; - if (p->on_rq) { + if (task_on_rq_queued(p)) { enqueue_task_dl(rq, p, ENQUEUE_REPLENISH); if (task_has_dl_policy(rq->curr)) check_preempt_curr_dl(rq, p, 0); @@ -1030,7 +1030,7 @@ struct task_struct *pick_next_task_dl(struct rq *rq, struct task_struct *prev) * means a stop task can slip in, in which case we need to * re-start task selection. */ - if (rq->stop && rq->stop->on_rq) + if (rq->stop && task_on_rq_queued(rq->stop)) return RETRY_TASK; } @@ -1257,7 +1257,8 @@ static struct rq *find_lock_later_rq(struct task_struct *task, struct rq *rq) if (unlikely(task_rq(task) != rq || !cpumask_test_cpu(later_rq->cpu, &task->cpus_allowed) || - task_running(rq, task) || !task->on_rq)) { + task_running(rq, task) || + !task_on_rq_queued(task))) { double_unlock_balance(rq, later_rq); later_rq = NULL; break; @@ -1296,7 +1297,7 @@ static struct task_struct *pick_next_pushable_dl_task(struct rq *rq) BUG_ON(task_current(rq, p)); BUG_ON(p->nr_cpus_allowed <= 1); - BUG_ON(!p->on_rq); + BUG_ON(!task_on_rq_queued(p)); BUG_ON(!dl_task(p)); return p; @@ -1443,7 +1444,7 @@ static int pull_dl_task(struct rq *this_rq) dl_time_before(p->dl.deadline, this_rq->dl.earliest_dl.curr))) { WARN_ON(p == src_rq->curr); - WARN_ON(!p->on_rq); + WARN_ON(!task_on_rq_queued(p)); /* * Then we pull iff p has actually an earlier @@ -1596,7 +1597,7 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p) if (unlikely(p->dl.dl_throttled)) return; - if (p->on_rq && rq->curr != p) { + if (task_on_rq_queued(p) && rq->curr != p) { #ifdef CONFIG_SMP if (rq->dl.overloaded && push_dl_task(rq) && rq != task_rq(p)) /* Only reschedule if pushing failed */ @@ -1614,7 +1615,7 @@ static void switched_to_dl(struct rq *rq, struct task_struct *p) static void prio_changed_dl(struct rq *rq, struct task_struct *p, int oldprio) { - if (p->on_rq || rq->curr == p) { + if (task_on_rq_queued(p) || rq->curr == p) { #ifdef CONFIG_SMP /* * This might be too much, but unfortunately diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index bc37bb97159f..9e6ca0d88f51 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7494,7 +7494,7 @@ static void task_fork_fair(struct task_struct *p) static void prio_changed_fair(struct rq *rq, struct task_struct *p, int oldprio) { - if (!p->on_rq) + if (!task_on_rq_queued(p)) return; /* @@ -7519,11 +7519,11 @@ static void switched_from_fair(struct rq *rq, struct task_struct *p) * switched back to the fair class the enqueue_entity(.flags=0) will * do the right thing. * - * If it's on_rq, then the dequeue_entity(.flags=0) will already - * have normalized the vruntime, if it's !on_rq, then only when + * If it's queued, then the dequeue_entity(.flags=0) will already + * have normalized the vruntime, if it's !queued, then only when * the task is sleeping will it still have non-normalized vruntime. */ - if (!p->on_rq && p->state != TASK_RUNNING) { + if (!task_on_rq_queued(p) && p->state != TASK_RUNNING) { /* * Fix up our vruntime so that the current sleep doesn't * cause 'unlimited' sleep bonus. @@ -7558,7 +7558,7 @@ static void switched_to_fair(struct rq *rq, struct task_struct *p) */ se->depth = se->parent ? se->parent->depth + 1 : 0; #endif - if (!p->on_rq) + if (!task_on_rq_queued(p)) return; /* @@ -7604,7 +7604,7 @@ void init_cfs_rq(struct cfs_rq *cfs_rq) } #ifdef CONFIG_FAIR_GROUP_SCHED -static void task_move_group_fair(struct task_struct *p, int on_rq) +static void task_move_group_fair(struct task_struct *p, int queued) { struct sched_entity *se = &p->se; struct cfs_rq *cfs_rq; @@ -7623,7 +7623,7 @@ static void task_move_group_fair(struct task_struct *p, int on_rq) * fair sleeper stuff for the first placement, but who cares. */ /* - * When !on_rq, vruntime of the task has usually NOT been normalized. + * When !queued, vruntime of the task has usually NOT been normalized. * But there are some cases where it has already been normalized: * * - Moving a forked child which is waiting for being woken up by @@ -7634,14 +7634,14 @@ static void task_move_group_fair(struct task_struct *p, int on_rq) * To prevent boost or penalty in the new cfs_rq caused by delta * min_vruntime between the two cfs_rqs, we skip vruntime adjustment. */ - if (!on_rq && (!se->sum_exec_runtime || p->state == TASK_WAKING)) - on_rq = 1; + if (!queued && (!se->sum_exec_runtime || p->state == TASK_WAKING)) + queued = 1; - if (!on_rq) + if (!queued) se->vruntime -= cfs_rq_of(se)->min_vruntime; set_task_rq(p, task_cpu(p)); se->depth = se->parent ? se->parent->depth + 1 : 0; - if (!on_rq) { + if (!queued) { cfs_rq = cfs_rq_of(se); se->vruntime += cfs_rq->min_vruntime; #ifdef CONFIG_SMP diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 5f6edca4fafd..4feac8fcb47f 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -1448,7 +1448,7 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev) * means a dl or stop task can slip in, in which case we need * to re-start task selection. */ - if (unlikely((rq->stop && rq->stop->on_rq) || + if (unlikely((rq->stop && task_on_rq_queued(rq->stop)) || rq->dl.dl_nr_running)) return RETRY_TASK; } @@ -1624,7 +1624,7 @@ static struct rq *find_lock_lowest_rq(struct task_struct *task, struct rq *rq) !cpumask_test_cpu(lowest_rq->cpu, tsk_cpus_allowed(task)) || task_running(rq, task) || - !task->on_rq)) { + !task_on_rq_queued(task))) { double_unlock_balance(rq, lowest_rq); lowest_rq = NULL; @@ -1658,7 +1658,7 @@ static struct task_struct *pick_next_pushable_task(struct rq *rq) BUG_ON(task_current(rq, p)); BUG_ON(p->nr_cpus_allowed <= 1); - BUG_ON(!p->on_rq); + BUG_ON(!task_on_rq_queued(p)); BUG_ON(!rt_task(p)); return p; @@ -1809,7 +1809,7 @@ static int pull_rt_task(struct rq *this_rq) */ if (p && (p->prio < this_rq->rt.highest_prio.curr)) { WARN_ON(p == src_rq->curr); - WARN_ON(!p->on_rq); + WARN_ON(!task_on_rq_queued(p)); /* * There's a chance that p is higher in priority @@ -1870,7 +1870,7 @@ static void set_cpus_allowed_rt(struct task_struct *p, BUG_ON(!rt_task(p)); - if (!p->on_rq) + if (!task_on_rq_queued(p)) return; weight = cpumask_weight(new_mask); @@ -1936,7 +1936,7 @@ static void switched_from_rt(struct rq *rq, struct task_struct *p) * we may need to handle the pulling of RT tasks * now. */ - if (!p->on_rq || rq->rt.rt_nr_running) + if (!task_on_rq_queued(p) || rq->rt.rt_nr_running) return; if (pull_rt_task(rq)) @@ -1970,7 +1970,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p) * If that current running task is also an RT task * then see if we can move to another run queue. */ - if (p->on_rq && rq->curr != p) { + if (task_on_rq_queued(p) && rq->curr != p) { #ifdef CONFIG_SMP if (p->nr_cpus_allowed > 1 && rq->rt.overloaded && /* Don't resched if we changed runqueues */ @@ -1989,7 +1989,7 @@ static void switched_to_rt(struct rq *rq, struct task_struct *p) static void prio_changed_rt(struct rq *rq, struct task_struct *p, int oldprio) { - if (!p->on_rq) + if (!task_on_rq_queued(p)) return; if (rq->curr == p) { diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 4c2b87fd5f52..26566d0c67ac 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -15,6 +15,9 @@ struct rq; +/* task_struct::on_rq states: */ +#define TASK_ON_RQ_QUEUED 1 + extern __read_mostly int scheduler_running; extern unsigned long calc_load_update; @@ -942,6 +945,10 @@ static inline int task_running(struct rq *rq, struct task_struct *p) #endif } +static inline int task_on_rq_queued(struct task_struct *p) +{ + return p->on_rq == TASK_ON_RQ_QUEUED; +} #ifndef prepare_arch_switch # define prepare_arch_switch(next) do { } while (0) diff --git a/kernel/sched/stop_task.c b/kernel/sched/stop_task.c index bfe0edadbfbb..67426e529f59 100644 --- a/kernel/sched/stop_task.c +++ b/kernel/sched/stop_task.c @@ -28,7 +28,7 @@ pick_next_task_stop(struct rq *rq, struct task_struct *prev) { struct task_struct *stop = rq->stop; - if (!stop || !stop->on_rq) + if (!stop || !task_on_rq_queued(stop)) return NULL; put_prev_task(rq, prev); -- GitLab From cca26e8009d1939a6a5bf0200d276fa26f03e536 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Wed, 20 Aug 2014 13:47:42 +0400 Subject: [PATCH 1006/9167] sched: Teach scheduler to understand TASK_ON_RQ_MIGRATING state This is a new p->on_rq state which will be used to indicate that a task is in a process of migrating between two RQs. It allows to get rid of double_rq_lock(), which we used to use to change a rq of a queued task before. Let's consider an example. To move a task between src_rq and dst_rq we will do the following: raw_spin_lock(&src_rq->lock); /* p is a task which is queued on src_rq */ p = ...; dequeue_task(src_rq, p, 0); p->on_rq = TASK_ON_RQ_MIGRATING; set_task_cpu(p, dst_cpu); raw_spin_unlock(&src_rq->lock); /* * Both RQs are unlocked here. * Task p is dequeued from src_rq * but its on_rq value is not zero. */ raw_spin_lock(&dst_rq->lock); p->on_rq = TASK_ON_RQ_QUEUED; enqueue_task(dst_rq, p, 0); raw_spin_unlock(&dst_rq->lock); While p->on_rq is TASK_ON_RQ_MIGRATING, task is considered as "migrating", and other parallel scheduler actions with it are not available to parallel callers. The parallel caller is spining till migration is completed. The unavailable actions are changing of cpu affinity, changing of priority etc, in other words all the functionality which used to require task_rq(p)->lock before (and related to the task). To implement TASK_ON_RQ_MIGRATING support we primarily are using the following fact. Most of scheduler users (from which we are protecting a migrating task) use task_rq_lock() and __task_rq_lock() to get the lock of task_rq(p). These primitives know that task's cpu may change, and they are spining while the lock of the right RQ is not held. We add one more condition into them, so they will be also spinning until the migration is finished. Signed-off-by: Kirill Tkhai Cc: Peter Zijlstra Cc: Paul Turner Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Mike Galbraith Cc: Kirill Tkhai Cc: Tim Chen Cc: Nicolas Pitre Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1408528062.23412.88.camel@tkhai Signed-off-by: Ingo Molnar --- kernel/sched/core.c | 12 +++++++++--- kernel/sched/sched.h | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index a02b624fee6c..71b836034912 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -333,9 +333,12 @@ static inline struct rq *__task_rq_lock(struct task_struct *p) for (;;) { rq = task_rq(p); raw_spin_lock(&rq->lock); - if (likely(rq == task_rq(p))) + if (likely(rq == task_rq(p) && !task_on_rq_migrating(p))) return rq; raw_spin_unlock(&rq->lock); + + while (unlikely(task_on_rq_migrating(p))) + cpu_relax(); } } @@ -352,10 +355,13 @@ static struct rq *task_rq_lock(struct task_struct *p, unsigned long *flags) raw_spin_lock_irqsave(&p->pi_lock, *flags); rq = task_rq(p); raw_spin_lock(&rq->lock); - if (likely(rq == task_rq(p))) + if (likely(rq == task_rq(p) && !task_on_rq_migrating(p))) return rq; raw_spin_unlock(&rq->lock); raw_spin_unlock_irqrestore(&p->pi_lock, *flags); + + while (unlikely(task_on_rq_migrating(p))) + cpu_relax(); } } @@ -1678,7 +1684,7 @@ try_to_wake_up(struct task_struct *p, unsigned int state, int wake_flags) success = 1; /* we're going to change ->state */ cpu = task_cpu(p); - if (task_on_rq_queued(p) && ttwu_remote(p, wake_flags)) + if (p->on_rq && ttwu_remote(p, wake_flags)) goto stat; #ifdef CONFIG_SMP diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 26566d0c67ac..aa0f73ba3777 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -17,6 +17,7 @@ struct rq; /* task_struct::on_rq states: */ #define TASK_ON_RQ_QUEUED 1 +#define TASK_ON_RQ_MIGRATING 2 extern __read_mostly int scheduler_running; @@ -950,6 +951,11 @@ static inline int task_on_rq_queued(struct task_struct *p) return p->on_rq == TASK_ON_RQ_QUEUED; } +static inline int task_on_rq_migrating(struct task_struct *p) +{ + return p->on_rq == TASK_ON_RQ_MIGRATING; +} + #ifndef prepare_arch_switch # define prepare_arch_switch(next) do { } while (0) #endif -- GitLab From a1e01829796aa7a993e28ffd7fee5c8d525be175 Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Wed, 20 Aug 2014 13:47:50 +0400 Subject: [PATCH 1007/9167] sched: Remove double_rq_lock() from __migrate_task() Avoid double_rq_lock() and use TASK_ON_RQ_MIGRATING for __migrate_task(). The advantage is (obviously) not holding two rq->lock's at the same time and thereby increasing parallelism. The important point to note is that because we acquire dst->lock immediately after releasing src->lock the potential wait time of task_rq_lock() callers on TASK_ON_RQ_MIGRATING is not longer than it would have been in the double rq lock scenario. Signed-off-by: Kirill Tkhai Cc: Peter Zijlstra Cc: Paul Turner Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Mike Galbraith Cc: Kirill Tkhai Cc: Tim Chen Cc: Nicolas Pitre Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1408528070.23412.89.camel@tkhai Signed-off-by: Ingo Molnar --- kernel/sched/core.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 71b836034912..a773c919d88d 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4679,20 +4679,20 @@ EXPORT_SYMBOL_GPL(set_cpus_allowed_ptr); */ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) { - struct rq *rq_dest, *rq_src; + struct rq *rq; int ret = 0; if (unlikely(!cpu_active(dest_cpu))) return ret; - rq_src = cpu_rq(src_cpu); - rq_dest = cpu_rq(dest_cpu); + rq = cpu_rq(src_cpu); raw_spin_lock(&p->pi_lock); - double_rq_lock(rq_src, rq_dest); + raw_spin_lock(&rq->lock); /* Already moved. */ if (task_cpu(p) != src_cpu) goto done; + /* Affinity changed (again). */ if (!cpumask_test_cpu(dest_cpu, tsk_cpus_allowed(p))) goto fail; @@ -4702,15 +4702,22 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) * placed properly. */ if (task_on_rq_queued(p)) { - dequeue_task(rq_src, p, 0); + dequeue_task(rq, p, 0); + p->on_rq = TASK_ON_RQ_MIGRATING; set_task_cpu(p, dest_cpu); - enqueue_task(rq_dest, p, 0); - check_preempt_curr(rq_dest, p, 0); + raw_spin_unlock(&rq->lock); + + rq = cpu_rq(dest_cpu); + raw_spin_lock(&rq->lock); + BUG_ON(task_rq(p) != rq); + p->on_rq = TASK_ON_RQ_QUEUED; + enqueue_task(rq, p, 0); + check_preempt_curr(rq, p, 0); } done: ret = 1; fail: - double_rq_unlock(rq_src, rq_dest); + raw_spin_unlock(&rq->lock); raw_spin_unlock(&p->pi_lock); return ret; } -- GitLab From e5673f280501298dbb56efa46e333cf64ee5080a Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Wed, 20 Aug 2014 13:48:01 +0400 Subject: [PATCH 1008/9167] sched/fair: Remove double_lock_balance() from active_load_balance_cpu_stop() Avoid double_rq_lock() and use the TASK_ON_RQ_MIGRATING state for active_load_balance_cpu_stop(). The advantage is (obviously) not holding two 'rq->lock's at the same time and thereby increasing parallelism. Further note that if there was no task to migrate we will not have acquired the second rq->lock at all. The important point to note is that because we acquire dst->lock immediately after releasing src->lock the potential wait time of task_rq_lock() callers on TASK_ON_RQ_MIGRATING is not longer than it would have been in the double rq lock scenario. Signed-off-by: Kirill Tkhai Cc: Peter Zijlstra Cc: Paul Turner Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Mike Galbraith Cc: Kirill Tkhai Cc: Tim Chen Cc: Nicolas Pitre Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1408528081.23412.92.camel@tkhai Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 60 +++++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 9e6ca0d88f51..7e5cf051c144 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -5138,6 +5138,8 @@ static int task_hot(struct task_struct *p, struct lb_env *env) { s64 delta; + lockdep_assert_held(&env->src_rq->lock); + if (p->sched_class != &fair_sched_class) return 0; @@ -5257,6 +5259,9 @@ static int can_migrate_task(struct task_struct *p, struct lb_env *env) { int tsk_cache_hot = 0; + + lockdep_assert_held(&env->src_rq->lock); + /* * We do not migrate tasks that are: * 1) throttled_lb_pair, or @@ -5341,30 +5346,49 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) } /* - * move_one_task tries to move exactly one task from busiest to this_rq, as + * detach_one_task() -- tries to dequeue exactly one task from env->src_rq, as * part of active balancing operations within "domain". - * Returns 1 if successful and 0 otherwise. * - * Called with both runqueues locked. + * Returns a task if successful and NULL otherwise. */ -static int move_one_task(struct lb_env *env) +static struct task_struct *detach_one_task(struct lb_env *env) { struct task_struct *p, *n; + lockdep_assert_held(&env->src_rq->lock); + list_for_each_entry_safe(p, n, &env->src_rq->cfs_tasks, se.group_node) { if (!can_migrate_task(p, env)) continue; - move_task(p, env); + deactivate_task(env->src_rq, p, 0); + p->on_rq = TASK_ON_RQ_MIGRATING; + set_task_cpu(p, env->dst_cpu); + /* - * Right now, this is only the second place move_task() - * is called, so we can safely collect move_task() - * stats here rather than inside move_task(). + * Right now, this is only the second place where + * lb_gained[env->idle] is updated (other is move_tasks) + * so we can safely collect stats here rather than + * inside move_tasks(). */ schedstat_inc(env->sd, lb_gained[env->idle]); - return 1; + return p; } - return 0; + return NULL; +} + +/* + * attach_one_task() -- attaches the task returned from detach_one_task() to + * its new rq. + */ +static void attach_one_task(struct rq *rq, struct task_struct *p) +{ + raw_spin_lock(&rq->lock); + BUG_ON(task_rq(p) != rq); + p->on_rq = TASK_ON_RQ_QUEUED; + activate_task(rq, p, 0); + check_preempt_curr(rq, p, 0); + raw_spin_unlock(&rq->lock); } static const unsigned int sched_nr_migrate_break = 32; @@ -6943,6 +6967,7 @@ static int active_load_balance_cpu_stop(void *data) int target_cpu = busiest_rq->push_cpu; struct rq *target_rq = cpu_rq(target_cpu); struct sched_domain *sd; + struct task_struct *p = NULL; raw_spin_lock_irq(&busiest_rq->lock); @@ -6962,9 +6987,6 @@ static int active_load_balance_cpu_stop(void *data) */ BUG_ON(busiest_rq == target_rq); - /* move a task from busiest_rq to target_rq */ - double_lock_balance(busiest_rq, target_rq); - /* Search for an sd spanning us and the target CPU. */ rcu_read_lock(); for_each_domain(target_cpu, sd) { @@ -6985,16 +7007,22 @@ static int active_load_balance_cpu_stop(void *data) schedstat_inc(sd, alb_count); - if (move_one_task(&env)) + p = detach_one_task(&env); + if (p) schedstat_inc(sd, alb_pushed); else schedstat_inc(sd, alb_failed); } rcu_read_unlock(); - double_unlock_balance(busiest_rq, target_rq); out_unlock: busiest_rq->active_balance = 0; - raw_spin_unlock_irq(&busiest_rq->lock); + raw_spin_unlock(&busiest_rq->lock); + + if (p) + attach_one_task(target_rq, p); + + local_irq_enable(); + return 0; } -- GitLab From 163122b7fcfa28c0e4a838fcc8043c616746802e Mon Sep 17 00:00:00 2001 From: Kirill Tkhai Date: Wed, 20 Aug 2014 13:48:29 +0400 Subject: [PATCH 1009/9167] sched/fair: Remove double_lock_balance() from load_balance() Avoid double_rq_lock() and use TASK_ON_RQ_MIGRATING for load_balance(). The advantage is (obviously) not holding two rq->lock's at the same time and thereby increasing parallelism. Further note that if there was no task to migrate we will not have acquired the second rq->lock at all. The important point to note is that because we acquire dst->lock immediately after releasing src->lock the potential wait time of task_rq_lock() callers on TASK_ON_RQ_MIGRATING is not longer than it would have been in the double rq lock scenario. Signed-off-by: Kirill Tkhai Cc: Peter Zijlstra Cc: Paul Turner Cc: Oleg Nesterov Cc: Steven Rostedt Cc: Mike Galbraith Cc: Kirill Tkhai Cc: Tim Chen Cc: Nicolas Pitre Cc: Linus Torvalds Link: http://lkml.kernel.org/r/1408528109.23412.94.camel@tkhai Signed-off-by: Ingo Molnar --- kernel/sched/fair.c | 151 +++++++++++++++++++++++++++++--------------- 1 file changed, 99 insertions(+), 52 deletions(-) diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 7e5cf051c144..d3427a8f254b 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4709,7 +4709,7 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ return; /* - * This is possible from callers such as move_task(), in which we + * This is possible from callers such as attach_tasks(), in which we * unconditionally check_prempt_curr() after an enqueue (which may have * lead to a throttle). This both saves work and prevents false * next-buddy nomination below. @@ -5117,20 +5117,9 @@ struct lb_env { unsigned int loop_max; enum fbq_type fbq_type; + struct list_head tasks; }; -/* - * move_task - move a task from one runqueue to another runqueue. - * Both runqueues must be locked. - */ -static void move_task(struct task_struct *p, struct lb_env *env) -{ - deactivate_task(env->src_rq, p, 0); - set_task_cpu(p, env->dst_cpu); - activate_task(env->dst_rq, p, 0); - check_preempt_curr(env->dst_rq, p, 0); -} - /* * Is this task likely cache-hot: */ @@ -5345,6 +5334,18 @@ int can_migrate_task(struct task_struct *p, struct lb_env *env) return 0; } +/* + * detach_task() -- detach the task for the migration specified in env + */ +static void detach_task(struct task_struct *p, struct lb_env *env) +{ + lockdep_assert_held(&env->src_rq->lock); + + deactivate_task(env->src_rq, p, 0); + p->on_rq = TASK_ON_RQ_MIGRATING; + set_task_cpu(p, env->dst_cpu); +} + /* * detach_one_task() -- tries to dequeue exactly one task from env->src_rq, as * part of active balancing operations within "domain". @@ -5361,15 +5362,13 @@ static struct task_struct *detach_one_task(struct lb_env *env) if (!can_migrate_task(p, env)) continue; - deactivate_task(env->src_rq, p, 0); - p->on_rq = TASK_ON_RQ_MIGRATING; - set_task_cpu(p, env->dst_cpu); + detach_task(p, env); /* * Right now, this is only the second place where - * lb_gained[env->idle] is updated (other is move_tasks) + * lb_gained[env->idle] is updated (other is detach_tasks) * so we can safely collect stats here rather than - * inside move_tasks(). + * inside detach_tasks(). */ schedstat_inc(env->sd, lb_gained[env->idle]); return p; @@ -5377,35 +5376,22 @@ static struct task_struct *detach_one_task(struct lb_env *env) return NULL; } -/* - * attach_one_task() -- attaches the task returned from detach_one_task() to - * its new rq. - */ -static void attach_one_task(struct rq *rq, struct task_struct *p) -{ - raw_spin_lock(&rq->lock); - BUG_ON(task_rq(p) != rq); - p->on_rq = TASK_ON_RQ_QUEUED; - activate_task(rq, p, 0); - check_preempt_curr(rq, p, 0); - raw_spin_unlock(&rq->lock); -} - static const unsigned int sched_nr_migrate_break = 32; /* - * move_tasks tries to move up to imbalance weighted load from busiest to - * this_rq, as part of a balancing operation within domain "sd". - * Returns 1 if successful and 0 otherwise. + * detach_tasks() -- tries to detach up to imbalance weighted load from + * busiest_rq, as part of a balancing operation within domain "sd". * - * Called with both runqueues locked. + * Returns number of detached tasks if successful and 0 otherwise. */ -static int move_tasks(struct lb_env *env) +static int detach_tasks(struct lb_env *env) { struct list_head *tasks = &env->src_rq->cfs_tasks; struct task_struct *p; unsigned long load; - int pulled = 0; + int detached = 0; + + lockdep_assert_held(&env->src_rq->lock); if (env->imbalance <= 0) return 0; @@ -5436,14 +5422,16 @@ static int move_tasks(struct lb_env *env) if ((load / 2) > env->imbalance) goto next; - move_task(p, env); - pulled++; + detach_task(p, env); + list_add(&p->se.group_node, &env->tasks); + + detached++; env->imbalance -= load; #ifdef CONFIG_PREEMPT /* * NEWIDLE balancing is a source of latency, so preemptible - * kernels will stop after the first task is pulled to minimize + * kernels will stop after the first task is detached to minimize * the critical section. */ if (env->idle == CPU_NEWLY_IDLE) @@ -5463,13 +5451,58 @@ static int move_tasks(struct lb_env *env) } /* - * Right now, this is one of only two places move_task() is called, - * so we can safely collect move_task() stats here rather than - * inside move_task(). + * Right now, this is one of only two places we collect this stat + * so we can safely collect detach_one_task() stats here rather + * than inside detach_one_task(). */ - schedstat_add(env->sd, lb_gained[env->idle], pulled); + schedstat_add(env->sd, lb_gained[env->idle], detached); - return pulled; + return detached; +} + +/* + * attach_task() -- attach the task detached by detach_task() to its new rq. + */ +static void attach_task(struct rq *rq, struct task_struct *p) +{ + lockdep_assert_held(&rq->lock); + + BUG_ON(task_rq(p) != rq); + p->on_rq = TASK_ON_RQ_QUEUED; + activate_task(rq, p, 0); + check_preempt_curr(rq, p, 0); +} + +/* + * attach_one_task() -- attaches the task returned from detach_one_task() to + * its new rq. + */ +static void attach_one_task(struct rq *rq, struct task_struct *p) +{ + raw_spin_lock(&rq->lock); + attach_task(rq, p); + raw_spin_unlock(&rq->lock); +} + +/* + * attach_tasks() -- attaches all tasks detached by detach_tasks() to their + * new rq. + */ +static void attach_tasks(struct lb_env *env) +{ + struct list_head *tasks = &env->tasks; + struct task_struct *p; + + raw_spin_lock(&env->dst_rq->lock); + + while (!list_empty(tasks)) { + p = list_first_entry(tasks, struct task_struct, se.group_node); + list_del_init(&p->se.group_node); + + attach_task(env->dst_rq, p); + } + + raw_spin_unlock(&env->dst_rq->lock); } #ifdef CONFIG_FAIR_GROUP_SCHED @@ -6603,6 +6636,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, .loop_break = sched_nr_migrate_break, .cpus = cpus, .fbq_type = all, + .tasks = LIST_HEAD_INIT(env.tasks), }; /* @@ -6652,16 +6686,29 @@ static int load_balance(int this_cpu, struct rq *this_rq, env.loop_max = min(sysctl_sched_nr_migrate, busiest->nr_running); more_balance: - local_irq_save(flags); - double_rq_lock(env.dst_rq, busiest); + raw_spin_lock_irqsave(&busiest->lock, flags); /* * cur_ld_moved - load moved in current iteration * ld_moved - cumulative load moved across iterations */ - cur_ld_moved = move_tasks(&env); - ld_moved += cur_ld_moved; - double_rq_unlock(env.dst_rq, busiest); + cur_ld_moved = detach_tasks(&env); + + /* + * We've detached some tasks from busiest_rq. Every + * task is masked "TASK_ON_RQ_MIGRATING", so we can safely + * unlock busiest->lock, and we are able to be sure + * that nobody can manipulate the tasks in parallel. + * See task_rq_lock() family for the details. + */ + + raw_spin_unlock(&busiest->lock); + + if (cur_ld_moved) { + attach_tasks(&env); + ld_moved += cur_ld_moved; + } + local_irq_restore(flags); /* @@ -6797,7 +6844,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, * If we've begun active balancing, start to back off. This * case may not be covered by the all_pinned logic if there * is only 1 task on the busy runqueue (because we don't call - * move_tasks). + * detach_tasks). */ if (sd->balance_interval < sd->max_interval) sd->balance_interval *= 2; -- GitLab From 8091c1f8ea2374695c105591179b1269fb5f2fbb Mon Sep 17 00:00:00 2001 From: Andreas Ruprecht Date: Wed, 20 Aug 2014 10:16:01 +0200 Subject: [PATCH 1010/9167] x86/apic/uv: Remove unnecessary #ifdef In the file x2apic_uv_x.c, some code is compiled conditionally depending on CONFIG_SMP. However, the file is only built, if CONFIG_X86_UV is enabled. CONFIG_X86_UV depends on CONFIG_NUMA, which itself depends on CONFIG_SMP, so the #ifdef will always evaluate to true, if the file is compiled. Thus, it is unnecessary and can be removed. Signed-off-by: Andreas Ruprecht Cc: David Rientjes Cc: Dimitri Sivanich Cc: Hedi Berriche Cc: Linus Torvalds Cc: Mike Travis Cc: Russ Anderson Link: http://lkml.kernel.org/r/1408522561-23389-1-git-send-email-rupran@einserver.de Signed-off-by: Ingo Molnar --- arch/x86/kernel/apic/x2apic_uv_x.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 293b41df54ef..2f1b5e0df660 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -204,7 +204,6 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second); static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) { -#ifdef CONFIG_SMP unsigned long val; int pnode; @@ -223,7 +222,6 @@ static int uv_wakeup_secondary(int phys_apicid, unsigned long start_rip) uv_write_global_mmr64(pnode, UVH_IPI_INT, val); atomic_set(&init_deasserted, 1); -#endif return 0; } -- GitLab From e91ded8db57472c20b59b2242b100764cc152a10 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 4 Aug 2014 04:50:41 -0400 Subject: [PATCH 1011/9167] uapi: netfilter_arp: use __u8 instead of u_int8_t Similarly, the u_int8_t type is non-standard and not defined. Change it to use __u8 like the rest of the netfilter headers. Signed-off-by: Mike Frysinger Signed-off-by: Pablo Neira Ayuso --- include/uapi/linux/netfilter_arp/arpt_mangle.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/netfilter_arp/arpt_mangle.h b/include/uapi/linux/netfilter_arp/arpt_mangle.h index 250f502902bb..8c2b16a1f5a0 100644 --- a/include/uapi/linux/netfilter_arp/arpt_mangle.h +++ b/include/uapi/linux/netfilter_arp/arpt_mangle.h @@ -13,7 +13,7 @@ struct arpt_mangle union { struct in_addr tgt_ip; } u_t; - u_int8_t flags; + __u8 flags; int target; }; -- GitLab From 06ed5c2bfacaf67039e87a213fa5d1cdde34246a Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 20 Aug 2014 16:02:59 +0200 Subject: [PATCH 1012/9167] kbuild: Make scripts executable The Makefiles call the respective interpreter explicitly, but this makes it easier to use the scripts manually. Signed-off-by: Michal Marek --- scripts/bootgraph.pl | 0 scripts/export_report.pl | 0 scripts/gcc-goto.sh | 0 scripts/gcc-ld | 0 scripts/gcc-version.sh | 0 scripts/gcc-x86_32-has-stack-protector.sh | 0 scripts/gcc-x86_64-has-stack-protector.sh | 0 scripts/gen_initramfs_list.sh | 0 scripts/headers_check.pl | 0 scripts/headers_install.sh | 0 scripts/kconfig/lxdialog/check-lxdialog.sh | 0 scripts/kconfig/streamline_config.pl | 0 scripts/link-vmlinux.sh | 0 scripts/markup_oops.pl | 0 scripts/mkmakefile | 0 scripts/mksysmap | 0 scripts/package/builddeb | 0 scripts/package/buildtar | 0 scripts/profile2linkerlist.pl | 0 scripts/rt-tester/rt-tester.py | 0 scripts/selinux/install_policy.sh | 0 scripts/tracing/draw_functrace.py | 0 scripts/xz_wrap.sh | 0 23 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/bootgraph.pl mode change 100644 => 100755 scripts/export_report.pl mode change 100644 => 100755 scripts/gcc-goto.sh mode change 100644 => 100755 scripts/gcc-ld mode change 100644 => 100755 scripts/gcc-version.sh mode change 100644 => 100755 scripts/gcc-x86_32-has-stack-protector.sh mode change 100644 => 100755 scripts/gcc-x86_64-has-stack-protector.sh mode change 100644 => 100755 scripts/gen_initramfs_list.sh mode change 100644 => 100755 scripts/headers_check.pl mode change 100644 => 100755 scripts/headers_install.sh mode change 100644 => 100755 scripts/kconfig/lxdialog/check-lxdialog.sh mode change 100644 => 100755 scripts/kconfig/streamline_config.pl mode change 100644 => 100755 scripts/link-vmlinux.sh mode change 100644 => 100755 scripts/markup_oops.pl mode change 100644 => 100755 scripts/mkmakefile mode change 100644 => 100755 scripts/mksysmap mode change 100644 => 100755 scripts/package/builddeb mode change 100644 => 100755 scripts/package/buildtar mode change 100644 => 100755 scripts/profile2linkerlist.pl mode change 100644 => 100755 scripts/rt-tester/rt-tester.py mode change 100644 => 100755 scripts/selinux/install_policy.sh mode change 100644 => 100755 scripts/tracing/draw_functrace.py mode change 100644 => 100755 scripts/xz_wrap.sh diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl old mode 100644 new mode 100755 diff --git a/scripts/export_report.pl b/scripts/export_report.pl old mode 100644 new mode 100755 diff --git a/scripts/gcc-goto.sh b/scripts/gcc-goto.sh old mode 100644 new mode 100755 diff --git a/scripts/gcc-ld b/scripts/gcc-ld old mode 100644 new mode 100755 diff --git a/scripts/gcc-version.sh b/scripts/gcc-version.sh old mode 100644 new mode 100755 diff --git a/scripts/gcc-x86_32-has-stack-protector.sh b/scripts/gcc-x86_32-has-stack-protector.sh old mode 100644 new mode 100755 diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh old mode 100644 new mode 100755 diff --git a/scripts/gen_initramfs_list.sh b/scripts/gen_initramfs_list.sh old mode 100644 new mode 100755 diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl old mode 100644 new mode 100755 diff --git a/scripts/headers_install.sh b/scripts/headers_install.sh old mode 100644 new mode 100755 diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh old mode 100644 new mode 100755 diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl old mode 100644 new mode 100755 diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh old mode 100644 new mode 100755 diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl old mode 100644 new mode 100755 diff --git a/scripts/mkmakefile b/scripts/mkmakefile old mode 100644 new mode 100755 diff --git a/scripts/mksysmap b/scripts/mksysmap old mode 100644 new mode 100755 diff --git a/scripts/package/builddeb b/scripts/package/builddeb old mode 100644 new mode 100755 diff --git a/scripts/package/buildtar b/scripts/package/buildtar old mode 100644 new mode 100755 diff --git a/scripts/profile2linkerlist.pl b/scripts/profile2linkerlist.pl old mode 100644 new mode 100755 diff --git a/scripts/rt-tester/rt-tester.py b/scripts/rt-tester/rt-tester.py old mode 100644 new mode 100755 diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh old mode 100644 new mode 100755 diff --git a/scripts/tracing/draw_functrace.py b/scripts/tracing/draw_functrace.py old mode 100644 new mode 100755 diff --git a/scripts/xz_wrap.sh b/scripts/xz_wrap.sh old mode 100644 new mode 100755 -- GitLab From 36e15dd4027a9b088264758fea292b6e876b5cdd Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 20 Aug 2014 17:07:58 +0900 Subject: [PATCH 1013/9167] perf hists browser: Get rid of unused 'remaining' variable It seems that the 'remaining' variable is not used by any real code. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1408522080-26556-4-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 4892480e8298..2f34c6b6d5dc 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -488,14 +488,13 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse { struct rb_node *node; int first_row = row, width, offset = level * LEVEL_OFFSET_STEP; - u64 new_total, remaining; + u64 new_total; if (callchain_param.mode == CHAIN_GRAPH_REL) new_total = chain_node->children_hit; else new_total = total; - remaining = new_total; node = rb_first(&chain_node->rb_root); while (node) { struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); @@ -506,8 +505,6 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse int first = true; int extra_offset = 0; - remaining -= cumul; - list_for_each_entry(chain, &child->val, list) { char bf[1024], *alloc_str; const char *str; @@ -1084,7 +1081,7 @@ static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *bro { struct rb_node *node; int offset = level * LEVEL_OFFSET_STEP; - u64 new_total, remaining; + u64 new_total; int printed = 0; if (callchain_param.mode == CHAIN_GRAPH_REL) @@ -1092,7 +1089,6 @@ static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *bro else new_total = total; - remaining = new_total; node = rb_first(&chain_node->rb_root); while (node) { struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node); @@ -1103,8 +1099,6 @@ static int hist_browser__fprintf_callchain_node_rb_tree(struct hist_browser *bro int first = true; int extra_offset = 0; - remaining -= cumul; - list_for_each_entry(chain, &child->val, list) { char bf[1024], *alloc_str; const char *str; -- GitLab From 2bfa152839e5adea66aa6309c94bf3a50a5d5d47 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 20 Aug 2014 17:07:56 +0900 Subject: [PATCH 1014/9167] perf hists browser: Fix children overhead dump When perf report runs on TUI, 'P' key dumps current screen to a file but it incorrectly displayed children overhead (as same of self overhead). This was because it fetched the value from self stats. Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1408522080-26556-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c index b5fa7019d2e2..75eb6ac821f8 100644 --- a/tools/perf/ui/hist.c +++ b/tools/perf/ui/hist.c @@ -304,7 +304,7 @@ static int hpp__color_##_type(struct perf_hpp_fmt *fmt, \ static int hpp__entry_##_type(struct perf_hpp_fmt *fmt, \ struct perf_hpp *hpp, struct hist_entry *he) \ { \ - return hpp__fmt_acc(fmt, hpp, he, he_get_##_field, " %*.2f%%", \ + return hpp__fmt_acc(fmt, hpp, he, he_get_acc_##_field, " %*.2f%%", \ hpp_entry_scnprintf, true); \ } -- GitLab From f4536ddd20d93b70d432b7ca5db873525e23c2c4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 20 Aug 2014 17:07:57 +0900 Subject: [PATCH 1015/9167] perf hists browser: Factor out hist_browser__show_callchain_entry() Factor out duplicate callchain printing code into the hist_browser__ show_callchain_entry(). Signed-off-by: Namhyung Kim Cc: Andi Kleen Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1408522080-26556-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/ui/browsers/hists.c | 64 ++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 2f34c6b6d5dc..d42d8a8f3810 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -477,6 +477,29 @@ static char *callchain_list__sym_name(struct callchain_list *cl, return bf; } +static void hist_browser__show_callchain_entry(struct hist_browser *browser, + struct callchain_list *chain, + unsigned short row, int offset, + char folded_sign, const char *str, + bool *is_current_entry) +{ + int color, width; + + color = HE_COLORSET_NORMAL; + width = browser->b.width - (offset + 2); + if (ui_browser__is_current_entry(&browser->b, row)) { + browser->selection = &chain->ms; + color = HE_COLORSET_SELECTED; + *is_current_entry = true; + } + + ui_browser__set_color(&browser->b, color); + hist_browser__gotorc(browser, row, 0); + slsmg_write_nstring(" ", offset); + slsmg_printf("%c ", folded_sign); + slsmg_write_nstring(str, width); +} + #define LEVEL_OFFSET_STEP 3 static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browser, @@ -487,7 +510,7 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse bool *is_current_entry) { struct rb_node *node; - int first_row = row, width, offset = level * LEVEL_OFFSET_STEP; + int first_row = row, offset = level * LEVEL_OFFSET_STEP; u64 new_total; if (callchain_param.mode == CHAIN_GRAPH_REL) @@ -508,7 +531,6 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse list_for_each_entry(chain, &child->val, list) { char bf[1024], *alloc_str; const char *str; - int color; bool was_first = first; if (first) @@ -534,19 +556,10 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse str = alloc_str; } - color = HE_COLORSET_NORMAL; - width = browser->b.width - (offset + extra_offset + 2); - if (ui_browser__is_current_entry(&browser->b, row)) { - browser->selection = &chain->ms; - color = HE_COLORSET_SELECTED; - *is_current_entry = true; - } - - ui_browser__set_color(&browser->b, color); - hist_browser__gotorc(browser, row, 0); - slsmg_write_nstring(" ", offset + extra_offset); - slsmg_printf("%c ", folded_sign); - slsmg_write_nstring(str, width); + hist_browser__show_callchain_entry(browser, chain, row, + offset + extra_offset, + folded_sign, str, + is_current_entry); free(alloc_str); if (++row == browser->b.rows) @@ -577,14 +590,12 @@ static int hist_browser__show_callchain_node(struct hist_browser *browser, bool *is_current_entry) { struct callchain_list *chain; - int first_row = row, - offset = level * LEVEL_OFFSET_STEP, - width = browser->b.width - offset; + int first_row = row; + int offset = level * LEVEL_OFFSET_STEP; char folded_sign = ' '; list_for_each_entry(chain, &node->val, list) { char bf[1024], *s; - int color; folded_sign = callchain_list__folded(chain); @@ -593,20 +604,11 @@ static int hist_browser__show_callchain_node(struct hist_browser *browser, continue; } - color = HE_COLORSET_NORMAL; - if (ui_browser__is_current_entry(&browser->b, row)) { - browser->selection = &chain->ms; - color = HE_COLORSET_SELECTED; - *is_current_entry = true; - } - s = callchain_list__sym_name(chain, bf, sizeof(bf), browser->show_dso); - hist_browser__gotorc(browser, row, 0); - ui_browser__set_color(&browser->b, color); - slsmg_write_nstring(" ", offset); - slsmg_printf("%c ", folded_sign); - slsmg_write_nstring(s, width - 2); + hist_browser__show_callchain_entry(browser, chain, row, + offset, folded_sign, s, + is_current_entry); if (++row == browser->b.rows) goto out; -- GitLab From b7c71823f11158340b9d61325d3c44124650dc4e Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Fri, 15 Aug 2014 12:01:31 +0100 Subject: [PATCH 1016/9167] drm/i915/bdw: Don't write PDP in the legacy way when using LRCs This is mostly for correctness so that we know we are running the LR context correctly (this is, the PDPs are contained inside the context object). v2: Move the check to inside the enable PPGTT function. The switch happens in two places: the legacy context switch (that we won't hit when Execlists are enabled) and the PPGTT enable, which unfortunately we need. This would look much nicer if the ppgtt->enable was part of the ring init, where it logically belongs. v3: Move the check to the start of the enable PPGTT function. None of the legacy PPGTT enabling is required when using LRCs as the PPGTT is enabled in the context descriptor and the PDPs are written in the LRC. v4: Clarify comment based on review feedback. Signed-off-by: Oscar Mateo Signed-off-by: Thomas Daniel Reviewed-by: Damien Lespiau [danvet: Resolve conflicts with ppgtt_enable rework.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index d97b280861ee..4db237065610 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -826,6 +826,12 @@ static void gen8_ppgtt_enable(struct drm_device *dev) struct intel_engine_cs *ring; int j; + /* In the case of execlists, PPGTT is enabled by the context descriptor + * and the PDPs are contained within the context itself. We don't + * need to do anything here. */ + if (i915.enable_execlists) + return; + for_each_ring(ring, dev_priv, j) { I915_WRITE(RING_MODE_GEN7(ring), _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); -- GitLab From cc9130be805d955f0e06642e57741dd9df1fbc86 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:42 +0100 Subject: [PATCH 1017/9167] drm/i915/bdw: Make sure gpu reset still works with Execlists If we reset a ring after a hang, we have to make sure that we clear out all queued Execlists requests. v2: The ring is, at this point, already being correctly re-programmed for Execlists, and the hangcheck counters cleared. v3: Daniel suggests to drop the "if (execlists)" because the Execlists queue should be empty in legacy mode (which is true, if we do the INIT_LIST_HEAD). v4: Do the pending intel_runtime_pm_put Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 12 ++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.c | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 32fa1e9eb844..aa4103bdd352 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2551,6 +2551,18 @@ 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_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 13543f8528c2..4fb1ec95ec08 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1612,6 +1612,7 @@ static int intel_init_ring_buffer(struct drm_device *dev, ring->dev = dev; INIT_LIST_HEAD(&ring->active_list); INIT_LIST_HEAD(&ring->request_list); + INIT_LIST_HEAD(&ring->execlist_queue); ringbuf->size = 32 * PAGE_SIZE; ringbuf->ring = ring; memset(ring->semaphore.sync_seqno, 0, sizeof(ring->semaphore.sync_seqno)); -- GitLab From 71386ef9008817feebd863e46d8711ebe9e7cbbb Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:44 +0100 Subject: [PATCH 1018/9167] drm/i915/bdw: Disable semaphores for Execlists Up until recently, semaphores weren't enabled in BDW so we didn't care about them. But then Rodrigo came and enabled them: commit 521e62e49a42661a4ee0102644517dbe2f100a23 Author: Rodrigo Vivi drm/i915: Enable semaphores on BDW So now we have to explicitly disable them for Execlists until both features play nicely. Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2f112853c36f..117f5c16df74 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -481,6 +481,10 @@ bool i915_semaphore_is_enabled(struct drm_device *dev) if (i915.semaphores >= 0) return i915.semaphores; + /* TODO: make semaphores and Execlists play nicely together */ + if (i915.enable_execlists) + return false; + /* Until we get further testing... */ if (IS_GEN8(dev)) return false; -- GitLab From 4ba70e448be91f52032595678c306e4aee2fae5c Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 7 Aug 2014 13:23:20 +0100 Subject: [PATCH 1019/9167] drm/i915/bdw: Display execlists info in debugfs v2: Warn and return if LRCs are not enabled. v3: Grab the Execlists spinlock (noticed by Daniel Vetter). Signed-off-by: Oscar Mateo v4: Lock the struct mutex for atomic state capture Signed-off-by: Thomas Daniel Reviewed-by: Damien Lespiau [danvet: Checkpatch.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 81 +++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_lrc.c | 6 --- drivers/gpu/drm/i915/intel_lrc.h | 7 +++ 3 files changed, 88 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d42db6bc34e0..68335813ef4c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1721,6 +1721,86 @@ static int i915_context_status(struct seq_file *m, void *unused) return 0; } +static int i915_execlists(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *)m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring; + u32 status_pointer; + u8 read_pointer; + u8 write_pointer; + u32 status; + u32 ctx_id; + struct list_head *cursor; + int ring_id, i; + int ret; + + if (!i915.enable_execlists) { + seq_puts(m, "Logical Ring Contexts are disabled\n"); + return 0; + } + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + + for_each_ring(ring, dev_priv, ring_id) { + struct intel_ctx_submit_request *head_req = NULL; + int count = 0; + unsigned long flags; + + seq_printf(m, "%s\n", ring->name); + + status = I915_READ(RING_EXECLIST_STATUS(ring)); + ctx_id = I915_READ(RING_EXECLIST_STATUS(ring) + 4); + seq_printf(m, "\tExeclist status: 0x%08X, context: %u\n", + status, ctx_id); + + status_pointer = I915_READ(RING_CONTEXT_STATUS_PTR(ring)); + seq_printf(m, "\tStatus pointer: 0x%08X\n", status_pointer); + + read_pointer = ring->next_context_status_buffer; + write_pointer = status_pointer & 0x07; + if (read_pointer > write_pointer) + write_pointer += 6; + seq_printf(m, "\tRead pointer: 0x%08X, write pointer 0x%08X\n", + read_pointer, write_pointer); + + for (i = 0; i < 6; i++) { + status = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + 8*i); + ctx_id = I915_READ(RING_CONTEXT_STATUS_BUF(ring) + 8*i + 4); + + seq_printf(m, "\tStatus buffer %d: 0x%08X, context: %u\n", + i, status, ctx_id); + } + + spin_lock_irqsave(&ring->execlist_lock, flags); + list_for_each(cursor, &ring->execlist_queue) + count++; + head_req = list_first_entry_or_null(&ring->execlist_queue, + struct intel_ctx_submit_request, execlist_link); + spin_unlock_irqrestore(&ring->execlist_lock, flags); + + seq_printf(m, "\t%d requests in queue\n", count); + if (head_req) { + struct drm_i915_gem_object *ctx_obj; + + ctx_obj = head_req->ctx->engine[ring_id].state; + seq_printf(m, "\tHead request id: %u\n", + intel_execlists_ctx_id(ctx_obj)); + seq_printf(m, "\tHead request tail: %u\n", + head_req->tail); + } + + seq_putc(m, '\n'); + } + + mutex_unlock(&dev->struct_mutex); + + return 0; +} + static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) { struct drm_info_node *node = m->private; @@ -3974,6 +4054,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_opregion", i915_opregion, 0}, {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_context_status", i915_context_status, 0}, + {"i915_execlists", i915_execlists, 0}, {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, {"i915_swizzle_info", i915_swizzle_info, 0}, {"i915_ppgtt_info", i915_ppgtt_info, 0}, diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index 6f6c5a931faf..cc923a96fa4c 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -46,12 +46,6 @@ #define GEN8_LR_CONTEXT_ALIGN 4096 -#define RING_ELSP(ring) ((ring)->mmio_base+0x230) -#define RING_EXECLIST_STATUS(ring) ((ring)->mmio_base+0x234) -#define RING_CONTEXT_CONTROL(ring) ((ring)->mmio_base+0x244) -#define RING_CONTEXT_STATUS_BUF(ring) ((ring)->mmio_base+0x370) -#define RING_CONTEXT_STATUS_PTR(ring) ((ring)->mmio_base+0x3a0) - #define RING_EXECLIST_QFULL (1 << 0x2) #define RING_EXECLIST1_VALID (1 << 0x3) #define RING_EXECLIST0_VALID (1 << 0x4) diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 331c6c2ba376..117d1a4eb3b9 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -24,6 +24,13 @@ #ifndef _INTEL_LRC_H_ #define _INTEL_LRC_H_ +/* Execlists regs */ +#define RING_ELSP(ring) ((ring)->mmio_base+0x230) +#define RING_EXECLIST_STATUS(ring) ((ring)->mmio_base+0x234) +#define RING_CONTEXT_CONTROL(ring) ((ring)->mmio_base+0x244) +#define RING_CONTEXT_STATUS_BUF(ring) ((ring)->mmio_base+0x370) +#define RING_CONTEXT_STATUS_PTR(ring) ((ring)->mmio_base+0x3a0) + /* Logical Rings */ void intel_logical_ring_stop(struct intel_engine_cs *ring); void intel_logical_ring_cleanup(struct intel_engine_cs *ring); -- GitLab From c9fe99bd4c4f8730207fed5e863d8f25224fd20b Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:46 +0100 Subject: [PATCH 1020/9167] drm/i915/bdw: Display context backing obj & ringbuffer info in debugfs Signed-off-by: Oscar Mateo Reviewed-by: Damien Lespiau [danvet: Checkpatch.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 37 +++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 68335813ef4c..4f279cfe67b8 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1677,6 +1677,14 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) return 0; } +static void describe_ctx_ringbuf(struct seq_file *m, + struct intel_ringbuffer *ringbuf) +{ + seq_printf(m, " (ringbuffer, space: %d, head: %u, tail: %u, last head: %d)", + ringbuf->space, ringbuf->head, ringbuf->tail, + ringbuf->last_retired_head); +} + static int i915_context_status(struct seq_file *m, void *unused) { struct drm_info_node *node = m->private; @@ -1703,16 +1711,37 @@ static int i915_context_status(struct seq_file *m, void *unused) } list_for_each_entry(ctx, &dev_priv->context_list, link) { - if (ctx->legacy_hw_ctx.rcs_state == NULL) + if (!i915.enable_execlists && + ctx->legacy_hw_ctx.rcs_state == NULL) continue; seq_puts(m, "HW context "); describe_ctx(m, ctx); - for_each_ring(ring, dev_priv, i) + for_each_ring(ring, dev_priv, i) { if (ring->default_context == ctx) - seq_printf(m, "(default context %s) ", ring->name); + seq_printf(m, "(default context %s) ", + ring->name); + } + + if (i915.enable_execlists) { + seq_putc(m, '\n'); + for_each_ring(ring, dev_priv, i) { + struct drm_i915_gem_object *ctx_obj = + ctx->engine[i].state; + struct intel_ringbuffer *ringbuf = + ctx->engine[i].ringbuf; + + seq_printf(m, "%s: ", ring->name); + if (ctx_obj) + describe_obj(m, ctx_obj); + if (ringbuf) + describe_ctx_ringbuf(m, ringbuf); + seq_putc(m, '\n'); + } + } else { + describe_obj(m, ctx->legacy_hw_ctx.rcs_state); + } - describe_obj(m, ctx->legacy_hw_ctx.rcs_state); seq_putc(m, '\n'); } -- GitLab From c0ab1ae9028f14bcb7bfb655bd2120c60681c479 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Thu, 7 Aug 2014 13:24:26 +0100 Subject: [PATCH 1021/9167] drm/i915/bdw: Print context state in debugfs This has turned out to be really handy in debug so far. Update: Since writing this patch, I've gotten similar code upstream for error state. I've used it quite a bit in debugfs however, and I'd like to keep it here at least until preemption is working. Signed-off-by: Ben Widawsky This patch was accidentally dropped in the first Execlists version, and it has been very useful indeed. Put it back again, but as a standalone debugfs file. Signed-off-by: Oscar Mateo v2: Take the device struct_mutex rather than mode_config mutex for atomic state capture. Signed-off-by: Thomas Daniel Reviewed-by: Damien Lespiau Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 52 +++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4f279cfe67b8..6c82bdaa0822 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1750,6 +1750,57 @@ static int i915_context_status(struct seq_file *m, void *unused) return 0; } +static int i915_dump_lrc(struct seq_file *m, void *unused) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_engine_cs *ring; + struct intel_context *ctx; + int ret, i; + + if (!i915.enable_execlists) { + seq_printf(m, "Logical Ring Contexts are disabled\n"); + return 0; + } + + ret = mutex_lock_interruptible(&dev->struct_mutex); + if (ret) + return ret; + + list_for_each_entry(ctx, &dev_priv->context_list, link) { + for_each_ring(ring, dev_priv, i) { + struct drm_i915_gem_object *ctx_obj = ctx->engine[i].state; + + if (ring->default_context == ctx) + continue; + + if (ctx_obj) { + struct page *page = i915_gem_object_get_page(ctx_obj, 1); + uint32_t *reg_state = kmap_atomic(page); + int j; + + seq_printf(m, "CONTEXT: %s %u\n", ring->name, + intel_execlists_ctx_id(ctx_obj)); + + for (j = 0; j < 0x600 / sizeof(u32) / 4; j += 4) { + seq_printf(m, "\t[0x%08lx] 0x%08x 0x%08x 0x%08x 0x%08x\n", + i915_gem_obj_ggtt_offset(ctx_obj) + 4096 + (j * 4), + reg_state[j], reg_state[j + 1], + reg_state[j + 2], reg_state[j + 3]); + } + kunmap_atomic(reg_state); + + seq_putc(m, '\n'); + } + } + } + + mutex_unlock(&dev->struct_mutex); + + return 0; +} + static int i915_execlists(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *)m->private; @@ -4083,6 +4134,7 @@ static const struct drm_info_list i915_debugfs_list[] = { {"i915_opregion", i915_opregion, 0}, {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_context_status", i915_context_status, 0}, + {"i915_dump_lrc", i915_dump_lrc, 0}, {"i915_execlists", i915_execlists, 0}, {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, {"i915_swizzle_info", i915_swizzle_info, 0}, -- GitLab From 73e4d07f8ae9cff8c869d73df4e299a3a6f5ad98 Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:48 +0100 Subject: [PATCH 1022/9167] drm/i915/bdw: Document Logical Rings, LR contexts and Execlists Add theory of operation notes to intel_lrc.c and comments to externally visible functions. v2: Add notes on logical ring context creation. v3: Use kerneldoc. v4: Integrate it in the DocBook template. Signed-off-by: Thomas Daniel (v1) Signed-off-by: Oscar Mateo (v2, v3) Reviewed-by: Damien Lespiau [danvet: Drop hunk about render ring init function since that's not yet merged.] Signed-off-by: Daniel Vetter --- Documentation/DocBook/drm.tmpl | 5 + drivers/gpu/drm/i915/intel_lrc.c | 203 ++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_lrc.h | 30 +++++ 3 files changed, 237 insertions(+), 1 deletion(-) diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 972759489376..689e3e38b9c3 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl @@ -3919,6 +3919,11 @@ int num_ioctls; !Pdrivers/gpu/drm/i915/i915_cmd_parser.c batch buffer command parser !Idrivers/gpu/drm/i915/i915_cmd_parser.c + + Logical Rings, Logical Ring Contexts and Execlists +!Pdrivers/gpu/drm/i915/intel_lrc.c Logical Rings, Logical Ring Contexts and Execlists +!Idrivers/gpu/drm/i915/intel_lrc.c + diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c index cc923a96fa4c..c096b9b7f22a 100644 --- a/drivers/gpu/drm/i915/intel_lrc.c +++ b/drivers/gpu/drm/i915/intel_lrc.c @@ -28,13 +28,108 @@ * */ -/* +/** + * DOC: Logical Rings, Logical Ring Contexts and Execlists + * + * Motivation: * GEN8 brings an expansion of the HW contexts: "Logical Ring Contexts". * These expanded contexts enable a number of new abilities, especially * "Execlists" (also implemented in this file). * + * One of the main differences with the legacy HW contexts is that logical + * ring contexts incorporate many more things to the context's state, like + * PDPs or ringbuffer control registers: + * + * The reason why PDPs are included in the context is straightforward: as + * PPGTTs (per-process GTTs) are actually per-context, having the PDPs + * contained there mean you don't need to do a ppgtt->switch_mm yourself, + * instead, the GPU will do it for you on the context switch. + * + * But, what about the ringbuffer control registers (head, tail, etc..)? + * shouldn't we just need a set of those per engine command streamer? This is + * where the name "Logical Rings" starts to make sense: by virtualizing the + * rings, the engine cs shifts to a new "ring buffer" with every context + * switch. When you want to submit a workload to the GPU you: A) choose your + * context, B) find its appropriate virtualized ring, C) write commands to it + * and then, finally, D) tell the GPU to switch to that context. + * + * Instead of the legacy MI_SET_CONTEXT, the way you tell the GPU to switch + * to a contexts is via a context execution list, ergo "Execlists". + * + * LRC implementation: + * Regarding the creation of contexts, we have: + * + * - One global default context. + * - One local default context for each opened fd. + * - One local extra context for each context create ioctl call. + * + * Now that ringbuffers belong per-context (and not per-engine, like before) + * and that contexts are uniquely tied to a given engine (and not reusable, + * like before) we need: + * + * - One ringbuffer per-engine inside each context. + * - One backing object per-engine inside each context. + * + * The global default context starts its life with these new objects fully + * allocated and populated. The local default context for each opened fd is + * more complex, because we don't know at creation time which engine is going + * to use them. To handle this, we have implemented a deferred creation of LR + * contexts: + * + * The local context starts its life as a hollow or blank holder, that only + * gets populated for a given engine once we receive an execbuffer. If later + * on we receive another execbuffer ioctl for the same context but a different + * engine, we allocate/populate a new ringbuffer and context backing object and + * so on. + * + * Finally, regarding local contexts created using the ioctl call: as they are + * only allowed with the render ring, we can allocate & populate them right + * away (no need to defer anything, at least for now). + * + * Execlists implementation: * Execlists are the new method by which, on gen8+ hardware, workloads are * submitted for execution (as opposed to the legacy, ringbuffer-based, method). + * This method works as follows: + * + * When a request is committed, its commands (the BB start and any leading or + * trailing commands, like the seqno breadcrumbs) are placed in the ringbuffer + * for the appropriate context. The tail pointer in the hardware context is not + * updated at this time, but instead, kept by the driver in the ringbuffer + * structure. A structure representing this request is added to a request queue + * for the appropriate engine: this structure contains a copy of the context's + * tail after the request was written to the ring buffer and a pointer to the + * context itself. + * + * If the engine's request queue was empty before the request was added, the + * queue is processed immediately. Otherwise the queue will be processed during + * a context switch interrupt. In any case, elements on the queue will get sent + * (in pairs) to the GPU's ExecLists Submit Port (ELSP, for short) with a + * globally unique 20-bits submission ID. + * + * When execution of a request completes, the GPU updates the context status + * buffer with a context complete event and generates a context switch interrupt. + * During the interrupt handling, the driver examines the events in the buffer: + * for each context complete event, if the announced ID matches that on the head + * of the request queue, then that request is retired and removed from the queue. + * + * After processing, if any requests were retired and the queue is not empty + * then a new execution list can be submitted. The two requests at the front of + * the queue are next to be submitted but since a context may not occur twice in + * an execution list, if subsequent requests have the same ID as the first then + * the two requests must be combined. This is done simply by discarding requests + * at the head of the queue until either only one requests is left (in which case + * we use a NULL second context) or the first two requests have unique IDs. + * + * By always executing the first two requests in the queue the driver ensures + * that the GPU is kept as busy as possible. In the case where a single context + * completes but a second context is still executing, the request for this second + * context will be at the head of the queue when we remove the first one. This + * request will then be resubmitted along with a new request for a different context, + * which will cause the hardware to continue executing the second request and queue + * the new request (the GPU detects the condition of a context getting preempted + * with the same context and optimizes the context switch flow by not doing + * preemption, but just sampling the new tail pointer). + * */ #include @@ -109,6 +204,17 @@ enum { }; #define GEN8_CTX_ID_SHIFT 32 +/** + * intel_sanitize_enable_execlists() - sanitize i915.enable_execlists + * @dev: DRM device. + * @enable_execlists: value of i915.enable_execlists module parameter. + * + * Only certain platforms support Execlists (the prerequisites being + * support for Logical Ring Contexts and Aliasing PPGTT or better), + * and only when enabled via module parameter. + * + * Return: 1 if Execlists is supported and has to be enabled. + */ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists) { WARN_ON(i915.enable_ppgtt == -1); @@ -123,6 +229,18 @@ int intel_sanitize_enable_execlists(struct drm_device *dev, int enable_execlists return 0; } +/** + * intel_execlists_ctx_id() - get the Execlists Context ID + * @ctx_obj: Logical Ring Context backing object. + * + * Do not confuse with ctx->id! Unfortunately we have a name overload + * here: the old context ID we pass to userspace as a handler so that + * they can refer to a context, and the new context ID we pass to the + * ELSP so that the GPU can inform us of the context status via + * interrupts. + * + * Return: 20-bits globally unique context ID. + */ u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj) { u32 lrca = i915_gem_obj_ggtt_offset(ctx_obj); @@ -313,6 +431,13 @@ static bool execlists_check_remove_request(struct intel_engine_cs *ring, return false; } +/** + * intel_execlists_handle_ctx_events() - handle Context Switch interrupts + * @ring: Engine Command Streamer to handle. + * + * Check the unread Context Status Buffers and manage the submission of new + * contexts to the ELSP accordingly. + */ void intel_execlists_handle_ctx_events(struct intel_engine_cs *ring) { struct drm_i915_private *dev_priv = ring->dev->dev_private; @@ -481,6 +606,23 @@ static int execlists_move_to_gpu(struct intel_ringbuffer *ringbuf, return logical_ring_invalidate_all_caches(ringbuf); } +/** + * execlists_submission() - submit a batchbuffer for execution, Execlists style + * @dev: DRM device. + * @file: DRM file. + * @ring: Engine Command Streamer to submit to. + * @ctx: Context to employ for this submission. + * @args: execbuffer call arguments. + * @vmas: list of vmas. + * @batch_obj: the batchbuffer to submit. + * @exec_start: batchbuffer start virtual address pointer. + * @flags: translated execbuffer call flags. + * + * This is the evil twin version of i915_gem_ringbuffer_submission. It abstracts + * away the submission details of the execbuffer ioctl call. + * + * Return: non-zero if the submission fails. + */ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, struct intel_engine_cs *ring, struct intel_context *ctx, @@ -608,6 +750,15 @@ int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf) return 0; } +/** + * intel_logical_ring_advance_and_submit() - advance the tail and submit the workload + * @ringbuf: Logical Ringbuffer to advance. + * + * The tail is updated in our logical ringbuffer struct, not in the actual context. What + * really happens during submission is that the context and current tail will be placed + * on a queue waiting for the ELSP to be ready to accept a new context submission. At that + * point, the tail *inside* the context is updated and the ELSP written to. + */ void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf) { struct intel_engine_cs *ring = ringbuf->ring; @@ -781,6 +932,19 @@ static int logical_ring_prepare(struct intel_ringbuffer *ringbuf, int bytes) return 0; } +/** + * intel_logical_ring_begin() - prepare the logical ringbuffer to accept some commands + * + * @ringbuf: Logical ringbuffer. + * @num_dwords: number of DWORDs that we plan to write to the ringbuffer. + * + * The ringbuffer might not be ready to accept the commands right away (maybe it needs to + * be wrapped, or wait a bit for the tail to be updated). This function takes care of that + * and also preallocates a request (every workload submission is still mediated through + * requests, same as it did with legacy ringbuffer submission). + * + * Return: non-zero if the ringbuffer is not ready to be written to. + */ int intel_logical_ring_begin(struct intel_ringbuffer *ringbuf, int num_dwords) { struct intel_engine_cs *ring = ringbuf->ring; @@ -1021,6 +1185,12 @@ static int gen8_emit_request(struct intel_ringbuffer *ringbuf) return 0; } +/** + * intel_logical_ring_cleanup() - deallocate the Engine Command Streamer + * + * @ring: Engine Command Streamer. + * + */ void intel_logical_ring_cleanup(struct intel_engine_cs *ring) { struct drm_i915_private *dev_priv = ring->dev->dev_private; @@ -1215,6 +1385,16 @@ static int logical_vebox_ring_init(struct drm_device *dev) return logical_ring_init(dev, ring); } +/** + * intel_logical_rings_init() - allocate, populate and init the Engine Command Streamers + * @dev: DRM device. + * + * This function inits the engines for an Execlists submission style (the equivalent in the + * legacy ringbuffer submission world would be i915_gem_init_rings). It does it only for + * those engines that are present in the hardware. + * + * Return: non-zero if the initialization failed. + */ int intel_logical_rings_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -1377,6 +1557,14 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o return 0; } +/** + * intel_lr_context_free() - free the LRC specific bits of a context + * @ctx: the LR context to free. + * + * The real context freeing is done in i915_gem_context_free: this only + * takes care of the bits that are LRC related: the per-engine backing + * objects and the logical ringbuffer. + */ void intel_lr_context_free(struct intel_context *ctx) { int i; @@ -1415,6 +1603,19 @@ static uint32_t get_lr_context_size(struct intel_engine_cs *ring) return ret; } +/** + * intel_lr_context_deferred_create() - create the LRC specific bits of a context + * @ctx: LR context to create. + * @ring: engine to be used with the context. + * + * This function can be called more than once, with different engines, if we plan + * to use the context with them. The context backing objects and the ringbuffers + * (specially the ringbuffer backing objects) suck a lot of memory up, and that's why + * 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. + */ int intel_lr_context_deferred_create(struct intel_context *ctx, struct intel_engine_cs *ring) { diff --git a/drivers/gpu/drm/i915/intel_lrc.h b/drivers/gpu/drm/i915/intel_lrc.h index 117d1a4eb3b9..991d4499fb03 100644 --- a/drivers/gpu/drm/i915/intel_lrc.h +++ b/drivers/gpu/drm/i915/intel_lrc.h @@ -38,10 +38,21 @@ int intel_logical_rings_init(struct drm_device *dev); int logical_ring_flush_all_caches(struct intel_ringbuffer *ringbuf); void intel_logical_ring_advance_and_submit(struct intel_ringbuffer *ringbuf); +/** + * intel_logical_ring_advance() - advance the ringbuffer tail + * @ringbuf: Ringbuffer to advance. + * + * The tail is only updated in our logical ringbuffer struct. + */ static inline void intel_logical_ring_advance(struct intel_ringbuffer *ringbuf) { ringbuf->tail &= ringbuf->size - 1; } +/** + * intel_logical_ring_emit() - write a DWORD to the ringbuffer. + * @ringbuf: Ringbuffer to write to. + * @data: DWORD to write. + */ static inline void intel_logical_ring_emit(struct intel_ringbuffer *ringbuf, u32 data) { @@ -66,6 +77,25 @@ int intel_execlists_submission(struct drm_device *dev, struct drm_file *file, u64 exec_start, u32 flags); u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj); +/** + * struct intel_ctx_submit_request - queued context submission request + * @ctx: Context to submit to the ELSP. + * @ring: Engine to submit it to. + * @tail: how far in the context's ringbuffer this request goes to. + * @execlist_link: link in the submission queue. + * @work: workqueue for processing this request in a bottom half. + * @elsp_submitted: no. of times this request has been sent to the ELSP. + * + * The ELSP only accepts two elements at a time, so we queue context/tail + * pairs on a given queue (ring->execlist_queue) until the hardware is + * available. The queue serves a double purpose: we also use it to keep track + * of the up to 2 contexts currently in the hardware (usually one in execution + * and the other queued up by the GPU): We only remove elements from the head + * of the queue when the hardware informs us that an element has been + * completed. + * + * All accesses to the queue are mediated by a spinlock (ring->execlist_lock). + */ struct intel_ctx_submit_request { struct intel_context *ctx; struct intel_engine_cs *ring; -- GitLab From d7f621e50704306c348ccb192f17047f1499f9bc Mon Sep 17 00:00:00 2001 From: Oscar Mateo Date: Thu, 24 Jul 2014 17:04:49 +0100 Subject: [PATCH 1023/9167] drm/i915/bdw: Enable Logical Ring Contexts (hence, Execlists) The time has come, the Walrus said, to talk of many things. Signed-off-by: Oscar Mateo Reviewed-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 ed52ac744105..d4d2abbb8e6c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -2088,7 +2088,7 @@ struct drm_i915_cmd_table { #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) #define HAS_HW_CONTEXTS(dev) (INTEL_INFO(dev)->gen >= 6) -#define HAS_LOGICAL_RING_CONTEXTS(dev) 0 +#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) -- GitLab From fd639ac6dcbcbae4f2131bf1390a032df659ffb7 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 15 Aug 2014 16:48:36 +0100 Subject: [PATCH 1024/9167] drm/i915/bdw: Disable execlists by default We still have a few missing bits and pieces to have execlists enabled by default eg. the error capture or the render state initialization and so it wouldn't be wise to enable it by default on BDW just yet. Cc: Daniel Vetter Cc: Thomas Daniel Signed-off-by: Damien Lespiau Reviewed-by: Paulo Zanoni Tested-by: Paulo Zanoni Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82740 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_params.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_params.c b/drivers/gpu/drm/i915/i915_params.c index f7f8350c3793..1dcb1bed5ef8 100644 --- a/drivers/gpu/drm/i915/i915_params.c +++ b/drivers/gpu/drm/i915/i915_params.c @@ -35,7 +35,7 @@ struct i915_params i915 __read_mostly = { .vbt_sdvo_panel_type = -1, .enable_rc6 = -1, .enable_fbc = -1, - .enable_execlists = -1, + .enable_execlists = 0, .enable_hangcheck = true, .enable_ppgtt = -1, .enable_psr = 1, @@ -122,7 +122,7 @@ MODULE_PARM_DESC(enable_ppgtt, module_param_named(enable_execlists, i915.enable_execlists, int, 0400); MODULE_PARM_DESC(enable_execlists, "Override execlists usage. " - "(-1=auto [default], 0=disabled, 1=enabled)"); + "(-1=auto, 0=disabled [default], 1=enabled)"); module_param_named(enable_psr, i915.enable_psr, int, 0600); MODULE_PARM_DESC(enable_psr, "Enable PSR (default: true)"); -- GitLab From 3a5f87c286515c54ff5c52c3e64d0c522b7570c0 Mon Sep 17 00:00:00 2001 From: Thomas Wood Date: Wed, 20 Aug 2014 14:45:00 +0100 Subject: [PATCH 1025/9167] drm: fix plane rotation when restoring fbdev configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure plane rotation is reset correctly when restoring the fbdev configuration by using drm_mode_plane_set_obj_prop which calls the driver's set_property callback. The rotation reset feature was introduced in commit 9783de2 (drm: Resetting rotation property) and the callback issue was originally addressed in a previous version of the patch, but the fix was not present in the final version. v2: Fix documentation warning Add some more details to the commit message (Daniel Vetter) Testcase: igt/kms_rotation_crc Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=82236 Cc: Sonika Jindal Cc: Ville Syrjälä Cc: Dave Airlie Cc: Daniel Vetter Signed-off-by: Thomas Wood Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_crtc.c | 25 ++++++++++++++++++++----- drivers/gpu/drm/drm_fb_helper.c | 6 +++--- include/drm/drm_crtc.h | 3 +++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 3c4a62169f28..d7e4c0e2e796 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -4156,12 +4156,25 @@ static int drm_mode_crtc_set_obj_prop(struct drm_mode_object *obj, return ret; } -static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj, - struct drm_property *property, - uint64_t value) +/** + * drm_mode_plane_set_obj_prop - set the value of a property + * @plane: drm plane object to set property value for + * @property: property to set + * @value: value the property should be set to + * + * This functions sets a given property on a given plane object. This function + * calls the driver's ->set_property callback and changes the software state of + * the property if the callback succeeds. + * + * Returns: + * Zero on success, error code on failure. + */ +int drm_mode_plane_set_obj_prop(struct drm_plane *plane, + struct drm_property *property, + uint64_t value) { int ret = -EINVAL; - struct drm_plane *plane = obj_to_plane(obj); + struct drm_mode_object *obj = &plane->base; if (plane->funcs->set_property) ret = plane->funcs->set_property(plane, property, value); @@ -4170,6 +4183,7 @@ static int drm_mode_plane_set_obj_prop(struct drm_mode_object *obj, return ret; } +EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); /** * drm_mode_getproperty_ioctl - get the current value of a object's property @@ -4308,7 +4322,8 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, ret = drm_mode_crtc_set_obj_prop(arg_obj, property, arg->value); break; case DRM_MODE_OBJECT_PLANE: - ret = drm_mode_plane_set_obj_prop(arg_obj, property, arg->value); + ret = drm_mode_plane_set_obj_prop(obj_to_plane(arg_obj), + property, arg->value); break; } diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index d139eddb3d61..99569ee5adee 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -350,9 +350,9 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper) drm_plane_force_disable(plane); if (dev->mode_config.rotation_property) { - drm_object_property_set_value(&plane->base, - dev->mode_config.rotation_property, - BIT(DRM_ROTATE_0)); + drm_mode_plane_set_obj_prop(plane, + dev->mode_config.rotation_property, + BIT(DRM_ROTATE_0)); } } diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 62f73bdbcc47..38fae5d9ad73 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -1121,6 +1121,9 @@ extern int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +extern int drm_mode_plane_set_obj_prop(struct drm_plane *plane, + struct drm_property *property, + uint64_t value); extern void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth, int *bpp); -- GitLab From 29b9c318025bece77d019eada2dee856e3ca50b2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 20 Aug 2014 10:04:17 +0800 Subject: [PATCH 1026/9167] regulator: max77802: Remove unused fields from struct max77802_regulator_prv Both num_regulators and *rdev[MAX77802_REG_MAX] are not used, remove them. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max77802.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/regulator/max77802.c b/drivers/regulator/max77802.c index 5f022f859d49..ad1caa902ef0 100644 --- a/drivers/regulator/max77802.c +++ b/drivers/regulator/max77802.c @@ -65,8 +65,6 @@ static unsigned int ramp_table_77802_4bit[] = { }; struct max77802_regulator_prv { - int num_regulators; - struct regulator_dev *rdev[MAX77802_REG_MAX]; unsigned int opmode[MAX77802_REG_MAX]; }; -- GitLab From 2cd64ae3d57b80f6d93682b98a59ed4b124cf2ef Mon Sep 17 00:00:00 2001 From: Chris Zhong Date: Wed, 20 Aug 2014 11:36:42 +0800 Subject: [PATCH 1027/9167] regulator: RK808: Add regulator driver for RK808 The regulator module consists of 4 DCDCs, 8 LDOs and 2 switches. The output voltages are configurable and are meant to supply power to the main processor and other components Signed-off-by: Chris Zhong Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/rk808-regulator.c | 410 ++++++++++++++++++++++++++++ 3 files changed, 421 insertions(+) create mode 100644 drivers/regulator/rk808-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc8289e5dba..fb32babf756e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -459,6 +459,16 @@ config REGULATOR_RC5T583 through regulator interface. The device supports multiple DCDC/LDO outputs which can be controlled by i2c communication. +config REGULATOR_RK808 + tristate "Rockchip RK808 Power regulators" + depends on MFD_RK808 + help + Select this option to enable the power regulator of ROCKCHIP + PMIC RK808. + This driver supports the control of different power rails of device + through regulator interface. The device supports multiple DCDC/LDO + outputs which can be controlled by i2c communication. + config REGULATOR_S2MPA01 tristate "Samsung S2MPA01 voltage regulator" depends on MFD_SEC_CORE diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index aa4a6aa7b558..236fdbb2b786 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_REGULATOR_PBIAS) += pbias-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o +obj-$(CONFIG_REGULATOR_RK808) += rk808-regulator.o obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c new file mode 100644 index 000000000000..94753fd311c1 --- /dev/null +++ b/drivers/regulator/rk808-regulator.c @@ -0,0 +1,410 @@ +/* + * Regulator driver for Rockchip RK808 + * + * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd + * + * Author: Chris Zhong + * Author: Zhang Qing + * + * 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 +/* + * Field Definitions. + */ +#define RK808_BUCK_VSEL_MASK 0x3f +#define RK808_BUCK4_VSEL_MASK 0xf +#define RK808_LDO_VSEL_MASK 0x1f + +static const int buck_set_vol_base_addr[] = { + RK808_BUCK1_ON_VSEL_REG, + RK808_BUCK2_ON_VSEL_REG, + RK808_BUCK3_CONFIG_REG, + RK808_BUCK4_ON_VSEL_REG, +}; + +static const int buck_contr_base_addr[] = { + RK808_BUCK1_CONFIG_REG, + RK808_BUCK2_CONFIG_REG, + RK808_BUCK3_CONFIG_REG, + RK808_BUCK4_CONFIG_REG, +}; + +#define rk808_BUCK_SET_VOL_REG(x) (buck_set_vol_base_addr[x]) +#define rk808_BUCK_CONTR_REG(x) (buck_contr_base_addr[x]) +#define rk808_LDO_SET_VOL_REG(x) (ldo_set_vol_base_addr[x]) + +static const int ldo_set_vol_base_addr[] = { + RK808_LDO1_ON_VSEL_REG, + RK808_LDO2_ON_VSEL_REG, + RK808_LDO3_ON_VSEL_REG, + RK808_LDO4_ON_VSEL_REG, + RK808_LDO5_ON_VSEL_REG, + RK808_LDO6_ON_VSEL_REG, + RK808_LDO7_ON_VSEL_REG, + RK808_LDO8_ON_VSEL_REG, +}; + +/* + * rk808 voltage number + */ +static const struct regulator_linear_range rk808_buck_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(700000, 0, 63, 12500), +}; + +static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(1800000, 0, 15, 100000), +}; + +static const struct regulator_linear_range rk808_ldo_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(1800000, 0, 16, 100000), +}; + +static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000), + REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0), +}; + +static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000), +}; + +static struct regulator_ops rk808_reg_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +static struct regulator_ops rk808_switch_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +static const struct regulator_desc rk808_reg[] = { + { + .name = "DCDC_REG1", + .id = RK808_ID_DCDC1, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 64, + .linear_ranges = rk808_buck_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges), + .vsel_reg = RK808_BUCK1_ON_VSEL_REG, + .vsel_mask = RK808_BUCK_VSEL_MASK, + .enable_reg = RK808_DCDC_EN_REG, + .enable_mask = BIT(0), + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG2", + .id = RK808_ID_DCDC2, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 64, + .linear_ranges = rk808_buck_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges), + .vsel_reg = RK808_BUCK2_ON_VSEL_REG, + .vsel_mask = RK808_BUCK_VSEL_MASK, + .enable_reg = RK808_DCDC_EN_REG, + .enable_mask = BIT(1), + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG3", + .id = RK808_ID_DCDC3, + .ops = &rk808_switch_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 1, + .enable_reg = RK808_DCDC_EN_REG, + .enable_mask = BIT(2), + .owner = THIS_MODULE, + }, { + .name = "DCDC_REG4", + .id = RK808_ID_DCDC4, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_buck4_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_buck4_voltage_ranges), + .vsel_reg = RK808_BUCK4_ON_VSEL_REG, + .vsel_mask = RK808_BUCK4_VSEL_MASK, + .enable_reg = RK808_DCDC_EN_REG, + .enable_mask = BIT(3), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG1", + .id = RK808_ID_LDO1, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK808_LDO1_ON_VSEL_REG, + .vsel_mask = RK808_LDO_VSEL_MASK, + .enable_reg = RK808_LDO_EN_REG, + .enable_mask = BIT(0), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG2", + .id = RK808_ID_LDO2, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK808_LDO2_ON_VSEL_REG, + .vsel_mask = RK808_LDO_VSEL_MASK, + .enable_reg = RK808_LDO_EN_REG, + .enable_mask = BIT(1), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG3", + .id = RK808_ID_LDO3, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 16, + .linear_ranges = rk808_ldo3_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges), + .vsel_reg = RK808_LDO3_ON_VSEL_REG, + .vsel_mask = RK808_BUCK4_VSEL_MASK, + .enable_reg = RK808_LDO_EN_REG, + .enable_mask = BIT(2), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG4", + .id = RK808_ID_LDO4, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK808_LDO4_ON_VSEL_REG, + .vsel_mask = RK808_LDO_VSEL_MASK, + .enable_reg = RK808_LDO_EN_REG, + .enable_mask = BIT(3), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG5", + .id = RK808_ID_LDO5, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK808_LDO5_ON_VSEL_REG, + .vsel_mask = RK808_LDO_VSEL_MASK, + .enable_reg = RK808_LDO_EN_REG, + .enable_mask = BIT(4), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG6", + .id = RK808_ID_LDO6, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 18, + .linear_ranges = rk808_ldo6_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges), + .vsel_reg = RK808_LDO6_ON_VSEL_REG, + .vsel_mask = RK808_LDO_VSEL_MASK, + .enable_reg = RK808_LDO_EN_REG, + .enable_mask = BIT(5), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG7", + .id = RK808_ID_LDO7, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 18, + .linear_ranges = rk808_ldo6_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges), + .vsel_reg = RK808_LDO7_ON_VSEL_REG, + .vsel_mask = RK808_LDO_VSEL_MASK, + .enable_reg = RK808_LDO_EN_REG, + .enable_mask = BIT(6), + .owner = THIS_MODULE, + }, { + .name = "LDO_REG8", + .id = RK808_ID_LDO8, + .ops = &rk808_reg_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 17, + .linear_ranges = rk808_ldo_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges), + .vsel_reg = RK808_LDO8_ON_VSEL_REG, + .vsel_mask = RK808_LDO_VSEL_MASK, + .enable_reg = RK808_LDO_EN_REG, + .enable_mask = BIT(7), + .owner = THIS_MODULE, + }, { + .name = "SWITCH_REG1", + .id = RK808_ID_SWITCH1, + .ops = &rk808_switch_ops, + .type = REGULATOR_VOLTAGE, + .enable_reg = RK808_DCDC_EN_REG, + .enable_mask = BIT(5), + .owner = THIS_MODULE, + }, { + .name = "SWITCH_REG2", + .id = RK808_ID_SWITCH2, + .ops = &rk808_switch_ops, + .type = REGULATOR_VOLTAGE, + .enable_reg = RK808_DCDC_EN_REG, + .enable_mask = BIT(6), + .owner = THIS_MODULE, + }, +}; + +static struct of_regulator_match rk808_reg_matches[] = { + [RK808_ID_DCDC1] = { .name = "DCDC_REG1" }, + [RK808_ID_DCDC2] = { .name = "DCDC_REG2" }, + [RK808_ID_DCDC3] = { .name = "DCDC_REG3" }, + [RK808_ID_DCDC4] = { .name = "DCDC_REG4" }, + [RK808_ID_LDO1] = { .name = "LDO_REG1" }, + [RK808_ID_LDO2] = { .name = "LDO_REG2" }, + [RK808_ID_LDO3] = { .name = "LDO_REG3" }, + [RK808_ID_LDO4] = { .name = "LDO_REG4" }, + [RK808_ID_LDO5] = { .name = "LDO_REG5" }, + [RK808_ID_LDO6] = { .name = "LDO_REG6" }, + [RK808_ID_LDO7] = { .name = "LDO_REG7" }, + [RK808_ID_LDO8] = { .name = "LDO_REG8" }, + [RK808_ID_SWITCH1] = { .name = "SWITCH_REG1" }, + [RK808_ID_SWITCH2] = { .name = "SWITCH_REG2" }, +}; + +static int rk808_regulator_dts(struct rk808 *rk808) +{ + struct rk808_board *pdata = rk808->pdata; + struct device_node *np, *reg_np; + int i, ret; + + np = rk808->dev->of_node; + if (!np) { + dev_err(rk808->dev, "could not find pmic sub-node\n"); + return -ENXIO; + } + + reg_np = of_get_child_by_name(np, "regulators"); + if (!reg_np) + return -ENXIO; + + ret = of_regulator_match(rk808->dev, reg_np, rk808_reg_matches, + RK808_NUM_REGULATORS); + if (ret < 0) { + dev_err(rk808->dev, + "failed to parse regulator data: %d\n", ret); + return ret; + } + + for (i = 0; i < RK808_NUM_REGULATORS; i++) { + if (!rk808_reg_matches[i].init_data || + !rk808_reg_matches[i].of_node) + continue; + + pdata->rk808_init_data[i] = rk808_reg_matches[i].init_data; + pdata->of_node[i] = rk808_reg_matches[i].of_node; + } + + return 0; +} + +static int rk808_regulator_probe(struct platform_device *pdev) +{ + struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); + struct rk808_board *pdata; + struct regulator_config config; + struct regulator_dev *rk808_rdev; + struct regulator_init_data *reg_data; + int i = 0; + int ret = 0; + + dev_dbg(rk808->dev, "%s\n", __func__); + + if (!rk808) { + dev_err(rk808->dev, "%s no rk808\n", __func__); + return -ENODEV; + } + + pdata = rk808->pdata; + if (!pdata) { + dev_warn(rk808->dev, "%s no pdata, create it\n", __func__); + pdata = devm_kzalloc(rk808->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + } + + ret = rk808_regulator_dts(rk808); + if (ret) + return ret; + + rk808->num_regulators = RK808_NUM_REGULATORS; + rk808->rdev = devm_kzalloc(&pdev->dev, RK808_NUM_REGULATORS * + sizeof(struct regulator_dev *), GFP_KERNEL); + if (!rk808->rdev) + return -ENOMEM; + + /* Instantiate the regulators */ + for (i = 0; i < RK808_NUM_REGULATORS; i++) { + reg_data = pdata->rk808_init_data[i]; + if (!reg_data) + continue; + + config.dev = rk808->dev; + config.driver_data = rk808; + config.regmap = rk808->regmap; + + if (rk808->dev->of_node) + config.of_node = pdata->of_node[i]; + + reg_data->supply_regulator = rk808_reg[i].name; + config.init_data = reg_data; + + rk808_rdev = devm_regulator_register(&pdev->dev, + &rk808_reg[i], &config); + if (IS_ERR(rk808_rdev)) { + dev_err(rk808->dev, + "failed to register %d regulator\n", i); + return PTR_ERR(rk808_rdev); + } + rk808->rdev[i] = rk808_rdev; + } + return 0; +} + +static struct platform_driver rk808_regulator_driver = { + .probe = rk808_regulator_probe, + .driver = { + .name = "rk808-regulator", + .owner = THIS_MODULE, + }, +}; + +module_platform_driver(rk808_regulator_driver); + +MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs"); +MODULE_AUTHOR("Chris Zhong"); +MODULE_AUTHOR("Zhang Qing"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:rk808-regulator"); -- GitLab From 734d5a5393ed8eedf70f13c7078cb4a6134f49f2 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 17 Jul 2014 12:45:11 +0900 Subject: [PATCH 1028/9167] usb: dwc3: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 9 +++------ drivers/usb/dwc3/dwc3-exynos.c | 4 +--- drivers/usb/dwc3/dwc3-omap.c | 4 +--- drivers/usb/dwc3/dwc3-pci.c | 4 +--- drivers/usb/dwc3/gadget.c | 11 ++--------- 5 files changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b769c1faaf03..f2050e844b4b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -186,10 +186,8 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned length) dwc->ev_buffs = devm_kzalloc(dwc->dev, sizeof(*dwc->ev_buffs) * num, GFP_KERNEL); - if (!dwc->ev_buffs) { - dev_err(dwc->dev, "can't allocate event buffers array\n"); + if (!dwc->ev_buffs) return -ENOMEM; - } for (i = 0; i < num; i++) { struct dwc3_event_buffer *evt; @@ -639,10 +637,9 @@ static int dwc3_probe(struct platform_device *pdev) void *mem; mem = devm_kzalloc(dev, sizeof(*dwc) + DWC3_ALIGN_MASK, GFP_KERNEL); - if (!mem) { - dev_err(dev, "not enough memory\n"); + if (!mem) return -ENOMEM; - } + dwc = PTR_ALIGN(mem, DWC3_ALIGN_MASK + 1); dwc->mem = mem; dwc->dev = dev; diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index f9fb8adb785b..3951a65fea04 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -113,10 +113,8 @@ static int dwc3_exynos_probe(struct platform_device *pdev) int ret; exynos = devm_kzalloc(dev, sizeof(*exynos), GFP_KERNEL); - if (!exynos) { - dev_err(dev, "not enough memory\n"); + if (!exynos) return -ENOMEM; - } /* * Right now device-tree probed devices don't get dma_mask set. diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index ef4936ff626c..76345aceb4b6 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -481,10 +481,8 @@ static int dwc3_omap_probe(struct platform_device *pdev) } omap = devm_kzalloc(dev, sizeof(*omap), GFP_KERNEL); - if (!omap) { - dev_err(dev, "not enough memory\n"); + if (!omap) return -ENOMEM; - } platform_set_drvdata(pdev, omap); diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index a60bab7dfa0a..436fb08c40b8 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -103,10 +103,8 @@ static int dwc3_pci_probe(struct pci_dev *pci, struct device *dev = &pci->dev; glue = devm_kzalloc(dev, sizeof(*glue), GFP_KERNEL); - if (!glue) { - dev_err(dev, "not enough memory\n"); + if (!glue) return -ENOMEM; - } glue->dev = dev; diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 349cacc577d8..307b5139faf3 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -789,13 +789,10 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep, { struct dwc3_request *req; struct dwc3_ep *dep = to_dwc3_ep(ep); - struct dwc3 *dwc = dep->dwc; req = kzalloc(sizeof(*req), gfp_flags); - if (!req) { - dev_err(dwc->dev, "not enough memory\n"); + if (!req) return NULL; - } req->epnum = dep->number; req->dep = dep; @@ -1743,11 +1740,8 @@ static int dwc3_gadget_init_hw_endpoints(struct dwc3 *dwc, u8 epnum = (i << 1) | (!!direction); dep = kzalloc(sizeof(*dep), GFP_KERNEL); - if (!dep) { - dev_err(dwc->dev, "can't allocate endpoint %d\n", - epnum); + if (!dep) return -ENOMEM; - } dep->dwc = dwc; dep->number = epnum; @@ -2759,7 +2753,6 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->setup_buf = kzalloc(DWC3_EP0_BOUNCE_SIZE, GFP_KERNEL); if (!dwc->setup_buf) { - dev_err(dwc->dev, "failed to allocate setup buffer\n"); ret = -ENOMEM; goto err2; } -- GitLab From 17c128e8c8b06138bb088e48be5a89c27257d405 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 20 Jul 2014 20:30:14 +0800 Subject: [PATCH 1029/9167] usb: gadget: Remove redundant dev_err call in r8a66597_sudmac_ioremap() There is a error message within devm_ioremap_resource already, so remove the dev_err call to avoid redundant error message. Acked-by: Laurent Pinchart Signed-off-by: Wei Yongjun Signed-off-by: Felipe Balbi --- drivers/usb/gadget/udc/r8a66597-udc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index 46008421c1ec..68a7d20b2bd8 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1846,10 +1846,8 @@ 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)) { - dev_err(&pdev->dev, "ioremap error(sudmac).\n"); + if (IS_ERR(r8a66597->sudmac_reg)) return PTR_ERR(r8a66597->sudmac_reg); - } return 0; } -- GitLab From 0dafc3d94596522787e216711d305add1c1dce99 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 4 Aug 2014 10:44:31 +0900 Subject: [PATCH 1030/9167] usb: phy: samsung: Remove unnecessary lines of register bit definitions Remove unnecessary lines of register bit definitions in order to enhance the readability. In this case, there are lines per register offset definitions. There is no functional change. Signed-off-by: Jingoo Han Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-samsung-usb.h | 36 ++----------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/drivers/usb/phy/phy-samsung-usb.h b/drivers/usb/phy/phy-samsung-usb.h index 68771bfd1825..4eef45555971 100644 --- a/drivers/usb/phy/phy-samsung-usb.h +++ b/drivers/usb/phy/phy-samsung-usb.h @@ -21,7 +21,6 @@ /* Register definitions */ #define SAMSUNG_PHYPWR (0x00) - #define PHYPWR_NORMAL_MASK (0x19 << 0) #define PHYPWR_OTG_DISABLE (0x1 << 4) #define PHYPWR_ANALOG_POWERDOWN (0x1 << 3) @@ -31,7 +30,6 @@ #define PHYPWR_SLEEP_PHY0 (0x1 << 5) #define SAMSUNG_PHYCLK (0x04) - #define PHYCLK_MODE_USB11 (0x1 << 6) #define PHYCLK_EXT_OSC (0x1 << 5) #define PHYCLK_COMMON_ON_N (0x1 << 4) @@ -42,7 +40,6 @@ #define PHYCLK_CLKSEL_24M (0x3 << 0) #define SAMSUNG_RSTCON (0x08) - #define RSTCON_PHYLINK_SWRST (0x1 << 2) #define RSTCON_HLINK_SWRST (0x1 << 1) #define RSTCON_SWRST (0x1 << 0) @@ -50,26 +47,20 @@ /* EXYNOS4X12 */ #define EXYNOS4X12_PHY_HSIC_CTRL0 (0x04) #define EXYNOS4X12_PHY_HSIC_CTRL1 (0x08) - #define PHYPWR_NORMAL_MASK_HSIC1 (0x7 << 12) #define PHYPWR_NORMAL_MASK_HSIC0 (0x7 << 9) #define PHYPWR_NORMAL_MASK_PHY1 (0x7 << 6) - #define RSTCON_HOSTPHY_SWRST (0xf << 3) /* EXYNOS5 */ #define EXYNOS5_PHY_HOST_CTRL0 (0x00) - #define HOST_CTRL0_PHYSWRSTALL (0x1 << 31) - #define HOST_CTRL0_REFCLKSEL_MASK (0x3 << 19) #define HOST_CTRL0_REFCLKSEL_XTAL (0x0 << 19) #define HOST_CTRL0_REFCLKSEL_EXTL (0x1 << 19) #define HOST_CTRL0_REFCLKSEL_CLKCORE (0x2 << 19) - #define HOST_CTRL0_FSEL_MASK (0x7 << 16) #define HOST_CTRL0_FSEL(_x) ((_x) << 16) - #define FSEL_CLKSEL_50M (0x7) #define FSEL_CLKSEL_24M (0x5) #define FSEL_CLKSEL_20M (0x4) @@ -77,7 +68,6 @@ #define FSEL_CLKSEL_12M (0x2) #define FSEL_CLKSEL_10M (0x1) #define FSEL_CLKSEL_9600K (0x0) - #define HOST_CTRL0_TESTBURNIN (0x1 << 11) #define HOST_CTRL0_RETENABLE (0x1 << 10) #define HOST_CTRL0_COMMONON_N (0x1 << 9) @@ -98,10 +88,8 @@ #define EXYNOS5_PHY_HSIC_CTRL2 (0x20) #define EXYNOS5_PHY_HSIC_TUNE2 (0x24) - #define HSIC_CTRL_REFCLKSEL_MASK (0x3 << 23) #define HSIC_CTRL_REFCLKSEL (0x2 << 23) - #define HSIC_CTRL_REFCLKDIV_MASK (0x7f << 16) #define HSIC_CTRL_REFCLKDIV(_x) ((_x) << 16) #define HSIC_CTRL_REFCLKDIV_12 (0x24 << 16) @@ -109,7 +97,6 @@ #define HSIC_CTRL_REFCLKDIV_16 (0x1a << 16) #define HSIC_CTRL_REFCLKDIV_19_2 (0x15 << 16) #define HSIC_CTRL_REFCLKDIV_20 (0x14 << 16) - #define HSIC_CTRL_SIDDQ (0x1 << 6) #define HSIC_CTRL_FORCESLEEP (0x1 << 5) #define HSIC_CTRL_FORCESUSPEND (0x1 << 4) @@ -118,36 +105,29 @@ #define HSIC_CTRL_PHYSWRST (0x1 << 0) #define EXYNOS5_PHY_HOST_EHCICTRL (0x30) - #define HOST_EHCICTRL_ENAINCRXALIGN (0x1 << 29) #define HOST_EHCICTRL_ENAINCR4 (0x1 << 28) #define HOST_EHCICTRL_ENAINCR8 (0x1 << 27) #define HOST_EHCICTRL_ENAINCR16 (0x1 << 26) #define EXYNOS5_PHY_HOST_OHCICTRL (0x34) - #define HOST_OHCICTRL_SUSPLGCY (0x1 << 3) #define HOST_OHCICTRL_APPSTARTCLK (0x1 << 2) #define HOST_OHCICTRL_CNTSEL (0x1 << 1) #define HOST_OHCICTRL_CLKCKTRST (0x1 << 0) #define EXYNOS5_PHY_OTG_SYS (0x38) - #define OTG_SYS_PHYLINK_SWRESET (0x1 << 14) #define OTG_SYS_LINKSWRST_UOTG (0x1 << 13) #define OTG_SYS_PHY0_SWRST (0x1 << 12) - #define OTG_SYS_REFCLKSEL_MASK (0x3 << 9) #define OTG_SYS_REFCLKSEL_XTAL (0x0 << 9) #define OTG_SYS_REFCLKSEL_EXTL (0x1 << 9) #define OTG_SYS_REFCLKSEL_CLKCORE (0x2 << 9) - #define OTG_SYS_IDPULLUP_UOTG (0x1 << 8) #define OTG_SYS_COMMON_ON (0x1 << 7) - #define OTG_SYS_FSEL_MASK (0x7 << 4) #define OTG_SYS_FSEL(_x) ((_x) << 4) - #define OTG_SYS_FORCESLEEP (0x1 << 3) #define OTG_SYS_OTGDISABLE (0x1 << 2) #define OTG_SYS_SIDDQ_UOTG (0x1 << 1) @@ -157,13 +137,11 @@ /* EXYNOS5: USB 3.0 DRD */ #define EXYNOS5_DRD_LINKSYSTEM (0x04) - #define LINKSYSTEM_FLADJ_MASK (0x3f << 1) #define LINKSYSTEM_FLADJ(_x) ((_x) << 1) #define LINKSYSTEM_XHCI_VERSION_CONTROL (0x1 << 27) #define EXYNOS5_DRD_PHYUTMI (0x08) - #define PHYUTMI_OTGDISABLE (0x1 << 6) #define PHYUTMI_FORCESUSPEND (0x1 << 1) #define PHYUTMI_FORCESLEEP (0x1 << 0) @@ -171,68 +149,58 @@ #define EXYNOS5_DRD_PHYPIPE (0x0c) #define EXYNOS5_DRD_PHYCLKRST (0x10) - #define PHYCLKRST_SSC_REFCLKSEL_MASK (0xff << 23) #define PHYCLKRST_SSC_REFCLKSEL(_x) ((_x) << 23) - #define PHYCLKRST_SSC_RANGE_MASK (0x03 << 21) #define PHYCLKRST_SSC_RANGE(_x) ((_x) << 21) - #define PHYCLKRST_SSC_EN (0x1 << 20) #define PHYCLKRST_REF_SSP_EN (0x1 << 19) #define PHYCLKRST_REF_CLKDIV2 (0x1 << 18) - #define PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11) #define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF (0x19 << 11) #define PHYCLKRST_MPLL_MULTIPLIER_50M_REF (0x02 << 11) #define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF (0x68 << 11) #define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF (0x7d << 11) #define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF (0x02 << 11) - #define PHYCLKRST_FSEL_MASK (0x3f << 5) #define PHYCLKRST_FSEL(_x) ((_x) << 5) #define PHYCLKRST_FSEL_PAD_100MHZ (0x27 << 5) #define PHYCLKRST_FSEL_PAD_24MHZ (0x2a << 5) #define PHYCLKRST_FSEL_PAD_20MHZ (0x31 << 5) #define PHYCLKRST_FSEL_PAD_19_2MHZ (0x38 << 5) - #define PHYCLKRST_RETENABLEN (0x1 << 4) - #define PHYCLKRST_REFCLKSEL_MASK (0x03 << 2) #define PHYCLKRST_REFCLKSEL_PAD_REFCLK (0x2 << 2) #define PHYCLKRST_REFCLKSEL_EXT_REFCLK (0x3 << 2) - #define PHYCLKRST_PORTRESET (0x1 << 1) #define PHYCLKRST_COMMONONN (0x1 << 0) #define EXYNOS5_DRD_PHYREG0 (0x14) + #define EXYNOS5_DRD_PHYREG1 (0x18) #define EXYNOS5_DRD_PHYPARAM0 (0x1c) - #define PHYPARAM0_REF_USE_PAD (0x1 << 31) #define PHYPARAM0_REF_LOSLEVEL_MASK (0x1f << 26) #define PHYPARAM0_REF_LOSLEVEL (0x9 << 26) #define EXYNOS5_DRD_PHYPARAM1 (0x20) - #define PHYPARAM1_PCS_TXDEEMPH_MASK (0x1f << 0) #define PHYPARAM1_PCS_TXDEEMPH (0x1c) #define EXYNOS5_DRD_PHYTERM (0x24) #define EXYNOS5_DRD_PHYTEST (0x28) - #define PHYTEST_POWERDOWN_SSP (0x1 << 3) #define PHYTEST_POWERDOWN_HSP (0x1 << 2) #define EXYNOS5_DRD_PHYADP (0x2c) #define EXYNOS5_DRD_PHYBATCHG (0x30) - #define PHYBATCHG_UTMI_CLKSEL (0x1 << 2) #define EXYNOS5_DRD_PHYRESUME (0x34) + #define EXYNOS5_DRD_LINKPORT (0x44) #ifndef MHZ -- GitLab From 8f90afd918886f10ac82aded9a30edfd80f2f69b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 20 Aug 2014 13:38:18 -0500 Subject: [PATCH 1031/9167] usb: phy: msm: mark msm_otg_mode_fops static that declaration is only used inside this driver, marking it static. Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index e4108eec5ef4..df8e1ba56509 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1394,7 +1394,7 @@ static ssize_t msm_otg_mode_write(struct file *file, const char __user *ubuf, return status; } -const struct file_operations msm_otg_mode_fops = { +static const struct file_operations msm_otg_mode_fops = { .open = msm_otg_mode_open, .read = seq_read, .write = msm_otg_mode_write, -- GitLab From 5d73abf2a77a090ca4c920ac99c8ec0e272398a9 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:29 +0200 Subject: [PATCH 1032/9167] usb: gadget: audio: Use container_of to free audio_dev Eliminate static struct *agdev_g from f_uac2.c. It is used for freeing its memory, but the same address can be found by calling container_of in afunc_unbind(). This implies eliminating uac2_unbind_config(). The audio_config_driver in audio.c does not have its unbind method any more. It has been used only when uac2 is used, so uac2 itself can handle unbinding in afunc_unbind(). Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac2.c | 35 +++++++++++----------------- drivers/usb/gadget/legacy/audio.c | 3 --- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 3ed89ecc8d6d..91615619c204 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -149,8 +149,6 @@ struct audio_dev { struct snd_uac2_chip uac2; }; -static struct audio_dev *agdev_g; - static inline struct audio_dev *func_to_agdev(struct usb_function *f) { @@ -1039,6 +1037,7 @@ afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn) agdev->in_ep->driver_data = NULL; if (agdev->out_ep) agdev->out_ep->driver_data = NULL; + kfree(agdev); } static int @@ -1311,10 +1310,11 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr) static int audio_bind_config(struct usb_configuration *cfg) { + struct audio_dev *agdev; int res; - agdev_g = kzalloc(sizeof *agdev_g, GFP_KERNEL); - if (agdev_g == NULL) + agdev = kzalloc(sizeof(*agdev), GFP_KERNEL); + if (agdev == NULL) return -ENOMEM; res = usb_string_ids_tab(cfg->cdev, strings_fn); @@ -1333,14 +1333,14 @@ static int audio_bind_config(struct usb_configuration *cfg) std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id; std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id; - agdev_g->func.name = "uac2_func"; - agdev_g->func.strings = fn_strings; - agdev_g->func.bind = afunc_bind; - agdev_g->func.unbind = afunc_unbind; - agdev_g->func.set_alt = afunc_set_alt; - agdev_g->func.get_alt = afunc_get_alt; - agdev_g->func.disable = afunc_disable; - agdev_g->func.setup = afunc_setup; + agdev->func.name = "uac2_func"; + agdev->func.strings = fn_strings; + agdev->func.bind = afunc_bind; + agdev->func.unbind = afunc_unbind; + agdev->func.set_alt = afunc_set_alt; + agdev->func.get_alt = afunc_get_alt; + agdev->func.disable = afunc_disable; + agdev->func.setup = afunc_setup; /* Initialize the configurable parameters */ usb_out_it_desc.bNrChannels = num_channels(c_chmask); @@ -1359,16 +1359,9 @@ static int audio_bind_config(struct usb_configuration *cfg) snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", p_srate); snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", c_srate); - res = usb_add_function(cfg, &agdev_g->func); + res = usb_add_function(cfg, &agdev->func); if (res < 0) - kfree(agdev_g); + kfree(agdev); return res; } - -static void -uac2_unbind_config(struct usb_configuration *cfg) -{ - kfree(agdev_g); - agdev_g = NULL; -} diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index 6eb695e5e43a..3c2328316c05 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -126,9 +126,6 @@ static struct usb_configuration audio_config_driver = { .bConfigurationValue = 1, /* .iConfiguration = DYNAMIC */ .bmAttributes = USB_CONFIG_ATT_SELFPOWER, -#ifndef CONFIG_GADGET_UAC1 - .unbind = uac2_unbind_config, -#endif }; /*-------------------------------------------------------------------------*/ -- GitLab From f8f93d244afad804e09595fcb14320fe2896fef5 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:30 +0200 Subject: [PATCH 1033/9167] usb: gadget: f_uac2: convert to new function interface with backward compatibility Converting uac2 to the new function interface requires converting the USB uac2's function code and its users. This patch converts the f_uac2.c to the new function interface. The file is now compiled into a separate usb_f_uac2.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. Tested-by: Sebastian Reimers 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_uac2.c | 244 ++++++++++++++++++++++----- drivers/usb/gadget/function/u_uac2.h | 32 ++++ drivers/usb/gadget/legacy/audio.c | 1 + 5 files changed, 242 insertions(+), 40 deletions(-) create mode 100644 drivers/usb/gadget/function/u_uac2.h diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 5c822afb6d70..ea8ebce60d8f 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -181,6 +181,9 @@ config USB_F_MASS_STORAGE config USB_F_FS tristate +config USB_F_UAC2 + tristate + choice tristate "USB Gadget Drivers" default USB_ETH diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 6d91f21b52a6..20775a87e51a 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -32,3 +32,5 @@ usb_f_mass_storage-y := f_mass_storage.o storage_common.o obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o usb_f_fs-y := f_fs.o obj-$(CONFIG_USB_F_FS) += usb_f_fs.o +usb_f_uac2-y := f_uac2.o +obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 91615619c204..29b477fa2050 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -20,6 +20,10 @@ #include #include +#include "u_uac2.h" + +#ifdef USB_FUAC2_INCLUDED + /* Playback(USB-IN) Default Stereo - Fl/Fr */ static int p_chmask = 0x3; module_param(p_chmask, uint, S_IRUGO); @@ -50,6 +54,8 @@ static int c_ssize = 2; module_param(c_ssize, uint, S_IRUGO); MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); +#endif + /* Keep everyone on toes */ #define USB_XFERS 2 @@ -340,6 +346,22 @@ static int uac2_pcm_open(struct snd_pcm_substream *substream) { struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; +#ifndef USB_FUAC2_INCLUDED + struct audio_dev *audio_dev; + struct f_uac2_opts *opts; + int p_ssize, c_ssize; + int p_srate, c_srate; + int p_chmask, c_chmask; + + audio_dev = uac2_to_agdev(uac2); + opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); + p_ssize = opts->p_ssize; + c_ssize = opts->c_ssize; + p_srate = opts->p_srate; + c_srate = opts->c_srate; + p_chmask = opts->p_chmask; + c_chmask = opts->c_chmask; +#endif runtime->hw = uac2_pcm_hardware; @@ -409,7 +431,19 @@ static int snd_uac2_probe(struct platform_device *pdev) struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); struct snd_card *card; struct snd_pcm *pcm; +#ifndef USB_FUAC2_INCLUDED + struct audio_dev *audio_dev; + struct f_uac2_opts *opts; +#endif int err; +#ifndef USB_FUAC2_INCLUDED + int p_chmask, c_chmask; + + audio_dev = uac2_to_agdev(uac2); + opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); + p_chmask = opts->p_chmask; + c_chmask = opts->c_chmask; +#endif /* Choose any slot, with no id */ err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); @@ -917,7 +951,7 @@ free_ep(struct uac2_rtd_params *prm, struct usb_ep *ep) "%s:%d Error!\n", __func__, __LINE__); } -static int __init +static int afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) { struct audio_dev *agdev = func_to_agdev(fn); @@ -925,8 +959,50 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) struct usb_composite_dev *cdev = cfg->cdev; struct usb_gadget *gadget = cdev->gadget; struct uac2_rtd_params *prm; +#ifndef USB_FUAC2_INCLUDED + struct f_uac2_opts *uac2_opts; +#endif int ret; +#ifndef USB_FUAC2_INCLUDED + uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst); +#endif + + ret = usb_string_ids_tab(cfg->cdev, strings_fn); + if (ret) + return ret; + iad_desc.iFunction = strings_fn[STR_ASSOC].id; + std_ac_if_desc.iInterface = strings_fn[STR_IF_CTRL].id; + in_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_IN].id; + out_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_OUT].id; + usb_out_it_desc.iTerminal = strings_fn[STR_USB_IT].id; + io_in_it_desc.iTerminal = strings_fn[STR_IO_IT].id; + usb_in_ot_desc.iTerminal = strings_fn[STR_USB_OT].id; + io_out_ot_desc.iTerminal = strings_fn[STR_IO_OT].id; + std_as_out_if0_desc.iInterface = strings_fn[STR_AS_OUT_ALT0].id; + std_as_out_if1_desc.iInterface = strings_fn[STR_AS_OUT_ALT1].id; + std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id; + std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id; + +#ifndef USB_FUAC2_INCLUDED + /* Initialize the configurable parameters */ + usb_out_it_desc.bNrChannels = num_channels(uac2_opts->c_chmask); + usb_out_it_desc.bmChannelConfig = cpu_to_le32(uac2_opts->c_chmask); + io_in_it_desc.bNrChannels = num_channels(uac2_opts->p_chmask); + io_in_it_desc.bmChannelConfig = cpu_to_le32(uac2_opts->p_chmask); + as_out_hdr_desc.bNrChannels = num_channels(uac2_opts->c_chmask); + as_out_hdr_desc.bmChannelConfig = cpu_to_le32(uac2_opts->c_chmask); + as_in_hdr_desc.bNrChannels = num_channels(uac2_opts->p_chmask); + as_in_hdr_desc.bmChannelConfig = cpu_to_le32(uac2_opts->p_chmask); + as_out_fmt1_desc.bSubslotSize = uac2_opts->c_ssize; + as_out_fmt1_desc.bBitResolution = uac2_opts->c_ssize * 8; + as_in_fmt1_desc.bSubslotSize = uac2_opts->p_ssize; + as_in_fmt1_desc.bBitResolution = uac2_opts->p_ssize * 8; + + snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", uac2_opts->p_srate); + snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", uac2_opts->c_srate); +#endif + ret = usb_interface_id(cfg, fn); if (ret < 0) { dev_err(&uac2->pdev.dev, @@ -1018,28 +1094,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) return -EINVAL; } -static void -afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn) -{ - struct audio_dev *agdev = func_to_agdev(fn); - struct uac2_rtd_params *prm; - - alsa_uac2_exit(agdev); - - prm = &agdev->uac2.p_prm; - kfree(prm->rbuf); - - prm = &agdev->uac2.c_prm; - kfree(prm->rbuf); - usb_free_all_descriptors(fn); - - if (agdev->in_ep) - agdev->in_ep->driver_data = NULL; - if (agdev->out_ep) - agdev->out_ep->driver_data = NULL; - kfree(agdev); -} - static int afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt) { @@ -1163,12 +1217,22 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) struct usb_request *req = fn->config->cdev->req; struct audio_dev *agdev = func_to_agdev(fn); struct snd_uac2_chip *uac2 = &agdev->uac2; +#ifndef USB_FUAC2_INCLUDED + struct f_uac2_opts *opts; +#endif u16 w_length = le16_to_cpu(cr->wLength); u16 w_index = le16_to_cpu(cr->wIndex); u16 w_value = le16_to_cpu(cr->wValue); u8 entity_id = (w_index >> 8) & 0xff; u8 control_selector = w_value >> 8; int value = -EOPNOTSUPP; +#ifndef USB_FUAC2_INCLUDED + int p_srate, c_srate; + + opts = container_of(agdev->func.fi, struct f_uac2_opts, func_inst); + p_srate = opts->p_srate; + c_srate = opts->c_srate; +#endif if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { struct cntrl_cur_lay3 c; @@ -1198,6 +1262,9 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) struct usb_request *req = fn->config->cdev->req; struct audio_dev *agdev = func_to_agdev(fn); struct snd_uac2_chip *uac2 = &agdev->uac2; +#ifndef USB_FUAC2_INCLUDED + struct f_uac2_opts *opts; +#endif u16 w_length = le16_to_cpu(cr->wLength); u16 w_index = le16_to_cpu(cr->wIndex); u16 w_value = le16_to_cpu(cr->wValue); @@ -1205,6 +1272,13 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) u8 control_selector = w_value >> 8; struct cntrl_range_lay3 r; int value = -EOPNOTSUPP; +#ifndef USB_FUAC2_INCLUDED + int p_srate, c_srate; + + opts = container_of(agdev->func.fi, struct f_uac2_opts, func_inst); + p_srate = opts->p_srate; + c_srate = opts->c_srate; +#endif if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { if (entity_id == USB_IN_CLK_ID) @@ -1308,6 +1382,30 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr) return value; } +#ifdef USB_FUAC2_INCLUDED + +static void +old_afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn) +{ + struct audio_dev *agdev = func_to_agdev(fn); + struct uac2_rtd_params *prm; + + alsa_uac2_exit(agdev); + + prm = &agdev->uac2.p_prm; + kfree(prm->rbuf); + + prm = &agdev->uac2.c_prm; + kfree(prm->rbuf); + usb_free_all_descriptors(fn); + + if (agdev->in_ep) + agdev->in_ep->driver_data = NULL; + if (agdev->out_ep) + agdev->out_ep->driver_data = NULL; + kfree(agdev); +} + static int audio_bind_config(struct usb_configuration *cfg) { struct audio_dev *agdev; @@ -1317,26 +1415,10 @@ static int audio_bind_config(struct usb_configuration *cfg) if (agdev == NULL) return -ENOMEM; - res = usb_string_ids_tab(cfg->cdev, strings_fn); - if (res) - return res; - iad_desc.iFunction = strings_fn[STR_ASSOC].id; - std_ac_if_desc.iInterface = strings_fn[STR_IF_CTRL].id; - in_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_IN].id; - out_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_OUT].id; - usb_out_it_desc.iTerminal = strings_fn[STR_USB_IT].id; - io_in_it_desc.iTerminal = strings_fn[STR_IO_IT].id; - usb_in_ot_desc.iTerminal = strings_fn[STR_USB_OT].id; - io_out_ot_desc.iTerminal = strings_fn[STR_IO_OT].id; - std_as_out_if0_desc.iInterface = strings_fn[STR_AS_OUT_ALT0].id; - std_as_out_if1_desc.iInterface = strings_fn[STR_AS_OUT_ALT1].id; - std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id; - std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id; - agdev->func.name = "uac2_func"; agdev->func.strings = fn_strings; agdev->func.bind = afunc_bind; - agdev->func.unbind = afunc_unbind; + agdev->func.unbind = old_afunc_unbind; agdev->func.set_alt = afunc_set_alt; agdev->func.get_alt = afunc_get_alt; agdev->func.disable = afunc_disable; @@ -1365,3 +1447,85 @@ static int audio_bind_config(struct usb_configuration *cfg) return res; } + +#else + +static void afunc_free_inst(struct usb_function_instance *f) +{ + struct f_uac2_opts *opts; + + opts = container_of(f, struct f_uac2_opts, func_inst); + kfree(opts); +} + +static struct usb_function_instance *afunc_alloc_inst(void) +{ + struct f_uac2_opts *opts; + + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) + return ERR_PTR(-ENOMEM); + + opts->func_inst.free_func_inst = afunc_free_inst; + + return &opts->func_inst; +} + +static void afunc_free(struct usb_function *f) +{ + struct audio_dev *agdev; + + agdev = func_to_agdev(f); + kfree(agdev); +} + +static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) +{ + struct audio_dev *agdev = func_to_agdev(f); + struct uac2_rtd_params *prm; + + alsa_uac2_exit(agdev); + + prm = &agdev->uac2.p_prm; + kfree(prm->rbuf); + + prm = &agdev->uac2.c_prm; + kfree(prm->rbuf); + usb_free_all_descriptors(f); + + if (agdev->in_ep) + agdev->in_ep->driver_data = NULL; + if (agdev->out_ep) + agdev->out_ep->driver_data = NULL; +} + +struct usb_function *afunc_alloc(struct usb_function_instance *fi) +{ + struct audio_dev *agdev; + struct f_uac2_opts *opts; + + agdev = kzalloc(sizeof(*agdev), GFP_KERNEL); + if (agdev == NULL) + return ERR_PTR(-ENOMEM); + + opts = container_of(fi, struct f_uac2_opts, func_inst); + + agdev->func.name = "uac2_func"; + agdev->func.strings = fn_strings; + agdev->func.bind = afunc_bind; + agdev->func.unbind = afunc_unbind; + agdev->func.set_alt = afunc_set_alt; + agdev->func.get_alt = afunc_get_alt; + agdev->func.disable = afunc_disable; + agdev->func.setup = afunc_setup; + agdev->func.free_func = afunc_free; + + return &agdev->func; +} + +DECLARE_USB_FUNCTION_INIT(uac2, afunc_alloc_inst, afunc_alloc); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Yadwinder Singh"); +MODULE_AUTHOR("Jaswinder Singh"); + +#endif diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h new file mode 100644 index 000000000000..290b83af1b69 --- /dev/null +++ b/drivers/usb/gadget/function/u_uac2.h @@ -0,0 +1,32 @@ +/* + * u_uac2.h + * + * Utility definitions for UAC2 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_UAC2_H +#define U_UAC2_H + +#include + +struct f_uac2_opts { + struct usb_function_instance func_inst; + int p_chmask; + int p_srate; + int p_ssize; + int c_chmask; + int c_srate; + int c_ssize; + bool bound; +}; + +#endif diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index 3c2328316c05..a41316bb436a 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -45,6 +45,7 @@ static struct usb_gadget_strings *audio_strings[] = { #include "u_uac1.c" #include "f_uac1.c" #else +#define USB_FUAC2_INCLUDED #include "f_uac2.c" #endif -- GitLab From ad94ac0cfdb6e28a2b0da740d2482a7306e947c3 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:31 +0200 Subject: [PATCH 1034/9167] usb: gadget: audio: convert to new interface of f_uac2 Use the new interface so that the old one can be removed. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/Kconfig | 1 + drivers/usb/gadget/legacy/audio.c | 85 ++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index aa376f006333..172a6a396fe2 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -54,6 +54,7 @@ config USB_AUDIO depends on SND select USB_LIBCOMPOSITE select SND_PCM + select USB_F_UAC2 if !GADGET_UAC1 help This Gadget Audio driver is compatible with USB Audio Class specification 2.0. It implements 1 AudioControl interface, diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index a41316bb436a..159af0345986 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -21,6 +21,38 @@ USB_GADGET_COMPOSITE_OPTIONS(); +#ifndef CONFIG_GADGET_UAC1 +/* Playback(USB-IN) Default Stereo - Fl/Fr */ +static int p_chmask = 0x3; +module_param(p_chmask, uint, S_IRUGO); +MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); + +/* Playback Default 48 KHz */ +static int p_srate = 48000; +module_param(p_srate, uint, S_IRUGO); +MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); + +/* Playback Default 16bits/sample */ +static int p_ssize = 2; +module_param(p_ssize, uint, S_IRUGO); +MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)"); + +/* Capture(USB-OUT) Default Stereo - Fl/Fr */ +static int c_chmask = 0x3; +module_param(c_chmask, uint, S_IRUGO); +MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); + +/* Capture Default 64 KHz */ +static int c_srate = 64000; +module_param(c_srate, uint, S_IRUGO); +MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); + +/* Capture Default 16bits/sample */ +static int c_ssize = 2; +module_param(c_ssize, uint, S_IRUGO); +MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); +#endif + /* string IDs are assigned dynamically */ static struct usb_string strings_dev[] = { @@ -40,13 +72,17 @@ static struct usb_gadget_strings *audio_strings[] = { NULL, }; +#ifndef CONFIG_GADGET_UAC1 +static struct usb_function_instance *fi_uac2; +static struct usb_function *f_uac2; +#endif + #ifdef CONFIG_GADGET_UAC1 #include "u_uac1.h" #include "u_uac1.c" #include "f_uac1.c" #else -#define USB_FUAC2_INCLUDED -#include "f_uac2.c" +#include "u_uac2.h" #endif /*-------------------------------------------------------------------------*/ @@ -110,6 +146,10 @@ static const struct usb_descriptor_header *otg_desc[] = { static int __init audio_do_config(struct usb_configuration *c) { +#ifndef CONFIG_GADGET_UAC1 + int status; +#endif + /* FIXME alloc iConfiguration string, set it in c->strings */ if (gadget_is_otg(c->cdev->gadget)) { @@ -117,7 +157,21 @@ static int __init audio_do_config(struct usb_configuration *c) c->bmAttributes |= USB_CONFIG_ATT_WAKEUP; } +#ifdef CONFIG_GADGET_UAC1 audio_bind_config(c); +#else + f_uac2 = usb_get_function(fi_uac2); + if (IS_ERR(f_uac2)) { + status = PTR_ERR(f_uac2); + return status; + } + + status = usb_add_function(c, f_uac2); + if (status < 0) { + usb_put_function(f_uac2); + return status; + } +#endif return 0; } @@ -133,8 +187,27 @@ static struct usb_configuration audio_config_driver = { static int __init audio_bind(struct usb_composite_dev *cdev) { +#ifndef CONFIG_GADGET_UAC1 + struct f_uac2_opts *uac2_opts; +#endif int status; +#ifndef CONFIG_GADGET_UAC1 + fi_uac2 = usb_get_function_instance("uac2"); + if (IS_ERR(fi_uac2)) + return PTR_ERR(fi_uac2); +#endif + +#ifndef CONFIG_GADGET_UAC1 + uac2_opts = container_of(fi_uac2, struct f_uac2_opts, func_inst); + uac2_opts->p_chmask = p_chmask; + uac2_opts->p_srate = p_srate; + uac2_opts->p_ssize = p_ssize; + uac2_opts->c_chmask = c_chmask; + uac2_opts->c_srate = c_srate; + uac2_opts->c_ssize = c_ssize; +#endif + status = usb_string_ids_tab(cdev, strings_dev); if (status < 0) goto fail; @@ -150,6 +223,9 @@ static int __init audio_bind(struct usb_composite_dev *cdev) return 0; fail: +#ifndef CONFIG_GADGET_UAC1 + usb_put_function_instance(fi_uac2); +#endif return status; } @@ -157,6 +233,11 @@ static int __exit audio_unbind(struct usb_composite_dev *cdev) { #ifdef CONFIG_GADGET_UAC1 gaudio_cleanup(); +#else + if (!IS_ERR_OR_NULL(f_uac2)) + usb_put_function(f_uac2); + if (!IS_ERR_OR_NULL(fi_uac2)) + usb_put_function_instance(fi_uac2); #endif return 0; } -- GitLab From d980039a89fafe03829e4423d0da5d8fd119189d Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:32 +0200 Subject: [PATCH 1035/9167] usb: gadget: f_uac2: remove compatibility layer There are no users of the old interface left, so it can be removed. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac2.c | 124 --------------------------- 1 file changed, 124 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 29b477fa2050..22910373510f 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -22,40 +22,6 @@ #include "u_uac2.h" -#ifdef USB_FUAC2_INCLUDED - -/* Playback(USB-IN) Default Stereo - Fl/Fr */ -static int p_chmask = 0x3; -module_param(p_chmask, uint, S_IRUGO); -MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); - -/* Playback Default 48 KHz */ -static int p_srate = 48000; -module_param(p_srate, uint, S_IRUGO); -MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); - -/* Playback Default 16bits/sample */ -static int p_ssize = 2; -module_param(p_ssize, uint, S_IRUGO); -MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)"); - -/* Capture(USB-OUT) Default Stereo - Fl/Fr */ -static int c_chmask = 0x3; -module_param(c_chmask, uint, S_IRUGO); -MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); - -/* Capture Default 64 KHz */ -static int c_srate = 64000; -module_param(c_srate, uint, S_IRUGO); -MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); - -/* Capture Default 16bits/sample */ -static int c_ssize = 2; -module_param(c_ssize, uint, S_IRUGO); -MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); - -#endif - /* Keep everyone on toes */ #define USB_XFERS 2 @@ -346,7 +312,6 @@ static int uac2_pcm_open(struct snd_pcm_substream *substream) { struct snd_uac2_chip *uac2 = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; -#ifndef USB_FUAC2_INCLUDED struct audio_dev *audio_dev; struct f_uac2_opts *opts; int p_ssize, c_ssize; @@ -361,7 +326,6 @@ static int uac2_pcm_open(struct snd_pcm_substream *substream) c_srate = opts->c_srate; p_chmask = opts->p_chmask; c_chmask = opts->c_chmask; -#endif runtime->hw = uac2_pcm_hardware; @@ -431,19 +395,15 @@ static int snd_uac2_probe(struct platform_device *pdev) struct snd_uac2_chip *uac2 = pdev_to_uac2(pdev); struct snd_card *card; struct snd_pcm *pcm; -#ifndef USB_FUAC2_INCLUDED struct audio_dev *audio_dev; struct f_uac2_opts *opts; -#endif int err; -#ifndef USB_FUAC2_INCLUDED int p_chmask, c_chmask; audio_dev = uac2_to_agdev(uac2); opts = container_of(audio_dev->func.fi, struct f_uac2_opts, func_inst); p_chmask = opts->p_chmask; c_chmask = opts->c_chmask; -#endif /* Choose any slot, with no id */ err = snd_card_new(&pdev->dev, -1, NULL, THIS_MODULE, 0, &card); @@ -959,14 +919,10 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) struct usb_composite_dev *cdev = cfg->cdev; struct usb_gadget *gadget = cdev->gadget; struct uac2_rtd_params *prm; -#ifndef USB_FUAC2_INCLUDED struct f_uac2_opts *uac2_opts; -#endif int ret; -#ifndef USB_FUAC2_INCLUDED uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst); -#endif ret = usb_string_ids_tab(cfg->cdev, strings_fn); if (ret) @@ -984,7 +940,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id; std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id; -#ifndef USB_FUAC2_INCLUDED /* Initialize the configurable parameters */ usb_out_it_desc.bNrChannels = num_channels(uac2_opts->c_chmask); usb_out_it_desc.bmChannelConfig = cpu_to_le32(uac2_opts->c_chmask); @@ -1001,7 +956,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", uac2_opts->p_srate); snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", uac2_opts->c_srate); -#endif ret = usb_interface_id(cfg, fn); if (ret < 0) { @@ -1217,22 +1171,18 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr) struct usb_request *req = fn->config->cdev->req; struct audio_dev *agdev = func_to_agdev(fn); struct snd_uac2_chip *uac2 = &agdev->uac2; -#ifndef USB_FUAC2_INCLUDED struct f_uac2_opts *opts; -#endif u16 w_length = le16_to_cpu(cr->wLength); u16 w_index = le16_to_cpu(cr->wIndex); u16 w_value = le16_to_cpu(cr->wValue); u8 entity_id = (w_index >> 8) & 0xff; u8 control_selector = w_value >> 8; int value = -EOPNOTSUPP; -#ifndef USB_FUAC2_INCLUDED int p_srate, c_srate; opts = container_of(agdev->func.fi, struct f_uac2_opts, func_inst); p_srate = opts->p_srate; c_srate = opts->c_srate; -#endif if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { struct cntrl_cur_lay3 c; @@ -1262,9 +1212,7 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) struct usb_request *req = fn->config->cdev->req; struct audio_dev *agdev = func_to_agdev(fn); struct snd_uac2_chip *uac2 = &agdev->uac2; -#ifndef USB_FUAC2_INCLUDED struct f_uac2_opts *opts; -#endif u16 w_length = le16_to_cpu(cr->wLength); u16 w_index = le16_to_cpu(cr->wIndex); u16 w_value = le16_to_cpu(cr->wValue); @@ -1272,13 +1220,11 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr) u8 control_selector = w_value >> 8; struct cntrl_range_lay3 r; int value = -EOPNOTSUPP; -#ifndef USB_FUAC2_INCLUDED int p_srate, c_srate; opts = container_of(agdev->func.fi, struct f_uac2_opts, func_inst); p_srate = opts->p_srate; c_srate = opts->c_srate; -#endif if (control_selector == UAC2_CS_CONTROL_SAM_FREQ) { if (entity_id == USB_IN_CLK_ID) @@ -1382,74 +1328,6 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr) return value; } -#ifdef USB_FUAC2_INCLUDED - -static void -old_afunc_unbind(struct usb_configuration *cfg, struct usb_function *fn) -{ - struct audio_dev *agdev = func_to_agdev(fn); - struct uac2_rtd_params *prm; - - alsa_uac2_exit(agdev); - - prm = &agdev->uac2.p_prm; - kfree(prm->rbuf); - - prm = &agdev->uac2.c_prm; - kfree(prm->rbuf); - usb_free_all_descriptors(fn); - - if (agdev->in_ep) - agdev->in_ep->driver_data = NULL; - if (agdev->out_ep) - agdev->out_ep->driver_data = NULL; - kfree(agdev); -} - -static int audio_bind_config(struct usb_configuration *cfg) -{ - struct audio_dev *agdev; - int res; - - agdev = kzalloc(sizeof(*agdev), GFP_KERNEL); - if (agdev == NULL) - return -ENOMEM; - - agdev->func.name = "uac2_func"; - agdev->func.strings = fn_strings; - agdev->func.bind = afunc_bind; - agdev->func.unbind = old_afunc_unbind; - agdev->func.set_alt = afunc_set_alt; - agdev->func.get_alt = afunc_get_alt; - agdev->func.disable = afunc_disable; - agdev->func.setup = afunc_setup; - - /* Initialize the configurable parameters */ - usb_out_it_desc.bNrChannels = num_channels(c_chmask); - usb_out_it_desc.bmChannelConfig = cpu_to_le32(c_chmask); - io_in_it_desc.bNrChannels = num_channels(p_chmask); - io_in_it_desc.bmChannelConfig = cpu_to_le32(p_chmask); - as_out_hdr_desc.bNrChannels = num_channels(c_chmask); - as_out_hdr_desc.bmChannelConfig = cpu_to_le32(c_chmask); - as_in_hdr_desc.bNrChannels = num_channels(p_chmask); - as_in_hdr_desc.bmChannelConfig = cpu_to_le32(p_chmask); - as_out_fmt1_desc.bSubslotSize = c_ssize; - as_out_fmt1_desc.bBitResolution = c_ssize * 8; - as_in_fmt1_desc.bSubslotSize = p_ssize; - as_in_fmt1_desc.bBitResolution = p_ssize * 8; - - snprintf(clksrc_in, sizeof(clksrc_in), "%uHz", p_srate); - snprintf(clksrc_out, sizeof(clksrc_out), "%uHz", c_srate); - - res = usb_add_function(cfg, &agdev->func); - if (res < 0) - kfree(agdev); - - return res; -} - -#else - static void afunc_free_inst(struct usb_function_instance *f) { struct f_uac2_opts *opts; @@ -1527,5 +1405,3 @@ DECLARE_USB_FUNCTION_INIT(uac2, afunc_alloc_inst, afunc_alloc); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Yadwinder Singh"); MODULE_AUTHOR("Jaswinder Singh"); - -#endif -- GitLab From f408757f819a5792e6d27865a12f4da4ae802d28 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:33 +0200 Subject: [PATCH 1036/9167] usb: gadget: f_uac2: use usb_gstrings_attach Use the new usb_gstring_attach interface. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac2.c | 33 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 22910373510f..1b9671effa12 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -920,25 +920,27 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) struct usb_gadget *gadget = cdev->gadget; struct uac2_rtd_params *prm; struct f_uac2_opts *uac2_opts; + struct usb_string *us; int ret; uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst); - ret = usb_string_ids_tab(cfg->cdev, strings_fn); - if (ret) - return ret; - iad_desc.iFunction = strings_fn[STR_ASSOC].id; - std_ac_if_desc.iInterface = strings_fn[STR_IF_CTRL].id; - in_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_IN].id; - out_clk_src_desc.iClockSource = strings_fn[STR_CLKSRC_OUT].id; - usb_out_it_desc.iTerminal = strings_fn[STR_USB_IT].id; - io_in_it_desc.iTerminal = strings_fn[STR_IO_IT].id; - usb_in_ot_desc.iTerminal = strings_fn[STR_USB_OT].id; - io_out_ot_desc.iTerminal = strings_fn[STR_IO_OT].id; - std_as_out_if0_desc.iInterface = strings_fn[STR_AS_OUT_ALT0].id; - std_as_out_if1_desc.iInterface = strings_fn[STR_AS_OUT_ALT1].id; - std_as_in_if0_desc.iInterface = strings_fn[STR_AS_IN_ALT0].id; - std_as_in_if1_desc.iInterface = strings_fn[STR_AS_IN_ALT1].id; + us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn)); + if (IS_ERR(us)) + return PTR_ERR(us); + iad_desc.iFunction = us[STR_ASSOC].id; + std_ac_if_desc.iInterface = us[STR_IF_CTRL].id; + in_clk_src_desc.iClockSource = us[STR_CLKSRC_IN].id; + out_clk_src_desc.iClockSource = us[STR_CLKSRC_OUT].id; + usb_out_it_desc.iTerminal = us[STR_USB_IT].id; + io_in_it_desc.iTerminal = us[STR_IO_IT].id; + usb_in_ot_desc.iTerminal = us[STR_USB_OT].id; + io_out_ot_desc.iTerminal = us[STR_IO_OT].id; + std_as_out_if0_desc.iInterface = us[STR_AS_OUT_ALT0].id; + std_as_out_if1_desc.iInterface = us[STR_AS_OUT_ALT1].id; + std_as_in_if0_desc.iInterface = us[STR_AS_IN_ALT0].id; + std_as_in_if1_desc.iInterface = us[STR_AS_IN_ALT1].id; + /* Initialize the configurable parameters */ usb_out_it_desc.bNrChannels = num_channels(uac2_opts->c_chmask); @@ -1389,7 +1391,6 @@ struct usb_function *afunc_alloc(struct usb_function_instance *fi) opts = container_of(fi, struct f_uac2_opts, func_inst); agdev->func.name = "uac2_func"; - agdev->func.strings = fn_strings; agdev->func.bind = afunc_bind; agdev->func.unbind = afunc_unbind; agdev->func.set_alt = afunc_set_alt; -- GitLab From 065a107cdd70f0621011424009b3ecd4e42481b1 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:34 +0200 Subject: [PATCH 1037/9167] usb: gadget: f_uac2: use defined constants as defaults When configfs is integrated the same values will have to be used as defaults. Use symbolic names in order not to duplicate magic numbers. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/u_uac2.h | 7 +++++++ drivers/usb/gadget/legacy/audio.c | 16 ++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index 290b83af1b69..ed7f7361a53e 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -18,6 +18,13 @@ #include +#define UAC2_DEF_PCHMASK 0x3 +#define UAC2_DEF_PSRATE 48000 +#define UAC2_DEF_PSSIZE 2 +#define UAC2_DEF_CCHMASK 0x3 +#define UAC2_DEF_CSRATE 64000 +#define UAC2_DEF_CSSIZE 2 + struct f_uac2_opts { struct usb_function_instance func_inst; int p_chmask; diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index 159af0345986..c28691fbb576 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -22,33 +22,35 @@ USB_GADGET_COMPOSITE_OPTIONS(); #ifndef CONFIG_GADGET_UAC1 +#include "u_uac2.h" + /* Playback(USB-IN) Default Stereo - Fl/Fr */ -static int p_chmask = 0x3; +static int p_chmask = UAC2_DEF_PCHMASK; module_param(p_chmask, uint, S_IRUGO); MODULE_PARM_DESC(p_chmask, "Playback Channel Mask"); /* Playback Default 48 KHz */ -static int p_srate = 48000; +static int p_srate = UAC2_DEF_PSRATE; module_param(p_srate, uint, S_IRUGO); MODULE_PARM_DESC(p_srate, "Playback Sampling Rate"); /* Playback Default 16bits/sample */ -static int p_ssize = 2; +static int p_ssize = UAC2_DEF_PSSIZE; module_param(p_ssize, uint, S_IRUGO); MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)"); /* Capture(USB-OUT) Default Stereo - Fl/Fr */ -static int c_chmask = 0x3; +static int c_chmask = UAC2_DEF_CCHMASK; module_param(c_chmask, uint, S_IRUGO); MODULE_PARM_DESC(c_chmask, "Capture Channel Mask"); /* Capture Default 64 KHz */ -static int c_srate = 64000; +static int c_srate = UAC2_DEF_CSRATE; module_param(c_srate, uint, S_IRUGO); MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); /* Capture Default 16bits/sample */ -static int c_ssize = 2; +static int c_ssize = UAC2_DEF_CSSIZE; module_param(c_ssize, uint, S_IRUGO); MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); #endif @@ -81,8 +83,6 @@ static struct usb_function *f_uac2; #include "u_uac1.h" #include "u_uac1.c" #include "f_uac1.c" -#else -#include "u_uac2.h" #endif /*-------------------------------------------------------------------------*/ -- GitLab From 3aeea3c53e73b972ff07a1d03d6cc07f97de4f2f Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:35 +0200 Subject: [PATCH 1038/9167] usb: gadget: f_uac2: add configfs support Add support for using f_uac2 function as a component of a gadget composed with configfs. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- .../ABI/testing/configfs-usb-gadget-uac2 | 12 ++ drivers/usb/gadget/function/f_uac2.c | 105 ++++++++++++++++++ drivers/usb/gadget/function/u_uac2.h | 3 + 3 files changed, 120 insertions(+) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac2 diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac2 b/Documentation/ABI/testing/configfs-usb-gadget-uac2 new file mode 100644 index 000000000000..2bfdd4efa9bd --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac2 @@ -0,0 +1,12 @@ +What: /config/usb-gadget/gadget/functions/uac2.name +Date: Sep 2014 +KernelVersion: 3.18 +Description: + The attributes: + + c_chmask - capture channel mask + c_srate - capture sampling rate + c_ssize - capture sample size (bytes) + p_chmask - playback channel mask + p_srate - playback sampling rate + p_ssize - playback sample size (bytes) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 1b9671effa12..0d65e7c08a93 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1330,6 +1330,93 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr) return value; } +static inline struct f_uac2_opts *to_f_uac2_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct f_uac2_opts, + func_inst.group); +} + +CONFIGFS_ATTR_STRUCT(f_uac2_opts); +CONFIGFS_ATTR_OPS(f_uac2_opts); + +static void f_uac2_attr_release(struct config_item *item) +{ + struct f_uac2_opts *opts = to_f_uac2_opts(item); + + usb_put_function_instance(&opts->func_inst); +} + +static struct configfs_item_operations f_uac2_item_ops = { + .release = f_uac2_attr_release, + .show_attribute = f_uac2_opts_attr_show, + .store_attribute = f_uac2_opts_attr_store, +}; + +#define UAC2_ATTRIBUTE(name) \ +static ssize_t f_uac2_opts_##name##_show(struct f_uac2_opts *opts, \ + char *page) \ +{ \ + int result; \ + \ + mutex_lock(&opts->lock); \ + result = sprintf(page, "%u\n", opts->name); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_uac2_opts_##name##_store(struct f_uac2_opts *opts, \ + const char *page, size_t len) \ +{ \ + int ret; \ + u32 num; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + ret = kstrtou32(page, 0, &num); \ + if (ret) \ + goto end; \ + \ + opts->name = num; \ + ret = len; \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +static struct f_uac2_opts_attribute f_uac2_opts_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ + f_uac2_opts_##name##_show, \ + f_uac2_opts_##name##_store) + +UAC2_ATTRIBUTE(p_chmask); +UAC2_ATTRIBUTE(p_srate); +UAC2_ATTRIBUTE(p_ssize); +UAC2_ATTRIBUTE(c_chmask); +UAC2_ATTRIBUTE(c_srate); +UAC2_ATTRIBUTE(c_ssize); + +static struct configfs_attribute *f_uac2_attrs[] = { + &f_uac2_opts_p_chmask.attr, + &f_uac2_opts_p_srate.attr, + &f_uac2_opts_p_ssize.attr, + &f_uac2_opts_c_chmask.attr, + &f_uac2_opts_c_srate.attr, + &f_uac2_opts_c_ssize.attr, + NULL, +}; + +static struct config_item_type f_uac2_func_type = { + .ct_item_ops = &f_uac2_item_ops, + .ct_attrs = f_uac2_attrs, + .ct_owner = THIS_MODULE, +}; + static void afunc_free_inst(struct usb_function_instance *f) { struct f_uac2_opts *opts; @@ -1346,17 +1433,32 @@ static struct usb_function_instance *afunc_alloc_inst(void) if (!opts) return ERR_PTR(-ENOMEM); + mutex_init(&opts->lock); opts->func_inst.free_func_inst = afunc_free_inst; + config_group_init_type_name(&opts->func_inst.group, "", + &f_uac2_func_type); + + opts->p_chmask = UAC2_DEF_PCHMASK; + opts->p_srate = UAC2_DEF_PSRATE; + opts->p_ssize = UAC2_DEF_PSSIZE; + opts->c_chmask = UAC2_DEF_CCHMASK; + opts->c_srate = UAC2_DEF_CSRATE; + opts->c_ssize = UAC2_DEF_CSSIZE; return &opts->func_inst; } static void afunc_free(struct usb_function *f) { struct audio_dev *agdev; + struct f_uac2_opts *opts; agdev = func_to_agdev(f); + opts = container_of(f->fi, struct f_uac2_opts, func_inst); kfree(agdev); + mutex_lock(&opts->lock); + --opts->refcnt; + mutex_unlock(&opts->lock); } static void afunc_unbind(struct usb_configuration *c, struct usb_function *f) @@ -1389,6 +1491,9 @@ struct usb_function *afunc_alloc(struct usb_function_instance *fi) return ERR_PTR(-ENOMEM); opts = container_of(fi, struct f_uac2_opts, func_inst); + mutex_lock(&opts->lock); + ++opts->refcnt; + mutex_unlock(&opts->lock); agdev->func.name = "uac2_func"; agdev->func.bind = afunc_bind; diff --git a/drivers/usb/gadget/function/u_uac2.h b/drivers/usb/gadget/function/u_uac2.h index ed7f7361a53e..78dd37279bd4 100644 --- a/drivers/usb/gadget/function/u_uac2.h +++ b/drivers/usb/gadget/function/u_uac2.h @@ -34,6 +34,9 @@ struct f_uac2_opts { int c_srate; int c_ssize; bool bound; + + struct mutex lock; + int refcnt; }; #endif -- GitLab From f73db69f95921512b7cba586066723b500770d1a Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:36 +0200 Subject: [PATCH 1039/9167] usb: gadget: f_uac1: add function strings uac1 function is missing strings. Add them. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac1.c | 51 +++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 2b4c82d84bfc..1c0c4b83cb8f 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -216,6 +216,37 @@ static struct usb_descriptor_header *f_audio_desc[] __initdata = { NULL, }; +enum { + STR_AC_IF, + STR_INPUT_TERMINAL, + STR_INPUT_TERMINAL_CH_NAMES, + STR_FEAT_DESC_0, + STR_OUTPUT_TERMINAL, + STR_AS_IF_ALT0, + STR_AS_IF_ALT1, +}; + +static struct usb_string strings_uac1[] = { + [STR_AC_IF].s = "AC Interface", + [STR_INPUT_TERMINAL].s = "Input terminal", + [STR_INPUT_TERMINAL_CH_NAMES].s = "Channels", + [STR_FEAT_DESC_0].s = "Volume control & mute", + [STR_OUTPUT_TERMINAL].s = "Output terminal", + [STR_AS_IF_ALT0].s = "AS Interface", + [STR_AS_IF_ALT1].s = "AS Interface", + { }, +}; + +static struct usb_gadget_strings str_uac1 = { + .language = 0x0409, /* en-us */ + .strings = strings_uac1, +}; + +static struct usb_gadget_strings *uac1_strings[] = { + &str_uac1, + NULL, +}; + /* * This function is an ALSA sound card following USB Audio Class Spec 1.0. */ @@ -724,6 +755,24 @@ static int __init audio_bind_config(struct usb_configuration *c) struct f_audio *audio; int status; + if (strings_uac1[0].id == 0) { + status = usb_string_ids_tab(c->cdev, strings_uac1); + if (status < 0) + return status; + ac_interface_desc.iInterface = strings_uac1[STR_AC_IF].id; + input_terminal_desc.iTerminal = + strings_uac1[STR_INPUT_TERMINAL].id; + input_terminal_desc.iChannelNames = + strings_uac1[STR_INPUT_TERMINAL_CH_NAMES].id; + feature_unit_desc.iFeature = strings_uac1[STR_FEAT_DESC_0].id; + output_terminal_desc.iTerminal = + strings_uac1[STR_OUTPUT_TERMINAL].id; + as_interface_alt_0_desc.iInterface = + strings_uac1[STR_AS_IF_ALT0].id; + as_interface_alt_1_desc.iInterface = + strings_uac1[STR_AS_IF_ALT1].id; + } + /* allocate and initialize one new instance */ audio = kzalloc(sizeof *audio, GFP_KERNEL); if (!audio) @@ -740,7 +789,7 @@ static int __init audio_bind_config(struct usb_configuration *c) if (status < 0) goto setup_fail; - audio->card.func.strings = audio_strings; + audio->card.func.strings = uac1_strings; audio->card.func.bind = f_audio_bind; audio->card.func.unbind = f_audio_unbind; audio->card.func.set_alt = f_audio_set_alt; -- GitLab From af1a58ca00b3735275c453ebd0b811a71a377470 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:37 +0200 Subject: [PATCH 1040/9167] usb: gadget: f_uac1: prepare for separate compilation Integrating configfs requires converting f_uac1 to new function interface, which in turn requires converting it to the new function interface, which involves separate compilation of f_uac1.c into usb_f_uac1.ko. u_uac1.c contains some module parameters. After this patch is applied they are still a part of the resulting g_audio.ko, but can be guarded with a compatiblity flag which will be removed when no users of the old function interface of f_uac1 are left. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac1.c | 1 + drivers/usb/gadget/legacy/audio.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 1c0c4b83cb8f..9cfaf1de7b90 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -15,6 +15,7 @@ #include #include "u_uac1.h" +#include "u_uac1.c" #define OUT_EP_MAX_PACKET_SIZE 200 static int req_buf_size = OUT_EP_MAX_PACKET_SIZE; diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index c28691fbb576..47a7de71f7fb 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -81,7 +81,6 @@ static struct usb_function *f_uac2; #ifdef CONFIG_GADGET_UAC1 #include "u_uac1.h" -#include "u_uac1.c" #include "f_uac1.c" #endif -- GitLab From f3a3406b3f562f8d15b89979c0ca9e184b269084 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:38 +0200 Subject: [PATCH 1041/9167] usb: gadget: f_uac1: convert to new function interface with backward compatibility Converting uac1 to the new function interface requires converting the USB uac1's function code and its users. This patch converts the f_uac1.c to the new function interface. The file is now compiled into a separate usb_f_uac1.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. Tested-by: Sebastian Reimers 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_uac1.c | 169 ++++++++++++++++++++++----- drivers/usb/gadget/function/u_uac1.c | 31 ++++- drivers/usb/gadget/function/u_uac1.h | 20 ++++ drivers/usb/gadget/legacy/audio.c | 1 + 6 files changed, 195 insertions(+), 31 deletions(-) diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index ea8ebce60d8f..68302aa604be 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -181,6 +181,9 @@ config USB_F_MASS_STORAGE config USB_F_FS tristate +config USB_F_UAC1 + tristate + config USB_F_UAC2 tristate diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile index 20775a87e51a..edb6dfa91932 100644 --- a/drivers/usb/gadget/function/Makefile +++ b/drivers/usb/gadget/function/Makefile @@ -32,5 +32,7 @@ usb_f_mass_storage-y := f_mass_storage.o storage_common.o obj-$(CONFIG_USB_F_MASS_STORAGE)+= usb_f_mass_storage.o usb_f_fs-y := f_fs.o obj-$(CONFIG_USB_F_FS) += usb_f_fs.o +usb_f_uac1-y := f_uac1.o u_uac1.o +obj-$(CONFIG_USB_F_UAC1) += usb_f_uac1.o usb_f_uac2-y := f_uac2.o obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 9cfaf1de7b90..787ed2bc4dd4 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -11,13 +11,17 @@ #include #include +#include #include #include #include "u_uac1.h" +#ifdef USBF_UAC1_INCLUDED #include "u_uac1.c" +#endif #define OUT_EP_MAX_PACKET_SIZE 200 +#ifdef USBF_UAC1_INCLUDED static int req_buf_size = OUT_EP_MAX_PACKET_SIZE; module_param(req_buf_size, int, S_IRUGO); MODULE_PARM_DESC(req_buf_size, "ISO OUT endpoint request buffer size"); @@ -29,6 +33,7 @@ MODULE_PARM_DESC(req_count, "ISO OUT endpoint request count"); static int audio_buf_size = 48000; module_param(audio_buf_size, int, S_IRUGO); MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); +#endif static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); @@ -47,7 +52,7 @@ static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); #define F_AUDIO_NUM_INTERFACES 2 /* B.3.1 Standard AC Interface Descriptor */ -static struct usb_interface_descriptor ac_interface_desc __initdata = { +static struct usb_interface_descriptor ac_interface_desc = { .bLength = USB_DT_INTERFACE_SIZE, .bDescriptorType = USB_DT_INTERFACE, .bNumEndpoints = 0, @@ -189,7 +194,7 @@ static struct usb_endpoint_descriptor as_out_ep_desc = { }; /* Class-specific AS ISO OUT Endpoint Descriptor */ -static struct uac_iso_endpoint_descriptor as_iso_out_desc __initdata = { +static struct uac_iso_endpoint_descriptor as_iso_out_desc = { .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, .bDescriptorType = USB_DT_CS_ENDPOINT, .bDescriptorSubtype = UAC_EP_GENERAL, @@ -198,7 +203,7 @@ static struct uac_iso_endpoint_descriptor as_iso_out_desc __initdata = { .wLockDelay = __constant_cpu_to_le16(1), }; -static struct usb_descriptor_header *f_audio_desc[] __initdata = { +static struct usb_descriptor_header *f_audio_desc[] = { (struct usb_descriptor_header *)&ac_interface_desc, (struct usb_descriptor_header *)&ac_header_desc, @@ -332,8 +337,17 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) struct f_audio *audio = req->context; struct usb_composite_dev *cdev = audio->card.func.config->cdev; struct f_audio_buf *copy_buf = audio->copy_buf; +#ifndef USBF_UAC1_INCLUDED + struct f_uac1_opts *opts; + int audio_buf_size; +#endif int err; +#ifndef USBF_UAC1_INCLUDED + opts = container_of(audio->card.func.fi, struct f_uac1_opts, + func_inst); + audio_buf_size = opts->audio_buf_size; +#endif if (!copy_buf) return -EINVAL; @@ -578,10 +592,21 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; struct usb_ep *out_ep = audio->out_ep; struct usb_request *req; +#ifndef USBF_UAC1_INCLUDED + struct f_uac1_opts *opts; + int req_buf_size, req_count, audio_buf_size; +#endif int i = 0, err = 0; DBG(cdev, "intf %d, alt %d\n", intf, alt); +#ifndef USBF_UAC1_INCLUDED + opts = container_of(f->fi, struct f_uac1_opts, func_inst); + req_buf_size = opts->req_buf_size; + req_count = opts->req_count; + audio_buf_size = opts->audio_buf_size; + +#endif if (intf == 1) { if (alt == 1) { usb_ep_enable(out_ep); @@ -657,13 +682,50 @@ static void f_audio_build_desc(struct f_audio *audio) } /* audio function driver setup/binding */ -static int __init +static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct f_audio *audio = func_to_audio(f); int status; struct usb_ep *ep = NULL; +#ifndef USBF_UAC1_INCLUDED + struct f_uac1_opts *audio_opts; + + audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); + audio->card.gadget = c->cdev->gadget; + audio_opts->card = &audio->card; + /* set up ASLA audio devices */ + if (!audio_opts->bound) { + status = gaudio_setup(&audio->card); + if (status < 0) + return status; + audio_opts->bound = true; + } +#else + audio->card.gadget = c->cdev->gadget; +#endif + if (strings_uac1[0].id == 0) { + status = usb_string_ids_tab(c->cdev, strings_uac1); + if (status < 0) +#ifdef USBF_UAC1_INCLUDED + return status; +#else + goto fail; +#endif + ac_interface_desc.iInterface = strings_uac1[STR_AC_IF].id; + input_terminal_desc.iTerminal = + strings_uac1[STR_INPUT_TERMINAL].id; + input_terminal_desc.iChannelNames = + strings_uac1[STR_INPUT_TERMINAL_CH_NAMES].id; + feature_unit_desc.iFeature = strings_uac1[STR_FEAT_DESC_0].id; + output_terminal_desc.iTerminal = + strings_uac1[STR_OUTPUT_TERMINAL].id; + as_interface_alt_0_desc.iInterface = + strings_uac1[STR_AS_IF_ALT0].id; + as_interface_alt_1_desc.iInterface = + strings_uac1[STR_AS_IF_ALT1].id; + } f_audio_build_desc(audio); @@ -698,19 +760,24 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: +#ifndef USBF_UAC1_INCLUDED + gaudio_cleanup(&audio->card); +#endif if (ep) ep->driver_data = NULL; return status; } +#ifdef USBF_UAC1_INCLUDED static void -f_audio_unbind(struct usb_configuration *c, struct usb_function *f) +old_f_audio_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_audio *audio = func_to_audio(f); usb_free_all_descriptors(f); kfree(audio); } +#endif /*-------------------------------------------------------------------------*/ @@ -727,7 +794,7 @@ static int generic_get_cmd(struct usb_audio_control *con, u8 cmd) } /* Todo: add more control selecotor dynamically */ -static int __init control_selector_init(struct f_audio *audio) +static int control_selector_init(struct f_audio *audio) { INIT_LIST_HEAD(&audio->cs); list_add(&feature_unit.list, &audio->cs); @@ -744,6 +811,7 @@ static int __init control_selector_init(struct f_audio *audio) return 0; } +#ifdef USBF_UAC1_INCLUDED /** * audio_bind_config - add USB audio function to a configuration * @c: the configuration to supcard the USB audio function @@ -756,24 +824,6 @@ static int __init audio_bind_config(struct usb_configuration *c) struct f_audio *audio; int status; - if (strings_uac1[0].id == 0) { - status = usb_string_ids_tab(c->cdev, strings_uac1); - if (status < 0) - return status; - ac_interface_desc.iInterface = strings_uac1[STR_AC_IF].id; - input_terminal_desc.iTerminal = - strings_uac1[STR_INPUT_TERMINAL].id; - input_terminal_desc.iChannelNames = - strings_uac1[STR_INPUT_TERMINAL_CH_NAMES].id; - feature_unit_desc.iFeature = strings_uac1[STR_FEAT_DESC_0].id; - output_terminal_desc.iTerminal = - strings_uac1[STR_OUTPUT_TERMINAL].id; - as_interface_alt_0_desc.iInterface = - strings_uac1[STR_AS_IF_ALT0].id; - as_interface_alt_1_desc.iInterface = - strings_uac1[STR_AS_IF_ALT1].id; - } - /* allocate and initialize one new instance */ audio = kzalloc(sizeof *audio, GFP_KERNEL); if (!audio) @@ -789,10 +839,9 @@ static int __init audio_bind_config(struct usb_configuration *c) status = gaudio_setup(&audio->card); if (status < 0) goto setup_fail; - audio->card.func.strings = uac1_strings; audio->card.func.bind = f_audio_bind; - audio->card.func.unbind = f_audio_unbind; + audio->card.func.unbind = old_f_audio_unbind; audio->card.func.set_alt = f_audio_set_alt; audio->card.func.setup = f_audio_setup; audio->card.func.disable = f_audio_disable; @@ -816,3 +865,71 @@ static int __init audio_bind_config(struct usb_configuration *c) kfree(audio); return status; } +#else +static void f_audio_free_inst(struct usb_function_instance *f) +{ + struct f_uac1_opts *opts; + + opts = container_of(f, struct f_uac1_opts, func_inst); + gaudio_cleanup(opts->card); + kfree(opts); +} + +static struct usb_function_instance *f_audio_alloc_inst(void) +{ + struct f_uac1_opts *opts; + + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) + return ERR_PTR(-ENOMEM); + + opts->func_inst.free_func_inst = f_audio_free_inst; + + return &opts->func_inst; +} + +static void f_audio_free(struct usb_function *f) +{ + struct f_audio *audio = func_to_audio(f); + + kfree(audio); +} + +static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) +{ + usb_free_all_descriptors(f); +} + +static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) +{ + struct f_audio *audio; + + /* allocate and initialize one new instance */ + audio = kzalloc(sizeof(*audio), GFP_KERNEL); + if (!audio) + return ERR_PTR(-ENOMEM); + + audio->card.func.name = "g_audio"; + + INIT_LIST_HEAD(&audio->play_queue); + spin_lock_init(&audio->lock); + + audio->card.func.strings = uac1_strings; + audio->card.func.bind = f_audio_bind; + audio->card.func.unbind = f_audio_unbind; + audio->card.func.set_alt = f_audio_set_alt; + audio->card.func.setup = f_audio_setup; + audio->card.func.disable = f_audio_disable; + audio->card.func.free_func = f_audio_free; + + control_selector_init(audio); + + INIT_WORK(&audio->playback_work, f_audio_playback_work); + + return &audio->card.func; +} + +DECLARE_USB_FUNCTION_INIT(uac1, f_audio_alloc_inst, f_audio_alloc); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Bryan Wu"); +#endif diff --git a/drivers/usb/gadget/function/u_uac1.c b/drivers/usb/gadget/function/u_uac1.c index 7a55fea43430..9a55e5cf4cd8 100644 --- a/drivers/usb/gadget/function/u_uac1.c +++ b/drivers/usb/gadget/function/u_uac1.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -23,6 +24,7 @@ * This component encapsulates the ALSA devices for USB audio gadget */ +#ifdef USBF_UAC1_INCLUDED #define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" #define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" #define FILE_CONTROL "/dev/snd/controlC0" @@ -38,7 +40,7 @@ MODULE_PARM_DESC(fn_cap, "Capture PCM device file name"); static char *fn_cntl = FILE_CONTROL; module_param(fn_cntl, charp, S_IRUGO); MODULE_PARM_DESC(fn_cntl, "Control device file name"); - +#endif /*-------------------------------------------------------------------------*/ /** @@ -167,7 +169,7 @@ static int playback_default_hw_params(struct gaudio_snd_dev *snd) /** * Playback audio buffer data by ALSA PCM device */ -static size_t u_audio_playback(struct gaudio *card, void *buf, size_t count) +size_t u_audio_playback(struct gaudio *card, void *buf, size_t count) { struct gaudio_snd_dev *snd = &card->playback; struct snd_pcm_substream *substream = snd->substream; @@ -202,12 +204,12 @@ static size_t u_audio_playback(struct gaudio *card, void *buf, size_t count) return 0; } -static int u_audio_get_playback_channels(struct gaudio *card) +int u_audio_get_playback_channels(struct gaudio *card) { return card->playback.channels; } -static int u_audio_get_playback_rate(struct gaudio *card) +int u_audio_get_playback_rate(struct gaudio *card) { return card->playback.rate; } @@ -220,6 +222,15 @@ static int gaudio_open_snd_dev(struct gaudio *card) { struct snd_pcm_file *pcm_file; struct gaudio_snd_dev *snd; +#ifndef USBF_UAC1_INCLUDED + struct f_uac1_opts *opts; + char *fn_play, *fn_cap, *fn_cntl; + + opts = container_of(card->func.fi, struct f_uac1_opts, func_inst); + fn_play = opts->fn_play; + fn_cap = opts->fn_cap; + fn_cntl = opts->fn_cntl; +#endif if (!card) return -ENODEV; @@ -293,7 +304,9 @@ static int gaudio_close_snd_dev(struct gaudio *gau) return 0; } +#ifdef USBF_UAC1_INCLUDED static struct gaudio *the_card; +#endif /** * gaudio_setup - setup ALSA interface and preparing for USB transfer * @@ -301,15 +314,17 @@ static struct gaudio *the_card; * * Returns negative errno, or zero on success */ -int __init gaudio_setup(struct gaudio *card) +int gaudio_setup(struct gaudio *card) { int ret; ret = gaudio_open_snd_dev(card); if (ret) ERROR(card, "we need at least one control device\n"); +#ifdef USBF_UAC1_INCLUDED else if (!the_card) the_card = card; +#endif return ret; @@ -320,11 +335,17 @@ int __init gaudio_setup(struct gaudio *card) * * This is called to free all resources allocated by @gaudio_setup(). */ +#ifdef USBF_UAC1_INCLUDED void gaudio_cleanup(void) +#else +void gaudio_cleanup(struct gaudio *the_card) +#endif { if (the_card) { gaudio_close_snd_dev(the_card); +#ifdef USBF_UAC1_INCLUDED the_card = NULL; +#endif } } diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index 18c2e729faf6..5b4fe9efb8f1 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -50,7 +50,27 @@ struct gaudio { /* TODO */ }; +struct f_uac1_opts { + struct usb_function_instance func_inst; + int req_buf_size; + int req_count; + int audio_buf_size; + char *fn_play; + char *fn_cap; + char *fn_cntl; + bool bound; + struct gaudio *card; +}; + int gaudio_setup(struct gaudio *card); +#ifdef USBF_UAC1_INCLUDED void gaudio_cleanup(void); +#else +void gaudio_cleanup(struct gaudio *the_card); +#endif + +size_t u_audio_playback(struct gaudio *card, void *buf, size_t count); +int u_audio_get_playback_channels(struct gaudio *card); +int u_audio_get_playback_rate(struct gaudio *card); #endif /* __U_AUDIO_H */ diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index 47a7de71f7fb..cf1a5434feaf 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -80,6 +80,7 @@ static struct usb_function *f_uac2; #endif #ifdef CONFIG_GADGET_UAC1 +#define USBF_UAC1_INCLUDED #include "u_uac1.h" #include "f_uac1.c" #endif -- GitLab From 0d992dec967d6edc97b3001598db7c4ac4e4b3c1 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:39 +0200 Subject: [PATCH 1042/9167] usb: gadget: audio: convert to new interface of f_uac1 Use the new interface so that the old one can be removed. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/legacy/Kconfig | 1 + drivers/usb/gadget/legacy/audio.c | 69 ++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/drivers/usb/gadget/legacy/Kconfig b/drivers/usb/gadget/legacy/Kconfig index 172a6a396fe2..bbd4b8545b9d 100644 --- a/drivers/usb/gadget/legacy/Kconfig +++ b/drivers/usb/gadget/legacy/Kconfig @@ -54,6 +54,7 @@ config USB_AUDIO depends on SND select USB_LIBCOMPOSITE select SND_PCM + select USB_F_UAC1 if GADGET_UAC1 select USB_F_UAC2 if !GADGET_UAC1 help This Gadget Audio driver is compatible with USB Audio Class diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index cf1a5434feaf..bb40b61e2555 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -53,6 +53,35 @@ MODULE_PARM_DESC(c_srate, "Capture Sampling Rate"); static int c_ssize = UAC2_DEF_CSSIZE; module_param(c_ssize, uint, S_IRUGO); MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); +#else +#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" +#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" +#define FILE_CONTROL "/dev/snd/controlC0" + +static char *fn_play = FILE_PCM_PLAYBACK; +module_param(fn_play, charp, S_IRUGO); +MODULE_PARM_DESC(fn_play, "Playback PCM device file name"); + +static char *fn_cap = FILE_PCM_CAPTURE; +module_param(fn_cap, charp, S_IRUGO); +MODULE_PARM_DESC(fn_cap, "Capture PCM device file name"); + +static char *fn_cntl = FILE_CONTROL; +module_param(fn_cntl, charp, S_IRUGO); +MODULE_PARM_DESC(fn_cntl, "Control device file name"); + +#define OUT_EP_MAX_PACKET_SIZE 200 +static int req_buf_size = OUT_EP_MAX_PACKET_SIZE; +module_param(req_buf_size, int, S_IRUGO); +MODULE_PARM_DESC(req_buf_size, "ISO OUT endpoint request buffer size"); + +static int req_count = 256; +module_param(req_count, int, S_IRUGO); +MODULE_PARM_DESC(req_count, "ISO OUT endpoint request count"); + +static int audio_buf_size = 48000; +module_param(audio_buf_size, int, S_IRUGO); +MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); #endif /* string IDs are assigned dynamically */ @@ -77,12 +106,13 @@ static struct usb_gadget_strings *audio_strings[] = { #ifndef CONFIG_GADGET_UAC1 static struct usb_function_instance *fi_uac2; static struct usb_function *f_uac2; +#else +static struct usb_function_instance *fi_uac1; +static struct usb_function *f_uac1; #endif #ifdef CONFIG_GADGET_UAC1 -#define USBF_UAC1_INCLUDED #include "u_uac1.h" -#include "f_uac1.c" #endif /*-------------------------------------------------------------------------*/ @@ -146,9 +176,7 @@ static const struct usb_descriptor_header *otg_desc[] = { static int __init audio_do_config(struct usb_configuration *c) { -#ifndef CONFIG_GADGET_UAC1 int status; -#endif /* FIXME alloc iConfiguration string, set it in c->strings */ @@ -158,7 +186,17 @@ static int __init audio_do_config(struct usb_configuration *c) } #ifdef CONFIG_GADGET_UAC1 - audio_bind_config(c); + f_uac1 = usb_get_function(fi_uac1); + if (IS_ERR(f_uac1)) { + status = PTR_ERR(f_uac1); + return status; + } + + status = usb_add_function(c, f_uac1); + if (status < 0) { + usb_put_function(f_uac1); + return status; + } #else f_uac2 = usb_get_function(fi_uac2); if (IS_ERR(f_uac2)) { @@ -189,6 +227,8 @@ static int __init audio_bind(struct usb_composite_dev *cdev) { #ifndef CONFIG_GADGET_UAC1 struct f_uac2_opts *uac2_opts; +#else + struct f_uac1_opts *uac1_opts; #endif int status; @@ -196,6 +236,10 @@ static int __init audio_bind(struct usb_composite_dev *cdev) fi_uac2 = usb_get_function_instance("uac2"); if (IS_ERR(fi_uac2)) return PTR_ERR(fi_uac2); +#else + fi_uac1 = usb_get_function_instance("uac1"); + if (IS_ERR(fi_uac1)) + return PTR_ERR(fi_uac1); #endif #ifndef CONFIG_GADGET_UAC1 @@ -206,6 +250,14 @@ static int __init audio_bind(struct usb_composite_dev *cdev) uac2_opts->c_chmask = c_chmask; uac2_opts->c_srate = c_srate; uac2_opts->c_ssize = c_ssize; +#else + uac1_opts = container_of(fi_uac1, struct f_uac1_opts, func_inst); + uac1_opts->fn_play = fn_play; + uac1_opts->fn_cap = fn_cap; + uac1_opts->fn_cntl = fn_cntl; + uac1_opts->req_buf_size = req_buf_size; + uac1_opts->req_count = req_count; + uac1_opts->audio_buf_size = audio_buf_size; #endif status = usb_string_ids_tab(cdev, strings_dev); @@ -225,6 +277,8 @@ static int __init audio_bind(struct usb_composite_dev *cdev) fail: #ifndef CONFIG_GADGET_UAC1 usb_put_function_instance(fi_uac2); +#else + usb_put_function_instance(fi_uac1); #endif return status; } @@ -232,7 +286,10 @@ static int __init audio_bind(struct usb_composite_dev *cdev) static int __exit audio_unbind(struct usb_composite_dev *cdev) { #ifdef CONFIG_GADGET_UAC1 - gaudio_cleanup(); + if (!IS_ERR_OR_NULL(f_uac1)) + usb_put_function(f_uac1); + if (!IS_ERR_OR_NULL(fi_uac1)) + usb_put_function_instance(fi_uac1); #else if (!IS_ERR_OR_NULL(f_uac2)) usb_put_function(f_uac2); -- GitLab From 605ef833f0c6f9e609e27ff1582a14a4dbc7d341 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:40 +0200 Subject: [PATCH 1043/9167] usb: gadget: f_uac1: remove compatibility layer There are no users of the old interface left, so it can be removed. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac1.c | 102 +-------------------------- drivers/usb/gadget/function/u_uac1.c | 33 --------- drivers/usb/gadget/function/u_uac1.h | 4 -- 3 files changed, 1 insertion(+), 138 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 787ed2bc4dd4..e0399d2aa818 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -16,24 +16,8 @@ #include #include "u_uac1.h" -#ifdef USBF_UAC1_INCLUDED -#include "u_uac1.c" -#endif #define OUT_EP_MAX_PACKET_SIZE 200 -#ifdef USBF_UAC1_INCLUDED -static int req_buf_size = OUT_EP_MAX_PACKET_SIZE; -module_param(req_buf_size, int, S_IRUGO); -MODULE_PARM_DESC(req_buf_size, "ISO OUT endpoint request buffer size"); - -static int req_count = 256; -module_param(req_count, int, S_IRUGO); -MODULE_PARM_DESC(req_count, "ISO OUT endpoint request count"); - -static int audio_buf_size = 48000; -module_param(audio_buf_size, int, S_IRUGO); -MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); -#endif static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); @@ -337,17 +321,14 @@ static int f_audio_out_ep_complete(struct usb_ep *ep, struct usb_request *req) struct f_audio *audio = req->context; struct usb_composite_dev *cdev = audio->card.func.config->cdev; struct f_audio_buf *copy_buf = audio->copy_buf; -#ifndef USBF_UAC1_INCLUDED struct f_uac1_opts *opts; int audio_buf_size; -#endif int err; -#ifndef USBF_UAC1_INCLUDED opts = container_of(audio->card.func.fi, struct f_uac1_opts, func_inst); audio_buf_size = opts->audio_buf_size; -#endif + if (!copy_buf) return -EINVAL; @@ -592,21 +573,17 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt) struct usb_composite_dev *cdev = f->config->cdev; struct usb_ep *out_ep = audio->out_ep; struct usb_request *req; -#ifndef USBF_UAC1_INCLUDED struct f_uac1_opts *opts; int req_buf_size, req_count, audio_buf_size; -#endif int i = 0, err = 0; DBG(cdev, "intf %d, alt %d\n", intf, alt); -#ifndef USBF_UAC1_INCLUDED opts = container_of(f->fi, struct f_uac1_opts, func_inst); req_buf_size = opts->req_buf_size; req_count = opts->req_count; audio_buf_size = opts->audio_buf_size; -#endif if (intf == 1) { if (alt == 1) { usb_ep_enable(out_ep); @@ -689,7 +666,6 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) struct f_audio *audio = func_to_audio(f); int status; struct usb_ep *ep = NULL; -#ifndef USBF_UAC1_INCLUDED struct f_uac1_opts *audio_opts; audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst); @@ -702,17 +678,10 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) return status; audio_opts->bound = true; } -#else - audio->card.gadget = c->cdev->gadget; -#endif if (strings_uac1[0].id == 0) { status = usb_string_ids_tab(c->cdev, strings_uac1); if (status < 0) -#ifdef USBF_UAC1_INCLUDED - return status; -#else goto fail; -#endif ac_interface_desc.iInterface = strings_uac1[STR_AC_IF].id; input_terminal_desc.iTerminal = strings_uac1[STR_INPUT_TERMINAL].id; @@ -760,25 +729,12 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) return 0; fail: -#ifndef USBF_UAC1_INCLUDED gaudio_cleanup(&audio->card); -#endif if (ep) ep->driver_data = NULL; return status; } -#ifdef USBF_UAC1_INCLUDED -static void -old_f_audio_unbind(struct usb_configuration *c, struct usb_function *f) -{ - struct f_audio *audio = func_to_audio(f); - - usb_free_all_descriptors(f); - kfree(audio); -} -#endif - /*-------------------------------------------------------------------------*/ static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value) @@ -811,61 +767,6 @@ static int control_selector_init(struct f_audio *audio) return 0; } -#ifdef USBF_UAC1_INCLUDED -/** - * audio_bind_config - add USB audio function to a configuration - * @c: the configuration to supcard the USB audio function - * Context: single threaded during gadget setup - * - * Returns zero on success, else negative errno. - */ -static int __init audio_bind_config(struct usb_configuration *c) -{ - struct f_audio *audio; - int status; - - /* allocate and initialize one new instance */ - audio = kzalloc(sizeof *audio, GFP_KERNEL); - if (!audio) - return -ENOMEM; - - audio->card.func.name = "g_audio"; - audio->card.gadget = c->cdev->gadget; - - INIT_LIST_HEAD(&audio->play_queue); - spin_lock_init(&audio->lock); - - /* set up ASLA audio devices */ - status = gaudio_setup(&audio->card); - if (status < 0) - goto setup_fail; - audio->card.func.strings = uac1_strings; - audio->card.func.bind = f_audio_bind; - audio->card.func.unbind = old_f_audio_unbind; - audio->card.func.set_alt = f_audio_set_alt; - audio->card.func.setup = f_audio_setup; - audio->card.func.disable = f_audio_disable; - - control_selector_init(audio); - - INIT_WORK(&audio->playback_work, f_audio_playback_work); - - status = usb_add_function(c, &audio->card.func); - if (status) - goto add_fail; - - INFO(c->cdev, "audio_buf_size %d, req_buf_size %d, req_count %d\n", - audio_buf_size, req_buf_size, req_count); - - return status; - -add_fail: - gaudio_cleanup(); -setup_fail: - kfree(audio); - return status; -} -#else static void f_audio_free_inst(struct usb_function_instance *f) { struct f_uac1_opts *opts; @@ -932,4 +833,3 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) DECLARE_USB_FUNCTION_INIT(uac1, f_audio_alloc_inst, f_audio_alloc); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Bryan Wu"); -#endif diff --git a/drivers/usb/gadget/function/u_uac1.c b/drivers/usb/gadget/function/u_uac1.c index 9a55e5cf4cd8..a44a07f30281 100644 --- a/drivers/usb/gadget/function/u_uac1.c +++ b/drivers/usb/gadget/function/u_uac1.c @@ -24,23 +24,6 @@ * This component encapsulates the ALSA devices for USB audio gadget */ -#ifdef USBF_UAC1_INCLUDED -#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" -#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" -#define FILE_CONTROL "/dev/snd/controlC0" - -static char *fn_play = FILE_PCM_PLAYBACK; -module_param(fn_play, charp, S_IRUGO); -MODULE_PARM_DESC(fn_play, "Playback PCM device file name"); - -static char *fn_cap = FILE_PCM_CAPTURE; -module_param(fn_cap, charp, S_IRUGO); -MODULE_PARM_DESC(fn_cap, "Capture PCM device file name"); - -static char *fn_cntl = FILE_CONTROL; -module_param(fn_cntl, charp, S_IRUGO); -MODULE_PARM_DESC(fn_cntl, "Control device file name"); -#endif /*-------------------------------------------------------------------------*/ /** @@ -222,7 +205,6 @@ static int gaudio_open_snd_dev(struct gaudio *card) { struct snd_pcm_file *pcm_file; struct gaudio_snd_dev *snd; -#ifndef USBF_UAC1_INCLUDED struct f_uac1_opts *opts; char *fn_play, *fn_cap, *fn_cntl; @@ -230,7 +212,6 @@ static int gaudio_open_snd_dev(struct gaudio *card) fn_play = opts->fn_play; fn_cap = opts->fn_cap; fn_cntl = opts->fn_cntl; -#endif if (!card) return -ENODEV; @@ -304,9 +285,6 @@ static int gaudio_close_snd_dev(struct gaudio *gau) return 0; } -#ifdef USBF_UAC1_INCLUDED -static struct gaudio *the_card; -#endif /** * gaudio_setup - setup ALSA interface and preparing for USB transfer * @@ -321,10 +299,6 @@ int gaudio_setup(struct gaudio *card) ret = gaudio_open_snd_dev(card); if (ret) ERROR(card, "we need at least one control device\n"); -#ifdef USBF_UAC1_INCLUDED - else if (!the_card) - the_card = card; -#endif return ret; @@ -335,17 +309,10 @@ int gaudio_setup(struct gaudio *card) * * This is called to free all resources allocated by @gaudio_setup(). */ -#ifdef USBF_UAC1_INCLUDED -void gaudio_cleanup(void) -#else void gaudio_cleanup(struct gaudio *the_card) -#endif { if (the_card) { gaudio_close_snd_dev(the_card); -#ifdef USBF_UAC1_INCLUDED - the_card = NULL; -#endif } } diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index 5b4fe9efb8f1..8507c27020c9 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -63,11 +63,7 @@ struct f_uac1_opts { }; int gaudio_setup(struct gaudio *card); -#ifdef USBF_UAC1_INCLUDED -void gaudio_cleanup(void); -#else void gaudio_cleanup(struct gaudio *the_card); -#endif size_t u_audio_playback(struct gaudio *card, void *buf, size_t count); int u_audio_get_playback_channels(struct gaudio *card); -- GitLab From 807dccdba5c157c7131772bb6bd9a114a2ed9760 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:41 +0200 Subject: [PATCH 1044/9167] usb: gadget: f_uac1: use usb_gstrings_attach Use the new usb_gstring_attach interface. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac1.c | 30 +++++++++++----------------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index e0399d2aa818..34575375760e 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -664,6 +664,7 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) { struct usb_composite_dev *cdev = c->cdev; struct f_audio *audio = func_to_audio(f); + struct usb_string *us; int status; struct usb_ep *ep = NULL; struct f_uac1_opts *audio_opts; @@ -678,23 +679,17 @@ f_audio_bind(struct usb_configuration *c, struct usb_function *f) return status; audio_opts->bound = true; } - if (strings_uac1[0].id == 0) { - status = usb_string_ids_tab(c->cdev, strings_uac1); - if (status < 0) - goto fail; - ac_interface_desc.iInterface = strings_uac1[STR_AC_IF].id; - input_terminal_desc.iTerminal = - strings_uac1[STR_INPUT_TERMINAL].id; - input_terminal_desc.iChannelNames = - strings_uac1[STR_INPUT_TERMINAL_CH_NAMES].id; - feature_unit_desc.iFeature = strings_uac1[STR_FEAT_DESC_0].id; - output_terminal_desc.iTerminal = - strings_uac1[STR_OUTPUT_TERMINAL].id; - as_interface_alt_0_desc.iInterface = - strings_uac1[STR_AS_IF_ALT0].id; - as_interface_alt_1_desc.iInterface = - strings_uac1[STR_AS_IF_ALT1].id; - } + us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1)); + if (IS_ERR(us)) + return PTR_ERR(us); + ac_interface_desc.iInterface = us[STR_AC_IF].id; + input_terminal_desc.iTerminal = us[STR_INPUT_TERMINAL].id; + input_terminal_desc.iChannelNames = us[STR_INPUT_TERMINAL_CH_NAMES].id; + feature_unit_desc.iFeature = us[STR_FEAT_DESC_0].id; + output_terminal_desc.iTerminal = us[STR_OUTPUT_TERMINAL].id; + as_interface_alt_0_desc.iInterface = us[STR_AS_IF_ALT0].id; + as_interface_alt_1_desc.iInterface = us[STR_AS_IF_ALT1].id; + f_audio_build_desc(audio); @@ -815,7 +810,6 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) INIT_LIST_HEAD(&audio->play_queue); spin_lock_init(&audio->lock); - audio->card.func.strings = uac1_strings; audio->card.func.bind = f_audio_bind; audio->card.func.unbind = f_audio_unbind; audio->card.func.set_alt = f_audio_set_alt; -- GitLab From bcec9784dd78abfa9d8ca8b7144f6e37ea6abfd5 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:42 +0200 Subject: [PATCH 1045/9167] usb: gadget: f_uac1: use defined constants as defaults When configfs support is added the values in question will have to be used in two different places. Substitute them with defined constants to avoid duplicating magic numbers. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uac1.c | 4 +--- drivers/usb/gadget/function/u_uac1.h | 8 ++++++++ drivers/usb/gadget/legacy/audio.c | 15 ++++----------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 34575375760e..9a6c7ec66757 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -17,8 +17,6 @@ #include "u_uac1.h" -#define OUT_EP_MAX_PACKET_SIZE 200 - static int generic_set_cmd(struct usb_audio_control *con, u8 cmd, int value); static int generic_get_cmd(struct usb_audio_control *con, u8 cmd); @@ -173,7 +171,7 @@ static struct usb_endpoint_descriptor as_out_ep_desc = { .bEndpointAddress = USB_DIR_OUT, .bmAttributes = USB_ENDPOINT_SYNC_ADAPTIVE | USB_ENDPOINT_XFER_ISOC, - .wMaxPacketSize = __constant_cpu_to_le16(OUT_EP_MAX_PACKET_SIZE), + .wMaxPacketSize = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE), .bInterval = 4, }; diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index 8507c27020c9..214441d96fe1 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -23,6 +23,14 @@ #include "gadget_chips.h" +#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" +#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" +#define FILE_CONTROL "/dev/snd/controlC0" + +#define UAC1_OUT_EP_MAX_PACKET_SIZE 200 +#define UAC1_REQ_COUNT 256 +#define UAC1_AUDIO_BUF_SIZE 48000 + /* * This represents the USB side of an audio card device, managed by a USB * function which provides control and stream interfaces. diff --git a/drivers/usb/gadget/legacy/audio.c b/drivers/usb/gadget/legacy/audio.c index bb40b61e2555..f46a3956e43d 100644 --- a/drivers/usb/gadget/legacy/audio.c +++ b/drivers/usb/gadget/legacy/audio.c @@ -54,9 +54,7 @@ static int c_ssize = UAC2_DEF_CSSIZE; module_param(c_ssize, uint, S_IRUGO); MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)"); #else -#define FILE_PCM_PLAYBACK "/dev/snd/pcmC0D0p" -#define FILE_PCM_CAPTURE "/dev/snd/pcmC0D0c" -#define FILE_CONTROL "/dev/snd/controlC0" +#include "u_uac1.h" static char *fn_play = FILE_PCM_PLAYBACK; module_param(fn_play, charp, S_IRUGO); @@ -70,16 +68,15 @@ static char *fn_cntl = FILE_CONTROL; module_param(fn_cntl, charp, S_IRUGO); MODULE_PARM_DESC(fn_cntl, "Control device file name"); -#define OUT_EP_MAX_PACKET_SIZE 200 -static int req_buf_size = OUT_EP_MAX_PACKET_SIZE; +static int req_buf_size = UAC1_OUT_EP_MAX_PACKET_SIZE; module_param(req_buf_size, int, S_IRUGO); MODULE_PARM_DESC(req_buf_size, "ISO OUT endpoint request buffer size"); -static int req_count = 256; +static int req_count = UAC1_REQ_COUNT; module_param(req_count, int, S_IRUGO); MODULE_PARM_DESC(req_count, "ISO OUT endpoint request count"); -static int audio_buf_size = 48000; +static int audio_buf_size = UAC1_AUDIO_BUF_SIZE; module_param(audio_buf_size, int, S_IRUGO); MODULE_PARM_DESC(audio_buf_size, "Audio buffer size"); #endif @@ -111,10 +108,6 @@ static struct usb_function_instance *fi_uac1; static struct usb_function *f_uac1; #endif -#ifdef CONFIG_GADGET_UAC1 -#include "u_uac1.h" -#endif - /*-------------------------------------------------------------------------*/ /* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! -- GitLab From 0854611a19ae4dfa56569e6f640017a1d2dd3312 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Tue, 22 Jul 2014 19:58:43 +0200 Subject: [PATCH 1046/9167] usb: gadget: f_uac1: add configfs support Add support for using f_uac1 function as a component of a gadget composed with configfs. Tested-by: Sebastian Reimers Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Felipe Balbi --- .../ABI/testing/configfs-usb-gadget-uac1 | 12 ++ drivers/usb/gadget/function/f_uac1.c | 158 ++++++++++++++++++ drivers/usb/gadget/function/u_uac1.h | 7 +- 3 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/configfs-usb-gadget-uac1 diff --git a/Documentation/ABI/testing/configfs-usb-gadget-uac1 b/Documentation/ABI/testing/configfs-usb-gadget-uac1 new file mode 100644 index 000000000000..8ba9a123316e --- /dev/null +++ b/Documentation/ABI/testing/configfs-usb-gadget-uac1 @@ -0,0 +1,12 @@ +What: /config/usb-gadget/gadget/functions/uac1.name +Date: Sep 2014 +KernelVersion: 3.18 +Description: + The attributes: + + audio_buf_size - audio buffer size + fn_cap - capture pcm device file name + fn_cntl - control device file name + fn_play - playback pcm device file name + req_buf_size - ISO OUT endpoint request buffer size + req_count - ISO OUT endpoint request count diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 9a6c7ec66757..f7b203293205 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -760,12 +760,150 @@ static int control_selector_init(struct f_audio *audio) return 0; } +static inline struct f_uac1_opts *to_f_uac1_opts(struct config_item *item) +{ + return container_of(to_config_group(item), struct f_uac1_opts, + func_inst.group); +} + +CONFIGFS_ATTR_STRUCT(f_uac1_opts); +CONFIGFS_ATTR_OPS(f_uac1_opts); + +static void f_uac1_attr_release(struct config_item *item) +{ + struct f_uac1_opts *opts = to_f_uac1_opts(item); + + usb_put_function_instance(&opts->func_inst); +} + +static struct configfs_item_operations f_uac1_item_ops = { + .release = f_uac1_attr_release, + .show_attribute = f_uac1_opts_attr_show, + .store_attribute = f_uac1_opts_attr_store, +}; + +#define UAC1_INT_ATTRIBUTE(name) \ +static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts, \ + char *page) \ +{ \ + int result; \ + \ + mutex_lock(&opts->lock); \ + result = sprintf(page, "%u\n", opts->name); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_uac1_opts_##name##_store(struct f_uac1_opts *opts, \ + const char *page, size_t len) \ +{ \ + int ret; \ + u32 num; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + ret = kstrtou32(page, 0, &num); \ + if (ret) \ + goto end; \ + \ + opts->name = num; \ + ret = len; \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +static struct f_uac1_opts_attribute f_uac1_opts_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ + f_uac1_opts_##name##_show, \ + f_uac1_opts_##name##_store) + +UAC1_INT_ATTRIBUTE(req_buf_size); +UAC1_INT_ATTRIBUTE(req_count); +UAC1_INT_ATTRIBUTE(audio_buf_size); + +#define UAC1_STR_ATTRIBUTE(name) \ +static ssize_t f_uac1_opts_##name##_show(struct f_uac1_opts *opts, \ + char *page) \ +{ \ + int result; \ + \ + mutex_lock(&opts->lock); \ + result = sprintf(page, "%s\n", opts->name); \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_uac1_opts_##name##_store(struct f_uac1_opts *opts, \ + const char *page, size_t len) \ +{ \ + int ret = -EBUSY; \ + char *tmp; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt) \ + goto end; \ + \ + tmp = kstrndup(page, len, GFP_KERNEL); \ + if (tmp) { \ + ret = -ENOMEM; \ + goto end; \ + } \ + if (opts->name##_alloc) \ + kfree(opts->name); \ + opts->name##_alloc = true; \ + opts->name = tmp; \ + ret = len; \ + \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +static struct f_uac1_opts_attribute f_uac1_opts_##name = \ + __CONFIGFS_ATTR(name, S_IRUGO | S_IWUSR, \ + f_uac1_opts_##name##_show, \ + f_uac1_opts_##name##_store) + +UAC1_STR_ATTRIBUTE(fn_play); +UAC1_STR_ATTRIBUTE(fn_cap); +UAC1_STR_ATTRIBUTE(fn_cntl); + +static struct configfs_attribute *f_uac1_attrs[] = { + &f_uac1_opts_req_buf_size.attr, + &f_uac1_opts_req_count.attr, + &f_uac1_opts_audio_buf_size.attr, + &f_uac1_opts_fn_play.attr, + &f_uac1_opts_fn_cap.attr, + &f_uac1_opts_fn_cntl.attr, + NULL, +}; + +static struct config_item_type f_uac1_func_type = { + .ct_item_ops = &f_uac1_item_ops, + .ct_attrs = f_uac1_attrs, + .ct_owner = THIS_MODULE, +}; + static void f_audio_free_inst(struct usb_function_instance *f) { struct f_uac1_opts *opts; opts = container_of(f, struct f_uac1_opts, func_inst); gaudio_cleanup(opts->card); + if (opts->fn_play_alloc) + kfree(opts->fn_play); + if (opts->fn_cap_alloc) + kfree(opts->fn_cap); + if (opts->fn_cntl_alloc) + kfree(opts->fn_cntl); kfree(opts); } @@ -777,16 +915,31 @@ static struct usb_function_instance *f_audio_alloc_inst(void) if (!opts) return ERR_PTR(-ENOMEM); + mutex_init(&opts->lock); opts->func_inst.free_func_inst = f_audio_free_inst; + config_group_init_type_name(&opts->func_inst.group, "", + &f_uac1_func_type); + + opts->req_buf_size = UAC1_OUT_EP_MAX_PACKET_SIZE; + opts->req_count = UAC1_REQ_COUNT; + opts->audio_buf_size = UAC1_AUDIO_BUF_SIZE; + opts->fn_play = FILE_PCM_PLAYBACK; + opts->fn_cap = FILE_PCM_CAPTURE; + opts->fn_cntl = FILE_CONTROL; return &opts->func_inst; } static void f_audio_free(struct usb_function *f) { struct f_audio *audio = func_to_audio(f); + struct f_uac1_opts *opts; + opts = container_of(f->fi, struct f_uac1_opts, func_inst); kfree(audio); + mutex_lock(&opts->lock); + --opts->refcnt; + mutex_unlock(&opts->lock); } static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) @@ -797,6 +950,7 @@ static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f) static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) { struct f_audio *audio; + struct f_uac1_opts *opts; /* allocate and initialize one new instance */ audio = kzalloc(sizeof(*audio), GFP_KERNEL); @@ -805,6 +959,10 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) audio->card.func.name = "g_audio"; + opts = container_of(fi, struct f_uac1_opts, func_inst); + mutex_lock(&opts->lock); + ++opts->refcnt; + mutex_unlock(&opts->lock); INIT_LIST_HEAD(&audio->play_queue); spin_lock_init(&audio->lock); diff --git a/drivers/usb/gadget/function/u_uac1.h b/drivers/usb/gadget/function/u_uac1.h index 214441d96fe1..f8b17fe82efe 100644 --- a/drivers/usb/gadget/function/u_uac1.h +++ b/drivers/usb/gadget/function/u_uac1.h @@ -66,8 +66,13 @@ struct f_uac1_opts { char *fn_play; char *fn_cap; char *fn_cntl; - bool bound; + unsigned bound:1; + unsigned fn_play_alloc:1; + unsigned fn_cap_alloc:1; + unsigned fn_cntl_alloc:1; struct gaudio *card; + struct mutex lock; + int refcnt; }; int gaudio_setup(struct gaudio *card); -- GitLab From 448466b723cc7b44016547116aa2b55a3736f1f0 Mon Sep 17 00:00:00 2001 From: Ross Zwisler Date: Mon, 19 May 2014 11:50:24 -0600 Subject: [PATCH 1047/9167] x86: Remove obsolete comment in uapi/e820.h A comment introduced by this old commit: 028b785888c5 ("x86 boot: extend some internal memory map arrays to handle larger EFI input") had to do with some nested preprocessor directives. The directives were split into separate files by this commit: af170c5061dd ("UAPI: (Scripted) Disintegrate arch/x86/include/asm") The comment explaining their interaction was retained and is now present in arch/x86/include/uapi/asm/e820.h. This comment is no longer correct, so delete it. Signed-off-by: Ross Zwisler Link: http://lkml.kernel.org/r/1400521824-21040-1-git-send-email-ross.zwisler@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/include/uapi/asm/e820.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/x86/include/uapi/asm/e820.h b/arch/x86/include/uapi/asm/e820.h index bbae02470701..d993e33f5236 100644 --- a/arch/x86/include/uapi/asm/e820.h +++ b/arch/x86/include/uapi/asm/e820.h @@ -21,11 +21,6 @@ * this size. */ -/* - * Odd: 'make headers_check' complains about numa.h if I try - * to collapse the next two #ifdef lines to a single line: - * #if defined(__KERNEL__) && defined(CONFIG_EFI) - */ #ifndef __KERNEL__ #define E820_X_MAX E820MAX #endif -- GitLab From 7103f60de8bed21a0ad5d15d2ad5b7a333dda201 Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 19 Aug 2014 16:45:56 +0200 Subject: [PATCH 1048/9167] KVM: avoid unnecessary synchronize_rcu We dont have to wait for a grace period if there is no oldpid that we are going to free. putpid also checks for NULL, so this patch only fences synchronize_rcu. Signed-off-by: Christian Borntraeger Signed-off-by: Paolo Bonzini --- virt/kvm/kvm_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 33712fb26eb1..39b16035386f 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -129,7 +129,8 @@ int vcpu_load(struct kvm_vcpu *vcpu) struct pid *oldpid = vcpu->pid; struct pid *newpid = get_task_pid(current, PIDTYPE_PID); rcu_assign_pointer(vcpu->pid, newpid); - synchronize_rcu(); + if (oldpid) + synchronize_rcu(); put_pid(oldpid); } cpu = get_cpu(); -- GitLab From 6689fbe3cf65b8c0dbbc87c40c085452997ffd8b Mon Sep 17 00:00:00 2001 From: Nadav Amit Date: Wed, 20 Aug 2014 16:38:19 +0300 Subject: [PATCH 1049/9167] KVM: x86: Replace X86_FEATURE_NX offset with the definition Replace reference to X86_FEATURE_NX using bit shift with the defined X86_FEATURE_NX. Signed-off-by: Nadav Amit Signed-off-by: Paolo Bonzini --- arch/x86/kvm/cpuid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 38a0afe83c6b..f4bad87ef256 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -112,8 +112,8 @@ static void cpuid_fix_nx_cap(struct kvm_vcpu *vcpu) break; } } - if (entry && (entry->edx & (1 << 20)) && !is_efer_nx()) { - entry->edx &= ~(1 << 20); + if (entry && (entry->edx & bit(X86_FEATURE_NX)) && !is_efer_nx()) { + entry->edx &= ~bit(X86_FEATURE_NX); printk(KERN_INFO "kvm: guest NX capability removed\n"); } } -- GitLab From 1c36d42c4ffee9e38e122ed822dd0a545a3a86da Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Aug 2014 16:49:32 +0200 Subject: [PATCH 1050/9167] irqchip: renesas-intc-irqpin: Add suspend-to-RAM wake up support Set the ->irq_enable() and ->irq_disable() methods to NULL to enable lazy disable of interrupts, and set IRQCHIP_MASK_ON_SUSPEND to tell the core that only IRQs marked as wake-ups need to stay enabled during suspend-to-RAM. This makes wake-up by gpio-keys from suspend-to-RAM work on r8a7740/Armadillo. Signed-off-by: Geert Uytterhoeven Link: https://lkml.kernel.org/r/1408546172-22484-1-git-send-email-geert+renesas@glider.be Signed-off-by: Jason Cooper --- drivers/irqchip/irq-renesas-intc-irqpin.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 3ee78f02e5d7..a9efceb0c4a0 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -454,10 +454,8 @@ static int intc_irqpin_probe(struct platform_device *pdev) irq_chip->name = name; irq_chip->irq_mask = disable_fn; irq_chip->irq_unmask = enable_fn; - irq_chip->irq_enable = enable_fn; - irq_chip->irq_disable = disable_fn; irq_chip->irq_set_type = intc_irqpin_irq_set_type; - irq_chip->flags = IRQCHIP_SKIP_SET_WAKE; + irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND; p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, p->number_of_irqs, -- GitLab From df11e506d330d9a0e5a701cd2c5fcb7d461b6060 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 21 Aug 2014 10:11:34 +0800 Subject: [PATCH 1051/9167] regulator: core: Add back the const qualifier for ops of struct regulator_desc Fix below build warning: CC [M] drivers/regulator/hi6421-regulator.o drivers/regulator/hi6421-regulator.c:356:2: warning: initialization discards 'const' qualifier from pointer target type [enabled by default] This is a revert of commit 716845ebeb50 ("regulator: core: Fix build error due to const qualifier for ops"). The build error was fixed by commit 39f5460d7f9c ("regulator: core: add const to regulator_ops and fix build error in mc13892"). Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- include/linux/regulator/driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 3abda7554d82..efe058f8f746 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -246,7 +246,7 @@ struct regulator_desc { int id; bool continuous_voltage_range; unsigned n_voltages; - struct regulator_ops *ops; + const struct regulator_ops *ops; int irq; enum regulator_type type; struct module *owner; -- GitLab From 8e820007caed7a03634fb14835a59bd0a232894d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 21 Aug 2014 10:31:33 +0800 Subject: [PATCH 1052/9167] regulator: hi6421: Remove unused fields from struct hi6421_regulator_info The valid_modes_mask and *dev are not used in this driver, remove them. Current code uses devm_regulator_register, so we don't need *regulator in hi6421_regulator_info. Use a local variable instead. Also removes a few unnecessary inclusion of header files. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/hi6421-regulator.c | 31 ++++------------------------ 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/drivers/regulator/hi6421-regulator.c b/drivers/regulator/hi6421-regulator.c index b0de92bee4a2..e3899201cd7e 100644 --- a/drivers/regulator/hi6421-regulator.c +++ b/drivers/regulator/hi6421-regulator.c @@ -17,19 +17,13 @@ #include #include #include -#include -#include #include #include -#include -#include #include #include #include #include #include -#include -#include /* * struct hi6421_regulator_pdata - Hi6421 regulator data of platform device @@ -41,20 +35,14 @@ struct hi6421_regulator_pdata { /* * struct hi6421_regulator_info - hi6421 regulator information - * @dev: device pointer * @desc: regulator description - * @regulator: regulator device * @mode_mask: ECO mode bitmask of LDOs; for BUCKs, this masks sleep * @eco_microamp: eco mode load upper limit (in mA), valid for LDOs only - * @valid_modes_mask: valid operating modes */ struct hi6421_regulator_info { - struct device *dev; struct regulator_desc desc; - struct regulator_dev *regulator; u8 mode_mask; u32 eco_microamp; - unsigned int valid_modes_mask; }; /* HI6421 regulators */ @@ -198,8 +186,6 @@ static const struct regulator_ops hi6421_buck345_ops; }, \ .mode_mask = ecomask, \ .eco_microamp = ecoamp, \ - .valid_modes_mask = (REGULATOR_MODE_NORMAL \ - | REGULATOR_MODE_IDLE), \ } /* HI6421 LDO1~3 are linear voltage regulators at fixed uV_step @@ -237,8 +223,6 @@ static const struct regulator_ops hi6421_buck345_ops; }, \ .mode_mask = ecomask, \ .eco_microamp = ecoamp, \ - .valid_modes_mask = (REGULATOR_MODE_NORMAL \ - | REGULATOR_MODE_IDLE), \ } /* HI6421 LDOAUDIO is a linear voltage regulator with two 4-step ranges @@ -276,8 +260,6 @@ static const struct regulator_ops hi6421_buck345_ops; }, \ .mode_mask = ecomask, \ .eco_microamp = ecoamp, \ - .valid_modes_mask = (REGULATOR_MODE_NORMAL \ - | REGULATOR_MODE_IDLE), \ } /* HI6421 BUCK0/1/2 are linear voltage regulators at fixed uV_step @@ -311,8 +293,6 @@ static const struct regulator_ops hi6421_buck345_ops; .off_on_delay = odelay, \ }, \ .mode_mask = sleepmask, \ - .valid_modes_mask = (REGULATOR_MODE_NORMAL \ - | REGULATOR_MODE_STANDBY), \ } /* HI6421 BUCK3/4/5 share similar configurations as LDOs, with exception @@ -346,8 +326,6 @@ static const struct regulator_ops hi6421_buck345_ops; .off_on_delay = odelay, \ }, \ .mode_mask = sleepmask, \ - .valid_modes_mask = (REGULATOR_MODE_NORMAL \ - | REGULATOR_MODE_STANDBY), \ } /* HI6421 regulator information */ @@ -580,10 +558,10 @@ static int hi6421_regulator_register(struct platform_device *pdev, { struct hi6421_regulator_info *info = NULL; struct regulator_config config = { }; + struct regulator_dev *rdev; /* assign per-regulator data */ info = &hi6421_regulator_info[id]; - info->dev = &pdev->dev; config.dev = &pdev->dev; config.init_data = init_data; @@ -592,12 +570,11 @@ static int hi6421_regulator_register(struct platform_device *pdev, config.of_node = np; /* register regulator with framework */ - info->regulator = devm_regulator_register(&pdev->dev, &info->desc, - &config); - if (IS_ERR(info->regulator)) { + rdev = devm_regulator_register(&pdev->dev, &info->desc, &config); + if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", info->desc.name); - return PTR_ERR(info->regulator); + return PTR_ERR(rdev); } return 0; -- GitLab From 6bc17375d2e787e5c7ef94bfb4e194b6c690a4a7 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Thu, 21 Aug 2014 16:54:43 +0200 Subject: [PATCH 1053/9167] usb: gadget: uvc: Change KERN_INFO to KERN_DEBUG on request shutdown The disconnect of the USB Device is a common pattern for an UVC Camera. In many cases this will give us an meaningless information for all buffers that couldn't be enqueued. That patch changes this to KERN_DEBUG. Signed-off-by: Michael Grzeschik Signed-off-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/uvc_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index 71e896d4c5ae..beba9168614a 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -171,7 +171,7 @@ uvc_video_complete(struct usb_ep *ep, struct usb_request *req) break; case -ESHUTDOWN: /* disconnect from host. */ - printk(KERN_INFO "VS request cancelled.\n"); + printk(KERN_DEBUG "VS request cancelled.\n"); uvc_queue_cancel(queue, 1); goto requeue; -- GitLab From ee7ec7f6b39d2ae25dca000398929edaa2ce412d Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 21 Aug 2014 16:54:44 +0200 Subject: [PATCH 1054/9167] usb: gadget: uvc: Add support for DMABUF importing Activate the videobuf2 DMABUF support. As vb2-vmalloc supports the importer role only, exporting buffers isn't supported yet. When the exporter role will be implemented in vb2-vmalloc the UVC gadget driver will automatically gain support for it. Signed-off-by: Philipp Zabel Signed-off-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/uvc_queue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/uvc_queue.c b/drivers/usb/gadget/function/uvc_queue.c index 1c29bc954db9..8590f9ff0849 100644 --- a/drivers/usb/gadget/function/uvc_queue.c +++ b/drivers/usb/gadget/function/uvc_queue.c @@ -132,7 +132,7 @@ static int uvc_queue_init(struct uvc_video_queue *queue, int ret; queue->queue.type = type; - queue->queue.io_modes = VB2_MMAP | VB2_USERPTR; + queue->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; queue->queue.drv_priv = queue; queue->queue.buf_struct_size = sizeof(struct uvc_buffer); queue->queue.ops = &uvc_queue_qops; -- GitLab From e73798572e115f73066567f5840d4e5c21da70a8 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Thu, 21 Aug 2014 16:54:45 +0200 Subject: [PATCH 1055/9167] usb: gadget: f_uvc: fix potential memory leak If uvc->control_buf is successfuly allocated but uvc->control_req is not, uvc->control_buf is not freed in the error recovery path. With this patch applied uvc->control_buf is freed unconditionally; if it happens to be NULL kfree on it is safe anyway. Signed-off-by: Andrzej Pietrasiewicz Acked-by: Sebastian Andrzej Siewior Signed-off-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/f_uvc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index e2a1f50bd93c..ff4340a1b4b3 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -720,10 +720,9 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f) if (uvc->video.ep) uvc->video.ep->driver_data = NULL; - if (uvc->control_req) { + if (uvc->control_req) usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); - kfree(uvc->control_buf); - } + kfree(uvc->control_buf); usb_free_all_descriptors(f); return ret; -- GitLab From 84d1b78af9b35d706de2d1c115b9194bcaaa97b0 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Thu, 21 Aug 2014 16:54:46 +0200 Subject: [PATCH 1056/9167] usb: gadget: uvc: remove DRIVER_VERSION{,_NUMBER} As the driver is in mainline we can remove the version numbers. Signed-off-by: Michael Grzeschik Signed-off-by: Laurent Pinchart Signed-off-by: Felipe Balbi --- drivers/usb/gadget/function/uvc.h | 3 --- drivers/usb/gadget/function/uvc_v4l2.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h index 7a9111de8054..0a283b1237d5 100644 --- a/drivers/usb/gadget/function/uvc.h +++ b/drivers/usb/gadget/function/uvc.h @@ -96,9 +96,6 @@ extern unsigned int uvc_gadget_trace_param; * Driver specific constants */ -#define DRIVER_VERSION "0.1.0" -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(0, 1, 0) - #define UVC_NUM_REQUESTS 4 #define UVC_MAX_REQUEST_SIZE 64 #define UVC_MAX_EVENTS 4 diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index ad48e81155e2..bcd71cee7b51 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -178,7 +178,7 @@ uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) strlcpy(cap->card, cdev->gadget->name, sizeof(cap->card)); strlcpy(cap->bus_info, dev_name(&cdev->gadget->dev), sizeof cap->bus_info); - cap->version = DRIVER_VERSION_NUMBER; + cap->version = LINUX_VERSION_CODE; cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; break; } -- GitLab From 98a295339e565457c732610585da965e4f4f6a26 Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Tue, 3 Jun 2014 17:29:40 +0300 Subject: [PATCH 1057/9167] ARM: dts: qcom: Add APQ8084 Global Clock Controller DT node This patch adds the necessary node to probe the global clock controller on APQ8084 platforms. Signed-off-by: Georgi Djakov Reviewed-by: Stephen Boyd --- arch/arm/boot/dts/qcom-apq8084.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index e3e009a5912b..1e785dfb365d 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -2,6 +2,8 @@ #include "skeleton.dtsi" +#include + / { model = "Qualcomm APQ 8084"; compatible = "qcom,apq8084"; @@ -175,5 +177,13 @@ compatible = "qcom,pshold"; reg = <0xfc4ab000 0x4>; }; + + gcc: clock-controller@fc400000 { + compatible = "qcom,gcc-apq8084"; + #clock-cells = <1>; + #reset-cells = <1>; + reg = <0xfc400000 0x4000>; + }; + }; }; -- GitLab From 14ff1c43881aa8f43d0ec0fa264dc9ed995f801b Mon Sep 17 00:00:00 2001 From: Georgi Djakov Date: Tue, 3 Jun 2014 17:29:41 +0300 Subject: [PATCH 1058/9167] ARM: dts: qcom: Add APQ8084 serial port DT node Add the necessary DT node to probe the serial driver on APQ8084 platforms. Signed-off-by: Georgi Djakov Reviewed-by: Stephen Boyd --- arch/arm/boot/dts/qcom-apq8084-mtp.dts | 6 ++++++ arch/arm/boot/dts/qcom-apq8084.dtsi | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/arch/arm/boot/dts/qcom-apq8084-mtp.dts b/arch/arm/boot/dts/qcom-apq8084-mtp.dts index 9dae3878b71d..8ecec58a9ff6 100644 --- a/arch/arm/boot/dts/qcom-apq8084-mtp.dts +++ b/arch/arm/boot/dts/qcom-apq8084-mtp.dts @@ -3,4 +3,10 @@ / { model = "Qualcomm APQ 8084-MTP"; compatible = "qcom,apq8084-mtp", "qcom,apq8084"; + + soc { + serial@f995e000 { + status = "okay"; + }; + }; }; diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index 1e785dfb365d..b5b156e328a0 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -185,5 +185,13 @@ reg = <0xfc400000 0x4000>; }; + serial@f995e000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0xf995e000 0x1000>; + interrupts = <0 114 0x0>; + clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; }; }; -- GitLab From 68de308b1c02f3b11705406b07e84790eb1a37e9 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 7 Mar 2014 10:56:59 -0600 Subject: [PATCH 1059/9167] ARM: qcom: Add initial IPQ8064 SoC and AP148 device trees Add basic IPQ8064 SoC include device tree and support for basic booting on the AP148 Reference board with support for UART, I2C, and SPI. Signed-off-by: Kumar Gala --- arch/arm/boot/dts/Makefile | 1 + arch/arm/boot/dts/qcom-ipq8064-ap148.dts | 85 ++++++++ arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi | 1 + arch/arm/boot/dts/qcom-ipq8064.dtsi | 250 +++++++++++++++++++++++ arch/arm/mach-qcom/board.c | 2 + 5 files changed, 339 insertions(+) create mode 100644 arch/arm/boot/dts/qcom-ipq8064-ap148.dts create mode 100644 arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi create mode 100644 arch/arm/boot/dts/qcom-ipq8064.dtsi diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index b8c5cd3ddeb9..a097a042bdb3 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile @@ -342,6 +342,7 @@ dtb-$(CONFIG_ARCH_QCOM) += \ qcom-apq8064-ifc6410.dtb \ qcom-apq8074-dragonboard.dtb \ qcom-apq8084-mtp.dtb \ + qcom-ipq8064-ap148.dtb \ qcom-msm8660-surf.dtb \ qcom-msm8960-cdp.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += \ diff --git a/arch/arm/boot/dts/qcom-ipq8064-ap148.dts b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts new file mode 100644 index 000000000000..95e64955fb8e --- /dev/null +++ b/arch/arm/boot/dts/qcom-ipq8064-ap148.dts @@ -0,0 +1,85 @@ +#include "qcom-ipq8064-v1.0.dtsi" + +/ { + model = "Qualcomm IPQ8064/AP148"; + compatible = "qcom,ipq8064-ap148", "qcom,ipq8064"; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + rsvd@41200000 { + reg = <0x41200000 0x300000>; + no-map; + }; + }; + + soc { + pinmux@800000 { + i2c4_pins: i2c4_pinmux { + pins = "gpio12", "gpio13"; + function = "gsbi4"; + bias-disable; + }; + + spi_pins: spi_pins { + mux { + pins = "gpio18", "gpio19", "gpio21"; + function = "gsbi5"; + drive-strength = <10>; + bias-none; + }; + }; + }; + + gsbi@16300000 { + qcom,mode = ; + status = "ok"; + serial@16340000 { + status = "ok"; + }; + + i2c4: i2c@16380000 { + status = "ok"; + + clock-frequency = <200000>; + + pinctrl-0 = <&i2c4_pins>; + pinctrl-names = "default"; + }; + }; + + gsbi5: gsbi@1a200000 { + qcom,mode = ; + status = "ok"; + + spi4: spi@1a280000 { + status = "ok"; + spi-max-frequency = <50000000>; + + pinctrl-0 = <&spi_pins>; + pinctrl-names = "default"; + + cs-gpios = <&qcom_pinmux 20 0>; + + flash: m25p80@0 { + compatible = "s25fl256s1"; + #address-cells = <1>; + #size-cells = <1>; + spi-max-frequency = <50000000>; + reg = <0>; + + partition@0 { + label = "rootfs"; + reg = <0x0 0x1000000>; + }; + + partition@1 { + label = "scratch"; + reg = <0x1000000 0x1000000>; + }; + }; + }; + }; + }; +}; diff --git a/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi new file mode 100644 index 000000000000..7093b075e408 --- /dev/null +++ b/arch/arm/boot/dts/qcom-ipq8064-v1.0.dtsi @@ -0,0 +1 @@ +#include "qcom-ipq8064.dtsi" diff --git a/arch/arm/boot/dts/qcom-ipq8064.dtsi b/arch/arm/boot/dts/qcom-ipq8064.dtsi new file mode 100644 index 000000000000..244f857f0e6f --- /dev/null +++ b/arch/arm/boot/dts/qcom-ipq8064.dtsi @@ -0,0 +1,250 @@ +/dts-v1/; + +#include "skeleton.dtsi" +#include +#include + +/ { + model = "Qualcomm IPQ8064"; + compatible = "qcom,ipq8064"; + interrupt-parent = <&intc>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "qcom,krait"; + enable-method = "qcom,kpss-acc-v1"; + device_type = "cpu"; + reg = <0>; + next-level-cache = <&L2>; + qcom,acc = <&acc0>; + qcom,saw = <&saw0>; + }; + + cpu@1 { + compatible = "qcom,krait"; + enable-method = "qcom,kpss-acc-v1"; + device_type = "cpu"; + reg = <1>; + next-level-cache = <&L2>; + qcom,acc = <&acc1>; + qcom,saw = <&saw1>; + }; + + L2: l2-cache { + compatible = "cache"; + cache-level = <2>; + }; + }; + + cpu-pmu { + compatible = "qcom,krait-pmu"; + interrupts = <1 10 0x304>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + nss@40000000 { + reg = <0x40000000 0x1000000>; + no-map; + }; + + smem@41000000 { + reg = <0x41000000 0x200000>; + no-map; + }; + }; + + soc: soc { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "simple-bus"; + + qcom_pinmux: pinmux@800000 { + compatible = "qcom,ipq8064-pinctrl"; + reg = <0x800000 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupts = <0 32 0x4>; + }; + + intc: interrupt-controller@2000000 { + compatible = "qcom,msm-qgic2"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x02000000 0x1000>, + <0x02002000 0x1000>; + }; + + timer@200a000 { + compatible = "qcom,kpss-timer", "qcom,msm-timer"; + interrupts = <1 1 0x301>, + <1 2 0x301>, + <1 3 0x301>; + reg = <0x0200a000 0x100>; + clock-frequency = <25000000>, + <32768>; + cpu-offset = <0x80000>; + }; + + acc0: clock-controller@2088000 { + compatible = "qcom,kpss-acc-v1"; + reg = <0x02088000 0x1000>, <0x02008000 0x1000>; + }; + + acc1: clock-controller@2098000 { + compatible = "qcom,kpss-acc-v1"; + reg = <0x02098000 0x1000>, <0x02008000 0x1000>; + }; + + saw0: regulator@2089000 { + compatible = "qcom,saw2"; + reg = <0x02089000 0x1000>, <0x02009000 0x1000>; + regulator; + }; + + saw1: regulator@2099000 { + compatible = "qcom,saw2"; + reg = <0x02099000 0x1000>, <0x02009000 0x1000>; + regulator; + }; + + gsbi2: gsbi@12480000 { + compatible = "qcom,gsbi-v1.0.0"; + reg = <0x12480000 0x100>; + clocks = <&gcc GSBI2_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "disabled"; + + serial@12490000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x12490000 0x1000>, + <0x12480000 0x1000>; + interrupts = <0 195 0x0>; + clocks = <&gcc GSBI2_UART_CLK>, <&gcc GSBI2_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + + i2c@124a0000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x124a0000 0x1000>; + interrupts = <0 196 0>; + + clocks = <&gcc GSBI2_QUP_CLK>, <&gcc GSBI2_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; + + }; + + gsbi4: gsbi@16300000 { + compatible = "qcom,gsbi-v1.0.0"; + reg = <0x16300000 0x100>; + clocks = <&gcc GSBI4_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "disabled"; + + serial@16340000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x16340000 0x1000>, + <0x16300000 0x1000>; + interrupts = <0 152 0x0>; + clocks = <&gcc GSBI4_UART_CLK>, <&gcc GSBI4_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + + i2c@16380000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x16380000 0x1000>; + interrupts = <0 153 0>; + + clocks = <&gcc GSBI4_QUP_CLK>, <&gcc GSBI4_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + gsbi5: gsbi@1a200000 { + compatible = "qcom,gsbi-v1.0.0"; + reg = <0x1a200000 0x100>; + clocks = <&gcc GSBI5_H_CLK>; + clock-names = "iface"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + status = "disabled"; + + serial@1a240000 { + compatible = "qcom,msm-uartdm-v1.3", "qcom,msm-uartdm"; + reg = <0x1a240000 0x1000>, + <0x1a200000 0x1000>; + interrupts = <0 154 0x0>; + clocks = <&gcc GSBI5_UART_CLK>, <&gcc GSBI5_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + }; + + i2c@1a280000 { + compatible = "qcom,i2c-qup-v1.1.1"; + reg = <0x1a280000 0x1000>; + interrupts = <0 155 0>; + + clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; + + spi@1a280000 { + compatible = "qcom,spi-qup-v1.1.1"; + reg = <0x1a280000 0x1000>; + interrupts = <0 155 0>; + + clocks = <&gcc GSBI5_QUP_CLK>, <&gcc GSBI5_H_CLK>; + clock-names = "core", "iface"; + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + qcom,ssbi@500000 { + compatible = "qcom,ssbi"; + reg = <0x00500000 0x1000>; + qcom,controller-type = "pmic-arbiter"; + }; + + gcc: clock-controller@900000 { + compatible = "qcom,gcc-ipq8064"; + reg = <0x00900000 0x4000>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + }; +}; diff --git a/arch/arm/mach-qcom/board.c b/arch/arm/mach-qcom/board.c index c437a9941726..6d8bbf7d39d8 100644 --- a/arch/arm/mach-qcom/board.c +++ b/arch/arm/mach-qcom/board.c @@ -18,6 +18,8 @@ static const char * const qcom_dt_match[] __initconst = { "qcom,apq8064", "qcom,apq8074-dragonboard", "qcom,apq8084", + "qcom,ipq8062", + "qcom,ipq8064", "qcom,msm8660-surf", "qcom,msm8960-cdp", NULL -- GitLab From e790d9ef6405633b007339d746b709aed43a928d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 21 Aug 2014 18:08:05 +0200 Subject: [PATCH 1060/9167] KVM: add kvm_arch_sched_in MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce preempt notifiers for architecture specific code. Advantage over creating a new notifier in every arch is slightly simpler code and guaranteed call order with respect to kvm_sched_in. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/arm/kvm/arm.c | 4 ++++ arch/mips/kvm/mips.c | 4 ++++ arch/powerpc/kvm/powerpc.c | 4 ++++ arch/s390/kvm/kvm-s390.c | 4 ++++ arch/x86/kvm/x86.c | 4 ++++ include/linux/kvm_host.h | 2 ++ virt/kvm/kvm_main.c | 2 ++ 7 files changed, 24 insertions(+) diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c index a99e0cdf8ba2..9f788ebac55b 100644 --- a/arch/arm/kvm/arm.c +++ b/arch/arm/kvm/arm.c @@ -288,6 +288,10 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) { } +void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ +} + void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { vcpu->cpu = cpu; diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index cd7114147ae7..2362df2a79f9 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -1002,6 +1002,10 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) { } +void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ +} + int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu, struct kvm_translation *tr) { diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 4c79284b58be..cbc432f4f0a6 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -720,6 +720,10 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) kvmppc_subarch_vcpu_uninit(vcpu); } +void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ +} + void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { #ifdef CONFIG_BOOKE diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index ce81eb2ab76a..a3c324ec4370 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -555,6 +555,10 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) /* Nothing todo */ } +void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ +} + void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { save_fp_ctl(&vcpu->arch.host_fpregs.fpc); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cd718c01cdf1..7d43dc7bb906 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7171,6 +7171,10 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) static_key_slow_dec(&kvm_no_apic_vcpu); } +void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ +} + int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) { if (type) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a4c33b34fe3f..ebd723676633 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -624,6 +624,8 @@ void kvm_arch_exit(void); int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu); +void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu); + void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu); void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu); void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 39b16035386f..5a0817ee996e 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -3124,6 +3124,8 @@ static void kvm_sched_in(struct preempt_notifier *pn, int cpu) if (vcpu->preempted) vcpu->preempted = false; + kvm_arch_sched_in(vcpu, cpu); + kvm_arch_vcpu_load(vcpu, cpu); } -- GitLab From ae97a3b818324b92b5b9cc885c63c3f4bd46ee9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 21 Aug 2014 18:08:06 +0200 Subject: [PATCH 1061/9167] KVM: x86: introduce sched_in to kvm_x86_ops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sched_in preempt notifier is available for x86, allow its use in specific virtualization technlogies as well. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/svm.c | 6 ++++++ arch/x86/kvm/vmx.c | 6 ++++++ arch/x86/kvm/x86.c | 1 + 4 files changed, 15 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 4bda61b582e6..ac0f90e26a0b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -771,6 +771,8 @@ struct kvm_x86_ops { bool (*mpx_supported)(void); int (*check_nested_events)(struct kvm_vcpu *vcpu, bool external_intr); + + void (*sched_in)(struct kvm_vcpu *kvm, int cpu); }; struct kvm_arch_async_pf { diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1f49c867e72e..1703aab84a6d 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -4305,6 +4305,10 @@ static void svm_handle_external_intr(struct kvm_vcpu *vcpu) local_irq_enable(); } +static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ +} + static struct kvm_x86_ops svm_x86_ops = { .cpu_has_kvm_support = has_svm, .disabled_by_bios = is_disabled, @@ -4405,6 +4409,8 @@ static struct kvm_x86_ops svm_x86_ops = { .check_intercept = svm_check_intercept, .handle_external_intr = svm_handle_external_intr, + + .sched_in = svm_sched_in, }; static int __init svm_init(void) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 286c2835e25c..7c26533e149c 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -8848,6 +8848,10 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, return X86EMUL_CONTINUE; } +void vmx_sched_in(struct kvm_vcpu *vcpu, int cpu) +{ +} + static struct kvm_x86_ops vmx_x86_ops = { .cpu_has_kvm_support = cpu_has_kvm_support, .disabled_by_bios = vmx_disabled_by_bios, @@ -8952,6 +8956,8 @@ static struct kvm_x86_ops vmx_x86_ops = { .mpx_supported = vmx_mpx_supported, .check_nested_events = vmx_check_nested_events, + + .sched_in = vmx_sched_in, }; static int __init vmx_init(void) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7d43dc7bb906..575d3fc67e7e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7173,6 +7173,7 @@ void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) { + kvm_x86_ops->sched_in(vcpu, cpu); } int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) -- GitLab From a7653ecdf34c68a1af4fc085511afcf7ff011903 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 21 Aug 2014 18:08:07 +0200 Subject: [PATCH 1062/9167] KVM: VMX: make PLE window per-VCPU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change PLE window into per-VCPU variable, seeded from module parameter, to allow greater flexibility. Brings in a small overhead on every vmentry. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 7c26533e149c..70175990536b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -484,6 +484,10 @@ struct vcpu_vmx { /* Support for a guest hypervisor (nested VMX) */ struct nested_vmx nested; + + /* Dynamic PLE window. */ + int ple_window; + bool ple_window_dirty; }; enum segment_cache_field { @@ -4402,7 +4406,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) if (ple_gap) { vmcs_write32(PLE_GAP, ple_gap); - vmcs_write32(PLE_WINDOW, ple_window); + vmx->ple_window = ple_window; + vmx->ple_window_dirty = true; } vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, 0); @@ -7389,6 +7394,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) if (vmx->emulation_required) return; + if (vmx->ple_window_dirty) { + vmx->ple_window_dirty = false; + vmcs_write32(PLE_WINDOW, vmx->ple_window); + } + if (vmx->nested.sync_shadow_vmcs) { copy_vmcs12_to_shadow(vmx); vmx->nested.sync_shadow_vmcs = false; -- GitLab From b4a2d31da812ce03efaf5d30c6b9d39c1cbd18d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 21 Aug 2014 18:08:08 +0200 Subject: [PATCH 1063/9167] KVM: VMX: dynamise PLE window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Window is increased on every PLE exit and decreased on every sched_in. The idea is that we don't want to PLE exit if there is no preemption going on. We do this with sched_in() because it does not hold rq lock. There are two new kernel parameters for changing the window: ple_window_grow and ple_window_shrink ple_window_grow affects the window on PLE exit and ple_window_shrink does it on sched_in; depending on their value, the window is modifier like this: (ple_window is kvm_intel's global) ple_window_shrink/ | ple_window_grow | PLE exit | sched_in -------------------+--------------------+--------------------- < 1 | = ple_window | = ple_window < ple_window | *= ple_window_grow | /= ple_window_shrink otherwise | += ple_window_grow | -= ple_window_shrink A third new parameter, ple_window_max, controls the maximal ple_window; it is internally rounded down to a closest multiple of ple_window_grow. VCPU's PLE window is never allowed below ple_window. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/vmx.c | 95 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 70175990536b..baeac7f580a7 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -125,14 +125,32 @@ module_param(nested, bool, S_IRUGO); * Time is measured based on a counter that runs at the same rate as the TSC, * refer SDM volume 3b section 21.6.13 & 22.1.3. */ -#define KVM_VMX_DEFAULT_PLE_GAP 128 -#define KVM_VMX_DEFAULT_PLE_WINDOW 4096 +#define KVM_VMX_DEFAULT_PLE_GAP 128 +#define KVM_VMX_DEFAULT_PLE_WINDOW 4096 +#define KVM_VMX_DEFAULT_PLE_WINDOW_GROW 2 +#define KVM_VMX_DEFAULT_PLE_WINDOW_SHRINK 0 +#define KVM_VMX_DEFAULT_PLE_WINDOW_MAX \ + INT_MAX / KVM_VMX_DEFAULT_PLE_WINDOW_GROW + static int ple_gap = KVM_VMX_DEFAULT_PLE_GAP; module_param(ple_gap, int, S_IRUGO); static int ple_window = KVM_VMX_DEFAULT_PLE_WINDOW; module_param(ple_window, int, S_IRUGO); +/* Default doubles per-vcpu window every exit. */ +static int ple_window_grow = KVM_VMX_DEFAULT_PLE_WINDOW_GROW; +module_param(ple_window_grow, int, S_IRUGO); + +/* Default resets per-vcpu window every exit to ple_window. */ +static int ple_window_shrink = KVM_VMX_DEFAULT_PLE_WINDOW_SHRINK; +module_param(ple_window_shrink, int, S_IRUGO); + +/* Default is to compute the maximum so we can never overflow. */ +static int ple_window_actual_max = KVM_VMX_DEFAULT_PLE_WINDOW_MAX; +static int ple_window_max = KVM_VMX_DEFAULT_PLE_WINDOW_MAX; +module_param(ple_window_max, int, S_IRUGO); + extern const ulong vmx_return; #define NR_AUTOLOAD_MSRS 8 @@ -5683,12 +5701,81 @@ static int handle_invalid_guest_state(struct kvm_vcpu *vcpu) return ret; } +static int __grow_ple_window(int val) +{ + if (ple_window_grow < 1) + return ple_window; + + val = min(val, ple_window_actual_max); + + if (ple_window_grow < ple_window) + val *= ple_window_grow; + else + val += ple_window_grow; + + return val; +} + +static int __shrink_ple_window(int val, int modifier, int minimum) +{ + if (modifier < 1) + return ple_window; + + if (modifier < ple_window) + val /= modifier; + else + val -= modifier; + + return max(val, minimum); +} + +static void grow_ple_window(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + int old = vmx->ple_window; + + vmx->ple_window = __grow_ple_window(old); + + if (vmx->ple_window != old) + vmx->ple_window_dirty = true; +} + +static void shrink_ple_window(struct kvm_vcpu *vcpu) +{ + struct vcpu_vmx *vmx = to_vmx(vcpu); + int old = vmx->ple_window; + + vmx->ple_window = __shrink_ple_window(old, + ple_window_shrink, ple_window); + + if (vmx->ple_window != old) + vmx->ple_window_dirty = true; +} + +/* + * ple_window_actual_max is computed to be one grow_ple_window() below + * ple_window_max. (See __grow_ple_window for the reason.) + * This prevents overflows, because ple_window_max is int. + * ple_window_max effectively rounded down to a multiple of ple_window_grow in + * this process. + * ple_window_max is also prevented from setting vmx->ple_window < ple_window. + */ +static void update_ple_window_actual_max(void) +{ + ple_window_actual_max = + __shrink_ple_window(max(ple_window_max, ple_window), + ple_window_grow, INT_MIN); +} + /* * Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE * exiting, so only get here on cpu with PAUSE-Loop-Exiting. */ static int handle_pause(struct kvm_vcpu *vcpu) { + if (ple_gap) + grow_ple_window(vcpu); + skip_emulated_instruction(vcpu); kvm_vcpu_on_spin(vcpu); @@ -8860,6 +8947,8 @@ static int vmx_check_intercept(struct kvm_vcpu *vcpu, void vmx_sched_in(struct kvm_vcpu *vcpu, int cpu) { + if (ple_gap) + shrink_ple_window(vcpu); } static struct kvm_x86_ops vmx_x86_ops = { @@ -9082,6 +9171,8 @@ static int __init vmx_init(void) } else kvm_disable_tdp(); + update_ple_window_actual_max(); + return 0; out7: -- GitLab From 7b46268d29543e313e731606d845e65c17f232e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Date: Thu, 21 Aug 2014 18:08:09 +0200 Subject: [PATCH 1064/9167] KVM: trace kvm_ple_window grow/shrink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tracepoint for dynamic PLE window, fired on every potential change. Signed-off-by: Radim Krčmář Signed-off-by: Paolo Bonzini --- arch/x86/kvm/trace.h | 30 ++++++++++++++++++++++++++++++ arch/x86/kvm/vmx.c | 4 ++++ arch/x86/kvm/x86.c | 1 + 3 files changed, 35 insertions(+) diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index e850a7d332be..1742dfbd26b3 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -848,6 +848,36 @@ TRACE_EVENT(kvm_track_tsc, __print_symbolic(__entry->host_clock, host_clocks)) ); +TRACE_EVENT(kvm_ple_window, + TP_PROTO(bool grow, unsigned int vcpu_id, int new, int old), + TP_ARGS(grow, vcpu_id, new, old), + + TP_STRUCT__entry( + __field( bool, grow ) + __field( unsigned int, vcpu_id ) + __field( int, new ) + __field( int, old ) + ), + + TP_fast_assign( + __entry->grow = grow; + __entry->vcpu_id = vcpu_id; + __entry->new = new; + __entry->old = old; + ), + + TP_printk("vcpu %u: ple_window %d (%s %d)", + __entry->vcpu_id, + __entry->new, + __entry->grow ? "grow" : "shrink", + __entry->old) +); + +#define trace_kvm_ple_window_grow(vcpu_id, new, old) \ + trace_kvm_ple_window(true, vcpu_id, new, old) +#define trace_kvm_ple_window_shrink(vcpu_id, new, old) \ + trace_kvm_ple_window(false, vcpu_id, new, old) + #endif /* CONFIG_X86_64 */ #endif /* _TRACE_KVM_H */ diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index baeac7f580a7..661abc2f7049 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -5738,6 +5738,8 @@ static void grow_ple_window(struct kvm_vcpu *vcpu) if (vmx->ple_window != old) vmx->ple_window_dirty = true; + + trace_kvm_ple_window_grow(vcpu->vcpu_id, vmx->ple_window, old); } static void shrink_ple_window(struct kvm_vcpu *vcpu) @@ -5750,6 +5752,8 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu) if (vmx->ple_window != old) vmx->ple_window_dirty = true; + + trace_kvm_ple_window_shrink(vcpu->vcpu_id, vmx->ple_window, old); } /* diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 575d3fc67e7e..c10408ef9ab1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -7673,3 +7673,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_invlpga); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_skinit); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_nested_intercepts); EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_write_tsc_offset); +EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_ple_window); -- GitLab From 4e942fa68425451672e2c9aa6de6373454142722 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 11 Apr 2014 14:18:29 -0500 Subject: [PATCH 1065/9167] ARM: qcom: Update defconfig * General defconfig update to match upstream changes * Enable IPQ806x & APQ8084 clk support * Enable pinctrl on MSM8960 * Enable CPU_IDLE to get basic wfi support * Enable SPI NOR and MTD M25P80 support (used on AP148 board) * Enable SATA PHY support on IPQ806x and APQ8064 * Enable Fixed regulator and ARM MMCI support (mmc support on APQ8064) Signed-off-by: Kumar Gala --- arch/arm/configs/qcom_defconfig | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index 42ebd72799e6..ab22dae79deb 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -29,6 +29,7 @@ CONFIG_HIGHPTE=y CONFIG_CLEANCACHE=y CONFIG_ARM_APPENDED_DTB=y CONFIG_ARM_ATAG_DTB_COMPAT=y +CONFIG_CPU_IDLE=y CONFIG_VFP=y CONFIG_NEON=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set @@ -53,14 +54,13 @@ CONFIG_DEVTMPFS_MOUNT=y CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_M25P80=y +CONFIG_MTD_SPI_NOR=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_SCSI=y -CONFIG_SCSI_TGT=y CONFIG_BLK_DEV_SD=y CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SCH=y -CONFIG_SCSI_MULTI_LUN=y CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y @@ -86,7 +86,6 @@ CONFIG_SERIO_LIBPS2=y CONFIG_SERIAL_MSM=y CONFIG_SERIAL_MSM_CONSOLE=y CONFIG_HW_RANDOM=y -CONFIG_HW_RANDOM_MSM=y CONFIG_I2C=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_QUP=y @@ -95,6 +94,7 @@ CONFIG_SPI_QUP=y CONFIG_SPMI=y CONFIG_PINCTRL_APQ8064=y CONFIG_PINCTRL_IPQ8064=y +CONFIG_PINCTRL_MSM8960=y CONFIG_PINCTRL_MSM8X74=y CONFIG_DEBUG_GPIO=y CONFIG_GPIO_SYSFS=y @@ -103,6 +103,7 @@ CONFIG_POWER_RESET=y CONFIG_POWER_RESET_MSM=y CONFIG_THERMAL=y CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_MEDIA_SUPPORT=y CONFIG_FB=y CONFIG_SOUND=y @@ -124,6 +125,7 @@ CONFIG_USB_GADGET_DEBUG_FILES=y CONFIG_USB_GADGET_VBUS_DRAW=500 CONFIG_MMC=y CONFIG_MMC_BLOCK_MINORS=16 +CONFIG_MMC_ARMMMCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y CONFIG_MMC_SDHCI_MSM=y @@ -133,11 +135,14 @@ CONFIG_QCOM_BAM_DMA=y CONFIG_STAGING=y CONFIG_QCOM_GSBI=y CONFIG_COMMON_CLK_QCOM=y +CONFIG_APQ_MMCC_8084=y +CONFIG_IPQ_GCC_806X=y CONFIG_MSM_GCC_8660=y CONFIG_MSM_MMCC_8960=y CONFIG_MSM_MMCC_8974=y CONFIG_MSM_IOMMU=y -CONFIG_GENERIC_PHY=y +CONFIG_PHY_QCOM_APQ8064_SATA=y +CONFIG_PHY_QCOM_IPQ806X_SATA=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT3_FS=y -- GitLab From 87cea76384257e6ac3fa4791b6a6b9d0335f7457 Mon Sep 17 00:00:00 2001 From: Xuelin Shi Date: Tue, 1 Jul 2014 16:32:38 +0800 Subject: [PATCH 1066/9167] dmaengine: fix xor sources continuation the partial xor result must be kept until the next tx is generated. Cc: Signed-off-by: Xuelin Shi Signed-off-by: Dan Williams --- crypto/async_tx/async_xor.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 3c562f5a60bb..e1bce26cd4f9 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c @@ -78,8 +78,6 @@ do_async_xor(struct dma_chan *chan, struct dmaengine_unmap_data *unmap, tx = dma->device_prep_dma_xor(chan, dma_dest, src_list, xor_src_cnt, unmap->len, dma_flags); - src_list[0] = tmp; - if (unlikely(!tx)) async_tx_quiesce(&submit->depend_tx); @@ -92,6 +90,7 @@ do_async_xor(struct dma_chan *chan, struct dmaengine_unmap_data *unmap, xor_src_cnt, unmap->len, dma_flags); } + src_list[0] = tmp; dma_set_unmap(tx, unmap); async_tx_submit(chan, tx, submit); -- GitLab From e628ce70cae5ccd67830b0e2c3d038831746d86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20Sch=C3=B6lling?= Date: Thu, 22 May 2014 22:11:06 +0200 Subject: [PATCH 1067/9167] ioat: Use time_before_jiffies() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To be future-proof and for better readability the time comparisons are modified to use time_before_jiffies() instead of plain, error-prone math. Signed-off-by: Manuel Schölling [djbw: use time_before_jiffies() to make argument order more clear] Signed-off-by: Dan Williams --- drivers/dma/ioat/dma_v2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 8d1058085eeb..2ce9be498608 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c @@ -735,7 +735,8 @@ int ioat2_check_space_lock(struct ioat2_dma_chan *ioat, int num_descs) * called under bh_disabled so we need to trigger the timer * event directly */ - if (jiffies > chan->timer.expires && timer_pending(&chan->timer)) { + if (time_is_before_jiffies(chan->timer.expires) + && timer_pending(&chan->timer)) { struct ioatdma_device *device = chan->device; mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT); -- GitLab From 8913dc0bb913ac3dc83ed5c10bac2f4e55431981 Mon Sep 17 00:00:00 2001 From: Paul Zimmerman Date: Thu, 21 Aug 2014 20:28:20 +0000 Subject: [PATCH 1068/9167] usb: gadget: document a usb_ep_dequeue() requirement Document the requirement that the request be dequeued and its completion routine called before usb_ep_dequeue() returns. Also fix some capitalization issues in the existing text. Signed-off-by: Paul Zimmerman Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- include/linux/usb/gadget.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index c3a61853cd13..c540557b564b 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h @@ -345,12 +345,13 @@ static inline int usb_ep_queue(struct usb_ep *ep, * @ep:the endpoint associated with the request * @req:the request being canceled * - * if the request is still active on the endpoint, it is dequeued and its + * If the request is still active on the endpoint, it is dequeued and its * completion routine is called (with status -ECONNRESET); else a negative - * error code is returned. + * error code is returned. This is guaranteed to happen before the call to + * usb_ep_dequeue() returns. * - * note that some hardware can't clear out write fifos (to unlink the request - * at the head of the queue) except as part of disconnecting from usb. such + * Note that some hardware can't clear out write fifos (to unlink the request + * at the head of the queue) except as part of disconnecting from usb. Such * restrictions prevent drivers from supporting configuration changes, * even to configuration zero (a "chapter 9" requirement). */ -- GitLab From 99923753e7c17a9c9d46bfe4d7fa543e426ec647 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Fri, 15 Aug 2014 06:36:28 +0900 Subject: [PATCH 1069/9167] ARM: shmobile: bockw: Do not disable SUSPEND in defconfig As of "ARM: shmobile: r8a7778: Add missing call to shmobile_init_late()" suspend-to-ram is now supported on the r8a7778 SoC and thus the bockw board. Signed-off-by: Simon Horman --- arch/arm/configs/bockw_defconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/configs/bockw_defconfig b/arch/arm/configs/bockw_defconfig index 70b3f451f065..1dde5daa84f9 100644 --- a/arch/arm/configs/bockw_defconfig +++ b/arch/arm/configs/bockw_defconfig @@ -29,7 +29,6 @@ CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_ARM_APPENDED_DTB=y CONFIG_VFP=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -# CONFIG_SUSPEND is not set CONFIG_PM_RUNTIME=y CONFIG_NET=y CONFIG_PACKET=y -- GitLab From da076a888ab19f13816372796ed231e7d6ff5fed Mon Sep 17 00:00:00 2001 From: Mikhail Ulyanov Date: Tue, 19 Aug 2014 16:50:49 +0400 Subject: [PATCH 1070/9167] ARM: shmobile: r8a7790: Add JPU clock dt and CPG define. Signed-off-by: Mikhail Ulyanov Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7790.dtsi | 6 +++--- include/dt-bindings/clock/r8a7790-clock.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 2278bd0968d1..c11541d6dc25 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -836,17 +836,17 @@ mstp1_clks: mstp1_clks@e6150134 { compatible = "renesas,r8a7790-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>; - clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, + clocks = <&m2_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>; #clock-cells = <1>; renesas,clock-indices = < - R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2 + R8A7790_CLK_JPU R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2 R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1 R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_R R8A7790_CLK_VSP1_S >; clock-output-names = - "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", + "jpu", "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", "vsp1-du0", "vsp1-rt", "vsp1-sy"; }; mstp2_clks: mstp2_clks@e6150138 { diff --git a/include/dt-bindings/clock/r8a7790-clock.h b/include/dt-bindings/clock/r8a7790-clock.h index f929a79e6998..8ea7ab0346ad 100644 --- a/include/dt-bindings/clock/r8a7790-clock.h +++ b/include/dt-bindings/clock/r8a7790-clock.h @@ -26,6 +26,7 @@ #define R8A7790_CLK_MSIOF0 0 /* MSTP1 */ +#define R8A7790_CLK_JPU 6 #define R8A7790_CLK_TMU1 11 #define R8A7790_CLK_TMU3 21 #define R8A7790_CLK_TMU2 22 -- GitLab From ed48b5d6fd339d145df5a6a1e48cf56ef265cf4f Mon Sep 17 00:00:00 2001 From: Mikhail Ulyanov Date: Tue, 19 Aug 2014 16:50:51 +0400 Subject: [PATCH 1071/9167] ARM: shmobile: r8a7791: Add JPU clock dt and CPG define. Signed-off-by: Mikhail Ulyanov Acked-by: Laurent Pinchart Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7791.dtsi | 6 +++--- include/dt-bindings/clock/r8a7791-clock.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index f26226e054b3..d62c237e137d 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi @@ -857,16 +857,16 @@ mstp1_clks: mstp1_clks@e6150134 { compatible = "renesas,r8a7791-mstp-clocks", "renesas,cpg-mstp-clocks"; reg = <0 0xe6150134 0 4>, <0 0xe6150038 0 4>; - clocks = <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, + clocks = <&m2_clk>, <&p_clk>, <&p_clk>, <&p_clk>, <&rclk_clk>, <&cp_clk>, <&zs_clk>, <&zs_clk>, <&zs_clk>; #clock-cells = <1>; renesas,clock-indices = < - R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2 + R8A7791_CLK_JPU R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2 R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1 R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_S >; clock-output-names = - "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", + "jpu", "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", "vsp1-du0", "vsp1-sy"; }; mstp2_clks: mstp2_clks@e6150138 { diff --git a/include/dt-bindings/clock/r8a7791-clock.h b/include/dt-bindings/clock/r8a7791-clock.h index f0d4d1049162..58c3f49d068c 100644 --- a/include/dt-bindings/clock/r8a7791-clock.h +++ b/include/dt-bindings/clock/r8a7791-clock.h @@ -25,6 +25,7 @@ #define R8A7791_CLK_MSIOF0 0 /* MSTP1 */ +#define R8A7791_CLK_JPU 6 #define R8A7791_CLK_TMU1 11 #define R8A7791_CLK_TMU3 21 #define R8A7791_CLK_TMU2 22 -- GitLab From 462004f1215ccb77969004a049aa5437f34c9b06 Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Thu, 21 Aug 2014 17:54:55 -0700 Subject: [PATCH 1072/9167] regulator: rk808: Fix uninitialized value The RK808 regulator driver was putting its config on the stack but not initting it. That means that you got a semi-random config. Fix this. Signed-off-by: Doug Anderson Signed-off-by: Mark Brown --- drivers/regulator/rk808-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 94753fd311c1..4d5041ceb56a 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -334,7 +334,7 @@ static int rk808_regulator_probe(struct platform_device *pdev) { struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); struct rk808_board *pdata; - struct regulator_config config; + struct regulator_config config = {}; struct regulator_dev *rk808_rdev; struct regulator_init_data *reg_data; int i = 0; -- GitLab From 2340cd112933ee837aa83017a6da23c72565d501 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:02:10 +0900 Subject: [PATCH 1073/9167] ARM: shmobile: sh7372: Update DTS to include CPU frequency Add CPU Frequency information to the sh7372 DTS file. This will allow us to use the shared C code on sh7372 and Mackerel which reads out the clock frequency from DT and calculates the delay settings from there. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/sh7372.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/boot/dts/sh7372.dtsi b/arch/arm/boot/dts/sh7372.dtsi index 249f65be2a50..f863a10cb1b2 100644 --- a/arch/arm/boot/dts/sh7372.dtsi +++ b/arch/arm/boot/dts/sh7372.dtsi @@ -21,6 +21,7 @@ compatible = "arm,cortex-a8"; device_type = "cpu"; reg = <0x0>; + clock-frequency = <800000000>; }; }; -- GitLab From 13bd825bdd5c087d156d294b427d05dcf9bff281 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:02:19 +0900 Subject: [PATCH 1074/9167] ARM: shmobile: sh73a0: Update DTS to include CPU frequency Add CPU Frequency information to the sh73a0 DTS file. This will allow us to use the shared C code on sh73a0 and KZM9G which reads out the clock frequency from DT and calculates the delay settings from there. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/sh73a0.dtsi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi index 910b79079d5a..175729e59170 100644 --- a/arch/arm/boot/dts/sh73a0.dtsi +++ b/arch/arm/boot/dts/sh73a0.dtsi @@ -23,11 +23,13 @@ device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <0>; + clock-frequency = <1196000000>; }; cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a9"; reg = <1>; + clock-frequency = <1196000000>; }; }; -- GitLab From 869f92aed207f2f6e595ea41c841bd9ad0c0d0d4 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:02:27 +0900 Subject: [PATCH 1075/9167] ARM: shmobile: r8a7778: Update DTS to include CPU frequency Add CPU Frequency information to the r8a7778 DTS file. This will allow us to use the shared C code on r8a7778 and BockW which reads out the clock frequency from DT and calculates the delay settings from there. Also add other missing CPU information to the r8a7778 DTS. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/boot/dts/r8a7778.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi index ecfdf4b01b5a..315ec62cb96b 100644 --- a/arch/arm/boot/dts/r8a7778.dtsi +++ b/arch/arm/boot/dts/r8a7778.dtsi @@ -23,8 +23,14 @@ interrupt-parent = <&gic>; cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu@0 { + device_type = "cpu"; compatible = "arm,cortex-a9"; + reg = <0>; + clock-frequency = <800000000>; }; }; -- GitLab From 39b22e20a3086002c5abe0c569cf11a71bc17faf Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:02:36 +0900 Subject: [PATCH 1076/9167] ARM: shmobile: sh7372: Use shmobile_init_delay() Adjust the sh7372 SoC support code to use shmobile_init_delay() together with CPU Frequency settings from the DTS. Get rid of the C code version. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh7372.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 3731eccccef4..ad7a82d0b1b7 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c @@ -984,7 +984,7 @@ void __init sh7372_add_early_devices(void) void __init sh7372_add_early_devices_dt(void) { - shmobile_setup_delay(800, 1, 3); /* Cortex-A8 @ 800MHz */ + shmobile_init_delay(); sh7372_add_early_devices(); } -- GitLab From f5720080b51d61c33dc559fedab9a601930e95c1 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:03:03 +0900 Subject: [PATCH 1077/9167] ARM: shmobile: r8a73a4: Use shmobile_init_delay() Adjust the r8a73a4 SoC support code to use shmobile_init_delay() together with CPU Frequency settings from the DTS. Get rid of the C code version and r8a73a4_init_early() that now are unused. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/r8a73a4.h | 1 - arch/arm/mach-shmobile/setup-r8a73a4.c | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/arch/arm/mach-shmobile/r8a73a4.h b/arch/arm/mach-shmobile/r8a73a4.h index ce8bdd1d8a8a..5fafd6fcedf7 100644 --- a/arch/arm/mach-shmobile/r8a73a4.h +++ b/arch/arm/mach-shmobile/r8a73a4.h @@ -14,6 +14,5 @@ void r8a73a4_add_standard_devices(void); void r8a73a4_add_dt_devices(void); void r8a73a4_clock_init(void); void r8a73a4_pinmux_init(void); -void r8a73a4_init_early(void); #endif /* __ASM_R8A73A4_H__ */ diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c index 6fbcdcc39d53..53f40b70680d 100644 --- a/arch/arm/mach-shmobile/setup-r8a73a4.c +++ b/arch/arm/mach-shmobile/setup-r8a73a4.c @@ -295,13 +295,6 @@ void __init r8a73a4_add_standard_devices(void) r8a73a4_register_dmac(); } -void __init r8a73a4_init_early(void) -{ -#ifndef CONFIG_ARM_ARCH_TIMER - shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */ -#endif -} - #ifdef CONFIG_USE_OF static const char *r8a73a4_boards_compat_dt[] __initdata = { @@ -310,7 +303,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") - .init_early = r8a73a4_init_early, + .init_early = shmobile_init_delay, .init_late = shmobile_init_late, .dt_compat = r8a73a4_boards_compat_dt, MACHINE_END -- GitLab From 7dd4cfd7f8c2976a8d65022146386480474501ca Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:03:12 +0900 Subject: [PATCH 1078/9167] ARM: shmobile: Remove shmobile_setup_delay() All ARM mach-shmobile SoCs and boards now rely on DTS for CPU Frequency information, so remove the unused function shmobile_setup_delay(). While at it, make the function shmobile_setup_delay_hz() static. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/common.h | 2 -- arch/arm/mach-shmobile/timer.c | 21 ++------------------- 2 files changed, 2 insertions(+), 21 deletions(-) diff --git a/arch/arm/mach-shmobile/common.h b/arch/arm/mach-shmobile/common.h index 98056081f0da..72087c79ad7b 100644 --- a/arch/arm/mach-shmobile/common.h +++ b/arch/arm/mach-shmobile/common.h @@ -2,8 +2,6 @@ #define __ARCH_MACH_COMMON_H extern void shmobile_earlytimer_init(void); -extern void shmobile_setup_delay(unsigned int max_cpu_core_mhz, - unsigned int mult, unsigned int div); extern void shmobile_init_delay(void); struct twd_local_timer; extern void shmobile_setup_console(void); diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c index 942efdc82a62..adce98b44f8a 100644 --- a/arch/arm/mach-shmobile/timer.c +++ b/arch/arm/mach-shmobile/timer.c @@ -23,8 +23,8 @@ #include #include -void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, - unsigned int mult, unsigned int div) +static void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, + unsigned int mult, unsigned int div) { /* calculate a worst-case loops-per-jiffy value * based on maximum cpu core hz setting and the @@ -40,23 +40,6 @@ void __init shmobile_setup_delay_hz(unsigned int max_cpu_core_hz, preset_lpj = max_cpu_core_hz / value; } -void __init shmobile_setup_delay(unsigned int max_cpu_core_mhz, - unsigned int mult, unsigned int div) -{ - /* calculate a worst-case loops-per-jiffy value - * based on maximum cpu core mhz setting and the - * __delay() implementation in arch/arm/lib/delay.S - * - * this will result in a longer delay than expected - * when the cpu core runs on lower frequencies. - */ - - unsigned int value = (1000000 * mult) / (HZ * div); - - if (!preset_lpj) - preset_lpj = max_cpu_core_mhz * value; -} - void __init shmobile_init_delay(void) { struct device_node *np, *cpus; -- GitLab From 5df622a56b7da3c54609f26cc6221ab3382efaaf Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:02:45 +0900 Subject: [PATCH 1079/9167] ARM: shmobile: sh73a0: Use shmobile_init_delay() Adjust the sh73a0 SoC support code to use shmobile_init_delay() together with CPU Frequency settings from the DTS. Get rid of the C code version. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh73a0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index e7a0296b81b1..fe29ebbe3dcf 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -746,7 +746,7 @@ void __init sh73a0_add_standard_devices(void) void __init sh73a0_init_delay(void) { - shmobile_setup_delay(1196, 44, 46); /* Cortex-A9 @ 1196MHz */ + shmobile_init_delay(); } /* do nothing for !CONFIG_SMP or !CONFIG_HAVE_TWD */ -- GitLab From 6fe950ebfd3a374c78ce66a335fce258648426a1 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:02:54 +0900 Subject: [PATCH 1080/9167] ARM: shmobile: r8a7778: Use shmobile_init_delay() Adjust the r8a7778 SoC support code to use shmobile_init_delay() together with CPU Frequency settings from the DTS. Get rid of the C code version. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7778.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c index e1a477bce447..85fe016d6a87 100644 --- a/arch/arm/mach-shmobile/setup-r8a7778.c +++ b/arch/arm/mach-shmobile/setup-r8a7778.c @@ -574,7 +574,7 @@ void __init r8a7778_init_irq_extpin(int irlm) void __init r8a7778_init_delay(void) { - shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ + shmobile_init_delay(); } #ifdef CONFIG_USE_OF -- GitLab From ca609e666c47cceb64610ad703dda1bebafef605 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:03:21 +0900 Subject: [PATCH 1081/9167] ARM: shmobile: bockw: Use shmobile_init_delay() Adjust the BockW board support code to use shmobile_init_delay() together with CPU Frequency settings from the DTS. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-bockw-reference.c | 2 +- arch/arm/mach-shmobile/board-bockw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-shmobile/board-bockw-reference.c b/arch/arm/mach-shmobile/board-bockw-reference.c index 9202f1641a16..79c47847f200 100644 --- a/arch/arm/mach-shmobile/board-bockw-reference.c +++ b/arch/arm/mach-shmobile/board-bockw-reference.c @@ -80,7 +80,7 @@ static const char *bockw_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(BOCKW_DT, "bockw") - .init_early = r8a7778_init_delay, + .init_early = shmobile_init_delay, .init_irq = r8a7778_init_irq_dt, .init_machine = bockw_init, .init_late = shmobile_init_late, diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index 8a83eb39d3f1..1cf2c75dacfb 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c @@ -733,7 +733,7 @@ static const char *bockw_boards_compat_dt[] __initdata = { }; DT_MACHINE_START(BOCKW_DT, "bockw") - .init_early = r8a7778_init_delay, + .init_early = shmobile_init_delay, .init_irq = r8a7778_init_irq_dt, .init_machine = bockw_init, .dt_compat = bockw_boards_compat_dt, -- GitLab From fc35ca258c079411b64ed94e517eb04e7d89bc44 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:03:30 +0900 Subject: [PATCH 1082/9167] ARM: shmobile: kzm9g: Use shmobile_init_delay() Adjust the KZM9G board support code to use shmobile_init_delay() together with CPU Frequency settings from the DTS. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-kzm9g-reference.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-kzm9g-reference.c b/arch/arm/mach-shmobile/board-kzm9g-reference.c index 1694a1609296..d9cdf9a97e23 100644 --- a/arch/arm/mach-shmobile/board-kzm9g-reference.c +++ b/arch/arm/mach-shmobile/board-kzm9g-reference.c @@ -51,7 +51,7 @@ static const char *kzm9g_boards_compat_dt[] __initdata = { DT_MACHINE_START(KZM9G_DT, "kzm9g-reference") .smp = smp_ops(sh73a0_smp_ops), .map_io = sh73a0_map_io, - .init_early = sh73a0_init_delay, + .init_early = shmobile_init_delay, .init_machine = kzm_init, .init_late = shmobile_init_late, .dt_compat = kzm9g_boards_compat_dt, -- GitLab From d6fb17ad7c9e0aa28ce0bc2e33790f9459677370 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 8 Aug 2014 16:23:09 +0200 Subject: [PATCH 1083/9167] ARM: shmobile: r8a7740: clock register bits Contains the header file with the clock pulse generator and MSTP bits. Signed-off-by: Ulrich Hecht Signed-off-by: Simon Horman --- include/dt-bindings/clock/r8a7740-clock.h | 77 +++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 include/dt-bindings/clock/r8a7740-clock.h diff --git a/include/dt-bindings/clock/r8a7740-clock.h b/include/dt-bindings/clock/r8a7740-clock.h new file mode 100644 index 000000000000..f6b4b0fe7a43 --- /dev/null +++ b/include/dt-bindings/clock/r8a7740-clock.h @@ -0,0 +1,77 @@ +/* + * Copyright 2014 Ulrich Hecht + * + * 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 __DT_BINDINGS_CLOCK_R8A7740_H__ +#define __DT_BINDINGS_CLOCK_R8A7740_H__ + +/* CPG */ +#define R8A7740_CLK_SYSTEM 0 +#define R8A7740_CLK_PLLC0 1 +#define R8A7740_CLK_PLLC1 2 +#define R8A7740_CLK_PLLC2 3 +#define R8A7740_CLK_R 4 +#define R8A7740_CLK_USB24S 5 +#define R8A7740_CLK_I 6 +#define R8A7740_CLK_ZG 7 +#define R8A7740_CLK_B 8 +#define R8A7740_CLK_M1 9 +#define R8A7740_CLK_HP 10 +#define R8A7740_CLK_HPP 11 +#define R8A7740_CLK_USBP 12 +#define R8A7740_CLK_S 13 +#define R8A7740_CLK_ZB 14 +#define R8A7740_CLK_M3 15 +#define R8A7740_CLK_CP 16 + +/* MSTP1 */ +#define R8A7740_CLK_CEU21 28 +#define R8A7740_CLK_CEU20 27 +#define R8A7740_CLK_TMU0 25 +#define R8A7740_CLK_LCDC1 17 +#define R8A7740_CLK_IIC0 16 +#define R8A7740_CLK_TMU1 11 +#define R8A7740_CLK_LCDC0 0 + +/* MSTP2 */ +#define R8A7740_CLK_SCIFA6 30 +#define R8A7740_CLK_SCIFA7 22 +#define R8A7740_CLK_DMAC1 18 +#define R8A7740_CLK_DMAC2 17 +#define R8A7740_CLK_DMAC3 16 +#define R8A7740_CLK_USBDMAC 14 +#define R8A7740_CLK_SCIFA5 7 +#define R8A7740_CLK_SCIFB 6 +#define R8A7740_CLK_SCIFA0 4 +#define R8A7740_CLK_SCIFA1 3 +#define R8A7740_CLK_SCIFA2 2 +#define R8A7740_CLK_SCIFA3 1 +#define R8A7740_CLK_SCIFA4 0 + +/* MSTP3 */ +#define R8A7740_CLK_CMT1 29 +#define R8A7740_CLK_FSI 28 +#define R8A7740_CLK_IIC1 23 +#define R8A7740_CLK_USBF 20 +#define R8A7740_CLK_SDHI0 14 +#define R8A7740_CLK_SDHI1 13 +#define R8A7740_CLK_MMC 12 +#define R8A7740_CLK_GETHER 9 +#define R8A7740_CLK_TPU0 4 + +/* MSTP4 */ +#define R8A7740_CLK_USBH 16 +#define R8A7740_CLK_SDHI2 15 +#define R8A7740_CLK_USBFUNC 7 +#define R8A7740_CLK_USBPHY 6 + +/* SUBCK* */ +#define R8A7740_CLK_SUBCK 9 +#define R8A7740_CLK_SUBCK2 10 + +#endif /* __DT_BINDINGS_CLOCK_R8A7740_H__ */ -- GitLab From aa0bdc303b0f8bc59fc0a0645560917810ba041b Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:07:07 +0900 Subject: [PATCH 1084/9167] ARM: shmobile: sh73a0: Remove duplicate CPUFreq bits The CPUFreq platform device is already registered by shmobile_init_late(), so get rid of sh73a0 specific bits. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-sh73a0.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c index e7a0296b81b1..8ff96799e66c 100644 --- a/arch/arm/mach-shmobile/setup-sh73a0.c +++ b/arch/arm/mach-shmobile/setup-sh73a0.c @@ -775,17 +775,12 @@ void __init sh73a0_add_early_devices(void) void __init sh73a0_add_standard_devices_dt(void) { - struct platform_device_info devinfo = { .name = "cpufreq-cpu0", .id = -1, }; - /* clocks are setup late during boot in the case of DT */ sh73a0_clock_init(); platform_add_devices(sh73a0_devices_dt, ARRAY_SIZE(sh73a0_devices_dt)); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); - - /* Instantiate cpufreq-cpu0 */ - platform_device_register_full(&devinfo); } static const char *sh73a0_boards_compat_dt[] __initdata = { -- GitLab From 664b4c172209f076866419a5a4162e4fc9631807 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 20 Aug 2014 22:10:15 +0900 Subject: [PATCH 1085/9167] ARM: shmobile: ape6evm: Remove duplicate CPUFreq bits The CPUFreq platform device is already registered by shmobile_init_late(), so get rid of ape6evm specific bits. Signed-off-by: Magnus Damm Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-ape6evm-reference.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-shmobile/board-ape6evm-reference.c b/arch/arm/mach-shmobile/board-ape6evm-reference.c index 2f7723e5fe91..ac371b78f05c 100644 --- a/arch/arm/mach-shmobile/board-ape6evm-reference.c +++ b/arch/arm/mach-shmobile/board-ape6evm-reference.c @@ -50,7 +50,6 @@ static void __init ape6evm_add_standard_devices(void) r8a73a4_add_dt_devices(); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); - platform_device_register_simple("cpufreq-cpu0", -1, NULL, 0); } static const char *ape6evm_boards_compat_dt[] __initdata = { -- GitLab From 86155b35d173317518458c6f9c0a3ea8c5324bed Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 20 Aug 2014 15:39:23 +0200 Subject: [PATCH 1086/9167] ARM: shmobile: Move legacy INTC definitions from irqs.h to intc.h Move all definitions for legacy INTC from the common "irqs.h" to the INTC-specific "intc.h". Include "intc.h" in sh7372/sh73a0 CPU and board files where needed. Signed-off-by: Geert Uytterhoeven Acked-by: Magnus Damm [horms+renesas@verge.net.au: omitted whitespace change] Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/board-kzm9g.c | 1 + arch/arm/mach-shmobile/board-mackerel.c | 1 + arch/arm/mach-shmobile/intc.h | 5 +++++ arch/arm/mach-shmobile/irqs.h | 6 ------ arch/arm/mach-shmobile/setup-sh7372.c | 1 + arch/arm/mach-shmobile/setup-sh73a0.c | 1 + 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index f8bc7f8f86ad..1bcd7eb8355c 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -50,6 +50,7 @@ #include