mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
Char/Misc driver fixes for 6.15-rc4
Here are some small char/misc driver fixes to resolve reported problems for 6.15-rc4. Included in here are: - misc chrdev region range fix reported by many people - nvmem driver fixes and dt updates - mei new device id and fixes - comedi driver fix - pps driver fix - binder debug log fix - pci1xxxx driver fixes - firmware driver fix All of these have been in linux-next for over a week with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCaAuQlQ8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ylrkQCgpZWWeKwuMlH4Lec6E16K3GXbuSAAn2Tr4MKM D2xY4nHBgBi2d2Oj9C7P =LJP6 -----END PGP SIGNATURE----- Merge tag 'char-misc-6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc driver fixes from Greg KH: "Here are some small char/misc driver fixes to resolve reported problems for 6.15-rc4. Included in here are: - misc chrdev region range fix reported by many people - nvmem driver fixes and dt updates - mei new device id and fixes - comedi driver fix - pps driver fix - binder debug log fix - pci1xxxx driver fixes - firmware driver fix All of these have been in linux-next for over a week with no reported issues" * tag 'char-misc-6.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (25 commits) firmware: stratix10-svc: Add of_platform_default_populate() mei: vsc: Use struct vsc_tp_packet as vsc-tp tx_buf and rx_buf type mei: vsc: Fix fortify-panic caused by invalid counted_by() use pps: generators: tio: fix platform_set_drvdata() mcb: fix a double free bug in chameleon_parse_gdd() misc: microchip: pci1xxxx: Fix incorrect IRQ status handling during ack misc: microchip: pci1xxxx: Fix Kernel panic during IRQ handler registration char: misc: register chrdev region with all possible minors mei: me: add panther lake H DID comedi: jr3_pci: Fix synchronous deletion of timer binder: fix offset calculation in debug log intel_th: avoid using deprecated page->mapping, index fields dt-bindings: nvmem: Add compatible for MSM8960 dt-bindings: nvmem: Add compatible for IPQ5018 nvmem: qfprom: switch to 4-byte aligned reads nvmem: core: update raw_len if the bit reading is required nvmem: core: verify cell's raw_len nvmem: core: fix bit offsets of more than one byte dt-bindings: nvmem: fixed-cell: increase bits start value to 31 dt-bindings: nvmem: Add compatible for MS8937 ...
This commit is contained in:
commit
5281c656d9
|
|
@ -27,7 +27,7 @@ properties:
|
|||
$ref: /schemas/types.yaml#/definitions/uint32-array
|
||||
items:
|
||||
- minimum: 0
|
||||
maximum: 7
|
||||
maximum: 31
|
||||
description:
|
||||
Offset in bit within the address range specified by reg.
|
||||
- minimum: 1
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ properties:
|
|||
- enum:
|
||||
- qcom,apq8064-qfprom
|
||||
- qcom,apq8084-qfprom
|
||||
- qcom,ipq5018-qfprom
|
||||
- qcom,ipq5332-qfprom
|
||||
- qcom,ipq5424-qfprom
|
||||
- qcom,ipq6018-qfprom
|
||||
|
|
@ -28,6 +29,8 @@ properties:
|
|||
- qcom,msm8226-qfprom
|
||||
- qcom,msm8916-qfprom
|
||||
- qcom,msm8917-qfprom
|
||||
- qcom,msm8937-qfprom
|
||||
- qcom,msm8960-qfprom
|
||||
- qcom,msm8974-qfprom
|
||||
- qcom,msm8976-qfprom
|
||||
- qcom,msm8996-qfprom
|
||||
|
|
@ -51,6 +54,7 @@ properties:
|
|||
- qcom,sm8450-qfprom
|
||||
- qcom,sm8550-qfprom
|
||||
- qcom,sm8650-qfprom
|
||||
- qcom,x1e80100-qfprom
|
||||
- const: qcom,qfprom
|
||||
|
||||
reg:
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ properties:
|
|||
enum:
|
||||
- rockchip,px30-otp
|
||||
- rockchip,rk3308-otp
|
||||
- rockchip,rk3576-otp
|
||||
- rockchip,rk3588-otp
|
||||
|
||||
reg:
|
||||
|
|
@ -62,12 +63,34 @@ allOf:
|
|||
properties:
|
||||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
maxItems: 3
|
||||
resets:
|
||||
maxItems: 1
|
||||
reset-names:
|
||||
items:
|
||||
- const: phy
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- rockchip,rk3576-otp
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
maxItems: 3
|
||||
clock-names:
|
||||
maxItems: 3
|
||||
resets:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
reset-names:
|
||||
items:
|
||||
- const: otp
|
||||
- const: apb
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -78,6 +101,8 @@ allOf:
|
|||
properties:
|
||||
clocks:
|
||||
minItems: 4
|
||||
clock-names:
|
||||
minItems: 4
|
||||
resets:
|
||||
minItems: 3
|
||||
reset-names:
|
||||
|
|
|
|||
|
|
@ -6373,7 +6373,7 @@ static void print_binder_transaction_ilocked(struct seq_file *m,
|
|||
seq_printf(m, " node %d", buffer->target_node->debug_id);
|
||||
seq_printf(m, " size %zd:%zd offset %lx\n",
|
||||
buffer->data_size, buffer->offsets_size,
|
||||
proc->alloc.vm_start - buffer->user_data);
|
||||
buffer->user_data - proc->alloc.vm_start);
|
||||
}
|
||||
|
||||
static void print_binder_work_ilocked(struct seq_file *m,
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ static int __init misc_init(void)
|
|||
goto fail_remove;
|
||||
|
||||
err = -EIO;
|
||||
if (register_chrdev(MISC_MAJOR, "misc", &misc_fops))
|
||||
if (__register_chrdev(MISC_MAJOR, 0, MINORMASK + 1, "misc", &misc_fops))
|
||||
goto fail_printk;
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -758,7 +758,7 @@ static void jr3_pci_detach(struct comedi_device *dev)
|
|||
struct jr3_pci_dev_private *devpriv = dev->private;
|
||||
|
||||
if (devpriv)
|
||||
timer_delete_sync(&devpriv->timer);
|
||||
timer_shutdown_sync(&devpriv->timer);
|
||||
|
||||
comedi_pci_detach(dev);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1224,22 +1224,28 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev)
|
|||
if (!svc->intel_svc_fcs) {
|
||||
dev_err(dev, "failed to allocate %s device\n", INTEL_FCS);
|
||||
ret = -ENOMEM;
|
||||
goto err_unregister_dev;
|
||||
goto err_unregister_rsu_dev;
|
||||
}
|
||||
|
||||
ret = platform_device_add(svc->intel_svc_fcs);
|
||||
if (ret) {
|
||||
platform_device_put(svc->intel_svc_fcs);
|
||||
goto err_unregister_dev;
|
||||
goto err_unregister_rsu_dev;
|
||||
}
|
||||
|
||||
ret = of_platform_default_populate(dev_of_node(dev), NULL, dev);
|
||||
if (ret)
|
||||
goto err_unregister_fcs_dev;
|
||||
|
||||
dev_set_drvdata(dev, svc);
|
||||
|
||||
pr_info("Intel Service Layer Driver Initialized\n");
|
||||
|
||||
return 0;
|
||||
|
||||
err_unregister_dev:
|
||||
err_unregister_fcs_dev:
|
||||
platform_device_unregister(svc->intel_svc_fcs);
|
||||
err_unregister_rsu_dev:
|
||||
platform_device_unregister(svc->stratix10_svc_rsu);
|
||||
err_free_kfifo:
|
||||
kfifo_free(&controller->svc_fifo);
|
||||
|
|
@ -1253,6 +1259,8 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev)
|
|||
struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev);
|
||||
struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev);
|
||||
|
||||
of_platform_depopulate(ctrl->dev);
|
||||
|
||||
platform_device_unregister(svc->intel_svc_fcs);
|
||||
platform_device_unregister(svc->stratix10_svc_rsu);
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ config INTEL_TH_STH
|
|||
|
||||
config INTEL_TH_MSU
|
||||
tristate "Intel(R) Trace Hub Memory Storage Unit"
|
||||
depends on MMU
|
||||
help
|
||||
Memory Storage Unit (MSU) trace output device enables
|
||||
storing STP traces to system memory. It supports single
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <linux/io.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/pfn_t.h>
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
#include <asm/set_memory.h>
|
||||
|
|
@ -976,7 +977,6 @@ static void msc_buffer_contig_free(struct msc *msc)
|
|||
for (off = 0; off < msc->nr_pages << PAGE_SHIFT; off += PAGE_SIZE) {
|
||||
struct page *page = virt_to_page(msc->base + off);
|
||||
|
||||
page->mapping = NULL;
|
||||
__free_page(page);
|
||||
}
|
||||
|
||||
|
|
@ -1158,9 +1158,6 @@ static void __msc_buffer_win_free(struct msc *msc, struct msc_window *win)
|
|||
int i;
|
||||
|
||||
for_each_sg(win->sgt->sgl, sg, win->nr_segs, i) {
|
||||
struct page *page = msc_sg_page(sg);
|
||||
|
||||
page->mapping = NULL;
|
||||
dma_free_coherent(msc_dev(win->msc)->parent->parent, PAGE_SIZE,
|
||||
sg_virt(sg), sg_dma_address(sg));
|
||||
}
|
||||
|
|
@ -1601,22 +1598,10 @@ static void msc_mmap_close(struct vm_area_struct *vma)
|
|||
{
|
||||
struct msc_iter *iter = vma->vm_file->private_data;
|
||||
struct msc *msc = iter->msc;
|
||||
unsigned long pg;
|
||||
|
||||
if (!atomic_dec_and_mutex_lock(&msc->mmap_count, &msc->buf_mutex))
|
||||
return;
|
||||
|
||||
/* drop page _refcounts */
|
||||
for (pg = 0; pg < msc->nr_pages; pg++) {
|
||||
struct page *page = msc_buffer_get_page(msc, pg);
|
||||
|
||||
if (WARN_ON_ONCE(!page))
|
||||
continue;
|
||||
|
||||
if (page->mapping)
|
||||
page->mapping = NULL;
|
||||
}
|
||||
|
||||
/* last mapping -- drop user_count */
|
||||
atomic_dec(&msc->user_count);
|
||||
mutex_unlock(&msc->buf_mutex);
|
||||
|
|
@ -1626,16 +1611,14 @@ static vm_fault_t msc_mmap_fault(struct vm_fault *vmf)
|
|||
{
|
||||
struct msc_iter *iter = vmf->vma->vm_file->private_data;
|
||||
struct msc *msc = iter->msc;
|
||||
struct page *page;
|
||||
|
||||
vmf->page = msc_buffer_get_page(msc, vmf->pgoff);
|
||||
if (!vmf->page)
|
||||
page = msc_buffer_get_page(msc, vmf->pgoff);
|
||||
if (!page)
|
||||
return VM_FAULT_SIGBUS;
|
||||
|
||||
get_page(vmf->page);
|
||||
vmf->page->mapping = vmf->vma->vm_file->f_mapping;
|
||||
vmf->page->index = vmf->pgoff;
|
||||
|
||||
return 0;
|
||||
get_page(page);
|
||||
return vmf_insert_mixed(vmf->vma, vmf->address, page_to_pfn_t(page));
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct msc_mmap_ops = {
|
||||
|
|
@ -1676,7 +1659,7 @@ static int intel_th_msc_mmap(struct file *file, struct vm_area_struct *vma)
|
|||
atomic_dec(&msc->user_count);
|
||||
|
||||
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
|
||||
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTCOPY);
|
||||
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTCOPY | VM_MIXEDMAP);
|
||||
vma->vm_ops = &msc_mmap_ops;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus,
|
|||
|
||||
ret = mcb_device_register(bus, mdev);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
struct pci1xxxx_gpio {
|
||||
struct auxiliary_device *aux_dev;
|
||||
void __iomem *reg_base;
|
||||
raw_spinlock_t wa_lock;
|
||||
struct gpio_chip gpio;
|
||||
spinlock_t lock;
|
||||
int irq_base;
|
||||
|
|
@ -167,7 +168,7 @@ static void pci1xxxx_gpio_irq_ack(struct irq_data *data)
|
|||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
pci1xxx_assign_bit(priv->reg_base, INTR_STAT_OFFSET(gpio), (gpio % 32), true);
|
||||
writel(BIT(gpio % 32), priv->reg_base + INTR_STAT_OFFSET(gpio));
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
}
|
||||
|
||||
|
|
@ -257,6 +258,7 @@ static irqreturn_t pci1xxxx_gpio_irq_handler(int irq, void *dev_id)
|
|||
struct pci1xxxx_gpio *priv = dev_id;
|
||||
struct gpio_chip *gc = &priv->gpio;
|
||||
unsigned long int_status = 0;
|
||||
unsigned long wa_flags;
|
||||
unsigned long flags;
|
||||
u8 pincount;
|
||||
int bit;
|
||||
|
|
@ -280,7 +282,9 @@ static irqreturn_t pci1xxxx_gpio_irq_handler(int irq, void *dev_id)
|
|||
writel(BIT(bit), priv->reg_base + INTR_STATUS_OFFSET(gpiobank));
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
irq = irq_find_mapping(gc->irq.domain, (bit + (gpiobank * 32)));
|
||||
handle_nested_irq(irq);
|
||||
raw_spin_lock_irqsave(&priv->wa_lock, wa_flags);
|
||||
generic_handle_irq(irq);
|
||||
raw_spin_unlock_irqrestore(&priv->wa_lock, wa_flags);
|
||||
}
|
||||
}
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@
|
|||
|
||||
#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
|
||||
|
||||
#define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */
|
||||
#define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
|
|||
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
|
||||
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)},
|
||||
{MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)},
|
||||
|
||||
/* required last entry */
|
||||
|
|
|
|||
|
|
@ -36,20 +36,24 @@
|
|||
#define VSC_TP_XFER_TIMEOUT_BYTES 700
|
||||
#define VSC_TP_PACKET_PADDING_SIZE 1
|
||||
#define VSC_TP_PACKET_SIZE(pkt) \
|
||||
(sizeof(struct vsc_tp_packet) + le16_to_cpu((pkt)->len) + VSC_TP_CRC_SIZE)
|
||||
(sizeof(struct vsc_tp_packet_hdr) + le16_to_cpu((pkt)->hdr.len) + VSC_TP_CRC_SIZE)
|
||||
#define VSC_TP_MAX_PACKET_SIZE \
|
||||
(sizeof(struct vsc_tp_packet) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE)
|
||||
(sizeof(struct vsc_tp_packet_hdr) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE)
|
||||
#define VSC_TP_MAX_XFER_SIZE \
|
||||
(VSC_TP_MAX_PACKET_SIZE + VSC_TP_XFER_TIMEOUT_BYTES)
|
||||
#define VSC_TP_NEXT_XFER_LEN(len, offset) \
|
||||
(len + sizeof(struct vsc_tp_packet) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
|
||||
(len + sizeof(struct vsc_tp_packet_hdr) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
|
||||
|
||||
struct vsc_tp_packet {
|
||||
struct vsc_tp_packet_hdr {
|
||||
__u8 sync;
|
||||
__u8 cmd;
|
||||
__le16 len;
|
||||
__le32 seq;
|
||||
__u8 buf[] __counted_by(len);
|
||||
};
|
||||
|
||||
struct vsc_tp_packet {
|
||||
struct vsc_tp_packet_hdr hdr;
|
||||
__u8 buf[VSC_TP_MAX_XFER_SIZE - sizeof(struct vsc_tp_packet_hdr)];
|
||||
};
|
||||
|
||||
struct vsc_tp {
|
||||
|
|
@ -67,8 +71,8 @@ struct vsc_tp {
|
|||
u32 seq;
|
||||
|
||||
/* command buffer */
|
||||
void *tx_buf;
|
||||
void *rx_buf;
|
||||
struct vsc_tp_packet *tx_buf;
|
||||
struct vsc_tp_packet *rx_buf;
|
||||
|
||||
atomic_t assert_cnt;
|
||||
wait_queue_head_t xfer_wait;
|
||||
|
|
@ -158,12 +162,12 @@ static int vsc_tp_dev_xfer(struct vsc_tp *tp, void *obuf, void *ibuf, size_t len
|
|||
static int vsc_tp_xfer_helper(struct vsc_tp *tp, struct vsc_tp_packet *pkt,
|
||||
void *ibuf, u16 ilen)
|
||||
{
|
||||
int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet);
|
||||
int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet_hdr);
|
||||
int next_xfer_len = VSC_TP_PACKET_SIZE(pkt) + VSC_TP_XFER_TIMEOUT_BYTES;
|
||||
u8 *src, *crc_src, *rx_buf = tp->rx_buf;
|
||||
u8 *src, *crc_src, *rx_buf = (u8 *)tp->rx_buf;
|
||||
int count_down = VSC_TP_MAX_XFER_COUNT;
|
||||
u32 recv_crc = 0, crc = ~0;
|
||||
struct vsc_tp_packet ack;
|
||||
struct vsc_tp_packet_hdr ack;
|
||||
u8 *dst = (u8 *)&ack;
|
||||
bool synced = false;
|
||||
|
||||
|
|
@ -280,10 +284,10 @@ int vsc_tp_xfer(struct vsc_tp *tp, u8 cmd, const void *obuf, size_t olen,
|
|||
|
||||
guard(mutex)(&tp->mutex);
|
||||
|
||||
pkt->sync = VSC_TP_PACKET_SYNC;
|
||||
pkt->cmd = cmd;
|
||||
pkt->len = cpu_to_le16(olen);
|
||||
pkt->seq = cpu_to_le32(++tp->seq);
|
||||
pkt->hdr.sync = VSC_TP_PACKET_SYNC;
|
||||
pkt->hdr.cmd = cmd;
|
||||
pkt->hdr.len = cpu_to_le16(olen);
|
||||
pkt->hdr.seq = cpu_to_le32(++tp->seq);
|
||||
memcpy(pkt->buf, obuf, olen);
|
||||
|
||||
crc = ~crc32(~0, (u8 *)pkt, sizeof(pkt) + olen);
|
||||
|
|
@ -320,7 +324,7 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len)
|
|||
guard(mutex)(&tp->mutex);
|
||||
|
||||
/* rom xfer is big endian */
|
||||
cpu_to_be32_array(tp->tx_buf, obuf, words);
|
||||
cpu_to_be32_array((u32 *)tp->tx_buf, obuf, words);
|
||||
|
||||
ret = read_poll_timeout(gpiod_get_value_cansleep, ret,
|
||||
!ret, VSC_TP_ROM_XFER_POLL_DELAY_US,
|
||||
|
|
@ -336,7 +340,7 @@ int vsc_tp_rom_xfer(struct vsc_tp *tp, const void *obuf, void *ibuf, size_t len)
|
|||
return ret;
|
||||
|
||||
if (ibuf)
|
||||
be32_to_cpu_array(ibuf, tp->rx_buf, words);
|
||||
be32_to_cpu_array(ibuf, (u32 *)tp->rx_buf, words);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -490,11 +494,11 @@ static int vsc_tp_probe(struct spi_device *spi)
|
|||
if (!tp)
|
||||
return -ENOMEM;
|
||||
|
||||
tp->tx_buf = devm_kzalloc(dev, VSC_TP_MAX_XFER_SIZE, GFP_KERNEL);
|
||||
tp->tx_buf = devm_kzalloc(dev, sizeof(*tp->tx_buf), GFP_KERNEL);
|
||||
if (!tp->tx_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
tp->rx_buf = devm_kzalloc(dev, VSC_TP_MAX_XFER_SIZE, GFP_KERNEL);
|
||||
tp->rx_buf = devm_kzalloc(dev, sizeof(*tp->rx_buf), GFP_KERNEL);
|
||||
if (!tp->rx_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -594,9 +594,11 @@ static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem,
|
|||
cell->nbits = info->nbits;
|
||||
cell->np = info->np;
|
||||
|
||||
if (cell->nbits)
|
||||
if (cell->nbits) {
|
||||
cell->bytes = DIV_ROUND_UP(cell->nbits + cell->bit_offset,
|
||||
BITS_PER_BYTE);
|
||||
cell->raw_len = ALIGN(cell->bytes, nvmem->word_size);
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(cell->offset, nvmem->stride)) {
|
||||
dev_err(&nvmem->dev,
|
||||
|
|
@ -605,6 +607,18 @@ static int nvmem_cell_info_to_nvmem_cell_entry_nodup(struct nvmem_device *nvmem,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(cell->raw_len, nvmem->word_size)) {
|
||||
dev_err(&nvmem->dev,
|
||||
"cell %s raw len %zd unaligned to nvmem word size %d\n",
|
||||
cell->name ?: "<unknown>", cell->raw_len,
|
||||
nvmem->word_size);
|
||||
|
||||
if (info->raw_len)
|
||||
return -EINVAL;
|
||||
|
||||
cell->raw_len = ALIGN(cell->raw_len, nvmem->word_size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -837,7 +851,9 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod
|
|||
if (addr && len == (2 * sizeof(u32))) {
|
||||
info.bit_offset = be32_to_cpup(addr++);
|
||||
info.nbits = be32_to_cpup(addr);
|
||||
if (info.bit_offset >= BITS_PER_BYTE || info.nbits < 1) {
|
||||
if (info.bit_offset >= BITS_PER_BYTE * info.bytes ||
|
||||
info.nbits < 1 ||
|
||||
info.bit_offset + info.nbits > BITS_PER_BYTE * info.bytes) {
|
||||
dev_err(dev, "nvmem: invalid bits on %pOF\n", child);
|
||||
of_node_put(child);
|
||||
return -EINVAL;
|
||||
|
|
@ -1630,21 +1646,29 @@ EXPORT_SYMBOL_GPL(nvmem_cell_put);
|
|||
static void nvmem_shift_read_buffer_in_place(struct nvmem_cell_entry *cell, void *buf)
|
||||
{
|
||||
u8 *p, *b;
|
||||
int i, extra, bit_offset = cell->bit_offset;
|
||||
int i, extra, bytes_offset;
|
||||
int bit_offset = cell->bit_offset;
|
||||
|
||||
p = b = buf;
|
||||
if (bit_offset) {
|
||||
|
||||
bytes_offset = bit_offset / BITS_PER_BYTE;
|
||||
b += bytes_offset;
|
||||
bit_offset %= BITS_PER_BYTE;
|
||||
|
||||
if (bit_offset % BITS_PER_BYTE) {
|
||||
/* First shift */
|
||||
*b++ >>= bit_offset;
|
||||
*p = *b++ >> bit_offset;
|
||||
|
||||
/* setup rest of the bytes if any */
|
||||
for (i = 1; i < cell->bytes; i++) {
|
||||
/* Get bits from next byte and shift them towards msb */
|
||||
*p |= *b << (BITS_PER_BYTE - bit_offset);
|
||||
*p++ |= *b << (BITS_PER_BYTE - bit_offset);
|
||||
|
||||
p = b;
|
||||
*b++ >>= bit_offset;
|
||||
*p = *b++ >> bit_offset;
|
||||
}
|
||||
} else if (p != b) {
|
||||
memmove(p, b, cell->bytes - bytes_offset);
|
||||
p += cell->bytes - 1;
|
||||
} else {
|
||||
/* point to the msb */
|
||||
p += cell->bytes - 1;
|
||||
|
|
|
|||
|
|
@ -321,19 +321,32 @@ static int qfprom_reg_read(void *context,
|
|||
unsigned int reg, void *_val, size_t bytes)
|
||||
{
|
||||
struct qfprom_priv *priv = context;
|
||||
u8 *val = _val;
|
||||
int i = 0, words = bytes;
|
||||
u32 *val = _val;
|
||||
void __iomem *base = priv->qfpcorrected;
|
||||
int words = DIV_ROUND_UP(bytes, sizeof(u32));
|
||||
int i;
|
||||
|
||||
if (read_raw_data && priv->qfpraw)
|
||||
base = priv->qfpraw;
|
||||
|
||||
while (words--)
|
||||
*val++ = readb(base + reg + i++);
|
||||
for (i = 0; i < words; i++)
|
||||
*val++ = readl(base + reg + i * sizeof(u32));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Align reads to word boundary */
|
||||
static void qfprom_fixup_dt_cell_info(struct nvmem_device *nvmem,
|
||||
struct nvmem_cell_info *cell)
|
||||
{
|
||||
unsigned int byte_offset = cell->offset % sizeof(u32);
|
||||
|
||||
cell->bit_offset += byte_offset * BITS_PER_BYTE;
|
||||
cell->offset -= byte_offset;
|
||||
if (byte_offset && !cell->nbits)
|
||||
cell->nbits = cell->bytes * BITS_PER_BYTE;
|
||||
}
|
||||
|
||||
static void qfprom_runtime_disable(void *data)
|
||||
{
|
||||
pm_runtime_disable(data);
|
||||
|
|
@ -358,10 +371,11 @@ static int qfprom_probe(struct platform_device *pdev)
|
|||
struct nvmem_config econfig = {
|
||||
.name = "qfprom",
|
||||
.add_legacy_fixed_of_cells = true,
|
||||
.stride = 1,
|
||||
.word_size = 1,
|
||||
.stride = 4,
|
||||
.word_size = 4,
|
||||
.id = NVMEM_DEVID_AUTO,
|
||||
.reg_read = qfprom_reg_read,
|
||||
.fixup_dt_cell_info = qfprom_fixup_dt_cell_info,
|
||||
};
|
||||
struct device *dev = &pdev->dev;
|
||||
struct resource *res;
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@
|
|||
#define RK3588_OTPC_AUTO_EN 0x08
|
||||
#define RK3588_OTPC_INT_ST 0x84
|
||||
#define RK3588_OTPC_DOUT0 0x20
|
||||
#define RK3588_NO_SECURE_OFFSET 0x300
|
||||
#define RK3588_NBYTES 4
|
||||
#define RK3588_BURST_NUM 1
|
||||
#define RK3588_BURST_SHIFT 8
|
||||
|
|
@ -69,6 +68,7 @@
|
|||
|
||||
struct rockchip_data {
|
||||
int size;
|
||||
int read_offset;
|
||||
const char * const *clks;
|
||||
int num_clks;
|
||||
nvmem_reg_read_t reg_read;
|
||||
|
|
@ -196,7 +196,7 @@ static int rk3588_otp_read(void *context, unsigned int offset,
|
|||
addr_start = round_down(offset, RK3588_NBYTES) / RK3588_NBYTES;
|
||||
addr_end = round_up(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
|
||||
addr_len = addr_end - addr_start;
|
||||
addr_start += RK3588_NO_SECURE_OFFSET;
|
||||
addr_start += otp->data->read_offset / RK3588_NBYTES;
|
||||
|
||||
buf = kzalloc(array_size(addr_len, RK3588_NBYTES), GFP_KERNEL);
|
||||
if (!buf)
|
||||
|
|
@ -274,12 +274,21 @@ static const struct rockchip_data px30_data = {
|
|||
.reg_read = px30_otp_read,
|
||||
};
|
||||
|
||||
static const struct rockchip_data rk3576_data = {
|
||||
.size = 0x100,
|
||||
.read_offset = 0x700,
|
||||
.clks = px30_otp_clocks,
|
||||
.num_clks = ARRAY_SIZE(px30_otp_clocks),
|
||||
.reg_read = rk3588_otp_read,
|
||||
};
|
||||
|
||||
static const char * const rk3588_otp_clocks[] = {
|
||||
"otp", "apb_pclk", "phy", "arb",
|
||||
};
|
||||
|
||||
static const struct rockchip_data rk3588_data = {
|
||||
.size = 0x400,
|
||||
.read_offset = 0xc00,
|
||||
.clks = rk3588_otp_clocks,
|
||||
.num_clks = ARRAY_SIZE(rk3588_otp_clocks),
|
||||
.reg_read = rk3588_otp_read,
|
||||
|
|
@ -294,6 +303,10 @@ static const struct of_device_id rockchip_otp_match[] = {
|
|||
.compatible = "rockchip,rk3308-otp",
|
||||
.data = &px30_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3576-otp",
|
||||
.data = &rk3576_data,
|
||||
},
|
||||
{
|
||||
.compatible = "rockchip,rk3588-otp",
|
||||
.data = &rk3588_data,
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ static int pps_gen_tio_probe(struct platform_device *pdev)
|
|||
hrtimer_setup(&tio->timer, hrtimer_callback, CLOCK_REALTIME,
|
||||
HRTIMER_MODE_ABS);
|
||||
spin_lock_init(&tio->lock);
|
||||
platform_set_drvdata(pdev, &tio);
|
||||
platform_set_drvdata(pdev, tio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user