powerpc/nohash: Fix use of mmu_has_feature() in setup_initial_memory_limit()
Subsystems (8)
PATCH 170/190 rtc: ac100: Fix multiple race conditions
In reply to Sasha LevinFrom: Alexandre Belloni <[email protected]>
[ Upstream commit 994ec64c0a193940be7a6fd074668b9446d3b6c3 ]
The probe function is not allowed to fail after registering the RTC because the following may happen:
CPU0: CPU1:sys_load_module()
do_init_module()
do_one_initcall()
cmos_do_probe()
rtc_device_register()
__register_chrdev()
cdev->owner = struct module*
open("/dev/rtc0")
rtc_device_unregister()
module_put()
free_module()
module_free(mod->module_core)
/* struct module *module is now
freed */
chrdev_open()
spin_lock(cdev_lock)
cdev_get()
try_module_get()
module_is_live()
/* dereferences already
freed struct module* */Also, the interrupt handler: ac100_rtc_irq() is dereferencing chip->rtc but this may still be NULL when it is called, resulting in:
Unable to handle kernel NULL pointer dereference at virtual address 00000194 pgd = (ptrval) [00000194] *pgd=00000000 Internal error: Oops: 5 [#1] SMP ARM Modules linked in: CPU: 0 PID: 72 Comm: irq/71-ac100-rt Not tainted 4.15.0-rc1-next-20171201-dirty #120 Hardware name: Allwinner sun8i Family task: (ptrval) task.stack: (ptrval) PC is at mutex_lock+0x14/0x3c LR is at ac100_rtc_irq+0x38/0xc8 pc : [<c06543a4>] lr : [<c04d9a2c>] psr: 60000053
sp : ee9c9f28 ip : 00000000 fp : ee9adfdc
r10: 00000000 r9 : c0a04c48 r8 : c015ed18
r7 : ee9bd600 r6 : ee9c9f28 r5 : ee9af590 r4 : c0a04c48 r3 : ef3cb3c0 r2 : 00000000 r1 : ee9af590 r0 : 00000194
Flags: nZCv IRQs on FIQs off Mode SVC_32 ISA ARM Segment none
Control: 10c5387d Table: 4000406a DAC: 00000051 Process irq/71-ac100-rt (pid: 72, stack limit = 0x(ptrval))
Stack: (0xee9c9f28 to 0xee9ca000)
9f20: 00000000 7c2fd1be c015ed18 ee9adf40 ee9c0400 ee9c0400
9f40: ee9adf40 c015ed34 ee9c8000 ee9adf64 ee9c0400 c015f040 ee9adf80 00000000 9f60: c015ee24 7c2fd1be ee9adfc0 ee9adf80 00000000 ee9c8000 ee9adf40 c015eef4 9f80: ef1eba34 c0138f14 ee9c8000 ee9adf80 c0138df4 00000000 00000000 00000000 9fa0: 00000000 00000000 00000000 c01010e8 00000000 00000000 00000000 00000000 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffffffff ffffffff [<c06543a4>] (mutex_lock) from [<c04d9a2c>] (ac100_rtc_irq+0x38/0xc8) [<c04d9a2c>] (ac100_rtc_irq) from [<c015ed34>] (irq_thread_fn+0x1c/0x54) [<c015ed34>] (irq_thread_fn) from [<c015f040>] (irq_thread+0x14c/0x214) [<c015f040>] (irq_thread) from [<c0138f14>] (kthread+0x120/0x150) [<c0138f14>] (kthread) from [<c01010e8>] (ret_from_fork+0x14/0x2c)
Solve both issues by moving to
devm_rtc_allocate_device()/rtc_register_device()
--- drivers/rtc/rtc-ac100.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-)
drivers/rtc/rtc-ac100.c +12 -7
@@ -567,6 +567,12 @@ static int ac100_rtc_probe(struct platform_device *pdev)return chip->irq; } + chip->rtc =devm_rtc_allocate_device (&pdev->dev); +if (IS_ERR (chip->rtc)) +return PTR_ERR (chip->rtc); + + chip->rtc->ops = &ac100_rtc_ops; + ret = devm_request_threaded_irq(&pdev->dev, chip->irq, NULL, ac100_rtc_irq, IRQF_SHARED | IRQF_ONESHOT,
@@ -586,17 +592,16 @@ static int ac100_rtc_probe(struct platform_device *pdev)/* clear counter alarm pending interrupts */ regmap_write (chip->regmap,AC100_ALM_INT_STA ,AC100_ALM_INT_ENABLE ); - chip->rtc =devm_rtc_device_register (&pdev->dev,"rtc-ac100" , - &ac100_rtc_ops,THIS_MODULE ); -if (IS_ERR (chip->rtc)) { -dev_err (&pdev->dev,"unable to register device\n" ); -return PTR_ERR (chip->rtc); - } - ret =ac100_rtc_register_clks (chip);if (ret)return ret; + ret =rtc_register_device (chip->rtc); +if (ret) { +dev_err (&pdev->dev,"unable to register device\n" ); +return ret; + } +dev_info (&pdev->dev,"RTC enabled\n" );return 0 ;
Signature · 1 line
2.14.1
PATCH 171/190 IB/ipoib: Avoid memory leak if the SA returns a different DGID
In reply to Sasha LevinFrom: Erez Shitrit <[email protected]>
[ Upstream commit 439000892ee17a9c92f1e4297818790ef8bb4ced ]
The ipoib path database is organized around DGIDs from the LLADDR, but the SA is free to return a different GID when asked for path. This causes a bug because the SA's modified DGID is copied into the database key, even though it is no longer the correct lookup key, causing a memory leak and other malfunctions.
Ensure the database key does not change after the SA query completes.
Demonstration of the bug is as follows
ipoib wants to send to GID fe80:0000:0000:0000:0002:c903:00ef:5ee2, it creates new record in the DB with that gid as a key, and issues a new request to the SM.
Now, the SM from some reason returns path-record with other SGID (for example, 2001:0000:0000:0000:0002:c903:00ef:5ee2 that contains the local subnet prefix) now ipoib will overwrite the current entry with the new one, and if new request to the original GID arrives ipoib will not find it in the DB (was overwritten) and will create new record that in its turn will also be overwritten by the response from the SM, and so on till the driver eats all the device memory.
--- drivers/infiniband/ulp/ipoib/ipoib_main.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
drivers/infiniband/ulp/ipoib/ipoib_main.c +16 -0
@@ -799,6 +799,22 @@ static void path_rec_completion(int status,spin_lock_irqsave (&priv->lock, flags);if (!IS_ERR_OR_NULL (ah)) { +/* +* pathrec.dgid is used as the database key from the LLADDR, +* it must remain unchanged even if the SA returns a different +* GID to use in the AH. +*/ +if (memcmp (pathrec->dgid.raw, path->pathrec.dgid.raw, +sizeof (union ib_gid ))) { +ipoib_dbg ( + priv, +"%s got PathRec for gid %pI6 while asked for %pI6\n" , + dev->name, pathrec->dgid.raw, + path->pathrec.dgid.raw); +memcpy (pathrec->dgid.raw, path->pathrec.dgid.raw, +sizeof (union ib_gid )); + } + path->pathrec = *pathrec; old_ah = path->ah;
Signature · 1 line
2.14.1
PATCH 172/190 RDMA/cma: Use correct size when writing netlink stats
In reply to Sasha LevinFrom: Parav Pandit <[email protected]>
[ Upstream commit 7baaa49af3716fb31877c61f59b74d029ce15b75 ]
The code was using the src size when formatting the dst. They are almost certainly the same value but it reads wrong.
--- drivers/infiniband/core/cma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/cma.c +1 -1
@@ -4336,7 +4336,7 @@ static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb) RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) goto out;if (ibnl_put_attr (skb, nlh, -rdma_addr_size (cma_src_addr (id_priv)), +rdma_addr_size (cma_dst_addr (id_priv)),cma_dst_addr (id_priv),RDMA_NL_RDMA_CM_ATTR_DST_ADDR )) goto out;
Signature · 1 line
2.14.1
PATCH 173/190 IB/umem: Fix use of npages/nmap fields
In reply to Sasha LevinFrom: Artemy Kovalyov <[email protected]>
[ Upstream commit edf1a84fe37c51290e2c88154ecaf48dadff3d27 ]
In ib_umem structure npages holds original number of sg entries, while nmap is number of DMA blocks returned by dma_map_sg.
--- drivers/infiniband/core/umem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/core/umem.c +1 -1
@@ -357,7 +357,7 @@ int ib_umem_copy_from(void *dst, struct ib_umem *umem, size_t offset,return -EINVAL ; } - ret =sg_pcopy_to_buffer (umem->sg_head.sgl, umem->nmap, dst, length, + ret =sg_pcopy_to_buffer (umem->sg_head.sgl, umem->npages, dst, length, offset +ib_umem_offset (umem));if (ret <0 )
Signature · 1 line
2.14.1
PATCH 174/190 iser-target: avoid reinitializing rdma contexts for isert commands
In reply to Sasha LevinFrom: Bharat Potnuri <[email protected]>
[ Upstream commit 66f53e6f5400578bae58db0c06d85a8820831f40 ]
isert commands that failed during isert_rdma_rw_ctx_post() are queued to Queue-Full(QF) queue and are scheduled to be reposted during queue-full queue processing. During this reposting, the rdma contexts are initialised again in isert_rdma_rw_ctx_post(), which is leaking significant memory.
unreferenced object 0xffff8830201d9640 (size 64):
comm "kworker/0:2", pid 195, jiffies 4295374851 (age 4528.436s) hex dump (first 32 bytes):
00 60 8b cb 2e 00 00 00 00 10 00 00 00 00 00 00 .`..............
00 90 e3 cb 2e 00 00 00 00 10 00 00 00 00 00 00 ................
backtrace:
[<ffffffff8170711e>] kmemleak_alloc+0x4e/0xb0
[<ffffffff811f8ba5>] __kmalloc+0x125/0x2b0
[<ffffffffa046b24f>] rdma_rw_ctx_init+0x15f/0x6f0 [ib_core]
[<ffffffffa07ab644>] isert_rdma_rw_ctx_post+0xc4/0x3c0 [ib_isert]
[<ffffffffa07ad972>] isert_put_datain+0x112/0x1c0 [ib_isert]
[<ffffffffa07dddce>] lio_queue_data_in+0x2e/0x30 [iscsi_target_mod]
[<ffffffffa076c322>] target_qf_do_work+0x2b2/0x4b0 [target_core_mod]
[<ffffffff81080c3b>] process_one_work+0x1db/0x5d0
[<ffffffff8108107d>] worker_thread+0x4d/0x3e0
[<ffffffff81088667>] kthread+0x117/0x150
[<ffffffff81713fa7>] ret_from_fork+0x27/0x40
[<ffffffffffffffff>] 0xffffffffffffffffHere is patch to use the older rdma contexts while reposting the isert commands intead of reinitialising them.
--- drivers/infiniband/ulp/isert/ib_isert.c | 7 +++++++ drivers/infiniband/ulp/isert/ib_isert.h | 1 + 2 files changed, 8 insertions(+)
drivers/infiniband/ulp/isert/ib_isert.c +7 -0
@@ -2098,6 +2098,9 @@ isert_rdma_rw_ctx_post(struct isert_cmd *cmd, struct isert_conn *conn,u32 rkey, offset;int ret; +if (cmd->ctx_init_done) + goto rdma_ctx_post; +if (dir ==DMA_FROM_DEVICE ) { addr = cmd->write_va; rkey = cmd->write_stag;
@@ -2125,11 +2128,15 @@ isert_rdma_rw_ctx_post(struct isert_cmd *cmd, struct isert_conn *conn, se_cmd->t_data_sg, se_cmd->t_data_nents, offset, addr, rkey, dir); } +if (ret <0 ) {isert_err ("Cmd: %p failed to prepare RDMA res\n" , cmd);return ret; } + cmd->ctx_init_done = true; + +rdma_ctx_post: ret =rdma_rw_ctx_post (&cmd->rw, conn->qp, port_num, cqe, chain_wr);if (ret <0 )isert_err ("Cmd: %p failed to post RDMA res\n" , cmd);
drivers/infiniband/ulp/isert/ib_isert.h +1 -0
@@ -124,6 +124,7 @@ struct isert_cmd {struct rdma_rw_ctx rw;struct work_struct comp_work;struct scatterlist sg; +bool ctx_init_done; };static inline struct isert_cmd *tx_desc_to_cmd (struct iser_tx_desc *desc)
Signature · 1 line
2.14.1
PATCH 175/190 vgacon: Set VGA struct resource types
In reply to Sasha LevinFrom: Bjorn Helgaas <[email protected]>
[ Upstream commit c82084117f79bcae085e40da526253736a247120 ]
Set the resource type when we reserve VGA-related I/O port resources.
The resource code doesn't actually look at the type, so it inserts resources without a type in the tree correctly even without this change. But if we ever print a resource without a type, it looks like this:
vga+ [??? 0x000003c0-0x000003df flags 0x0]
Setting the type means it will be printed correctly as:
vga+ [io 0x000003c0-0x000003df]
--- arch/alpha/kernel/console.c | 1 + drivers/video/console/vgacon.c | 34 ++++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-)
arch/alpha/kernel/console.c +1 -0
@@ -20,6 +20,7 @@struct pci_controller *pci_vga_hose;static struct resource alpha_vga = { .name ="alpha-vga+" , + .flags =IORESOURCE_IO , .start =0x3C0 , .end =0x3DF };
drivers/video/console/vgacon.c +26 -8
@@ -405,7 +405,10 @@ static const char *vgacon_startup(void) vga_video_port_val =VGA_CRT_DM ;if ((screen_info.orig_video_ega_bx &0xff ) !=0x10 ) {static struct resource ega_console_resource = - { .name ="ega" , .start =0x3B0 , .end =0x3BF }; + { .name ="ega" , + .flags =IORESOURCE_IO , + .start =0x3B0 , + .end =0x3BF }; vga_video_type =VIDEO_TYPE_EGAM ; vga_vram_size =0x8000 ; display_desc ="EGA+" ;
@@ -413,9 +416,15 @@ static const char *vgacon_startup(void) &ega_console_resource); }else {static struct resource mda1_console_resource = - { .name ="mda" , .start =0x3B0 , .end =0x3BB }; + { .name ="mda" , + .flags =IORESOURCE_IO , + .start =0x3B0 , + .end =0x3BB };static struct resource mda2_console_resource = - { .name ="mda" , .start =0x3BF , .end =0x3BF }; + { .name ="mda" , + .flags =IORESOURCE_IO , + .start =0x3BF , + .end =0x3BF }; vga_video_type =VIDEO_TYPE_MDA ; vga_vram_size =0x2000 ; display_desc ="*MDA" ;
@@ -437,15 +446,21 @@ static const char *vgacon_startup(void) vga_vram_size =0x8000 ;if (!screen_info.orig_video_isVGA) { -static struct resource ega_console_resource - = { .name ="ega" , .start =0x3C0 , .end =0x3DF }; +static struct resource ega_console_resource = + { .name ="ega" , + .flags =IORESOURCE_IO , + .start =0x3C0 , + .end =0x3DF }; vga_video_type =VIDEO_TYPE_EGAC ; display_desc ="EGA" ;request_resource (&ioport_resource, &ega_console_resource); }else { -static struct resource vga_console_resource - = { .name ="vga+" , .start =0x3C0 , .end =0x3DF }; +static struct resource vga_console_resource = + { .name ="vga+" , + .flags =IORESOURCE_IO , + .start =0x3C0 , + .end =0x3DF }; vga_video_type =VIDEO_TYPE_VGAC ; display_desc ="VGA+" ; request_resource(&ioport_resource,
@@ -489,7 +504,10 @@ static const char *vgacon_startup(void) } }else {static struct resource cga_console_resource = - { .name ="cga" , .start =0x3D4 , .end =0x3D5 }; + { .name ="cga" , + .flags =IORESOURCE_IO , + .start =0x3D4 , + .end =0x3D5 }; vga_video_type =VIDEO_TYPE_CGA ; vga_vram_size =0x2000 ; display_desc ="*CGA" ;
Signature · 1 line
2.14.1
PATCH 176/190 omapdrm: panel: fix compatible vendor string for td028ttec1
In reply to Sasha LevinFrom: "H. Nikolaus Schaller" <[email protected]>
[ Upstream commit c1b9d4c75cd549e08bd0596d7f9dcc20f7f6e8fa ]
The vendor name was "toppoly" but other panels and the vendor list have defined it as "tpo". So let's fix it in driver and bindings.
We keep the old definition in parallel to stay compatible with potential older DTB setup.
---
.../display/panel/{toppoly,td028ttec1.txt => tpo,td028ttec1.txt} | 4 ++--
drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c | 3 +++
drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c | 3 +++
3 files changed, 8 insertions(+), 2 deletions(-)
rename Documentation/devicetree/bindings/display/panel/{toppoly,td028ttec1.txt => tpo,td028ttec1.txt} (84%)Documentation/devicetree/bindings/display/panel/tpo,td028ttec1.txt renamed from Documentation/devicetree/bindings/display/panel/toppoly,td028ttec1.txt +2 -2
@@ -2,7 +2,7 @@ Toppoly TD028TTEC1 Panel ======================== Required properties: -- compatible: "toppoly,td028ttec1" +- compatible: "tpo,td028ttec1" Optional properties: - label: a symbolic name for the panel
@@ -14,7 +14,7 @@ Example ------- lcd-panel: td028ttec1@0 { - compatible = "toppoly,td028ttec1"; + compatible = "tpo,td028ttec1"; reg = <0>; spi-max-frequency = <100000>; spi-cpol;
drivers/gpu/drm/omapdrm/displays/panel-tpo-td028ttec1.c +3 -0
@@ -456,6 +456,8 @@ static int td028ttec1_panel_remove(struct spi_device *spi) }static const struct of_device_id td028ttec1_of_match[] = { + { .compatible ="omapdss,tpo,td028ttec1" , }, +/* keep to not break older DTB */ { .compatible ="omapdss,toppoly,td028ttec1" , }, {}, };
@@ -475,6 +477,7 @@ static struct spi_driver td028ttec1_spi_driver = {module_spi_driver (td028ttec1_spi_driver); +MODULE_ALIAS ("spi:tpo,td028ttec1" );MODULE_ALIAS ("spi:toppoly,td028ttec1" );MODULE_AUTHOR ("H. Nikolaus Schaller <[email protected]>" );MODULE_DESCRIPTION ("Toppoly TD028TTEC1 panel driver" );
drivers/video/fbdev/omap2/omapfb/displays/panel-tpo-td028ttec1.c +3 -0
@@ -455,6 +455,8 @@ static int td028ttec1_panel_remove(struct spi_device *spi) }static const struct of_device_id td028ttec1_of_match[] = { + { .compatible ="omapdss,tpo,td028ttec1" , }, +/* keep to not break older DTB */ { .compatible ="omapdss,toppoly,td028ttec1" , }, {}, };
@@ -474,6 +476,7 @@ static struct spi_driver td028ttec1_spi_driver = {module_spi_driver (td028ttec1_spi_driver); +MODULE_ALIAS ("spi:tpo,td028ttec1" );MODULE_ALIAS ("spi:toppoly,td028ttec1" );MODULE_AUTHOR ("H. Nikolaus Schaller <[email protected]>" );MODULE_DESCRIPTION ("Toppoly TD028TTEC1 panel driver" );
Signature · 1 line
2.14.1
PATCH 177/190 drm/omap: DMM: Check for DMM readiness after successful transaction commit
In reply to Sasha LevinFrom: Peter Ujfalusi <[email protected]>
[ Upstream commit b7ea6b286c4051e043f691781785e3c4672f014a ]
Check the status of the DMM engine after it is reported that the transaction was completed as in rare cases the engine might not reached a working state.
The wait_status() will print information in case the DMM is not reached the expected state and the dmm_txn_commit() will return with an error code to make sure that we are not continuing with a broken setup.
--- drivers/gpu/drm/omapdrm/omap_dmm_tiler.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +5 -0
@@ -298,7 +298,12 @@ static int dmm_txn_commit(struct dmm_txn *txn, bool wait) msecs_to_jiffies(100))) {dev_err (dmm->dev,"timed out waiting for done\n" ); ret = -ETIMEDOUT ; + goto cleanup; } + +/* Check the engine status before continue */ + ret =wait_status (engine,DMM_PATSTATUS_READY | +DMM_PATSTATUS_VALID |DMM_PATSTATUS_DONE ); } cleanup:
Signature · 1 line
2.14.1
PATCH 178/190 pty: cancel pty slave port buf's work in tty_release
In reply to Sasha LevinFrom: Sahara <[email protected]>
[ Upstream commit 2b022ab7542df60021ab57854b3faaaf42552eaf ]
In case that CONFIG_SLUB_DEBUG is on and pty is used, races between release_one_tty and flush_to_ldisc work threads may happen and lead to use-after-free condition on tty->link->port. Because SLUB_DEBUG is turned on, freed tty->link->port is filled with POISON_FREE value. So far without SLUB_DEBUG, port was filled with zero and flush_to_ldisc could return without a problem by checking if tty is NULL.
CPU 0 CPU 1
----- -----
release_tty pty_write
cancel_work_sync(tty) to = tty->link
tty_kref_put(tty->link) tty_schedule_flip(to->port)
<< workqueue >> ...
release_one_tty ...
pty_cleanup ...
kfree(tty->link->port) << workqueue >>
flush_to_ldisc
tty = READ_ONCE(port->itty)
tty is 0x6b6b6b6b6b6b6b6b
!!PANIC!! access tty->ldiscUnable to handle kernel paging request at virtual address 6b6b6b6b6b6b6b93 pgd = ffffffc0eb1c3000 [6b6b6b6b6b6b6b93] *pgd=0000000000000000, *pud=0000000000000000 ------------[ cut here ]------------ Kernel BUG at ffffff800851154c [verbose debug info unavailable] Internal error: Oops - BUG: 96000004 [#1] PREEMPT SMP CPU: 3 PID: 265 Comm: kworker/u8:9 Tainted: G W 3.18.31-g0a58eeb #1 Hardware name: Qualcomm Technologies, Inc. MSM 8996pro v1.1 + PMI8996 Carbide (DT) Workqueue: events_unbound flush_to_ldisc task: ffffffc0ed610ec0 ti: ffffffc0ed624000 task.ti: ffffffc0ed624000 PC is at ldsem_down_read_trylock+0x0/0x4c LR is at tty_ldisc_ref+0x24/0x4c pc : [<ffffff800851154c>] lr : [<ffffff800850f6c0>] pstate: 80400145 sp : ffffffc0ed627cd0 x29: ffffffc0ed627cd0 x28: 0000000000000000 x27: ffffff8009e05000 x26: ffffffc0d382cfa0 x25: 0000000000000000 x24: ffffff800a012f08 x23: 0000000000000000 x22: ffffffc0703fbc88 x21: 6b6b6b6b6b6b6b6b x20: 6b6b6b6b6b6b6b93 x19: 0000000000000000 x18: 0000000000000001 x17: 00e80000f80d6f53 x16: 0000000000000001 x15: 0000007f7d826fff x14: 00000000000000a0 x13: 0000000000000000 x12: 0000000000000109 x11: 0000000000000000 x10: 0000000000000000 x9 : ffffffc0ed624000 x8 : ffffffc0ed611580 x7 : 0000000000000000 x6 : ffffff800a42e000 x5 : 00000000000003fc x4 : 0000000003bd1201 x3 : 0000000000000001 x2 : 0000000000000001 x1 : ffffff800851004c x0 : 6b6b6b6b6b6b6b93
--- drivers/tty/tty_io.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/tty/tty_io.c +2 -0
@@ -1702,6 +1702,8 @@ static void release_tty(struct tty_struct *tty, int idx)if (tty->link) tty->link->port->itty =NULL ;tty_buffer_cancel_work (tty->port); +if (tty->link) +tty_buffer_cancel_work (tty->link->port);tty_kref_put (tty->link);tty_kref_put (tty);
Signature · 1 line
2.14.1
PATCH 179/190 coresight: Fix disabling of CoreSight TPIU
In reply to Sasha LevinFrom: Robert Walker <[email protected]>
[ Upstream commit 11595db8e17faaa05fadc25746c870e31276962f ]
The CoreSight TPIU should be disabled when tracing to other sinks to allow them to operate at full bandwidth.
This patch fixes tpiu_disable_hw() to correctly disable the TPIU by configuring the TPIU to stop on flush, initiating a manual flush, waiting for the flush to complete and then waits for the TPIU to indicate it has stopped.
--- drivers/hwtracing/coresight/coresight-tpiu.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
drivers/hwtracing/coresight/coresight-tpiu.c +10 -3
@@ -46,8 +46,11 @@#define TPIU_ITATBCTR0 0xef8/** register definition **/ +/* FFSR - 0x300 */ +#define FFSR_FT_STOPPED BIT(1)/* FFCR - 0x304 */ #define FFCR_FON_MAN BIT(6) +#define FFCR_STOP_FI BIT(12)/** * @base: memory mapped base address for this component.
@@ -85,10 +88,14 @@ static void tpiu_disable_hw(struct tpiu_drvdata *drvdata) {CS_UNLOCK (drvdata->base); -/* Clear formatter controle reg. */ -writel_relaxed (0x0 , drvdata->base +TPIU_FFCR ); +/* Clear formatter and stop on flush */ +writel_relaxed (FFCR_STOP_FI , drvdata->base +TPIU_FFCR );/* Generate manual flush */ -writel_relaxed (FFCR_FON_MAN , drvdata->base +TPIU_FFCR ); +writel_relaxed (FFCR_STOP_FI |FFCR_FON_MAN , drvdata->base +TPIU_FFCR ); +/* Wait for flush to complete */ +coresight_timeout (drvdata->base,TPIU_FFCR ,FFCR_FON_MAN ,0 ); +/* Wait for formatter to stop */ +coresight_timeout (drvdata->base,TPIU_FFSR ,FFSR_FT_STOPPED ,1 );CS_LOCK (drvdata->base); }
Signature · 1 line
2.14.1
PATCH 180/190 pinctrl: Really force states during suspend/resume
In reply to Sasha LevinFrom: Florian Fainelli <[email protected]>
[ Upstream commit 981ed1bfbc6c4660b2ddaa8392893e20a6255048 ]
In case a platform only defaults a "default" set of pins, but not a "sleep" set of pins, and this particular platform suspends and resumes in a way that the pin states are not preserved by the hardware, when we resume, we would call pinctrl_single_resume() -> pinctrl_force_default() -> pinctrl_select_state() and the first thing we do is check that the pins state is the same as before, and do nothing.
In order to fix this, decouple the actual state change from pinctrl_select_state() and move it pinctrl_commit_state(), while keeping the p->state == state check in pinctrl_select_state() not to change the caller assumptions. pinctrl_force_sleep() and pinctrl_force_default() are updated to bypass the state check by calling pinctrl_commit_state().
[Linus Walleij]
The forced pin control states are currently only used in some pin controller drivers that grab their own reference to their own pins. This is equal to the pin control hogs: pins taken by pin control devices since there are no corresponding device in the Linux device hierarchy, such as memory controller lines or unused GPIO lines, or GPIO lines that are used orthogonally from the GPIO subsystem but pincontrol-wise managed as hogs (non-strict mode, allowing simultaneous use by GPIO and pin control). For this case forcing the state from the drivers' suspend()/resume() callbacks makes sense and should semantically match the name of the function.
--- drivers/pinctrl/core.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-)
drivers/pinctrl/core.c +17 -7
@@ -992,19 +992,16 @@ struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p,EXPORT_SYMBOL_GPL (pinctrl_lookup_state);/** -* pinctrl_select_state() - select/activate/program a pinctrl state to HW +* pinctrl_commit_state() - select/activate/program a pinctrl state to HW * @p: the pinctrl handle for the device that requests configuration * @state: the state handle to select/activate/program */ -int pinctrl_select_state (struct pinctrl *p,struct pinctrl_state *state) +static int pinctrl_commit_state (struct pinctrl *p,struct pinctrl_state *state) {struct pinctrl_setting *setting, *setting2;struct pinctrl_state *old_state = p->state;int ret; -if (p->state == state) -return 0 ; -if (p->state) {/* * For each pinmux setting in the old state, forget SW's record
@@ -1068,6 +1065,19 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)return ret; } + +/** +* pinctrl_select_state() - select/activate/program a pinctrl state to HW +* @p: the pinctrl handle for the device that requests configuration +* @state: the state handle to select/activate/program +*/ +int pinctrl_select_state (struct pinctrl *p,struct pinctrl_state *state) +{ +if (p->state == state) +return 0 ; + +return pinctrl_commit_state (p, state); +}EXPORT_SYMBOL_GPL (pinctrl_select_state);static void devm_pinctrl_release (struct device *dev,void *res)
@@ -1236,7 +1246,7 @@ void pinctrl_unregister_map(struct pinctrl_map const *map)int pinctrl_force_sleep (struct pinctrl_dev *pctldev) {if (!IS_ERR (pctldev->p) && !IS_ERR (pctldev->hog_sleep)) -return pinctrl_select_state (pctldev->p, pctldev->hog_sleep); +return pinctrl_commit_state (pctldev->p, pctldev->hog_sleep);return 0 ; }EXPORT_SYMBOL_GPL (pinctrl_force_sleep);
@@ -1248,7 +1258,7 @@ EXPORT_SYMBOL_GPL(pinctrl_force_sleep);int pinctrl_force_default (struct pinctrl_dev *pctldev) {if (!IS_ERR (pctldev->p) && !IS_ERR (pctldev->hog_default)) -return pinctrl_select_state (pctldev->p, pctldev->hog_default); +return pinctrl_commit_state (pctldev->p, pctldev->hog_default);return 0 ; }EXPORT_SYMBOL_GPL (pinctrl_force_default);
Signature · 1 line
2.14.1
PATCH 181/190 pinctrl: rockchip: enable clock when reading pin direction register
In reply to Sasha LevinFrom: Brian Norris <[email protected]>
[ Upstream commit 5c9d8c4f6b8168738a26bcf288516cc3a0886810 ]
We generally leave the GPIO clock disabled, unless an interrupt is requested or we're accessing IO registers. We forgot to do this for the ->get_direction() callback, which means we can sometimes [1] get incorrect results [2] from, e.g., /sys/kernel/debug/gpio.
Enable the clock, so we get the right results!
[1] Sometimes, because many systems have 1 or mor interrupt requested on each GPIO bank, so they always leave their clock on.
[2] Incorrect, meaning the register returns 0, and so we interpret that as "input".
--- drivers/pinctrl/pinctrl-rockchip.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/pinctrl/pinctrl-rockchip.c +8 -0
@@ -1278,8 +1278,16 @@ static int rockchip_gpio_get_direction(struct gpio_chip *chip, unsigned offset) {struct rockchip_pin_bank *bank =gpiochip_get_data (chip);u32 data; +int ret; + ret =clk_enable (bank->clk); +if (ret <0 ) { +dev_err (bank->drvdata->dev, +"failed to enable clock for bank %s\n" , bank->name); +return ret; + } data =readl_relaxed (bank->reg_base +GPIO_SWPORT_DDR ); +clk_disable (bank->clk);return !(data &BIT (offset)); }
Signature · 1 line
2.14.1
PATCH 182/190 iommu/vt-d: clean up pr_irq if request_threaded_irq fails
In reply to Sasha LevinFrom: Jerry Snitselaar <[email protected]>
[ Upstream commit 72d548113881dd32bf7f0b221d031e6586468437 ]
It is unlikely request_threaded_irq will fail, but if it does for some reason we should clear iommu->pr_irq in the error path. Also intel_svm_finish_prq shouldn't try to clean up the page request interrupt if pr_irq is 0. Without these, if request_threaded_irq were to fail the following occurs:
fail with no fixes:
[ 0.683147] ------------[ cut here ]------------ [ 0.683148] NULL pointer, cannot free irq [ 0.683158] WARNING: CPU: 1 PID: 1 at kernel/irq/irqdomain.c:1632 irq_domain_free_irqs+0x126/0x140 [ 0.683160] Modules linked in: [ 0.683163] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc2 #3 [ 0.683165] Hardware name: /NUC7i3BNB, BIOS BNKBL357.86A.0036.2017.0105.1112 01/05/2017 [ 0.683168] RIP: 0010:irq_domain_free_irqs+0x126/0x140 [ 0.683169] RSP: 0000:ffffc90000037ce8 EFLAGS: 00010292 [ 0.683171] RAX: 000000000000001d RBX: ffff880276283c00 RCX: ffffffff81c5e5e8 [ 0.683172] RDX: 0000000000000001 RSI: 0000000000000096 RDI: 0000000000000246 [ 0.683174] RBP: ffff880276283c00 R08: 0000000000000000 R09: 000000000000023c [ 0.683175] R10: 0000000000000007 R11: 0000000000000000 R12: 000000000000007a [ 0.683176] R13: 0000000000000001 R14: 0000000000000000 R15: 0000010010000000 [ 0.683178] FS: 0000000000000000(0000) GS:ffff88027ec80000(0000) knlGS:0000000000000000 [ 0.683180] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.683181] CR2: 0000000000000000 CR3: 0000000001c09001 CR4: 00000000003606e0 [ 0.683182] Call Trace: [ 0.683189] intel_svm_finish_prq+0x3c/0x60 [ 0.683191] free_dmar_iommu+0x1ac/0x1b0 [ 0.683195] init_dmars+0xaaa/0xaea [ 0.683200] ? klist_next+0x19/0xc0 [ 0.683203] ? pci_do_find_bus+0x50/0x50 [ 0.683205] ? pci_get_dev_by_id+0x52/0x70 [ 0.683208] intel_iommu_init+0x498/0x5c7 [ 0.683211] pci_iommu_init+0x13/0x3c [ 0.683214] ? e820__memblock_setup+0x61/0x61 [ 0.683217] do_one_initcall+0x4d/0x1a0 [ 0.683220] kernel_init_freeable+0x186/0x20e [ 0.683222] ? set_debug_rodata+0x11/0x11 [ 0.683225] ? rest_init+0xb0/0xb0 [ 0.683226] kernel_init+0xa/0xff [ 0.683229] ret_from_fork+0x1f/0x30 [ 0.683259] Code: 89 ee 44 89 e7 e8 3b e8 ff ff 5b 5d 44 89 e7 44 89 ee 41 5c 41 5d 41 5e e9 a8 84 ff ff 48 c7 c7 a8 71 a7 81 31 c0 e8 6a d3 f9 ff <0f> ff 5b 5d 41 5c 41 5d 41 5 e c3 0f 1f 44 00 00 66 2e 0f 1f 84 [ 0.683285] ---[ end trace f7650e42792627ca ]---
with iommu->pr_irq = 0, but no check in intel_svm_finish_prq:
[ 0.669561] ------------[ cut here ]------------ [ 0.669563] Trying to free already-free IRQ 0 [ 0.669573] WARNING: CPU: 3 PID: 1 at kernel/irq/manage.c:1546 __free_irq+0xa4/0x2c0 [ 0.669574] Modules linked in: [ 0.669577] CPU: 3 PID: 1 Comm: swapper/0 Not tainted 4.15.0-rc2 #4 [ 0.669579] Hardware name: /NUC7i3BNB, BIOS BNKBL357.86A.0036.2017.0105.1112 01/05/2017 [ 0.669581] RIP: 0010:__free_irq+0xa4/0x2c0 [ 0.669582] RSP: 0000:ffffc90000037cc0 EFLAGS: 00010082 [ 0.669584] RAX: 0000000000000021 RBX: 0000000000000000 RCX: ffffffff81c5e5e8 [ 0.669585] RDX: 0000000000000001 RSI: 0000000000000086 RDI: 0000000000000046 [ 0.669587] RBP: 0000000000000000 R08: 0000000000000000 R09: 000000000000023c [ 0.669588] R10: 0000000000000007 R11: 0000000000000000 R12: ffff880276253960 [ 0.669589] R13: ffff8802762538a4 R14: ffff880276253800 R15: ffff880276283600 [ 0.669593] FS: 0000000000000000(0000) GS:ffff88027ed80000(0000) knlGS:0000000000000000 [ 0.669594] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 0.669596] CR2: 0000000000000000 CR3: 0000000001c09001 CR4: 00000000003606e0 [ 0.669602] Call Trace: [ 0.669616] free_irq+0x30/0x60 [ 0.669620] intel_svm_finish_prq+0x34/0x60 [ 0.669623] free_dmar_iommu+0x1ac/0x1b0 [ 0.669627] init_dmars+0xaaa/0xaea [ 0.669631] ? klist_next+0x19/0xc0 [ 0.669634] ? pci_do_find_bus+0x50/0x50 [ 0.669637] ? pci_get_dev_by_id+0x52/0x70 [ 0.669639] intel_iommu_init+0x498/0x5c7 [ 0.669642] pci_iommu_init+0x13/0x3c [ 0.669645] ? e820__memblock_setup+0x61/0x61 [ 0.669648] do_one_initcall+0x4d/0x1a0 [ 0.669651] kernel_init_freeable+0x186/0x20e [ 0.669653] ? set_debug_rodata+0x11/0x11 [ 0.669656] ? rest_init+0xb0/0xb0 [ 0.669658] kernel_init+0xa/0xff [ 0.669661] ret_from_fork+0x1f/0x30 [ 0.669662] Code: 7a 08 75 0e e9 c3 01 00 00 4c 39 7b 08 74 57 48 89 da 48 8b 5a 18 48 85 db 75 ee 89 ee 48 c7 c7 78 67 a7 81 31 c0 e8 4c 37 fa ff <0f> ff 48 8b 34 24 4c 89 ef e 8 0e 4c 68 00 49 8b 46 40 48 8b 80 [ 0.669688] ---[ end trace 58a470248700f2fc ]---
--- drivers/iommu/intel-svm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/iommu/intel-svm.c +6 -3
@@ -127,6 +127,7 @@ int intel_svm_enable_prq(struct intel_iommu *iommu)pr_err ("IOMMU: %s: Failed to request IRQ for page request queue\n" , iommu->name);dmar_free_hwirq (irq); + iommu->pr_irq =0 ; goto err; }dmar_writeq (iommu->reg +DMAR_PQH_REG ,0ULL );
@@ -142,9 +143,11 @@ int intel_svm_finish_prq(struct intel_iommu *iommu)dmar_writeq (iommu->reg +DMAR_PQT_REG ,0ULL );dmar_writeq (iommu->reg +DMAR_PQA_REG ,0ULL ); -free_irq (iommu->pr_irq, iommu); -dmar_free_hwirq (iommu->pr_irq); - iommu->pr_irq =0 ; +if (iommu->pr_irq) { +free_irq (iommu->pr_irq, iommu); +dmar_free_hwirq (iommu->pr_irq); + iommu->pr_irq =0 ; + }free_pages ((unsigned long )iommu->prq,PRQ_ORDER ); iommu->prq =NULL ;
Signature · 1 line
2.14.1
PATCH 183/190 ip6_vti: adjust vti mtu according to mtu of lower device
In reply to Sasha LevinFrom: Alexey Kodanev <[email protected]>
[ Upstream commit 53c81e95df1793933f87748d36070a721f6cb287 ]
LTP/udp6_ipsec_vti tests fail when sending large UDP datagrams over ip6_vti that require fragmentation and the underlying device has an MTU smaller than 1500 plus some extra space for headers. This happens because ip6_vti, by default, sets MTU to ETH_DATA_LEN and not updating it depending on a destination address or link parameter. Further attempts to send UDP packets may succeed because pmtu gets updated on ICMPV6_PKT_TOOBIG in vti6_err().
In case the lower device has larger MTU size, e.g. 9000, ip6_vti works but not using the possible maximum size, output packets have 1500 limit.
The above cases require manual MTU setup after ip6_vti creation. However ip_vti already updates MTU based on lower device with ip_tunnel_bind_dev().
Here is the example when the lower device MTU is set to 9000:
# ip a sh ltp_ns_veth2
ltp_ns_veth2@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 ...
inet 10.0.0.2/24 scope global ltp_ns_veth2
inet6 fd00::2/64 scope global # ip li add vti6 type vti6 local fd00::2 remote fd00::1
# ip li show vti6
vti6@NONE: <POINTOPOINT,NOARP> mtu 1500 ...
link/tunnel6 fd00::2 peer fd00::1After the patch:
# ip li add vti6 type vti6 local fd00::2 remote fd00::1
# ip li show vti6
vti6@NONE: <POINTOPOINT,NOARP> mtu 8832 ...
link/tunnel6 fd00::2 peer fd00::1--- net/ipv6/ip6_vti.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
net/ipv6/ip6_vti.c +20 -0
@@ -625,6 +625,7 @@ static void vti6_link_config(struct ip6_tnl *t) {struct net_device *dev = t->dev;struct __ip6_tnl_parm *p = &t->parms; +struct net_device *tdev =NULL ;memcpy (dev->dev_addr, &p->laddr,sizeof (struct in6_addr ));memcpy (dev->broadcast, &p->raddr,sizeof (struct in6_addr ));
@@ -637,6 +638,25 @@ static void vti6_link_config(struct ip6_tnl *t) dev->flags |=IFF_POINTOPOINT ; else dev->flags &= ~IFF_POINTOPOINT; + +if (p->flags &IP6_TNL_F_CAP_XMIT ) { +int strict = (ipv6_addr_type (&p->raddr) & + (IPV6_ADDR_MULTICAST |IPV6_ADDR_LINKLOCAL )); +struct rt6_info *rt =rt6_lookup (t->net, + &p->raddr, &p->laddr, + p->link, strict); + +if (rt) + tdev = rt->dst.dev; +ip6_rt_put (rt); + } + +if (!tdev && p->link) + tdev =__dev_get_by_index (t->net, p->link); + +if (tdev) + dev->mtu =max_t (int, tdev->mtu - dev->hard_header_len, +IPV6_MIN_MTU ); }/**
Signature · 1 line
2.14.1
PATCH 184/190 RDMA/ocrdma: Fix permissions for OCRDMA_RESET_STATS
In reply to Sasha LevinFrom: Anton Vasilyev <[email protected]>
[ Upstream commit 744820869166c8c78be891240cf5f66e8a333694 ]
Debugfs file reset_stats is created with S_IRUSR permissions, but ocrdma_dbgfs_ops_read() doesn't support OCRDMA_RESET_STATS, whereas ocrdma_dbgfs_ops_write() supports only OCRDMA_RESET_STATS.
The patch fixes misstype with permissions.
Found by Linux Driver Verification project (linuxtesting.org).
--- drivers/infiniband/hw/ocrdma/ocrdma_stats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/ocrdma/ocrdma_stats.c +1 -1
@@ -836,7 +836,7 @@ void ocrdma_add_port_stats(struct ocrdma_dev *dev) dev->reset_stats.type =OCRDMA_RESET_STATS ; dev->reset_stats.dev = dev; -if (!debugfs_create_file ("reset_stats" ,S_IRUSR , dev->dir, +if (!debugfs_create_file ("reset_stats" ,0200 , dev->dir, &dev->reset_stats, &ocrdma_dbg_ops)) goto err;
Signature · 1 line
2.14.1
PATCH 185/190 ARM: dts: aspeed-evb: Add unit name to memory node
In reply to Sasha LevinFrom: Joel Stanley <[email protected]>
[ Upstream commit e40ed274489a5f516da120186578eb379b452ac6 ]
Fixes a warning when building with W=1.
All of the ASPEED device trees build without warnings now.
--- arch/arm/boot/dts/aspeed-ast2500-evb.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/boot/dts/aspeed-ast2500-evb.dts +1 -1
@@ -15,7 +15,7 @@ bootargs = "console=ttyS4,115200 earlyprintk"; }; - memory { + memory@80000000 { reg = <0x80000000 0x20000000>; }; };
Signature · 1 line
2.14.1
PATCH 186/190 nfsd4: permit layoutget of executable-only files
In reply to Sasha LevinFrom: Benjamin Coddington <[email protected]>
[ Upstream commit 66282ec1cf004c09083c29cb5e49019037937bbd ]
Clients must be able to read a file in order to execute it, and for pNFS that means the client needs to be able to perform a LAYOUTGET on the file.
This behavior for executable-only files was added for OPEN in commit a043226bc140 "nfsd4: permit read opens of executable-only files".
This fixes up xfstests generic/126 on block/scsi layouts.
--- fs/nfsd/nfs4proc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
fs/nfsd/nfs4proc.c +3 -3
@@ -1338,14 +1338,14 @@ nfsd4_layoutget(struct svc_rqst *rqstp,const struct nfsd4_layout_ops *ops;struct nfs4_layout_stateid *ls;__be32 nfserr; -int accmode; +int accmode =NFSD_MAY_READ_IF_EXEC ;switch (lgp->lg_seg.iomode) {case IOMODE_READ : - accmode =NFSD_MAY_READ ; + accmode |=NFSD_MAY_READ ;break ;case IOMODE_RW : - accmode =NFSD_MAY_READ |NFSD_MAY_WRITE ; + accmode |=NFSD_MAY_READ |NFSD_MAY_WRITE ;break ;default : dprintk("%s: invalid iomode %d\n",
Signature · 1 line
2.14.1
PATCH 187/190 clk: Don't touch hardware when reparenting during registration
In reply to Sasha LevinFrom: Stephen Boyd <[email protected]>
[ Upstream commit f8f8f1d04494d3a6546bee3f0618c4dba31d7b72 ]
The orphan clocks reparent operation shouldn't touch the hardware if clocks are enabled, otherwise it may get a chance to disable a newly registered critical clock which triggers the warning below.
Assuming we have two clocks: A and B, B is the parent of A. Clock A has flag: CLK_OPS_PARENT_ENABLE
Clock B has flag: CLK_IS_CRITICAL
Step 1:
Clock A is registered, then it becomes orphan.
Step 2:
Clock B is registered. Before clock B reach the critical clock enable operation, orphan A will find the newly registered parent B and do reparent operation, then parent B will be finally disabled in __clk_set_parent_after() due to CLK_OPS_PARENT_ENABLE flag as there's still no users of B which will then trigger the following warning.
WARNING: CPU: 0 PID: 0 at drivers/clk/clk.c:597 clk_core_disable+0xb4/0xe0 Modules linked in: CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.11.0-rc1-00056-gdff1f66-dirty #1373 Hardware name: Generic DT based system Backtrace: [<c010c4bc>] (dump_backtrace) from [<c010c764>] (show_stack+0x18/0x1c) r6:600000d3 r5:00000000 r4:c0e26358 r3:00000000 [<c010c74c>] (show_stack) from [<c040599c>] (dump_stack+0xb4/0xe8) [<c04058e8>] (dump_stack) from [<c0125c94>] (__warn+0xd8/0x104) r10:c0c21cd0 r9:c048aa78 r8:00000255 r7:00000009 r6:c0c1cd90 r5:00000000 r4:00000000 r3:c0e01d34 [<c0125bbc>] (__warn) from [<c0125d74>] (warn_slowpath_null+0x28/0x30) r9:00000000 r8:ef00bf80 r7:c165ac4c r6:ef00bf80 r5:ef00bf80 r4:ef00bf80 [<c0125d4c>] (warn_slowpath_null) from [<c048aa78>] (clk_core_disable+0xb4/0xe0) [<c048a9c4>] (clk_core_disable) from [<c048be88>] (clk_core_disable_lock+0x20/0x2c) r4:000000d3 r3:c0e0af00 [<c048be68>] (clk_core_disable_lock) from [<c048c224>] (clk_core_disable_unprepare+0x14/0x28) r5:00000000 r4:ef00bf80 [<c048c210>] (clk_core_disable_unprepare) from [<c048c270>] (__clk_set_parent_after+0x38/0x54) r4:ef00bd80 r3:000010a0 [<c048c238>] (__clk_set_parent_after) from [<c048daa8>] (clk_register+0x4d0/0x648) r6:ef00d500 r5:ef00bf80 r4:ef00bd80 r3:ef00bfd4 [<c048d5d8>] (clk_register) from [<c048dc30>] (clk_hw_register+0x10/0x1c) r9:00000000 r8:00000003 r7:00000000 r6:00000824 r5:00000001 r4:ef00d500 [<c048dc20>] (clk_hw_register) from [<c048e698>] (_register_divider+0xcc/0x120) [<c048e5cc>] (_register_divider) from [<c048e730>] (clk_register_divider+0x44/0x54) r10:00000004 r9:00000003 r8:00000001 r7:00000000 r6:00000003 r5:00000001 r4:f0810030 [<c048e6ec>] (clk_register_divider) from [<c0d3ff58>] (imx7ulp_clocks_init+0x558/0xe98) r7:c0e296f8 r6:c165c808 r5:00000000 r4:c165c808 [<c0d3fa00>] (imx7ulp_clocks_init) from [<c0d24db0>] (of_clk_init+0x118/0x1e0) r10:00000001 r9:c0e01f68 r8:00000000 r7:c0e01f60 r6:ef7f8974 r5:ef0035c0 r4:00000006 [<c0d24c98>] (of_clk_init) from [<c0d04a50>] (time_init+0x2c/0x38) r10:efffed40 r9:c0d61a48 r8:c0e78000 r7:c0e07900 r6:ffffffff r5:c0e78000 r4:00000000 [<c0d04a24>] (time_init) from [<c0d00b8c>] (start_kernel+0x218/0x394)
[<c0d00974>] (start_kernel) from [<6000807c>] (0x6000807c)
r10:00000000 r9:410fc075 r8:6000406a r7:c0e0c930 r6:c0d61a44 r5:c0e07918 r4:c0e78294
We know that the clk isn't enabled with any sort of prepare_count here so we don't need to enable anything to prevent a race. And we're holding the prepare mutex so set_rate/set_parent can't race here either. Based on an earlier patch by Dong Aisheng.
--- drivers/clk/clk.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/clk/clk.c +5 -2
@@ -2443,14 +2443,17 @@ static int __clk_core_init(struct clk_core *core)*/ hlist_for_each_entry_safe (orphan, tmp2, &clk_orphan_list, child_node) {struct clk_core *parent =__clk_init_parent (orphan); +unsigned long flags;/* * we could call __clk_set_parent, but that would result in a * redundant call to the .set_rate op, if it exists */ if (parent) { -__clk_set_parent_before (orphan, parent); -__clk_set_parent_after (orphan, parent,NULL ); +/* update the clk tree topology */ + flags =clk_enable_lock (); +clk_reparent (orphan, parent); +clk_enable_unlock (flags);__clk_recalc_accuracies (orphan);__clk_recalc_rates (orphan,0 ); }
Signature · 1 line
2.14.1
PATCH 188/190 clk: axi-clkgen: Correctly handle nocount bit in recalc_rate()
In reply to Sasha LevinFrom: Lars-Peter Clausen <[email protected]>
[ Upstream commit 063578dc5f407f67d149133818efabe457daafda ]
If the nocount bit is set the divider is bypassed and the settings for the divider count should be ignored and a divider value of 1 should be assumed. Handle this correctly in the driver recalc_rate() callback.
While the driver sets up the part so that the read back dividers values yield the correct result the power-on reset settings of the part might not reflect this and hence calling e.g. clk_get_rate() without prior calls to clk_set_rate() will yield the wrong result.
--- drivers/clk/clk-axi-clkgen.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
drivers/clk/clk-axi-clkgen.c +24 -5
@@ -40,6 +40,10 @@#define MMCM_REG_FILTER1 0x4e#define MMCM_REG_FILTER2 0x4f +#define MMCM_CLKOUT_NOCOUNT BIT(6) + +#define MMCM_CLK_DIV_NOCOUNT BIT(12) +struct axi_clkgen {void __iomem *base;struct clk_hw clk_hw;
@@ -315,12 +319,27 @@ static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,unsigned int reg;unsigned long long tmp; -axi_clkgen_mmcm_read (axi_clkgen,MMCM_REG_CLKOUT0_1 , ®); - dout = (reg &0x3f ) + ((reg >>6 ) &0x3f ); +axi_clkgen_mmcm_read (axi_clkgen,MMCM_REG_CLKOUT0_2 , ®); +if (reg &MMCM_CLKOUT_NOCOUNT ) { + dout =1 ; + }else { +axi_clkgen_mmcm_read (axi_clkgen,MMCM_REG_CLKOUT0_1 , ®); + dout = (reg &0x3f ) + ((reg >>6 ) &0x3f ); + } +axi_clkgen_mmcm_read (axi_clkgen,MMCM_REG_CLK_DIV , ®); - d = (reg &0x3f ) + ((reg >>6 ) &0x3f ); -axi_clkgen_mmcm_read (axi_clkgen,MMCM_REG_CLK_FB1 , ®); - m = (reg &0x3f ) + ((reg >>6 ) &0x3f ); +if (reg &MMCM_CLK_DIV_NOCOUNT ) + d =1 ; +else + d = (reg &0x3f ) + ((reg >>6 ) &0x3f ); + +axi_clkgen_mmcm_read (axi_clkgen,MMCM_REG_CLK_FB2 , ®); +if (reg &MMCM_CLKOUT_NOCOUNT ) { + m =1 ; + }else { +axi_clkgen_mmcm_read (axi_clkgen,MMCM_REG_CLK_FB1 , ®); + m = (reg &0x3f ) + ((reg >>6 ) &0x3f ); + }if (d ==0 || dout ==0 )return 0 ;
Signature · 1 line
2.14.1
PATCH 189/190 clk: si5351: Rename internal plls to avoid name collisions
In reply to Sasha LevinFrom: Sergej Sawazki <[email protected]>
[ Upstream commit cdba9a4fb0b53703959ac861e415816cb61aded4 ]
This drivers probe fails due to a clock name collision if a clock named 'plla' or 'pllb' is already registered when registering this drivers internal plls.
Fix it by renaming internal plls to avoid name collisions.
--- drivers/clk/clk-si5351.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/clk/clk-si5351.c +1 -1
@@ -72,7 +72,7 @@ static const char * const si5351_input_names[] = {"xtal" ,"clkin" };static const char *const si5351_pll_names[] = { -"plla" ,"pllb" ,"vxco" +"si5351_plla" ,"si5351_pllb" ,"si5351_vxco" };static const char *const si5351_msynth_names[] = { "ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7"
Signature · 1 line
2.14.1
PATCH 190/190 dmaengine: ti-dma-crossbar: Fix event mapping for TPCC_EVT_MUX_60_63
In reply to Sasha LevinFrom: Vignesh R <[email protected]>
[ Upstream commit d087f15786021a9605b20f4c678312510be4cac1 ]
Register layout of a typical TPCC_EVT_MUX_M_N register is such that the lowest numbered event is at the lowest byte address and highest numbered event at highest byte address. But TPCC_EVT_MUX_60_63 register layout is different, in that the lowest numbered event is at the highest address and highest numbered event is at the lowest address. Therefore, modify ti_am335x_xbar_write() to handle TPCC_EVT_MUX_60_63 register accordingly.
--- drivers/dma/ti-dma-crossbar.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/dma/ti-dma-crossbar.c +9 -1
@@ -54,7 +54,15 @@ struct ti_am335x_xbar_map {static inline void ti_am335x_xbar_write (void __iomem *iomem,int event,u8 val) { -writeb_relaxed (val, iomem + event); +/* +* TPCC_EVT_MUX_60_63 register layout is different than the +* rest, in the sense, that event 63 is mapped to lowest byte +* and event 60 is mapped to highest, handle it separately. +*/ +if (event >=60 && event <=63 ) +writeb_relaxed (val, iomem + (63 - event %4 )); +else +writeb_relaxed (val, iomem + event); }static void ti_am335x_xbar_free (struct device *dev,void *route_data)
Signature · 1 line
2.14.1