* Re: [PATCH] net: check payload length limit for all frames
From: Li Qiang @ 2020-07-17 0:53 UTC (permalink / raw)
To: P J P
Cc: Alexander Bulekov, Jason Wang, Dmitry Fleytman, QEMU Developers,
Prasad J Pandit
In-Reply-To: <20200716192335.1212638-1-ppandit@redhat.com>
P J P <ppandit@redhat.com> 于2020年7月17日周五 上午3:26写道:
>
> From: Prasad J Pandit <pjp@fedoraproject.org>
>
> While sending packets, the check that packet 'payload_len'
> is within 64kB limit, seems to happen only for GSO frames.
> It may lead to use-after-free or out-of-bounds access like
> issues when sending non-GSO frames. Check the 'payload_len'
> limit for all packets, irrespective of the gso type.
>
Hello Prasad,
Which issue are you trying to solve, any reference linking?
I also send a patch related this part and also a UAF.
Thanks,
Li Qiang
> Reported-by: Alexander Bulekov <alxndr@bu.edu>
> Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
> ---
> hw/net/net_tx_pkt.c | 10 ++++------
> 1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c
> index 162f802dd7..e66998a8f9 100644
> --- a/hw/net/net_tx_pkt.c
> +++ b/hw/net/net_tx_pkt.c
> @@ -607,12 +607,10 @@ bool net_tx_pkt_send(struct NetTxPkt *pkt, NetClientState *nc)
> * Since underlying infrastructure does not support IP datagrams longer
> * than 64K we should drop such packets and don't even try to send
> */
> - if (VIRTIO_NET_HDR_GSO_NONE != pkt->virt_hdr.gso_type) {
> - if (pkt->payload_len >
> - ETH_MAX_IP_DGRAM_LEN -
> - pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len) {
> - return false;
> - }
> + if (pkt->payload_len >
> + ETH_MAX_IP_DGRAM_LEN -
> + pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_len) {
> + return false;
> }
>
> if (pkt->has_virt_hdr ||
> --
> 2.26.2
>
>
^ permalink raw reply
* Re: [PATCH net-next 2/2] hinic: add log in exception handling processes
From: luobin (L) @ 2020-07-17 0:52 UTC (permalink / raw)
To: Jakub Kicinski
Cc: davem, linux-kernel, netdev, luoxianjun, yin.yinshi,
cloud.wangxiaoyun, chiqijun
In-Reply-To: <20200716082710.22dd7c97@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com>
On 2020/7/16 23:27, Jakub Kicinski wrote:
> On Thu, 16 Jul 2020 20:50:56 +0800 Luo bin wrote:
>> improve the error message when functions return failure and dump
>> relevant registers in some exception handling processes
>>
>> Signed-off-by: Luo bin <luobin9@huawei.com>
>
> For kernel builds with W=1 C=1 flags this patch adds 12 warnings to
> drivers/net/ethernet/huawei/hinic/hinic_hw_eqs.c and 39 warnings to
> drivers/net/ethernet/huawei/hinic/hinic_hw_if.h.
>
> It seems like you're missing byte swaps.
> .
>
Will fix. Thank you!
^ permalink raw reply
* Re: [PATCH V3 net-next 1/8] net: ena: avoid unnecessary rearming of interrupt vector when busy-polling
From: Jakub Kicinski @ 2020-07-17 0:52 UTC (permalink / raw)
To: akiyano
Cc: davem, netdev, dwmw, zorik, matua, saeedb, msw, aliguori, nafea,
gtzalik, netanel, alisaidi, benh, ndagan, shayagr, sameehj,
Eric Dumazet
In-Reply-To: <1594923010-6234-2-git-send-email-akiyano@amazon.com>
On Thu, 16 Jul 2020 21:10:03 +0300 akiyano@amazon.com wrote:
> This patch doesn't require smp_rmb() instruction in the napi routine
> because it assumes cache coherency between two cores. I.e. the
> 'interrupts_masked' flag set would be seen by the napi routine, even if
> the flag is stored in L1 cache.
> To the best of my knowledge this assumption holds for ARM64 and x86_64
> architecture which use a MESI like cache coherency model.
If that's the case - for those architectures smb_rmb() should be defined
to barrier(). Why can't you adhere to kernel's memory model, rather
than guessing the architecture in the driver.
^ permalink raw reply
* [PATCH V4 3/3] nvme-pci: get rid of the division in the fast path
From: Chaitanya Kulkarni @ 2020-07-17 0:51 UTC (permalink / raw)
To: kbusch, hch, sagi; +Cc: Chaitanya Kulkarni, linux-nvme
In-Reply-To: <20200717005139.18923-1-chaitanya.kulkarni@wdc.com>
Since we have a macro for calculating the size of the ctrl page we can
remove the division in the fast path for nvme-pci in nvme_unmap_data().
Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
drivers/nvme/host/pci.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 3c852a8f18ed..616db1ae137c 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -513,7 +513,8 @@ static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req)
static void nvme_unmap_data(struct nvme_dev *dev, struct request *req)
{
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
- const int last_prp = NVME_CTRL_PAGE_SIZE / sizeof(__le64) - 1;
+ const int last_prp = (NVME_CTRL_PAGE_SIZE >> ilog2(sizeof(__le64))) - 1;
+
dma_addr_t dma_addr = iod->first_dma, next_dma_addr;
int i;
--
2.26.0
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
^ permalink raw reply related
* [PATCH V4 1/3] nvme-core: replace ctrl page size with a macro
From: Chaitanya Kulkarni @ 2020-07-17 0:51 UTC (permalink / raw)
To: kbusch, hch, sagi; +Cc: Chaitanya Kulkarni, linux-nvme
In-Reply-To: <20200717005139.18923-1-chaitanya.kulkarni@wdc.com>
Saving the nvme controller's page size was from a time when the driver
tried to use different sized pages, but this value is always set to
a constant, and has been this way for some time. Remove the 'page_size'
field and replace its usage with the constant value.
This also lets the compiler make some micro-optimizations in the io
path, and that's always a good thing.
Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
drivers/nvme/host/core.c | 19 +++++-----------
drivers/nvme/host/nvme.h | 9 +++++++-
drivers/nvme/host/pci.c | 47 ++++++++++++++++++++--------------------
3 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f49085bcaa42..1d7c7afb1348 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2345,12 +2345,7 @@ EXPORT_SYMBOL_GPL(nvme_disable_ctrl);
int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
{
- /*
- * Default to a 4K page size, with the intention to update this
- * path in the future to accomodate architectures with differing
- * kernel and IO page sizes.
- */
- unsigned dev_page_min, page_shift = 12;
+ unsigned dev_page_min;
int ret;
ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &ctrl->cap);
@@ -2360,20 +2355,18 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl)
}
dev_page_min = NVME_CAP_MPSMIN(ctrl->cap) + 12;
- if (page_shift < dev_page_min) {
+ if (NVME_CTRL_PAGE_SHIFT < dev_page_min) {
dev_err(ctrl->device,
"Minimum device page size %u too large for host (%u)\n",
- 1 << dev_page_min, 1 << page_shift);
+ 1 << dev_page_min, 1 << NVME_CTRL_PAGE_SHIFT);
return -ENODEV;
}
- ctrl->page_size = 1 << page_shift;
-
if (NVME_CAP_CSS(ctrl->cap) & NVME_CAP_CSS_CSI)
ctrl->ctrl_config = NVME_CC_CSS_CSI;
else
ctrl->ctrl_config = NVME_CC_CSS_NVM;
- ctrl->ctrl_config |= (page_shift - 12) << NVME_CC_MPS_SHIFT;
+ ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT;
ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE;
ctrl->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
ctrl->ctrl_config |= NVME_CC_ENABLE;
@@ -2423,13 +2416,13 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
if (ctrl->max_hw_sectors) {
u32 max_segments =
- (ctrl->max_hw_sectors / (ctrl->page_size >> 9)) + 1;
+ (ctrl->max_hw_sectors / (NVME_CTRL_PAGE_SIZE >> 9)) + 1;
max_segments = min_not_zero(max_segments, ctrl->max_segments);
blk_queue_max_hw_sectors(q, ctrl->max_hw_sectors);
blk_queue_max_segments(q, min_t(u32, max_segments, USHRT_MAX));
}
- blk_queue_virt_boundary(q, ctrl->page_size - 1);
+ blk_queue_virt_boundary(q, NVME_CTRL_PAGE_SIZE - 1);
blk_queue_dma_alignment(q, 7);
if (ctrl->vwc & NVME_CTRL_VWC_PRESENT)
vwc = true;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 13ca90bcd352..2ee91a3dd8e0 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -37,6 +37,14 @@ extern unsigned int admin_timeout;
#define NVME_INLINE_METADATA_SG_CNT 1
#endif
+/*
+ * Default to a 4K page size, with the intention to update this
+ * path in the future to accommodate architectures with differing
+ * kernel and IO page sizes.
+ */
+#define NVME_CTRL_PAGE_SHIFT 12
+#define NVME_CTRL_PAGE_SIZE (1 << NVME_CTRL_PAGE_SHIFT)
+
extern struct workqueue_struct *nvme_wq;
extern struct workqueue_struct *nvme_reset_wq;
extern struct workqueue_struct *nvme_delete_wq;
@@ -234,7 +242,6 @@ struct nvme_ctrl {
u32 queue_count;
u64 cap;
- u32 page_size;
u32 max_hw_sectors;
u32 max_segments;
u32 max_integrity_segments;
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 45e94f016ec2..b092df266501 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -348,8 +348,8 @@ static bool nvme_dbbuf_update_and_check_event(u16 value, u32 *dbbuf_db,
*/
static int nvme_npages(unsigned size, struct nvme_dev *dev)
{
- unsigned nprps = DIV_ROUND_UP(size + dev->ctrl.page_size,
- dev->ctrl.page_size);
+ unsigned nprps = DIV_ROUND_UP(size + NVME_CTRL_PAGE_SIZE,
+ NVME_CTRL_PAGE_SIZE);
return DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
}
@@ -515,7 +515,7 @@ static inline bool nvme_pci_use_sgls(struct nvme_dev *dev, struct request *req)
static void nvme_unmap_data(struct nvme_dev *dev, struct request *req)
{
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
- const int last_prp = dev->ctrl.page_size / sizeof(__le64) - 1;
+ const int last_prp = NVME_CTRL_PAGE_SIZE / sizeof(__le64) - 1;
dma_addr_t dma_addr = iod->first_dma, next_dma_addr;
int i;
@@ -582,34 +582,33 @@ static blk_status_t nvme_pci_setup_prps(struct nvme_dev *dev,
struct scatterlist *sg = iod->sg;
int dma_len = sg_dma_len(sg);
u64 dma_addr = sg_dma_address(sg);
- u32 page_size = dev->ctrl.page_size;
- int offset = dma_addr & (page_size - 1);
+ int offset = dma_addr & (NVME_CTRL_PAGE_SIZE - 1);
__le64 *prp_list;
void **list = nvme_pci_iod_list(req);
dma_addr_t prp_dma;
int nprps, i;
- length -= (page_size - offset);
+ length -= (NVME_CTRL_PAGE_SIZE - offset);
if (length <= 0) {
iod->first_dma = 0;
goto done;
}
- dma_len -= (page_size - offset);
+ dma_len -= (NVME_CTRL_PAGE_SIZE - offset);
if (dma_len) {
- dma_addr += (page_size - offset);
+ dma_addr += (NVME_CTRL_PAGE_SIZE - offset);
} else {
sg = sg_next(sg);
dma_addr = sg_dma_address(sg);
dma_len = sg_dma_len(sg);
}
- if (length <= page_size) {
+ if (length <= NVME_CTRL_PAGE_SIZE) {
iod->first_dma = dma_addr;
goto done;
}
- nprps = DIV_ROUND_UP(length, page_size);
+ nprps = DIV_ROUND_UP(length, NVME_CTRL_PAGE_SIZE);
if (nprps <= (256 / 8)) {
pool = dev->prp_small_pool;
iod->npages = 0;
@@ -628,7 +627,7 @@ static blk_status_t nvme_pci_setup_prps(struct nvme_dev *dev,
iod->first_dma = prp_dma;
i = 0;
for (;;) {
- if (i == page_size >> 3) {
+ if (i == NVME_CTRL_PAGE_SIZE >> 3) {
__le64 *old_prp_list = prp_list;
prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
if (!prp_list)
@@ -639,9 +638,9 @@ static blk_status_t nvme_pci_setup_prps(struct nvme_dev *dev,
i = 1;
}
prp_list[i++] = cpu_to_le64(dma_addr);
- dma_len -= page_size;
- dma_addr += page_size;
- length -= page_size;
+ dma_len -= NVME_CTRL_PAGE_SIZE;
+ dma_addr += NVME_CTRL_PAGE_SIZE;
+ length -= NVME_CTRL_PAGE_SIZE;
if (length <= 0)
break;
if (dma_len > 0)
@@ -751,8 +750,8 @@ static blk_status_t nvme_setup_prp_simple(struct nvme_dev *dev,
struct bio_vec *bv)
{
struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
- unsigned int offset = bv->bv_offset & (dev->ctrl.page_size - 1);
- unsigned int first_prp_len = dev->ctrl.page_size - offset;
+ unsigned int offset = bv->bv_offset & (NVME_CTRL_PAGE_SIZE - 1);
+ unsigned int first_prp_len = NVME_CTRL_PAGE_SIZE - offset;
iod->first_dma = dma_map_bvec(dev->dev, bv, rq_dma_dir(req), 0);
if (dma_mapping_error(dev->dev, iod->first_dma))
@@ -794,7 +793,7 @@ static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req,
struct bio_vec bv = req_bvec(req);
if (!is_pci_p2pdma_page(bv.bv_page)) {
- if (bv.bv_offset + bv.bv_len <= dev->ctrl.page_size * 2)
+ if (bv.bv_offset + bv.bv_len <= NVME_CTRL_PAGE_SIZE * 2)
return nvme_setup_prp_simple(dev, req,
&cmnd->rw, &bv);
@@ -1396,12 +1395,12 @@ static int nvme_cmb_qdepth(struct nvme_dev *dev, int nr_io_queues,
{
int q_depth = dev->q_depth;
unsigned q_size_aligned = roundup(q_depth * entry_size,
- dev->ctrl.page_size);
+ NVME_CTRL_PAGE_SIZE);
if (q_size_aligned * nr_io_queues > dev->cmb_size) {
u64 mem_per_q = div_u64(dev->cmb_size, nr_io_queues);
- mem_per_q = round_down(mem_per_q, dev->ctrl.page_size);
+ mem_per_q = round_down(mem_per_q, NVME_CTRL_PAGE_SIZE);
q_depth = div_u64(mem_per_q, entry_size);
/*
@@ -1816,6 +1815,7 @@ static inline void nvme_release_cmb(struct nvme_dev *dev)
static int nvme_set_host_mem(struct nvme_dev *dev, u32 bits)
{
+ u32 host_mem_size = dev->host_mem_size >> NVME_CTRL_PAGE_SHIFT;
u64 dma_addr = dev->host_mem_descs_dma;
struct nvme_command c;
int ret;
@@ -1824,8 +1824,7 @@ static int nvme_set_host_mem(struct nvme_dev *dev, u32 bits)
c.features.opcode = nvme_admin_set_features;
c.features.fid = cpu_to_le32(NVME_FEAT_HOST_MEM_BUF);
c.features.dword11 = cpu_to_le32(bits);
- c.features.dword12 = cpu_to_le32(dev->host_mem_size >>
- ilog2(dev->ctrl.page_size));
+ c.features.dword12 = cpu_to_le32(host_mem_size);
c.features.dword13 = cpu_to_le32(lower_32_bits(dma_addr));
c.features.dword14 = cpu_to_le32(upper_32_bits(dma_addr));
c.features.dword15 = cpu_to_le32(dev->nr_host_mem_descs);
@@ -1845,7 +1844,7 @@ static void nvme_free_host_mem(struct nvme_dev *dev)
for (i = 0; i < dev->nr_host_mem_descs; i++) {
struct nvme_host_mem_buf_desc *desc = &dev->host_mem_descs[i];
- size_t size = le32_to_cpu(desc->size) * dev->ctrl.page_size;
+ size_t size = le32_to_cpu(desc->size) * NVME_CTRL_PAGE_SIZE;
dma_free_attrs(dev->dev, size, dev->host_mem_desc_bufs[i],
le64_to_cpu(desc->addr),
@@ -1897,7 +1896,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
break;
descs[i].addr = cpu_to_le64(dma_addr);
- descs[i].size = cpu_to_le32(len / dev->ctrl.page_size);
+ descs[i].size = cpu_to_le32(len / NVME_CTRL_PAGE_SIZE);
i++;
}
@@ -1913,7 +1912,7 @@ static int __nvme_alloc_host_mem(struct nvme_dev *dev, u64 preferred,
out_free_bufs:
while (--i >= 0) {
- size_t size = le32_to_cpu(descs[i].size) * dev->ctrl.page_size;
+ size_t size = le32_to_cpu(descs[i].size) * NVME_CTRL_PAGE_SIZE;
dma_free_attrs(dev->dev, size, bufs[i],
le64_to_cpu(descs[i].addr),
--
2.26.0
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
^ permalink raw reply related
* [PATCH V4 2/3] nvme-pci: use max of PRP or SGL for iod size
From: Chaitanya Kulkarni @ 2020-07-17 0:51 UTC (permalink / raw)
To: kbusch, hch, sagi; +Cc: Chaitanya Kulkarni, linux-nvme
In-Reply-To: <20200717005139.18923-1-chaitanya.kulkarni@wdc.com>
From the initial implementation of NVMe SGL kernel support
commit a7a7cbe353a5 ("nvme-pci: add SGL support") with addition of the
commit 943e942e6266 ("nvme-pci: limit max IO size and segments to avoid
high order allocations") now there is only caller left for
nvme_pci_iod_alloc_size() which statically passes true for last
parameter that calculates allocation size based on SGL since we need
size of biggest command supported for mempool allocation.
This patch modifies the helper functions nvme_pci_iod_alloc_size() such
that it is now uses maximum of PRP and SGL size for iod allocation size
calculation.
Signed-off-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
---
drivers/nvme/host/pci.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index b092df266501..3c852a8f18ed 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -362,17 +362,15 @@ static int nvme_pci_npages_sgl(unsigned int num_seg)
return DIV_ROUND_UP(num_seg * sizeof(struct nvme_sgl_desc), PAGE_SIZE);
}
-static size_t nvme_pci_iod_alloc_size(struct nvme_dev *dev,
- unsigned int size, unsigned int nseg, bool use_sgl)
+static size_t nvme_pci_iod_alloc_size(struct nvme_dev *dev)
{
- size_t alloc_size;
+ size_t npages_sgl = nvme_pci_npages_sgl(NVME_MAX_SEGS);
+ size_t npages = nvme_npages(NVME_MAX_KB_SZ, dev);
+ size_t alloc_size = sizeof(__le64 *);
- if (use_sgl)
- alloc_size = sizeof(__le64 *) * nvme_pci_npages_sgl(nseg);
- else
- alloc_size = sizeof(__le64 *) * nvme_npages(size, dev);
+ alloc_size *= max_t(size_t, npages_sgl, npages);
- return alloc_size + sizeof(struct scatterlist) * nseg;
+ return alloc_size + sizeof(struct scatterlist) * NVME_MAX_SEGS;
}
static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
@@ -2811,8 +2809,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
* Double check that our mempool alloc size will cover the biggest
* command we support.
*/
- alloc_size = nvme_pci_iod_alloc_size(dev, NVME_MAX_KB_SZ,
- NVME_MAX_SEGS, true);
+ alloc_size = nvme_pci_iod_alloc_size(dev);
WARN_ON_ONCE(alloc_size > PAGE_SIZE);
dev->iod_mempool = mempool_create_node(1, mempool_kmalloc,
--
2.26.0
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
^ permalink raw reply related
* [PATCH V4 0/3] nvme: fix iod size calculation in nvme_probe()
From: Chaitanya Kulkarni @ 2020-07-17 0:51 UTC (permalink / raw)
To: kbusch, hch, sagi; +Cc: Chaitanya Kulkarni, linux-nvme
Hi,
This is a small patch series which fixes the IO size calulation in the
nvme_probe.
The first patch replaces the ctrl->page_size with a macro. The second
patch calculates the maximum value based on NVMe PRP and SGL size.
I've tested this patch with different block sizes 4k-128k on NVMe QEMU
and NVMe PCIe (non-SGL) controller.
In this version I've also added 3rd patch to get rid of the division in
nvme_unmap_data() since we've hardcoded the value of the ctrl page size
in the macro.
Regards,
Chaitanya
* Chagnes from V3:-
-------------------
1. Use (1 << NVME_CTRL_PAGE_SHIF)T for NVME_CTRL_PAGE_SIZE value.
2. Remove size and nseg parameters for the nvme_pci_iod_alloc_size() and
hardcode them in the code.
3. Added 3rd patch to get rid of the division in nvme_unmap_data().
* Changes from V2:-
-------------------
1. Modify commit log for patch 1.
2. Repalace ilog2(NVME_CTRL_PAGE_SIZE) -> NVME_CTRL_PAGE_SHIFT.
* Changes from V1:-
-------------------
1. Remove the ctrl->page_size and use macro instead.
2. Get rid of the conditional operater and use max_t() for SGL vs PRP
size calulation.
Chaitanya Kulkarni (3):
nvme-core: replace ctrl page size with a macro
nvme-pci: use max of PRP or SGL for iod size
nvme-pci: get rid of the division in the fast path
drivers/nvme/host/core.c | 19 ++++--------
drivers/nvme/host/nvme.h | 9 +++++-
drivers/nvme/host/pci.c | 65 +++++++++++++++++++---------------------
3 files changed, 45 insertions(+), 48 deletions(-)
--
2.26.0
_______________________________________________
Linux-nvme mailing list
Linux-nvme@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-nvme
^ permalink raw reply
* [pinctrl:devel 63/64] drivers/pinctrl/mediatek/pinctrl-mt6779.c:775:15: error: a parameter list without types is only allowed in a function definition
From: kernel test robot @ 2020-07-17 0:46 UTC (permalink / raw)
To: Hanks Chen
Cc: kbuild-all, clang-built-linux, linux-gpio, Linus Walleij,
Mars Cheng, Andy Teng
[-- Attachment #1: Type: text/plain, Size: 1792 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
head: d9ce0e9fdfd37d45f669b831d0c084a7c9338ee8
commit: e6f744c6ad4fb3b7ac06d4e22b79e435578a6d54 [63/64] pinctrl: mediatek: add pinctrl support for MT6779 SoC
config: x86_64-allmodconfig (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project ed6b578040a85977026c93bf4188f996148f3218)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
git checkout e6f744c6ad4fb3b7ac06d4e22b79e435578a6d54
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
>> drivers/pinctrl/mediatek/pinctrl-mt6779.c:775:1: warning: declaration specifier missing, defaulting to 'int'
arch_initcall(mt6779_pinctrl_init);
^
int
>> drivers/pinctrl/mediatek/pinctrl-mt6779.c:775:15: error: a parameter list without types is only allowed in a function definition
arch_initcall(mt6779_pinctrl_init);
^
1 warning and 1 error generated.
vim +775 drivers/pinctrl/mediatek/pinctrl-mt6779.c
770
771 static int __init mt6779_pinctrl_init(void)
772 {
773 return platform_driver_register(&mt6779_pinctrl_driver);
774 }
> 775 arch_initcall(mt6779_pinctrl_init);
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 75947 bytes --]
^ permalink raw reply
* Re: [PATCH v18 06/14] mm/damon: Implement callbacks for the virtual memory address spaces
From: Shakeel Butt @ 2020-07-17 0:46 UTC (permalink / raw)
To: SeongJae Park
Cc: Andrew Morton, SeongJae Park, Jonathan.Cameron, Andrea Arcangeli,
acme, alexander.shishkin, amit, benh, brendan.d.gregg,
Brendan Higgins, Qian Cai, Colin Ian King, Jonathan Corbet,
David Hildenbrand, dwmw, foersleo, Ian Rogers, jolsa,
Kirill A. Shutemov, mark.rutland, Mel Gorman, Minchan Kim,
Ingo Molnar, namhyung, Peter Zijlstra (Intel), Randy Dunlap,
Rik van Riel, David Rientjes, Steven Rostedt, rppt, sblbir, shuah,
sj38.park, snu, Vlastimil Babka, Vladimir Davydov, Yang Shi,
Huang Ying, linux-damon, Linux MM, linux-doc, LKML
In-Reply-To: <20200713084144.4430-7-sjpark@amazon.com>
On Mon, Jul 13, 2020 at 1:44 AM SeongJae Park <sjpark@amazon.com> wrote:
>
> From: SeongJae Park <sjpark@amazon.de>
>
> This commit introduces a reference implementation of the address space
> specific low level primitives for the virtual address space, so that
> users of DAMON can easily monitor the data accesses on virtual address
> spaces of specific processes by simply configuring the implementation to
> be used by DAMON.
>
> The low level primitives for the fundamental access monitoring are
> defined in two parts:
> 1. Identification of the monitoring target address range for the address
> space.
> 2. Access check of specific address range in the target space.
>
> The reference implementation for the virtual address space provided by
> this commit is designed as below.
>
> PTE Accessed-bit Based Access Check
> -----------------------------------
>
> The implementation uses PTE Accessed-bit for basic access checks. That
> is, it clears the bit for next sampling target page and checks whether
> it set again after one sampling period. To avoid disturbing other
> Accessed bit users such as the reclamation logic, the implementation
> adjusts the ``PG_Idle`` and ``PG_Young`` appropriately, as same to the
> 'Idle Page Tracking'.
>
> VMA-based Target Address Range Construction
> -------------------------------------------
>
> Only small parts in the super-huge virtual address space of the
> processes are mapped to physical memory and accessed. Thus, tracking
> the unmapped address regions is just wasteful. However, because DAMON
> can deal with some level of noise using the adaptive regions adjustment
> mechanism, tracking every mapping is not strictly required but could
> even incur a high overhead in some cases. That said, too huge unmapped
> areas inside the monitoring target should be removed to not take the
> time for the adaptive mechanism.
>
> For the reason, this implementation converts the complex mappings to
> three distinct regions that cover every mapped area of the address
> space. Also, the two gaps between the three regions are the two biggest
> unmapped areas in the given address space. The two biggest unmapped
> areas would be the gap between the heap and the uppermost mmap()-ed
> region, and the gap between the lowermost mmap()-ed region and the stack
> in most of the cases. Because these gaps are exceptionally huge in
> usual address spacees, excluding these will be sufficient to make a
> reasonable trade-off. Below shows this in detail::
>
> <heap>
> <BIG UNMAPPED REGION 1>
> <uppermost mmap()-ed region>
> (small mmap()-ed regions and munmap()-ed regions)
> <lowermost mmap()-ed region>
> <BIG UNMAPPED REGION 2>
> <stack>
>
> Signed-off-by: SeongJae Park <sjpark@amazon.de>
> Reviewed-by: Leonard Foerster <foersleo@amazon.de>
[snip]
> +
> +static void damon_mkold(struct mm_struct *mm, unsigned long addr)
> +{
> + pte_t *pte = NULL;
> + pmd_t *pmd = NULL;
> + spinlock_t *ptl;
> +
> + if (follow_pte_pmd(mm, addr, NULL, &pte, &pmd, &ptl))
> + return;
> +
> + if (pte) {
> + if (pte_young(*pte)) {
Any reason for skipping mmu_notifier_clear_young()? Why exclude VMs as
DAMON's target applications?
> + clear_page_idle(pte_page(*pte));
> + set_page_young(pte_page(*pte));
> + }
> + *pte = pte_mkold(*pte);
> + pte_unmap_unlock(pte, ptl);
> + return;
> + }
> +
^ permalink raw reply
* [pinctrl:devel 63/64] drivers/pinctrl/mediatek/pinctrl-mt6779.c:775:15: error: a parameter list without types is only allowed in a function definition
From: kernel test robot @ 2020-07-17 0:46 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 1834 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git devel
head: d9ce0e9fdfd37d45f669b831d0c084a7c9338ee8
commit: e6f744c6ad4fb3b7ac06d4e22b79e435578a6d54 [63/64] pinctrl: mediatek: add pinctrl support for MT6779 SoC
config: x86_64-allmodconfig (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project ed6b578040a85977026c93bf4188f996148f3218)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
git checkout e6f744c6ad4fb3b7ac06d4e22b79e435578a6d54
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All error/warnings (new ones prefixed by >>):
>> drivers/pinctrl/mediatek/pinctrl-mt6779.c:775:1: warning: declaration specifier missing, defaulting to 'int'
arch_initcall(mt6779_pinctrl_init);
^
int
>> drivers/pinctrl/mediatek/pinctrl-mt6779.c:775:15: error: a parameter list without types is only allowed in a function definition
arch_initcall(mt6779_pinctrl_init);
^
1 warning and 1 error generated.
vim +775 drivers/pinctrl/mediatek/pinctrl-mt6779.c
770
771 static int __init mt6779_pinctrl_init(void)
772 {
773 return platform_driver_register(&mt6779_pinctrl_driver);
774 }
> 775 arch_initcall(mt6779_pinctrl_init);
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 75947 bytes --]
^ permalink raw reply
* [PATCH 3/3] media: Add support for the AM/FM radio chip KT0913 from KT Micro.
From: Santiago Hormazabal @ 2020-07-17 0:44 UTC (permalink / raw)
To: linux-media, devicetree, Rob Herring, Ezequiel Garcia,
Hans Verkuil, linux-kernel
Cc: Santiago Hormazabal
In-Reply-To: <20200717004441.116248-1-santiagohssl@gmail.com>
This chip requires almost no support components and can used over I2C.
The driver uses the I2C bus and exposes the controls as a V4L2 radio.
Tested with a module that contains this chip (from SZZSJDZ.com,
part number ZJ-801B) and a H2+ AllWinner SoC running the master
(at this time) of the media_tree.
Signed-off-by: Santiago Hormazabal <santiagohssl@gmail.com>
---
drivers/media/radio/radio-kt0913.c | 1181 ++++++++++++++++++++++++++++
1 file changed, 1181 insertions(+)
create mode 100644 drivers/media/radio/radio-kt0913.c
diff --git a/drivers/media/radio/radio-kt0913.c b/drivers/media/radio/radio-kt0913.c
new file mode 100644
index 000000000000..9350d1764d44
--- /dev/null
+++ b/drivers/media/radio/radio-kt0913.c
@@ -0,0 +1,1181 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * drivers/media/radio/radio-kt0913.c
+ *
+ * Driver for the KT0913 radio chip from KTMicro.
+ * This driver provides a v4l2 interface to the tuner, using the I2C
+ * protocol to communicate with the chip.
+ * It exposes two bands, one for AM and another for FM. If the "campus
+ * band" feature needs to be enabled, set the corresponding module parameter
+ * to 1.
+ * Reference Clock and Audio DAC anti-pop configurations should be
+ * set via a device tree node. Defaults will be used otherwise.
+ *
+ * Audio output should be routed to a speaker or an audio capture
+ * device.
+ *
+ * Based on radio-tea5764 by Fabio Belavenuto <belavenuto@gmail.com>
+ *
+ * Copyright (c) 2020 Santiago Hormazabal <santiagohssl@gmail.com>
+ *
+ * TODO:
+ * use rd and wr support for the regmap instead of volatile regs.
+ * add support for the hardware-assisted frequency seek.
+ * export FM SNR and AM/FM AFC deviation values as RO controls.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/math64.h>
+#include <linux/regmap.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
+
+ /* ************************************************************************* */
+
+ /* registers of the kt0913 */
+#define KT0913_REG_CHIP_ID 0x01
+#define KT0913_REG_SEEK 0x02
+#define KT0913_REG_TUNE 0x03
+#define KT0913_REG_VOLUME 0x04
+#define KT0913_REG_DSPCFGA 0x05
+#define KT0913_REG_LOCFGA 0x0A
+#define KT0913_REG_LOCFGC 0x0C
+#define KT0913_REG_RXCFG 0x0F
+#define KT0913_REG_STATUSA 0x12
+#define KT0913_REG_STATUSB 0x13
+#define KT0913_REG_STATUSC 0x14
+#define KT0913_REG_AMSYSCFG 0x16
+#define KT0913_REG_AMCHAN 0x17
+#define KT0913_REG_AMCALI 0x18
+#define KT0913_REG_GPIOCFG 0x1D
+#define KT0913_REG_AMDSP 0x22
+#define KT0913_REG_AMSTATUSA 0x24
+#define KT0913_REG_AMSTATUSB 0x25
+#define KT0913_REG_SOFTMUTE 0x2E
+#define KT0913_REG_AMCFG 0x33
+#define KT0913_REG_AMCFG2 0x34
+#define KT0913_REG_AFC 0x3C
+
+/* register symbols masks, values and shift count */
+#define KT0913_TUNE_FMTUNE_MASK 0x8000 /* FM Tune enable */
+#define KT0913_TUNE_FMTUNE_ON 0x8000 /* FM Tune enabled */
+#define KT0913_TUNE_FMTUNE_OFF 0x0000 /* FM Tune disabled */
+#define KT0913_TUNE_FMCHAN_MASK 0x0FFF /* frequency in kHz / 50kHz */
+
+#define KT0913_VOLUME_DMUTE_MASK 0x2000
+#define KT0913_VOLUME_DMUTE_ON 0x0000
+#define KT0913_VOLUME_DMUTE_OFF 0x2000
+#define KT0913_VOLUME_DE_MASK 0x0800 /* de-emphasis time constant */
+#define KT0913_VOLUME_DE_75US 0x0000 /* 75us */
+#define KT0913_VOLUME_DE_50US 0x0800 /* 50us */
+#define KT0913_VOLUME_POP_MASK 0x30 /* audio dac anti-pop config */
+#define KT0913_VOLUME_POP_SHIFT 4
+
+#define KT0913_DSPCFGA_MONO_MASK 0x8000 /* mono select (0=stereo, 1=mono) */
+#define KT0913_DSPCFGA_MONO_ON 0x8000 /* mono */
+#define KT0913_DSPCFGA_MONO_OFF 0x0000 /* stereo */
+
+#define KT0913_LOCFG_CAMPUSBAND_EN_MASK 0x0008 /* campus band fm enable */
+#define KT0913_LOCFG_CAMPUSBAND_EN_ON 0x0008 /* FM range 64-110MHz */
+#define KT0913_LOCFG_CAMPUSBAND_EN_OFF 0x0000 /* FM range 32-110MHz */
+
+#define KT0913_RXCFGA_STDBY_MASK 0x1000 /* standby mode enable */
+#define KT0913_RXCFGA_STDBY_ON 0x1000 /* standby mode enabled */
+#define KT0913_RXCFGA_STDBY_OFF 0x0000 /* standby mode disabled */
+#define KT0913_RXCFGA_VOLUME_MASK 0x001F /* volume control */
+
+#define KT0913_STATUSA_XTAL_OK 0x8000 /* crystal ready indicator */
+#define KT0913_STATUSA_STC 0x4000 /* seek/tune complete */
+
+#define KT0913_STATUSA_PLL_LOCK_MASK 0x800 /* system pll ready indicator */
+#define KT0913_STATUSA_PLL_LOCK_LOCKED 0x800 /* system pll ready */
+#define KT0913_STATUSA_PLL_LOCK_UNLOCKED 0x000 /* not ready */
+#define KT0913_STATUSA_LO_LOCK 0x400 /* LO synthesizer ready indicator */
+#define KT0913_STATUSA_ST_MASK 0x300 /* stereo indicator (0x300=stereo, otherwise mono) */
+#define KT0913_STATUSA_ST_STEREO 0x300 /* stereo */
+#define KT0913_STATUSA_FMRSSI_MASK 0xF8 /* FM RSSI (-100dBm + FMRSSI*3dBm) */
+#define KT0913_STATUSA_FMRSSI_SHIFT 3
+
+#define KT0913_STATUSC_PWSTATUS 0x8000 /* power status indicator */
+#define KT0913_STATUSC_CHIPRDY 0x2000 /* chip ready indicator */
+#define KT0913_STATUSC_FMSNR 0x1FC0 /* FM SNR (unknown units) */
+
+#define KT0913_AMCHAN_AMTUNE_MASK 0x8000 /* AM tune enable */
+#define KT0913_AMCHAN_AMTUNE_ON 0x8000 /* AM tune enabled */
+#define KT0913_AMCHAN_AMTUNE_OFF 0x0000 /* AM tune disabled */
+#define KT0913_AMCHAN_AMCHAN_MASK 0x7FF /* am channel in kHz */
+
+#define KT0913_AMSYSCFG_AM_FM_MASK 0x8000 /* am/fm mode control */
+#define KT0913_AMSYSCFG_AM_FM_AM 0x8000 /* am mode */
+#define KT0913_AMSYSCFG_AM_FM_FM 0x0000 /* fm mode (default) */
+#define KT0913_AMSYSCFG_REFCLK_MASK 0x0F00 /* reference clock selection */
+#define KT0913_AMSYSCFG_REFCLK_SHIFT 8
+#define KT0913_AMSYSCFG_AU_GAIN_MASK 0x00C0 /* audio gain selection */
+#define KT0913_AMSYSCFG_AU_GAIN_6DB 0x0040 /* 6dB audio gain */
+#define KT0913_AMSYSCFG_AU_GAIN_3DB 0x0000 /* 3dB audio gain (default) */
+#define KT0913_AMSYSCFG_AU_GAIN_0DB 0x00C0 /* 0dB audio gain */
+#define KT0913_AMSYSCFG_AU_GAIN_MIN_3DB 0x0080 /* -3dB audio gain */
+
+#define KT0913_AMSTATUSA_AMRSSI_MASK 0x1F00 /* am channel rssi */
+#define KT0913_AMSTATUSA_AMRSSI_SHIFT 8
+
+/* constants */
+#define KT0913_CHIP_ID 0x544B /* ASCII of 'KT' */
+
+#define V4L2_KHZ_FREQ_MUL 16U /* v4l2 uses 16x the kHz value as their freq */
+#define KT0913_FMCHAN_MUL 50U /* kt0913 uses freqs with a 50kHz multiplier */
+#define KT0913_FM_RANGE_LOW_NO_CAMPUS 64000U /* 64MHz lower bound for FM */
+#define KT0913_FM_RANGE_LOW_CAMPUS 32000U /* 32MHz lower bound for campus FM */
+#define KT0913_FM_RANGE_HIGH 110000U /* 110MHz upper bound for FM */
+#define KT0913_AM_RANGE_LOW 500U /* 500kHz lower bound for AM */
+#define KT0913_AM_RANGE_HIGH 1710U /* 1710kHz upper bound for AM */
+
+#define KT0913_FM_AM_DRIVER_NAME "kt0913-fm-am"
+
+/* ************************************************************************* */
+
+/* v4l2 device number to use. -1 will assign the next free one */
+static int kt0913_v4l2_radio_nr = -1;
+/* use the extended range of FM down to 32MHz. disabled by default */
+static int kt0913_use_campus_band;
+
+/* ************************************************************************* */
+
+/* kt0913 status struct */
+struct kt0913_device {
+ struct v4l2_device v4l2_dev; /* main v4l2 struct */
+ struct i2c_client *client; /* I2C client */
+ struct video_device vdev; /* vide_device struct */
+ struct v4l2_ctrl_handler ctrl_handler; /* ctrl_handler struct */
+
+ /* V4L2 Controls */
+ struct v4l2_ctrl *ctrl_pll_lock; /* PLL lock */
+ struct v4l2_ctrl *ctrl_volume; /* Overall volume */
+ struct v4l2_ctrl *ctrl_au_gain; /* Audio Gain */
+ struct v4l2_ctrl *ctrl_mute; /* Master mute */
+ struct v4l2_ctrl *ctrl_deemphasis; /* Deemphasis */
+
+ /* current operation band (fm, fm_campus, am) */
+ unsigned int band;
+
+ /* audio dac anti-pop setting:
+ * 0 -> 100uF (default)
+ * 1 -> 60uF
+ * 2 -> 20uF
+ * 3 -> 10uF
+ */
+ unsigned int audio_anti_pop;
+
+ /*
+ * reference clock selection:
+ * 0 -> 32.768kHz (default)
+ * 1 -> 6.5MHz
+ * 2 -> 7.6MHz
+ * 3 -> 12MHz
+ * 4 -> 13MHz
+ * 5 -> 15.2MHz
+ * 6 -> 19.2MHz
+ * 7 -> 24MHz
+ * 8 -> 26MHz
+ * 9 -> 38kHz
+ */
+ unsigned int refclock_val;
+
+ /* Regmap */
+ struct regmap *regmap;
+
+ /* For core assisted locking */
+ struct mutex mutex;
+};
+
+/* ************************************************************************* */
+
+/* Regmap settings */
+static const struct regmap_range kt0913_regmap_all_registers_range[] = {
+ regmap_reg_range(0x01, 0x05),
+ regmap_reg_range(0x0A, 0x0A),
+ regmap_reg_range(0x0C, 0x0C),
+ regmap_reg_range(0x0F, 0x0F),
+ regmap_reg_range(0x12, 0x14),
+ regmap_reg_range(0x16, 0x18),
+ regmap_reg_range(0x1D, 0x1D),
+ regmap_reg_range(0x22, 0x22),
+ regmap_reg_range(0x24, 0x25),
+ regmap_reg_range(0x2E, 0x2F),
+ regmap_reg_range(0x30, 0x34),
+ regmap_reg_range(0x3A, 0x3A),
+ regmap_reg_range(0x3C, 0x3C),
+};
+
+static const struct regmap_access_table kt0913_all_registers_access_table = {
+ .yes_ranges = kt0913_regmap_all_registers_range,
+ .n_yes_ranges = ARRAY_SIZE(kt0913_regmap_all_registers_range),
+};
+
+static const struct reg_sequence kt0913_init_regs_to_defaults[] = {
+ /* Standby disabled, volume 0dB */
+ { KT0913_REG_RXCFG, 0x881F },
+ /* FM Channel spacing = 50kHz, Right & Left unmuted */
+ { KT0913_REG_SEEK, 0x000B },
+ /* Stereo, High Stereo/Mono blend level, blend disabled */
+ { KT0913_REG_DSPCFGA, 0x1000 },
+ /* FM AFC Enabled */
+ { KT0913_REG_LOCFGA, 0x0100 },
+ /* Campus band disabled by default */
+ { KT0913_REG_LOCFGC, 0x0024 },
+ /*
+ * FM mode, internal defined bands, clock from XT, 32.768kHz
+ * 3dB audio gain, AM AFC Enabled
+ */
+ { KT0913_REG_AMSYSCFG, 0x0002 },
+ /* Default AM freq = 504kHz */
+ { KT0913_REG_AMCHAN, 0x01F8},
+ /* VOL and CH GPIOs set to HiZ */
+ { KT0913_REG_GPIOCFG, 0x0000 },
+ /* AM Channel bandwidth = 6kHz, non-differential output */
+ { KT0913_REG_AMDSP, 0xAFC4 },
+ /*
+ * softmute is disabled on AM and FM, but set the defaults:
+ * strong softmute attn., slow softmute attack/recover,
+ * lowest AM softumte start level, almost the minimum
+ * softmute target volume, RSSI mode for softmute, lowest
+ * FM softmute start level
+ */
+ { KT0913_REG_SOFTMUTE, 0x0010 },
+ /* 1kHz for AM channel space, working mode A for the keys */
+ { KT0913_REG_AMCFG, 0x1401 },
+ /* TIME1 = shortest, TIME2 = fastest */
+ { KT0913_REG_AMCFG, 0x4050 },
+ /* set 86MHz as the default frequency, and tune it */
+ { KT0913_REG_TUNE, 0x86B8 },
+ /*
+ * FM&AM Softmute disabled, Mute disabled, 75us deemp.,
+ * no bass boost, 100uF anti pop cap
+ */
+ { KT0913_REG_VOLUME, 0xE080 },
+};
+
+static const struct regmap_config kt0913_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 16,
+ .max_register = KT0913_REG_AFC,
+ .volatile_table = &kt0913_all_registers_access_table,
+ .cache_type = REGCACHE_RBTREE,
+ .val_format_endian = REGMAP_ENDIAN_BIG,
+};
+
+/* ************************************************************************* */
+
+/* bands where the kt0913 operates */
+enum { BAND_FM, BAND_FM_CAMUS, BAND_AM };
+
+static const struct v4l2_frequency_band kt0913_bands[] = {
+ {
+ /* BAND_FM */
+ .type = V4L2_TUNER_RADIO,
+ .index = 0, /* index provided to v4l2 */
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = KT0913_FM_RANGE_LOW_NO_CAMPUS * V4L2_KHZ_FREQ_MUL,
+ .rangehigh = KT0913_FM_RANGE_HIGH * V4L2_KHZ_FREQ_MUL,
+ .modulation = V4L2_BAND_MODULATION_FM,
+ },
+ {
+ /* BAND_FM_CAMUS */
+ .type = V4L2_TUNER_RADIO,
+ .index = 0, /* index provided to v4l2 */
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = KT0913_FM_RANGE_LOW_CAMPUS * V4L2_KHZ_FREQ_MUL,
+ .rangehigh = KT0913_FM_RANGE_HIGH * V4L2_KHZ_FREQ_MUL,
+ .modulation = V4L2_BAND_MODULATION_FM,
+ },
+ {
+ /* BAND_AM */
+ .type = V4L2_TUNER_RADIO,
+ .index = 1, /* index provided to v4l2 */
+ .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_FREQ_BANDS,
+ .rangelow = KT0913_AM_RANGE_LOW * V4L2_KHZ_FREQ_MUL,
+ .rangehigh = KT0913_AM_RANGE_HIGH * V4L2_KHZ_FREQ_MUL,
+ .modulation = V4L2_BAND_MODULATION_AM,
+ },
+};
+
+/* ************************************************************************* */
+
+static inline struct kt0913_device *v4l2_device_to_device(
+ struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev,
+ struct kt0913_device, v4l2_dev);
+}
+
+static inline struct kt0913_device *v4l2_ctrl_to_device(
+ struct v4l2_ctrl *ctrl_handler)
+{
+ return container_of(ctrl_handler->handler,
+ struct kt0913_device, ctrl_handler);
+}
+
+/* ************************************************************************* */
+
+static inline u32 khz_to_v4l2_freq(unsigned int freq)
+{
+ return freq * V4L2_KHZ_FREQ_MUL;
+}
+
+static inline unsigned int v4l2_freq_to_khz(u32 v4l2_freq)
+{
+ return v4l2_freq / V4L2_KHZ_FREQ_MUL;
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_get_fm_frequency(struct kt0913_device *radio,
+ unsigned int *frequency)
+{
+ unsigned int tune_reg;
+ int ret = regmap_read(radio->regmap, KT0913_REG_TUNE, &tune_reg);
+
+ if (ret)
+ return ret;
+
+ *frequency = (tune_reg & KT0913_TUNE_FMCHAN_MASK) * KT0913_FMCHAN_MUL;
+
+ return 0;
+}
+
+static int __kt0913_set_fm_frequency(struct kt0913_device *radio,
+ unsigned int frequency)
+{
+ return regmap_write(radio->regmap, KT0913_REG_TUNE,
+ KT0913_TUNE_FMTUNE_ON | (frequency / KT0913_FMCHAN_MUL));
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_set_mute(struct kt0913_device *radio, int on)
+{
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_VOLUME, KT0913_VOLUME_DMUTE_MASK,
+ on ? KT0913_VOLUME_DMUTE_ON : KT0913_VOLUME_DMUTE_OFF);
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_set_deemphasis(struct kt0913_device *radio, s32 deemp)
+{
+ switch (deemp) {
+ case V4L2_DEEMPHASIS_75_uS:
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_VOLUME, KT0913_VOLUME_DE_MASK,
+ KT0913_VOLUME_DE_50US);
+
+ /* 50us is used for the disabled option (which is not supported
+ * on the chip) and the 50uS value
+ */
+ default:
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_VOLUME, KT0913_VOLUME_DE_MASK,
+ KT0913_VOLUME_DE_75US);
+ }
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_set_volume(struct kt0913_device *radio, s32 volume)
+{
+ /* map [-60, 0] to [1, 31] which is what the kt0913 expects */
+ volume = (volume / 2) + 31;
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_RXCFG, KT0913_RXCFGA_VOLUME_MASK,
+ volume);
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_set_standby(struct kt0913_device *radio, int standby)
+{
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_RXCFG, KT0913_RXCFGA_STDBY_MASK,
+ standby ? KT0913_RXCFGA_STDBY_ON : KT0913_RXCFGA_STDBY_OFF);
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_get_pll_status(struct kt0913_device *radio, int *locked)
+{
+ unsigned int statusa_reg;
+ int ret = regmap_read(radio->regmap, KT0913_REG_STATUSA, &statusa_reg);
+
+ if (ret)
+ return ret;
+
+ *locked = (statusa_reg & KT0913_STATUSA_PLL_LOCK_MASK) ==
+ KT0913_STATUSA_PLL_LOCK_LOCKED ? 1 : 0;
+
+ return 0;
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_get_rx_stereo_or_mono(struct kt0913_device *radio,
+ int *stereo)
+{
+ unsigned int statusa_reg;
+ int ret = regmap_read(radio->regmap, KT0913_REG_STATUSA, &statusa_reg);
+
+ if (ret)
+ return ret;
+
+ *stereo = (statusa_reg & KT0913_STATUSA_ST_MASK) ==
+ KT0913_STATUSA_ST_STEREO ? 1 : 0;
+
+ return 0;
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_get_fm_rssi(struct kt0913_device *radio, s32 *rssi)
+{
+ unsigned int statusa_reg;
+ int ret = regmap_read(radio->regmap, KT0913_REG_STATUSA, &statusa_reg);
+
+ if (ret)
+ return ret;
+
+ /* RSSI(dBm) = -100 + FMRSSI<4:0> * 3dBm
+ * even tho we can get the value in dBm, we want a %
+ */
+ *rssi = (statusa_reg & KT0913_STATUSA_FMRSSI_MASK) >>
+ KT0913_STATUSA_FMRSSI_SHIFT;
+ /* map range 0-31 to 0-65535 */
+ *rssi *= 65535;
+ *rssi /= KT0913_STATUSA_FMRSSI_MASK >> KT0913_STATUSA_FMRSSI_SHIFT;
+
+ return 0;
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_get_cfg_stereo_enabled(struct kt0913_device *radio,
+ int *stereo)
+{
+ unsigned int dspcfga_reg;
+ int ret = regmap_read(radio->regmap, KT0913_REG_DSPCFGA, &dspcfga_reg);
+
+ if (ret)
+ return ret;
+
+ *stereo = (dspcfga_reg & KT0913_DSPCFGA_MONO_MASK) ==
+ KT0913_DSPCFGA_MONO_OFF ? 1 : 0;
+
+ return ret;
+}
+
+static int __kt0913_set_cfg_stereo_enabled(struct kt0913_device *radio,
+ int stereo)
+{
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_DSPCFGA, KT0913_DSPCFGA_MONO_MASK,
+ stereo ? KT0913_DSPCFGA_MONO_OFF : KT0913_DSPCFGA_MONO_ON);
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_set_au_gain(struct kt0913_device *radio, s32 gain)
+{
+ switch (gain) {
+ case 6:
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_AMSYSCFG, KT0913_AMSYSCFG_AU_GAIN_MASK,
+ KT0913_AMSYSCFG_AU_GAIN_6DB);
+ case 3:
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_AMSYSCFG, KT0913_AMSYSCFG_AU_GAIN_MASK,
+ KT0913_AMSYSCFG_AU_GAIN_3DB);
+ case 0:
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_AMSYSCFG, KT0913_AMSYSCFG_AU_GAIN_MASK,
+ KT0913_AMSYSCFG_AU_GAIN_0DB);
+ case -3:
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_AMSYSCFG, KT0913_AMSYSCFG_AU_GAIN_MASK,
+ KT0913_AMSYSCFG_AU_GAIN_MIN_3DB);
+ default:
+ return -EINVAL;
+ }
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_set_am_fm_band(struct kt0913_device *radio,
+ unsigned int band)
+{
+ return regmap_update_bits(radio->regmap,
+ KT0913_REG_AMSYSCFG, KT0913_AMSYSCFG_AM_FM_MASK,
+ band == BAND_AM ?
+ KT0913_AMSYSCFG_AM_FM_AM : KT0913_AMSYSCFG_AM_FM_FM);
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_get_am_frequency(struct kt0913_device *radio,
+ unsigned int *frequency)
+{
+ unsigned int amchan_reg;
+ int ret = regmap_read(radio->regmap, KT0913_REG_AMCHAN, &amchan_reg);
+
+ if (ret)
+ return ret;
+
+ *frequency = (amchan_reg & KT0913_AMCHAN_AMCHAN_MASK);
+
+ return 0;
+}
+
+static int __kt0913_set_am_frequency(struct kt0913_device *radio,
+ unsigned int frequency)
+{
+ return regmap_write(radio->regmap, KT0913_REG_AMCHAN,
+ KT0913_AMCHAN_AMTUNE_ON | frequency);
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_get_am_rssi(struct kt0913_device *radio, s32 *rssi)
+{
+ unsigned int amstatusa_reg;
+ int ret = regmap_read(radio->regmap, KT0913_REG_AMSTATUSA, &amstatusa_reg);
+
+ if (ret)
+ return ret;
+
+ /* AMRSSI(dBm) = -90 + AMRSSI<4:0> * 3dBm
+ * even tho we can get the value in dBm, we want a %
+ */
+ *rssi = (amstatusa_reg & KT0913_AMSTATUSA_AMRSSI_MASK) >>
+ KT0913_AMSTATUSA_AMRSSI_SHIFT;
+ /* map range 0-31 to 0-65535 */
+ *rssi *= 65535;
+ *rssi /= KT0913_AMSTATUSA_AMRSSI_MASK >> KT0913_AMSTATUSA_AMRSSI_SHIFT;
+
+ return 0;
+}
+
+/* ************************************************************************* */
+
+static int __kt0913_init(struct kt0913_device *radio)
+{
+ int ret = 0;
+
+ /* write the defaults */
+ ret = regmap_multi_reg_write(radio->regmap,
+ kt0913_init_regs_to_defaults,
+ ARRAY_SIZE(kt0913_init_regs_to_defaults));
+ if (ret) {
+ v4l2_err(radio->client,
+ "regmap_multi_reg_write() failed! %d", ret);
+ return ret;
+ }
+
+ /* set the audio dac anti-pop config */
+ ret = regmap_update_bits(radio->regmap,
+ KT0913_REG_VOLUME, KT0913_VOLUME_POP_MASK,
+ radio->audio_anti_pop << KT0913_VOLUME_POP_SHIFT);
+ if (ret) {
+ v4l2_err(radio->client,
+ "regmap_update_bits() failed for anti-pop cfg! %d", ret);
+ return ret;
+ }
+
+ /* set the reference clock config */
+ ret = regmap_update_bits(radio->regmap,
+ KT0913_REG_AMSYSCFG, KT0913_AMSYSCFG_REFCLK_MASK,
+ radio->refclock_val << KT0913_AMSYSCFG_REFCLK_SHIFT);
+ if (ret) {
+ v4l2_err(radio->client,
+ "regmap_update_bits() failed for refclk cfg! %d", ret);
+ return ret;
+ }
+
+ if (kt0913_use_campus_band) {
+ v4l2_info(radio->client,
+ "campus band is enabled!");
+ /* set the campus band bit */
+ ret = regmap_update_bits(radio->regmap,
+ KT0913_REG_LOCFGC, KT0913_LOCFG_CAMPUSBAND_EN_MASK,
+ KT0913_LOCFG_CAMPUSBAND_EN_ON);
+ if (ret) {
+ v4l2_err(radio->client,
+ "regmap_update_bits() failed for campus band! %d",
+ ret);
+ return ret;
+ }
+ }
+
+ return __kt0913_set_mute(radio, true);
+}
+
+/* ************************************************************************* */
+
+static int kt0913_ioctl_vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *f)
+{
+ struct kt0913_device *radio = video_drvdata(file);
+ int ret;
+
+ if (f->tuner != 0)
+ return -EINVAL;
+
+ f->type = V4L2_TUNER_RADIO;
+
+ if (radio->band == BAND_AM)
+ ret = __kt0913_get_am_frequency(radio, &f->frequency);
+ else
+ ret = __kt0913_get_fm_frequency(radio, &f->frequency);
+
+ if (ret)
+ return ret;
+
+ /* convert kHz freq into v4l2 freq */
+ f->frequency = khz_to_v4l2_freq(f->frequency);
+
+ return 0;
+}
+
+static int kt0913_ioctl_vidioc_s_frequency(struct file *file, void *priv,
+ const struct v4l2_frequency *f)
+{
+ struct kt0913_device *radio = video_drvdata(file);
+ unsigned int freq = f->frequency;
+ unsigned int new_band = BAND_FM;
+ int ret;
+
+ if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+
+ if (freq == 0)
+ return -EINVAL;
+
+ /* check if the requested frequency is contained on the AM band */
+ if (freq <= kt0913_bands[BAND_AM].rangehigh)
+ new_band = BAND_AM;
+ else {
+ /* check if the requested frequency is contained on the FM band */
+ if (freq >= kt0913_bands[BAND_FM].rangelow)
+ new_band = BAND_FM;
+ /* check if the requested frequency is contained on the campus
+ * FM band only if that feature was enabled
+ */
+ else if (kt0913_use_campus_band &&
+ (freq >= kt0913_bands[BAND_FM_CAMUS].rangelow))
+ new_band = BAND_FM_CAMUS;
+ else {
+ v4l2_warn(radio->client,
+ "frequency out of allowed RF bands (%u kHz)",
+ v4l2_freq_to_khz(freq));
+ return -EINVAL;
+ }
+ }
+
+ /* is the requested band different than the one currently set? */
+ if (radio->band != new_band) {
+ ret = __kt0913_set_am_fm_band(radio, new_band);
+ if (ret)
+ return ret;
+ radio->band = new_band;
+ }
+
+ /* clamp the frequency to the band boundaries */
+ freq = clamp(freq, kt0913_bands[new_band].rangelow,
+ kt0913_bands[new_band].rangehigh);
+
+ /* convert v4l2 freq to kHz */
+ freq = v4l2_freq_to_khz(freq);
+
+ if (radio->band == BAND_AM)
+ return __kt0913_set_am_frequency(radio, freq);
+ else
+ return __kt0913_set_fm_frequency(radio, freq);
+}
+
+static int kt0913_ioctl_vidioc_enum_freq_bands(struct file *file, void *priv,
+ struct v4l2_frequency_band *band)
+{
+ if (band->tuner != 0)
+ return -EINVAL;
+
+ switch (band->index) {
+ case 0:
+ if (kt0913_use_campus_band)
+ *band = kt0913_bands[BAND_FM_CAMUS];
+ else
+ *band = kt0913_bands[BAND_FM];
+ return 0;
+ case 1:
+ *band = kt0913_bands[BAND_AM];
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+/* ************************************************************************* */
+
+/* V4L2 vidioc */
+static int kt0913_ioctl_vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *capability)
+{
+ struct kt0913_device *radio = video_drvdata(file);
+ struct video_device *dev;
+
+ if (!radio)
+ return -ENODEV;
+
+ dev = &radio->vdev;
+
+ if (!dev)
+ return -ENODEV;
+
+ strscpy(capability->driver, KT0913_FM_AM_DRIVER_NAME,
+ sizeof(capability->driver));
+ strscpy(capability->card, dev->name, sizeof(capability->card));
+ snprintf(capability->bus_info, sizeof(capability->bus_info),
+ "I2C:%s", dev_name(&dev->dev));
+ return 0;
+}
+
+static int kt0913_ioctl_vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ struct kt0913_device *radio = video_drvdata(file);
+ int ret;
+ int stereo_enabled;
+ int is_stereo;
+
+ if (v->index != 0)
+ return -EINVAL;
+
+ strscpy(v->name, "FM/AM", sizeof(v->name));
+ v->type = V4L2_TUNER_RADIO;
+
+ v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_FREQ_BANDS;
+
+ v->rangelow = kt0913_bands[BAND_AM].rangelow;
+ v->rangehigh = kt0913_bands[BAND_FM].rangehigh;
+
+ if (radio->band == BAND_AM) {
+ v->rxsubchans = V4L2_TUNER_SUB_MONO;
+ v->audmode = V4L2_TUNER_MODE_MONO;
+
+ ret = __kt0913_get_am_rssi(radio, &v->signal);
+ if (ret)
+ return ret;
+ } else {
+ ret = __kt0913_get_cfg_stereo_enabled(radio, &stereo_enabled);
+ if (ret)
+ return ret;
+
+ v->rxsubchans = stereo_enabled ?
+ V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
+
+ ret = __kt0913_get_rx_stereo_or_mono(radio, &is_stereo);
+ if (ret)
+ return ret;
+
+ v->audmode = is_stereo ?
+ V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO;
+
+ ret = __kt0913_get_fm_rssi(radio, &v->signal);
+ if (ret)
+ return ret;
+ }
+
+ /* AFC is enabled and active by default */
+ v->afc = 1;
+
+ return 0;
+}
+
+static int kt0913_ioctl_vidioc_s_tuner(struct file *file, void *priv,
+ const struct v4l2_tuner *v)
+{
+ struct kt0913_device *radio = video_drvdata(file);
+
+ if (v->index != 0)
+ return -EINVAL;
+
+ /* only mono and stereo are supported */
+ if (v->audmode != V4L2_TUNER_MODE_MONO &&
+ v->audmode != V4L2_TUNER_MODE_STEREO)
+ return 0;
+
+ /* AM is mono only, so don't try to set it to stereo */
+ if (radio->band == BAND_AM && v->audmode != V4L2_TUNER_MODE_MONO)
+ return 0;
+
+ /* set to stereo if specified, otherwise set to mono */
+ return __kt0913_set_cfg_stereo_enabled(radio,
+ v->audmode == V4L2_TUNER_MODE_STEREO);
+}
+
+static int kt0913_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct kt0913_device *radio = v4l2_ctrl_to_device(ctrl);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return __kt0913_set_mute(radio, ctrl->val);
+ case V4L2_CID_AUDIO_VOLUME:
+ return __kt0913_set_volume(radio, ctrl->val);
+ case V4L2_CID_GAIN:
+ return __kt0913_set_au_gain(radio, ctrl->val);
+ case V4L2_CID_TUNE_DEEMPHASIS:
+ return __kt0913_set_deemphasis(radio, ctrl->val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int kt0913_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct kt0913_device *radio = v4l2_ctrl_to_device(ctrl);
+
+ switch (ctrl->id) {
+ case V4L2_CID_RF_TUNER_PLL_LOCK:
+ return __kt0913_get_pll_status(radio, &ctrl->val);
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ctrl_ops kt0913_ctrl_ops = {
+ .s_ctrl = kt0913_s_ctrl,
+ .g_volatile_ctrl = kt0913_g_volatile_ctrl,
+};
+
+/* ************************************************************************* */
+
+/* File system interface (use the ancillary fops for v4l2) */
+static const struct v4l2_file_operations kt0913_radio_fops = {
+ .owner = THIS_MODULE,
+ .open = v4l2_fh_open,
+ .release = v4l2_fh_release,
+ .poll = v4l2_ctrl_poll,
+ .unlocked_ioctl = video_ioctl2,
+};
+
+/* ioctl ops */
+static const struct v4l2_ioctl_ops kt0913_ioctl_ops = {
+ .vidioc_querycap = kt0913_ioctl_vidioc_querycap,
+ .vidioc_g_tuner = kt0913_ioctl_vidioc_g_tuner,
+ .vidioc_s_tuner = kt0913_ioctl_vidioc_s_tuner,
+ .vidioc_g_frequency = kt0913_ioctl_vidioc_g_frequency,
+ .vidioc_s_frequency = kt0913_ioctl_vidioc_s_frequency,
+ .vidioc_enum_freq_bands = kt0913_ioctl_vidioc_enum_freq_bands,
+ /* use ancillary functions for these: */
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
+};
+
+/* V4L2 RADIO device structure */
+static struct video_device kt0913_radio_template = {
+ .name = KT0913_FM_AM_DRIVER_NAME,
+ .fops = &kt0913_radio_fops,
+ .ioctl_ops = &kt0913_ioctl_ops,
+ .release = video_device_release_empty,
+ .vfl_dir = VFL_DIR_RX,
+ .device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO,
+};
+
+/* ************************************************************************* */
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id kt0913_of_match[] = {
+ {.compatible = "ktm,kt0913" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, kt0913_of_match);
+#endif /* IS_ENABLED(CONFIG_OF) */
+
+static void __kt0913_parse_dt(struct kt0913_device *radio)
+{
+ const void *ptr_anti_pop = of_get_property(radio->client->dev.of_node,
+ "ktm,anti-pop", NULL);
+ const void *ptr_refclk = of_get_property(radio->client->dev.of_node,
+ "ktm,refclk", NULL);
+
+ if (ptr_anti_pop) {
+ radio->audio_anti_pop =
+ clamp(be32_to_cpup(ptr_anti_pop), 0U, 3U);
+ } else {
+ radio->audio_anti_pop = 0;
+ v4l2_warn(radio->client,
+ "No ktm,anti-pop on dt node, using default");
+ }
+
+ if (ptr_refclk) {
+ radio->refclock_val =
+ clamp(be32_to_cpup(ptr_refclk), 0U, 9U);
+ } else {
+ radio->refclock_val = 0;
+ v4l2_warn(radio->client,
+ "No ktm,refclk on dt node, using default");
+ }
+}
+
+/* ************************************************************************* */
+
+static int kt0913_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct kt0913_device *radio;
+ struct v4l2_device *v4l2_dev;
+ struct v4l2_ctrl_handler *hdl;
+ struct regmap *regmap;
+ int ret;
+
+ pr_debug("%s\n", __func__);
+
+ /* this driver uses word R/W i2c operations, check if it's supported */
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA)) {
+ v4l2_err(client,
+ "I2C adapter doesn't support word operations");
+ return -EIO;
+ }
+
+ /* check if the device exist on the bus before initializing it */
+ ret = i2c_smbus_read_word_data(client, KT0913_REG_CHIP_ID);
+ if (ret < 0) {
+ v4l2_err(client,
+ "Error reading CHIP ID of the kt0913 (%d)", ret);
+ return ret;
+ }
+
+ /* check if the CHIP ID register value matches the expected value */
+ if (ret != KT0913_CHIP_ID) {
+ v4l2_err(radio->client,
+ "Invalid CHIP ID: 0x%x, expected 0x%x", ret, KT0913_CHIP_ID);
+ return -ENODEV;
+ }
+
+ v4l2_info(client,
+ "kt0913 found @ 0x%x (%s)\n",
+ client->addr, client->adapter->name);
+
+ /* alloc context for the kt0913 radio struct */
+ radio = devm_kzalloc(&client->dev, sizeof(*radio), GFP_KERNEL);
+ if (!radio)
+ return -ENOMEM;
+
+ v4l2_dev = &radio->v4l2_dev;
+ ret = v4l2_device_register(&client->dev, v4l2_dev);
+ if (ret < 0) {
+ v4l2_err(client,
+ "could not register v4l2_dev\n");
+ goto errfr;
+ }
+
+ mutex_init(&radio->mutex);
+
+ /* register the control handler from the context struct */
+ hdl = &radio->ctrl_handler;
+ v4l2_ctrl_handler_init(hdl, 5);
+
+ /* add the control: Mute */
+ radio->ctrl_mute = v4l2_ctrl_new_std(hdl, &kt0913_ctrl_ops,
+ V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
+ if (hdl->error) {
+ ret = hdl->error;
+ v4l2_err(v4l2_dev, "Could not register control: mute\n");
+ goto errunreg;
+ }
+
+ /* add the control: Volume */
+ radio->ctrl_volume = v4l2_ctrl_new_std(hdl, &kt0913_ctrl_ops,
+ V4L2_CID_AUDIO_VOLUME, -60, 0, 2, 0);
+ if (hdl->error) {
+ ret = hdl->error;
+ v4l2_err(v4l2_dev, "Could not register control: Volume\n");
+ goto errunreg;
+ }
+
+ /* add the control: audio gain */
+ radio->ctrl_au_gain = v4l2_ctrl_new_std(hdl, &kt0913_ctrl_ops,
+ V4L2_CID_GAIN, -3, 6, 3, 3);
+ if (hdl->error) {
+ ret = hdl->error;
+ v4l2_err(v4l2_dev, "Could not register control: audio gain\n");
+ goto errunreg;
+ }
+ radio->ctrl_au_gain->flags |= V4L2_CTRL_FLAG_SLIDER;
+
+ /* add the control: PLL Lock */
+ radio->ctrl_pll_lock = v4l2_ctrl_new_std(hdl, &kt0913_ctrl_ops,
+ V4L2_CID_RF_TUNER_PLL_LOCK, 0, 1, 1, 0);
+ if (hdl->error) {
+ ret = hdl->error;
+ v4l2_err(v4l2_dev, "Could not register control: pll lock\n");
+ goto errunreg;
+ }
+ radio->ctrl_pll_lock->flags |= (V4L2_CTRL_FLAG_VOLATILE |
+ V4L2_CTRL_FLAG_READ_ONLY);
+
+ /* add the control: deemphasis */
+ radio->ctrl_deemphasis = v4l2_ctrl_new_std_menu(hdl, &kt0913_ctrl_ops,
+ V4L2_CID_TUNE_DEEMPHASIS, V4L2_DEEMPHASIS_75_uS,
+ 0, V4L2_DEEMPHASIS_75_uS);
+ if (hdl->error) {
+ ret = hdl->error;
+ v4l2_err(v4l2_dev, "Could not register control: deemphasis\n");
+ goto errunreg;
+ }
+ /* the control handler is ready to be used */
+ v4l2_dev->ctrl_handler = hdl;
+
+ radio->vdev = kt0913_radio_template;
+ radio->vdev.lock = &radio->mutex;
+ radio->vdev.v4l2_dev = v4l2_dev;
+ video_set_drvdata(&radio->vdev, radio);
+
+ radio->client = client;
+ i2c_set_clientdata(client, radio);
+
+ /* init the regmap of the kt0913 */
+ regmap = devm_regmap_init_i2c(client, &kt0913_regmap_config);
+ if (IS_ERR(regmap)) {
+ ret = PTR_ERR(regmap);
+ v4l2_err(client,
+ "devm_regmap_init_i2c() failed! %d", ret);
+ goto errunreg;
+ }
+ radio->regmap = regmap;
+
+ __kt0913_parse_dt(radio);
+
+ /* init the kt0913 into a known state */
+ ret = __kt0913_init(radio);
+ if (ret) {
+ v4l2_err(client,
+ "__kt0913_init() failed! %d", ret);
+ goto errunreg;
+ }
+
+ pm_runtime_get_noresume(&client->dev);
+ pm_runtime_set_active(&client->dev);
+ pm_runtime_enable(&client->dev);
+ pm_runtime_dont_use_autosuspend(&client->dev);
+
+ ret = video_register_device(&radio->vdev,
+ VFL_TYPE_RADIO, kt0913_v4l2_radio_nr);
+ if (ret < 0) {
+ v4l2_err(client,
+ "Could not register video device!");
+ goto error_pm_disable;
+ }
+
+ v4l2_info(client, "registered.");
+ return 0;
+error_pm_disable:
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+errunreg:
+ v4l2_ctrl_handler_free(hdl);
+ v4l2_device_unregister(v4l2_dev);
+errfr:
+ __kt0913_set_standby(radio, true);
+ kfree(radio);
+ return ret;
+}
+
+static int kt0913_remove(struct i2c_client *client)
+{
+ struct kt0913_device *radio = i2c_get_clientdata(client);
+
+ pr_debug("%s\n", __func__);
+ if (!radio)
+ return -EINVAL;
+
+ __kt0913_set_standby(radio, true);
+
+ pm_runtime_get_sync(&client->dev);
+ pm_runtime_disable(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ pm_runtime_put_noidle(&client->dev);
+
+ video_unregister_device(&radio->vdev);
+ v4l2_ctrl_handler_free(&radio->ctrl_handler);
+ v4l2_device_unregister(&radio->v4l2_dev);
+
+ v4l2_info(client, "removed.");
+ return 0;
+}
+
+/* ************************************************************************* */
+
+#ifdef CONFIG_PM
+static int kt0913_i2c_pm_runtime_suspend(struct device *dev)
+{
+ struct kt0913_device *radio = i2c_get_clientdata(to_i2c_client(dev));
+
+ pr_debug("%s\n", __func__);
+ if (!radio)
+ return 0;
+
+ return __kt0913_set_standby(radio, true);
+}
+
+static int kt0913_i2c_pm_runtime_resume(struct device *dev)
+{
+ struct kt0913_device *radio = i2c_get_clientdata(to_i2c_client(dev));
+
+ pr_debug("%s\n", __func__);
+ if (!radio)
+ return 0;
+
+ return __kt0913_set_standby(radio, false);
+}
+#endif /* CONFIG_PM */
+
+static const struct dev_pm_ops kt0913_i2c_pm_ops = {
+ SET_RUNTIME_PM_OPS(kt0913_i2c_pm_runtime_suspend,
+ kt0913_i2c_pm_runtime_resume, NULL)
+};
+
+static const struct i2c_device_id kt0913_idtable[] = {
+ { "kt0913", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, kt0913_idtable);
+
+static struct i2c_driver kt0913_driver = {
+ .driver = {
+ .name = "kt0913",
+ .of_match_table = of_match_ptr(kt0913_of_match),
+ .pm = &kt0913_i2c_pm_ops,
+ },
+ .probe = kt0913_probe,
+ .remove = kt0913_remove,
+ .id_table = kt0913_idtable,
+};
+module_i2c_driver(kt0913_driver);
+
+MODULE_AUTHOR("Santiago Hormazabal <santiagohssl@gmail.com>");
+MODULE_DESCRIPTION("KTMicro KT0913 AM/FM receiver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.0.1");
+
+module_param(kt0913_use_campus_band, int, 0);
+MODULE_PARM_DESC(kt0913_use_campus_band, "Use the Campus Band feature (FM range 32MHz-110MHz)");
+module_param(kt0913_v4l2_radio_nr, int, 0);
+MODULE_PARM_DESC(kt0913_v4l2_radio_nr, "v4l2 device number to use (i.e. /dev/radioX)");
--
2.24.1
^ permalink raw reply related
* [PATCH 2/3] media: kt0913: device tree binding
From: Santiago Hormazabal @ 2020-07-17 0:44 UTC (permalink / raw)
To: linux-media, devicetree, Rob Herring, Ezequiel Garcia,
Hans Verkuil, linux-kernel
Cc: Santiago Hormazabal
In-Reply-To: <20200717004441.116248-1-santiagohssl@gmail.com>
Document bindings for the kt0913 AM/FM radio tuner.
Signed-off-by: Santiago Hormazabal <santiagohssl@gmail.com>
---
.../bindings/media/i2c/ktm,kt0913.yaml | 56 +++++++++++++++++++
1 file changed, 56 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/ktm,kt0913.yaml
diff --git a/Documentation/devicetree/bindings/media/i2c/ktm,kt0913.yaml b/Documentation/devicetree/bindings/media/i2c/ktm,kt0913.yaml
new file mode 100644
index 000000000000..2c3d1795da43
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ktm,kt0913.yaml
@@ -0,0 +1,56 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+# Copyright (c) 2020 Santiago Hormazabal <santiagohssl@gmail.com>
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/media/ktm,kt0913.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Device-Tree bindings for the KTMicro KT0913 FM/AM radio tuner.
+
+maintainers:
+ - Santiago Hormazabal <santiagohssl@gmail.com>
+
+description: |-
+ The KT0913 is a low cost, low components FM/AM radio chip.
+ It uses the I2C protocol for operation.
+
+properties:
+ compatible:
+ const: ktm,kt0913
+
+ reg:
+ description: I2C device address
+ const: 0x35
+
+ ktm,anti-pop:
+ description: |
+ Selects the DAC Anti-Pop capacitor. Possible values are
+ 0 thru 3, which corresponds to 100uF (default), 60uF, 20uF or 10uF.
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ enum: [0, 1, 2, 3]
+
+ ktm,refclk:
+ description: |
+ Selects the reference clock used on the KT0913. Possible
+ values are 0 thru 9, which corresponds to 32.768kHz (default),
+ 6.5MHz, 7.6MHz, 12MHz, 13MHz, 15.2MHz, 19.2MHz, 24MHz, 26MHz, 38kHz.
+ $ref: "/schemas/types.yaml#/definitions/uint32"
+ enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ i2c {
+ kt0913: fm-am-tuner@35 {
+ compatible = "ktm,kt0913";
+ reg = <0x35>;
+ ktm,anti-pop = <0x01>;
+ ktm,refclk = <0x00>;
+ };
+ };
+...
--
2.24.1
^ permalink raw reply related
* [PATCH 1/3] dt-bindings: vendor-prefixes: Add KT Micro
From: Santiago Hormazabal @ 2020-07-17 0:44 UTC (permalink / raw)
To: linux-media, devicetree, Rob Herring, Ezequiel Garcia,
Hans Verkuil, linux-kernel
Cc: Santiago Hormazabal
In-Reply-To: <20200717004441.116248-1-santiagohssl@gmail.com>
Adds ktm as the prefix of KT Micro, Inc.
Signed-off-by: Santiago Hormazabal <santiagohssl@gmail.com>
---
Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index 9aeab66be85f..35985934a672 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -545,6 +545,8 @@ patternProperties:
description: Kontron S&T AG
"^kosagi,.*":
description: Sutajio Ko-Usagi PTE Ltd.
+ "^ktm,.*":
+ description: KT Micro, Inc.
"^kyo,.*":
description: Kyocera Corporation
"^lacie,.*":
--
2.24.1
^ permalink raw reply related
* [PATCH 0/3] KT091 FM/AM driver
From: Santiago Hormazabal @ 2020-07-17 0:44 UTC (permalink / raw)
To: linux-media, devicetree, Rob Herring, Ezequiel Garcia,
Hans Verkuil, linux-kernel
Cc: Santiago Hormazabal
media: adds support for kt0913 FM/AM tuner chip
Adds a driver for the KT0913 FM/AM tuner chip from KT Micro. This chip
is found on many low cost FM/AM radios and DVD/Home Theaters.
The chip provides two ways of usage, a manual mode (requiring only a
few buttons) or complete control via I2C. This driver uses the latter.
It exposes the minimum functionality of this chip, which includes tuning
an AM or FM station given its frequency, reading the signal strength,
setting Stereo (only on FM) or Mono (available on AM/FM), Mute, Volume
and Audio Gain.
I left some TODOs on the code, like supporting the chip's hardware seek
feature, using a RW/RO regmaps rather than a single volatile regmap,
show the FM SNR as a RO control and the FM/AM AFC deviation as another
RO control.
I tested this on two systems, the first one being a Raspberry Pi 4 with
the unstable 5.x kernel, but later I moved to a Banana Pi 2 Zero where
I used the (current at this time) master of this repo for testing.
I've also compiled the v4l-compliance from sources and it passed all the
tests. The output of that is at the end of this note.
v4l2-compliance SHA: e50041186be9f69dd94b64fb924115201726e72a, 32 bits, 32-bit time_t
Compliance test for kt0913-fm-am device /dev/radio0:
Driver Info:
Driver name : kt0913-fm-am
Card type : kt0913-fm-am
Bus info : I2C:radio0
Driver version : 5.8.0
Capabilities : 0x80250000
Tuner
Radio
Extended Pix Format
Device Capabilities
Device Caps : 0x00250000
Tuner
Radio
Extended Pix Format
Required ioctls:
test VIDIOC_QUERYCAP: OK
Allow for multiple opens:
test second /dev/radio0 open: OK
test VIDIOC_QUERYCAP: OK
test VIDIOC_G/S_PRIORITY: OK
test for unlimited opens: OK
test invalid ioctls: OK
Debug ioctls:
test VIDIOC_DBG_G/S_REGISTER: OK
test VIDIOC_LOG_STATUS: OK
Input ioctls:
test VIDIOC_G/S_TUNER/ENUM_FREQ_BANDS: OK
test VIDIOC_G/S_FREQUENCY: OK
test VIDIOC_S_HW_FREQ_SEEK: OK (Not Supported)
test VIDIOC_ENUMAUDIO: OK (Not Supported)
test VIDIOC_G/S/ENUMINPUT: OK (Not Supported)
test VIDIOC_G/S_AUDIO: OK (Not Supported)
Inputs: 0 Audio Inputs: 0 Tuners: 1
Output ioctls:
test VIDIOC_G/S_MODULATOR: OK (Not Supported)
test VIDIOC_G/S_FREQUENCY: OK
test VIDIOC_ENUMAUDOUT: OK (Not Supported)
test VIDIOC_G/S/ENUMOUTPUT: OK (Not Supported)
test VIDIOC_G/S_AUDOUT: OK (Not Supported)
Outputs: 0 Audio Outputs: 0 Modulators: 0
Input/Output configuration ioctls:
test VIDIOC_ENUM/G/S/QUERY_STD: OK (Not Supported)
test VIDIOC_ENUM/G/S/QUERY_DV_TIMINGS: OK (Not Supported)
test VIDIOC_DV_TIMINGS_CAP: OK (Not Supported)
test VIDIOC_G/S_EDID: OK (Not Supported)
Control ioctls:
test VIDIOC_QUERY_EXT_CTRL/QUERYMENU: OK
test VIDIOC_QUERYCTRL: OK
test VIDIOC_G/S_CTRL: OK
test VIDIOC_G/S/TRY_EXT_CTRLS: OK
test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: OK
test VIDIOC_G/S_JPEGCOMP: OK (Not Supported)
Standard Controls: 8 Private Controls: 0
Format ioctls:
test VIDIOC_ENUM_FMT/FRAMESIZES/FRAMEINTERVALS: OK (Not Supported)
test VIDIOC_G/S_PARM: OK (Not Supported)
test VIDIOC_G_FBUF: OK (Not Supported)
test VIDIOC_G_FMT: OK (Not Supported)
test VIDIOC_TRY_FMT: OK (Not Supported)
test VIDIOC_S_FMT: OK (Not Supported)
test VIDIOC_G_SLICED_VBI_CAP: OK (Not Supported)
test Cropping: OK (Not Supported)
test Composing: OK (Not Supported)
test Scaling: OK (Not Supported)
Codec ioctls:
test VIDIOC_(TRY_)ENCODER_CMD: OK (Not Supported)
test VIDIOC_G_ENC_INDEX: OK (Not Supported)
test VIDIOC_(TRY_)DECODER_CMD: OK (Not Supported)
Buffer ioctls:
test VIDIOC_REQBUFS/CREATE_BUFS/QUERYBUF: OK (Not Supported)
test VIDIOC_EXPBUF: OK (Not Supported)
test Requests: OK (Not Supported)
Total for kt0913-fm-am device /dev/radio0: 45, Succeeded: 45, Failed: 0, Warnings: 0
Santiago Hormazabal (3):
dt-bindings: vendor-prefixes: Add KT Micro
media: kt0913: device tree binding
media: Add support for the AM/FM radio chip KT0913 from KT Micro.
.../bindings/media/i2c/ktm,kt0913.yaml | 56 +
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
drivers/media/radio/radio-kt0913.c | 1181 +++++++++++++++++
3 files changed, 1239 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/ktm,kt0913.yaml
create mode 100644 drivers/media/radio/radio-kt0913.c
--
2.24.1
^ permalink raw reply
* [soc:drivers/scmi 15/20] drivers/firmware/arm_scmi/clock.c:142:21: sparse: sparse: Using plain integer as NULL pointer
From: kernel test robot @ 2020-07-17 0:41 UTC (permalink / raw)
To: Sudeep Holla; +Cc: arm, kbuild-all, linux-arm-kernel
[-- Attachment #1: Type: text/plain, Size: 3789 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git drivers/scmi
head: 72a5eb9d9c319c99c11cfd9cfb486380dd136840
commit: dccec73de91de04f2a62c877411ecbe368a775f7 [15/20] firmware: arm_scmi: Keep the discrete clock rates sorted
config: arm64-randconfig-s031-20200716 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.2-49-g707c5017-dirty
git checkout dccec73de91de04f2a62c877411ecbe368a775f7
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=arm64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> drivers/firmware/arm_scmi/clock.c:142:21: sparse: sparse: Using plain integer as NULL pointer
vim +142 drivers/firmware/arm_scmi/clock.c
137
138 static int
139 scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
140 struct scmi_clock_info *clk)
141 {
> 142 u64 *rate = 0;
143 int ret, cnt;
144 bool rate_discrete = false;
145 u32 tot_rate_cnt = 0, rates_flag;
146 u16 num_returned, num_remaining;
147 struct scmi_xfer *t;
148 struct scmi_msg_clock_describe_rates *clk_desc;
149 struct scmi_msg_resp_clock_describe_rates *rlist;
150
151 ret = scmi_xfer_get_init(handle, CLOCK_DESCRIBE_RATES,
152 SCMI_PROTOCOL_CLOCK, sizeof(*clk_desc), 0, &t);
153 if (ret)
154 return ret;
155
156 clk_desc = t->tx.buf;
157 rlist = t->rx.buf;
158
159 do {
160 clk_desc->id = cpu_to_le32(clk_id);
161 /* Set the number of rates to be skipped/already read */
162 clk_desc->rate_index = cpu_to_le32(tot_rate_cnt);
163
164 ret = scmi_do_xfer(handle, t);
165 if (ret)
166 goto err;
167
168 rates_flag = le32_to_cpu(rlist->num_rates_flags);
169 num_remaining = NUM_REMAINING(rates_flag);
170 rate_discrete = RATE_DISCRETE(rates_flag);
171 num_returned = NUM_RETURNED(rates_flag);
172
173 if (tot_rate_cnt + num_returned > SCMI_MAX_NUM_RATES) {
174 dev_err(handle->dev, "No. of rates > MAX_NUM_RATES");
175 break;
176 }
177
178 if (!rate_discrete) {
179 clk->range.min_rate = RATE_TO_U64(rlist->rate[0]);
180 clk->range.max_rate = RATE_TO_U64(rlist->rate[1]);
181 clk->range.step_size = RATE_TO_U64(rlist->rate[2]);
182 dev_dbg(handle->dev, "Min %llu Max %llu Step %llu Hz\n",
183 clk->range.min_rate, clk->range.max_rate,
184 clk->range.step_size);
185 break;
186 }
187
188 rate = &clk->list.rates[tot_rate_cnt];
189 for (cnt = 0; cnt < num_returned; cnt++, rate++) {
190 *rate = RATE_TO_U64(rlist->rate[cnt]);
191 dev_dbg(handle->dev, "Rate %llu Hz\n", *rate);
192 }
193
194 tot_rate_cnt += num_returned;
195 /*
196 * check for both returned and remaining to avoid infinite
197 * loop due to buggy firmware
198 */
199 } while (num_returned && num_remaining);
200
201 if (rate_discrete && rate) {
202 clk->list.num_rates = tot_rate_cnt;
203 sort(rate, tot_rate_cnt, sizeof(*rate), rate_cmp_func, NULL);
204 }
205
206 clk->rate_discrete = rate_discrete;
207
208 err:
209 scmi_xfer_put(handle, t);
210 return ret;
211 }
212
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 38434 bytes --]
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: nouveau regression with 5.7 caused by "PCI/PM: Assume ports without DLL Link Active train links in 100 ms"
From: Karol Herbst @ 2020-07-17 0:43 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Linux PCI, Mika Westerberg, Ben Skeggs, Bjorn Helgaas, Lyude Paul,
nouveau, dri-devel, Patrick Volkerding, LKML, Kai-Heng Feng,
Sasha Levin
In-Reply-To: <20200716235440.GA675421@bjorn-Precision-5520>
On Fri, Jul 17, 2020 at 1:54 AM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> [+cc Sasha -- stable kernel regression]
> [+cc Patrick, Kai-Heng, LKML]
>
> On Fri, Jul 17, 2020 at 12:10:39AM +0200, Karol Herbst wrote:
> > On Tue, Jul 7, 2020 at 9:30 PM Karol Herbst <kherbst@redhat.com> wrote:
> > >
> > > Hi everybody,
> > >
> > > with the mentioned commit Nouveau isn't able to load firmware onto the
> > > GPU on one of my systems here. Even though the issue doesn't always
> > > happen I am quite confident this is the commit breaking it.
> > >
> > > I am still digging into the issue and trying to figure out what
> > > exactly breaks, but it shows up in different ways. Either we are not
> > > able to boot the engines on the GPU or the GPU becomes unresponsive.
> > > Btw, this is also a system where our runtime power management issue
> > > shows up, so maybe there is indeed something funky with the bridge
> > > controller.
> > >
> > > Just pinging you in case you have an idea on how this could break Nouveau
> > >
> > > most of the times it shows up like this:
> > > nouveau 0000:01:00.0: acr: AHESASC binary failed
> > >
> > > Sometimes it works at boot and fails at runtime resuming with random
> > > faults. So I will be investigating a bit more, but yeah... I am super
> > > sure the commit triggered this issue, no idea if it actually causes
> > > it.
> >
> > so yeah.. I reverted that locally and never ran into issues again.
> > Still valid on latest 5.7. So can we get this reverted or properly
> > fixed? This breaks runtime pm for us on at least some hardware.
>
> Yeah, that stinks. We had another similar report from Patrick:
>
> https://lore.kernel.org/r/CAErSpo5sTeK_my1dEhWp7aHD0xOp87+oHYWkTjbL7ALgDbXo-Q@mail.gmail.com
>
> Apparently the problem is ec411e02b7a2 ("PCI/PM: Assume ports without
> DLL Link Active train links in 100 ms"), which Patrick found was
> backported to v5.4.49 as 828b192c57e8, and you found was backported to
> v5.7.6 as afaff825e3a4.
>
> Oddly, Patrick reported that v5.7.7 worked correctly, even though it
> still contains afaff825e3a4.
>
> I guess in the absence of any other clues we'll have to revert it.
> I hate to do that because that means we'll have slow resume of
> Thunderbolt-connected devices again, but that's better than having
> GPUs completely broken.
>
> Could you and Patrick open bugzilla.kernel.org reports, attach dmesg
> logs and "sudo lspci -vv" output, and add the URLs to Kai-Heng's
> original report at https://bugzilla.kernel.org/show_bug.cgi?id=206837
> and to this thread?
>
> There must be a way to fix the slow resume problem without breaking
> the GPUs.
>
I wouldn't be surprised if this is related to the Intel bridge we
check against for Nouveau.. I still have to check on another laptop
with the same bridge our workaround was required as well but wouldn't
be surprised if it shows the same problem. Will get you the
information from both systems tomorrow then.
> Bjorn
>
^ permalink raw reply
* Re: nouveau regression with 5.7 caused by "PCI/PM: Assume ports without DLL Link Active train links in 100 ms"
From: Karol Herbst @ 2020-07-17 0:43 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Sasha Levin, Patrick Volkerding, Linux PCI, LKML, dri-devel,
Kai-Heng Feng, Ben Skeggs, nouveau, Bjorn Helgaas,
Mika Westerberg
In-Reply-To: <20200716235440.GA675421@bjorn-Precision-5520>
On Fri, Jul 17, 2020 at 1:54 AM Bjorn Helgaas <helgaas@kernel.org> wrote:
>
> [+cc Sasha -- stable kernel regression]
> [+cc Patrick, Kai-Heng, LKML]
>
> On Fri, Jul 17, 2020 at 12:10:39AM +0200, Karol Herbst wrote:
> > On Tue, Jul 7, 2020 at 9:30 PM Karol Herbst <kherbst@redhat.com> wrote:
> > >
> > > Hi everybody,
> > >
> > > with the mentioned commit Nouveau isn't able to load firmware onto the
> > > GPU on one of my systems here. Even though the issue doesn't always
> > > happen I am quite confident this is the commit breaking it.
> > >
> > > I am still digging into the issue and trying to figure out what
> > > exactly breaks, but it shows up in different ways. Either we are not
> > > able to boot the engines on the GPU or the GPU becomes unresponsive.
> > > Btw, this is also a system where our runtime power management issue
> > > shows up, so maybe there is indeed something funky with the bridge
> > > controller.
> > >
> > > Just pinging you in case you have an idea on how this could break Nouveau
> > >
> > > most of the times it shows up like this:
> > > nouveau 0000:01:00.0: acr: AHESASC binary failed
> > >
> > > Sometimes it works at boot and fails at runtime resuming with random
> > > faults. So I will be investigating a bit more, but yeah... I am super
> > > sure the commit triggered this issue, no idea if it actually causes
> > > it.
> >
> > so yeah.. I reverted that locally and never ran into issues again.
> > Still valid on latest 5.7. So can we get this reverted or properly
> > fixed? This breaks runtime pm for us on at least some hardware.
>
> Yeah, that stinks. We had another similar report from Patrick:
>
> https://lore.kernel.org/r/CAErSpo5sTeK_my1dEhWp7aHD0xOp87+oHYWkTjbL7ALgDbXo-Q@mail.gmail.com
>
> Apparently the problem is ec411e02b7a2 ("PCI/PM: Assume ports without
> DLL Link Active train links in 100 ms"), which Patrick found was
> backported to v5.4.49 as 828b192c57e8, and you found was backported to
> v5.7.6 as afaff825e3a4.
>
> Oddly, Patrick reported that v5.7.7 worked correctly, even though it
> still contains afaff825e3a4.
>
> I guess in the absence of any other clues we'll have to revert it.
> I hate to do that because that means we'll have slow resume of
> Thunderbolt-connected devices again, but that's better than having
> GPUs completely broken.
>
> Could you and Patrick open bugzilla.kernel.org reports, attach dmesg
> logs and "sudo lspci -vv" output, and add the URLs to Kai-Heng's
> original report at https://bugzilla.kernel.org/show_bug.cgi?id=206837
> and to this thread?
>
> There must be a way to fix the slow resume problem without breaking
> the GPUs.
>
I wouldn't be surprised if this is related to the Intel bridge we
check against for Nouveau.. I still have to check on another laptop
with the same bridge our workaround was required as well but wouldn't
be surprised if it shows the same problem. Will get you the
information from both systems tomorrow then.
> Bjorn
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: nouveau regression with 5.7 caused by "PCI/PM: Assume ports without DLL Link Active train links in 100 ms"
From: Karol Herbst @ 2020-07-17 0:43 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Sasha Levin, Patrick Volkerding, Linux PCI, LKML, dri-devel,
Kai-Heng Feng, Ben Skeggs, nouveau, Bjorn Helgaas,
Mika Westerberg
In-Reply-To: <20200716235440.GA675421@bjorn-Precision-5520>
On Fri, Jul 17, 2020 at 1:54 AM Bjorn Helgaas <helgaas-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
>
> [+cc Sasha -- stable kernel regression]
> [+cc Patrick, Kai-Heng, LKML]
>
> On Fri, Jul 17, 2020 at 12:10:39AM +0200, Karol Herbst wrote:
> > On Tue, Jul 7, 2020 at 9:30 PM Karol Herbst <kherbst-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> > >
> > > Hi everybody,
> > >
> > > with the mentioned commit Nouveau isn't able to load firmware onto the
> > > GPU on one of my systems here. Even though the issue doesn't always
> > > happen I am quite confident this is the commit breaking it.
> > >
> > > I am still digging into the issue and trying to figure out what
> > > exactly breaks, but it shows up in different ways. Either we are not
> > > able to boot the engines on the GPU or the GPU becomes unresponsive.
> > > Btw, this is also a system where our runtime power management issue
> > > shows up, so maybe there is indeed something funky with the bridge
> > > controller.
> > >
> > > Just pinging you in case you have an idea on how this could break Nouveau
> > >
> > > most of the times it shows up like this:
> > > nouveau 0000:01:00.0: acr: AHESASC binary failed
> > >
> > > Sometimes it works at boot and fails at runtime resuming with random
> > > faults. So I will be investigating a bit more, but yeah... I am super
> > > sure the commit triggered this issue, no idea if it actually causes
> > > it.
> >
> > so yeah.. I reverted that locally and never ran into issues again.
> > Still valid on latest 5.7. So can we get this reverted or properly
> > fixed? This breaks runtime pm for us on at least some hardware.
>
> Yeah, that stinks. We had another similar report from Patrick:
>
> https://lore.kernel.org/r/CAErSpo5sTeK_my1dEhWp7aHD0xOp87+oHYWkTjbL7ALgDbXo-Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
>
> Apparently the problem is ec411e02b7a2 ("PCI/PM: Assume ports without
> DLL Link Active train links in 100 ms"), which Patrick found was
> backported to v5.4.49 as 828b192c57e8, and you found was backported to
> v5.7.6 as afaff825e3a4.
>
> Oddly, Patrick reported that v5.7.7 worked correctly, even though it
> still contains afaff825e3a4.
>
> I guess in the absence of any other clues we'll have to revert it.
> I hate to do that because that means we'll have slow resume of
> Thunderbolt-connected devices again, but that's better than having
> GPUs completely broken.
>
> Could you and Patrick open bugzilla.kernel.org reports, attach dmesg
> logs and "sudo lspci -vv" output, and add the URLs to Kai-Heng's
> original report at https://bugzilla.kernel.org/show_bug.cgi?id=206837
> and to this thread?
>
> There must be a way to fix the slow resume problem without breaking
> the GPUs.
>
I wouldn't be surprised if this is related to the Intel bridge we
check against for Nouveau.. I still have to check on another laptop
with the same bridge our workaround was required as well but wouldn't
be surprised if it shows the same problem. Will get you the
information from both systems tomorrow then.
> Bjorn
>
^ permalink raw reply
* [soc:drivers/scmi 15/20] drivers/firmware/arm_scmi/clock.c:142:21: sparse: sparse: Using plain integer as NULL pointer
From: kernel test robot @ 2020-07-17 0:41 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 3895 bytes --]
tree: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git drivers/scmi
head: 72a5eb9d9c319c99c11cfd9cfb486380dd136840
commit: dccec73de91de04f2a62c877411ecbe368a775f7 [15/20] firmware: arm_scmi: Keep the discrete clock rates sorted
config: arm64-randconfig-s031-20200716 (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.2-49-g707c5017-dirty
git checkout dccec73de91de04f2a62c877411ecbe368a775f7
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=arm64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
>> drivers/firmware/arm_scmi/clock.c:142:21: sparse: sparse: Using plain integer as NULL pointer
vim +142 drivers/firmware/arm_scmi/clock.c
137
138 static int
139 scmi_clock_describe_rates_get(const struct scmi_handle *handle, u32 clk_id,
140 struct scmi_clock_info *clk)
141 {
> 142 u64 *rate = 0;
143 int ret, cnt;
144 bool rate_discrete = false;
145 u32 tot_rate_cnt = 0, rates_flag;
146 u16 num_returned, num_remaining;
147 struct scmi_xfer *t;
148 struct scmi_msg_clock_describe_rates *clk_desc;
149 struct scmi_msg_resp_clock_describe_rates *rlist;
150
151 ret = scmi_xfer_get_init(handle, CLOCK_DESCRIBE_RATES,
152 SCMI_PROTOCOL_CLOCK, sizeof(*clk_desc), 0, &t);
153 if (ret)
154 return ret;
155
156 clk_desc = t->tx.buf;
157 rlist = t->rx.buf;
158
159 do {
160 clk_desc->id = cpu_to_le32(clk_id);
161 /* Set the number of rates to be skipped/already read */
162 clk_desc->rate_index = cpu_to_le32(tot_rate_cnt);
163
164 ret = scmi_do_xfer(handle, t);
165 if (ret)
166 goto err;
167
168 rates_flag = le32_to_cpu(rlist->num_rates_flags);
169 num_remaining = NUM_REMAINING(rates_flag);
170 rate_discrete = RATE_DISCRETE(rates_flag);
171 num_returned = NUM_RETURNED(rates_flag);
172
173 if (tot_rate_cnt + num_returned > SCMI_MAX_NUM_RATES) {
174 dev_err(handle->dev, "No. of rates > MAX_NUM_RATES");
175 break;
176 }
177
178 if (!rate_discrete) {
179 clk->range.min_rate = RATE_TO_U64(rlist->rate[0]);
180 clk->range.max_rate = RATE_TO_U64(rlist->rate[1]);
181 clk->range.step_size = RATE_TO_U64(rlist->rate[2]);
182 dev_dbg(handle->dev, "Min %llu Max %llu Step %llu Hz\n",
183 clk->range.min_rate, clk->range.max_rate,
184 clk->range.step_size);
185 break;
186 }
187
188 rate = &clk->list.rates[tot_rate_cnt];
189 for (cnt = 0; cnt < num_returned; cnt++, rate++) {
190 *rate = RATE_TO_U64(rlist->rate[cnt]);
191 dev_dbg(handle->dev, "Rate %llu Hz\n", *rate);
192 }
193
194 tot_rate_cnt += num_returned;
195 /*
196 * check for both returned and remaining to avoid infinite
197 * loop due to buggy firmware
198 */
199 } while (num_returned && num_remaining);
200
201 if (rate_discrete && rate) {
202 clk->list.num_rates = tot_rate_cnt;
203 sort(rate, tot_rate_cnt, sizeof(*rate), rate_cmp_func, NULL);
204 }
205
206 clk->rate_discrete = rate_discrete;
207
208 err:
209 scmi_xfer_put(handle, t);
210 return ret;
211 }
212
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 38434 bytes --]
^ permalink raw reply
* Re: [PATCH net-next v3 0/2] net: sched: Do not drop root lock in tcf_qevent_handle()
From: Jakub Kicinski @ 2020-07-17 0:37 UTC (permalink / raw)
To: Petr Machata
Cc: netdev, David Miller, Cong Wang, Ido Schimmel, Jiri Pirko,
Eric Dumazet
In-Reply-To: <cover.1594746074.git.petrm@mellanox.com>
On Tue, 14 Jul 2020 20:03:06 +0300 Petr Machata wrote:
> Mirred currently does not mix well with blocks executed after the qdisc
> root lock is taken. This includes classification blocks (such as in PRIO,
> ETS, DRR qdiscs) and qevents. The locking caused by the packet mirrored by
> mirred can cause deadlocks: either when the thread of execution attempts to
> take the lock a second time, or when two threads end up waiting on each
> other's locks.
>
> The qevent patchset attempted to not introduce further badness of this
> sort, and dropped the lock before executing the qevent block. However this
> lead to too little locking and races between qdisc configuration and packet
> enqueue in the RED qdisc.
>
> Before the deadlock issues are solved in a way that can be applied across
> many qdiscs reasonably easily, do for qevents what is done for the
> classification blocks and just keep holding the root lock.
>
> That is done in patch #1. Patch #2 then drops the now unnecessary root_lock
> argument from Qdisc_ops.enqueue.
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net 2/3] net: bcmgenet: test RBUF_ACPI_EN when resuming
From: Florian Fainelli @ 2020-07-17 0:37 UTC (permalink / raw)
To: Doug Berger, David S. Miller
Cc: Jakub Kicinski, bcm-kernel-feedback-list, netdev, linux-kernel
In-Reply-To: <1594942697-37954-3-git-send-email-opendmb@gmail.com>
On 7/16/2020 4:38 PM, Doug Berger wrote:
> When the GENET driver resumes from deep sleep the UMAC_CMD
> register may not be accessible and therefore should not be
> accessed from bcmgenet_wol_power_up_cfg() if the GENET has
> been reset.
>
> This commit adds a check of the RBUF_ACPI_EN flag when Wake
> on Filter is enabled. A clear flag indicates that the GENET
> hardware must have been reset so the remainder of the
> hardware programming is bypassed.
>
> Fixes: f50932cca632 ("net: bcmgenet: add WAKE_FILTER support")
> Signed-off-by: Doug Berger <opendmb@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* Re: [PATCH net 1/3] net: bcmgenet: test MPD_EN when resuming
From: Florian Fainelli @ 2020-07-17 0:36 UTC (permalink / raw)
To: Doug Berger, David S. Miller
Cc: Jakub Kicinski, bcm-kernel-feedback-list, netdev, linux-kernel
In-Reply-To: <1594942697-37954-2-git-send-email-opendmb@gmail.com>
On 7/16/2020 4:38 PM, Doug Berger wrote:
> When the GENET driver resumes from deep sleep the UMAC_CMD
> register may not be accessible and therefore should not be
> accessed from bcmgenet_wol_power_up_cfg() if the GENET has
> been reset.
>
> This commit adds a check of the MPD_EN flag when Wake on
> Magic Packet is enabled. A clear flag indicates that the
> GENET hardware must have been reset so the remainder of the
> hardware programming is bypassed.
>
> Fixes: 1a1d5106c1e3 ("net: bcmgenet: move clk_wol management to bcmgenet_wol")
> Signed-off-by: Doug Berger <opendmb@gmail.com>
Acked-by: Florian Fainelli <f.fainelli@gmail.com>
--
Florian
^ permalink raw reply
* [PATCH] mmc: msm_sdhci: Use mmc_of_parse for setting host_caps
From: Jaehoon Chung @ 2020-07-17 0:36 UTC (permalink / raw)
To: u-boot
In-Reply-To: <20200716090726.13343-1-manivannan.sadhasivam@linaro.org>
On 7/16/20 6:07 PM, Manivannan Sadhasivam wrote:
> Since the introduction of 'get_cd' callback in sdhci core,
> dragonboard410c's MMC interface is broken. It turns out that 'get_cd'
> callback checks for the host_caps for validating the chip select. And
> since the msm_sdhci driver is not parsing the host_caps from DT, not
> all of the cababilities are parsed properly. This results in the MMC
> interfaces to be broken.
>
> Hence, fix this by adding a call to 'mmc_of_parse' during driver probe.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com>
Best Regards,
Jaehoon Chung
> ---
> drivers/mmc/msm_sdhci.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c
> index da3ae2ec35..23e2e0fbc3 100644
> --- a/drivers/mmc/msm_sdhci.c
> +++ b/drivers/mmc/msm_sdhci.c
> @@ -142,6 +142,10 @@ static int msm_sdc_probe(struct udevice *dev)
> writel(caps, host->ioaddr + SDHCI_VENDOR_SPEC_CAPABILITIES0);
> }
>
> + ret = mmc_of_parse(dev, &plat->cfg);
> + if (ret)
> + return ret;
> +
> host->mmc = &plat->mmc;
> host->mmc->dev = dev;
> ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
>
^ permalink raw reply
* [hch-misc:sockptr 30/46] net/xfrm/xfrm_state.c:2289 xfrm_user_policy() warn: passing a valid pointer to 'PTR_ERR'
From: kernel test robot @ 2020-07-17 0:33 UTC (permalink / raw)
To: kbuild
[-- Attachment #1: Type: text/plain, Size: 4705 bytes --]
CC: kbuild-all(a)lists.01.org
TO: Christoph Hellwig <hch@lst.de>
tree: git://git.infradead.org/users/hch/misc.git sockptr
head: ffd998f4245814309d3715c6d03c479f9585abed
commit: b684e3c7f7793431667af178c60aba13d2361481 [30/46] net/xfrm: switch xfrm_user_policy to sockptr_t
:::::: branch date: 5 hours ago
:::::: commit date: 11 hours ago
config: openrisc-randconfig-m031-20200716 (attached as .config)
compiler: or1k-linux-gcc (GCC) 9.3.0
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
smatch warnings:
net/xfrm/xfrm_state.c:2289 xfrm_user_policy() warn: passing a valid pointer to 'PTR_ERR'
git remote add hch-misc git://git.infradead.org/users/hch/misc.git
git remote update hch-misc
git checkout b684e3c7f7793431667af178c60aba13d2361481
vim +/PTR_ERR +2289 net/xfrm/xfrm_state.c
0f24558e9156388 Horia Geanta 2014-02-12 2266
b684e3c7f779343 Christoph Hellwig 2020-07-16 2267 int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval, int optlen)
^1da177e4c3f415 Linus Torvalds 2005-04-16 2268 {
^1da177e4c3f415 Linus Torvalds 2005-04-16 2269 int err;
^1da177e4c3f415 Linus Torvalds 2005-04-16 2270 u8 *data;
^1da177e4c3f415 Linus Torvalds 2005-04-16 2271 struct xfrm_mgr *km;
^1da177e4c3f415 Linus Torvalds 2005-04-16 2272 struct xfrm_policy *pol = NULL;
^1da177e4c3f415 Linus Torvalds 2005-04-16 2273
19d7df69fdb2636 Steffen Klassert 2018-02-01 2274 if (in_compat_syscall())
19d7df69fdb2636 Steffen Klassert 2018-02-01 2275 return -EOPNOTSUPP;
19d7df69fdb2636 Steffen Klassert 2018-02-01 2276
b684e3c7f779343 Christoph Hellwig 2020-07-16 2277 if (sockptr_is_null(optval) && !optlen) {
be8f8284cd897af Lorenzo Colitti 2017-11-20 2278 xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
be8f8284cd897af Lorenzo Colitti 2017-11-20 2279 xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
be8f8284cd897af Lorenzo Colitti 2017-11-20 2280 __sk_dst_reset(sk);
be8f8284cd897af Lorenzo Colitti 2017-11-20 2281 return 0;
be8f8284cd897af Lorenzo Colitti 2017-11-20 2282 }
be8f8284cd897af Lorenzo Colitti 2017-11-20 2283
^1da177e4c3f415 Linus Torvalds 2005-04-16 2284 if (optlen <= 0 || optlen > PAGE_SIZE)
^1da177e4c3f415 Linus Torvalds 2005-04-16 2285 return -EMSGSIZE;
^1da177e4c3f415 Linus Torvalds 2005-04-16 2286
b684e3c7f779343 Christoph Hellwig 2020-07-16 2287 data = memdup_sockptr(optval, optlen);
a133d93054fa063 Geliang Tang 2017-05-06 2288 if (IS_ERR(data))
a133d93054fa063 Geliang Tang 2017-05-06 @2289 return PTR_ERR(data);
^1da177e4c3f415 Linus Torvalds 2005-04-16 2290
^1da177e4c3f415 Linus Torvalds 2005-04-16 2291 err = -EINVAL;
85168c0036fadf3 Cong Wang 2013-01-16 2292 rcu_read_lock();
85168c0036fadf3 Cong Wang 2013-01-16 2293 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
cb969f072b6d677 Venkat Yekkirala 2006-07-24 2294 pol = km->compile_policy(sk, optname, data,
^1da177e4c3f415 Linus Torvalds 2005-04-16 2295 optlen, &err);
^1da177e4c3f415 Linus Torvalds 2005-04-16 2296 if (err >= 0)
^1da177e4c3f415 Linus Torvalds 2005-04-16 2297 break;
^1da177e4c3f415 Linus Torvalds 2005-04-16 2298 }
85168c0036fadf3 Cong Wang 2013-01-16 2299 rcu_read_unlock();
^1da177e4c3f415 Linus Torvalds 2005-04-16 2300
^1da177e4c3f415 Linus Torvalds 2005-04-16 2301 if (err >= 0) {
^1da177e4c3f415 Linus Torvalds 2005-04-16 2302 xfrm_sk_policy_insert(sk, err, pol);
^1da177e4c3f415 Linus Torvalds 2005-04-16 2303 xfrm_pol_put(pol);
2b06cdf3e688b98 Jonathan Basseri 2017-10-25 2304 __sk_dst_reset(sk);
^1da177e4c3f415 Linus Torvalds 2005-04-16 2305 err = 0;
^1da177e4c3f415 Linus Torvalds 2005-04-16 2306 }
^1da177e4c3f415 Linus Torvalds 2005-04-16 2307
^1da177e4c3f415 Linus Torvalds 2005-04-16 2308 kfree(data);
^1da177e4c3f415 Linus Torvalds 2005-04-16 2309 return err;
^1da177e4c3f415 Linus Torvalds 2005-04-16 2310 }
^1da177e4c3f415 Linus Torvalds 2005-04-16 2311 EXPORT_SYMBOL(xfrm_user_policy);
^1da177e4c3f415 Linus Torvalds 2005-04-16 2312
:::::: The code at line 2289 was first introduced by commit
:::::: a133d93054fa063fb3bd328abdc3d09a7e687afe xfrm: use memdup_user
:::::: TO: Geliang Tang <geliangtang@gmail.com>
:::::: CC: Steffen Klassert <steffen.klassert@secunet.com>
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 33224 bytes --]
^ permalink raw reply
* [PATCH 0/9] mmc: fsl_esdhc: support eMMC HS200/HS400 modes
From: Jaehoon Chung @ 2020-07-17 0:31 UTC (permalink / raw)
To: u-boot
In-Reply-To: <20200716022954.36774-1-yangbo.lu@nxp.com>
Hi Yangbo,
On 7/16/20 11:29 AM, Yangbo Lu wrote:
> This patch-set is to support eMMC HS200 and HS400 speed modes for
> eSDHC, and enable them on LX2160ARDB board.
Is there any result about performance?
Best Regards,
Jaehoon Chung
>
> CI build link
> https://travis-ci.org/github/yangbolu1991/u-boot-test/builds/708215558
>
> Yangbo Lu (9):
> mmc: add a reinit() API
> mmc: fsl_esdhc: add a reinit() callback
> mmc: fsl_esdhc: support tuning for eMMC HS200
> mmc: fsl_esdhc: clean TBCTL[TB_EN] manually during init
> mmc: add a hs400_tuning flag
> mmc: add a mmc_hs400_prepare_ddr() interface
> mmc: fsl_esdhc: support eMMC HS400 mode
> arm: dts: lx2160ardb: support eMMC HS400 mode
> configs: lx2160ardb: enable eMMC HS400 mode support
>
> arch/arm/dts/fsl-lx2160a-rdb.dts | 2 +
> configs/lx2160ardb_tfa_SECURE_BOOT_defconfig | 1 +
> configs/lx2160ardb_tfa_defconfig | 1 +
> configs/lx2160ardb_tfa_stmm_defconfig | 1 +
> drivers/mmc/fsl_esdhc.c | 148 ++++++++++++++++++++++++++-
> drivers/mmc/mmc-uclass.c | 30 ++++++
> drivers/mmc/mmc.c | 12 ++-
> include/fsl_esdhc.h | 29 +++++-
> include/mmc.h | 26 ++++-
> 9 files changed, 240 insertions(+), 10 deletions(-)
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.