Date: Tue, 15 Mar 2016 15:28:24 +0000 (UTC) From: Michal Meloun <mmel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r296905 - head/sys/dev/extres/clk Message-ID: <201603151528.u2FFSOi5071554@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mmel Date: Tue Mar 15 15:28:24 2016 New Revision: 296905 URL: https://svnweb.freebsd.org/changeset/base/296905 Log: CLK: Add and use explicit locking for access to clock device registers. Implicit locking (for read/write/modify) is not sufficient for complex cases. Modified: head/sys/dev/extres/clk/clk_div.c head/sys/dev/extres/clk/clk_gate.c head/sys/dev/extres/clk/clk_mux.c head/sys/dev/extres/clk/clkdev_if.m Modified: head/sys/dev/extres/clk/clk_div.c ============================================================================== --- head/sys/dev/extres/clk/clk_div.c Tue Mar 15 15:27:15 2016 (r296904) +++ head/sys/dev/extres/clk/clk_div.c Tue Mar 15 15:28:24 2016 (r296905) @@ -46,6 +46,10 @@ __FBSDID("$FreeBSD$"); CLKDEV_READ_4(clknode_get_device(_clk), off, val) #define MD4(_clk, off, clr, set ) \ CLKDEV_MODIFY_4(clknode_get_device(_clk), off, clr, set) +#define DEVICE_LOCK(_clk) \ + CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) +#define DEVICE_UNLOCK(_clk) \ + CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) static int clknode_div_init(struct clknode *clk, device_t dev); static int clknode_div_recalc(struct clknode *clk, uint64_t *req); @@ -86,7 +90,9 @@ clknode_div_init(struct clknode *clk, de sc = clknode_get_softc(clk); + DEVICE_LOCK(clk); rv = RD4(clk, sc->offset, ®); + DEVICE_UNLOCK(clk); if (rv != 0) return (rv); @@ -171,12 +177,17 @@ clknode_div_set_freq(struct clknode *clk (*fout != (_fin / divider))) return (ERANGE); + DEVICE_LOCK(clk); rv = MD4(clk, sc->offset, (sc->i_mask << sc->i_shift) | (sc->f_mask << sc->f_shift), (i_div << sc->i_shift) | (f_div << sc->f_shift)); - if (rv != 0) + if (rv != 0) { + DEVICE_UNLOCK(clk); return (rv); + } RD4(clk, sc->offset, ®); + DEVICE_UNLOCK(clk); + sc->divider = divider; } Modified: head/sys/dev/extres/clk/clk_gate.c ============================================================================== --- head/sys/dev/extres/clk/clk_gate.c Tue Mar 15 15:27:15 2016 (r296904) +++ head/sys/dev/extres/clk/clk_gate.c Tue Mar 15 15:28:24 2016 (r296905) @@ -46,7 +46,10 @@ __FBSDID("$FreeBSD$"); CLKDEV_READ_4(clknode_get_device(_clk), off, val) #define MD4(_clk, off, clr, set ) \ CLKDEV_MODIFY_4(clknode_get_device(_clk), off, clr, set) - +#define DEVICE_LOCK(_clk) \ + CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) +#define DEVICE_UNLOCK(_clk) \ + CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) static int clknode_gate_init(struct clknode *clk, device_t dev); static int clknode_gate_set_gate(struct clknode *clk, bool enable); @@ -77,7 +80,9 @@ clknode_gate_init(struct clknode *clk, d int rv; sc = clknode_get_softc(clk); + DEVICE_LOCK(clk); rv = RD4(clk, sc->offset, ®); + DEVICE_UNLOCK(clk); if (rv != 0) return (rv); reg = (reg >> sc->shift) & sc->mask; @@ -95,11 +100,15 @@ clknode_gate_set_gate(struct clknode *cl sc = clknode_get_softc(clk); sc->ungated = enable; + DEVICE_LOCK(clk); rv = MD4(clk, sc->offset, sc->mask << sc->shift, (sc->ungated ? sc->on_value : sc->off_value) << sc->shift); - if (rv != 0) + if (rv != 0) { + DEVICE_UNLOCK(clk); return (rv); + } RD4(clk, sc->offset, ®); + DEVICE_UNLOCK(clk); return(0); } Modified: head/sys/dev/extres/clk/clk_mux.c ============================================================================== --- head/sys/dev/extres/clk/clk_mux.c Tue Mar 15 15:27:15 2016 (r296904) +++ head/sys/dev/extres/clk/clk_mux.c Tue Mar 15 15:28:24 2016 (r296905) @@ -46,6 +46,10 @@ __FBSDID("$FreeBSD$"); CLKDEV_READ_4(clknode_get_device(_clk), off, val) #define MD4(_clk, off, clr, set ) \ CLKDEV_MODIFY_4(clknode_get_device(_clk), off, clr, set) +#define DEVICE_LOCK(_clk) \ + CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) +#define DEVICE_UNLOCK(_clk) \ + CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) static int clknode_mux_init(struct clknode *clk, device_t dev); static int clknode_mux_set_mux(struct clknode *clk, int idx); @@ -76,9 +80,12 @@ clknode_mux_init(struct clknode *clk, de sc = clknode_get_softc(clk); + DEVICE_LOCK(clk); rv = RD4(clk, sc->offset, ®); - if (rv != 0) + DEVICE_UNLOCK(clk); + if (rv != 0) { return (rv); + } reg = (reg >> sc->shift) & sc->mask; clknode_init_parent_idx(clk, reg); return(0); @@ -93,11 +100,16 @@ clknode_mux_set_mux(struct clknode *clk, sc = clknode_get_softc(clk); + DEVICE_LOCK(clk); rv = MD4(clk, sc->offset, sc->mask << sc->shift, (idx & sc->mask) << sc->shift); - if (rv != 0) + if (rv != 0) { + DEVICE_UNLOCK(clk); return (rv); + } RD4(clk, sc->offset, ®); + DEVICE_UNLOCK(clk); + return(0); } Modified: head/sys/dev/extres/clk/clkdev_if.m ============================================================================== --- head/sys/dev/extres/clk/clkdev_if.m Tue Mar 15 15:27:15 2016 (r296904) +++ head/sys/dev/extres/clk/clkdev_if.m Tue Mar 15 15:28:24 2016 (r296905) @@ -30,6 +30,23 @@ INTERFACE clkdev; +CODE { + #include <sys/systm.h> + static void + clkdev_default_device_lock(device_t dev) + { + + panic("clkdev_device_lock() is not implemented"); + } + + static void + clkdev_default_device_unlock(device_t dev) + { + + panic("clkdev_device_unlock() is not implemented"); + } +} + # # Write single register # @@ -57,3 +74,17 @@ METHOD int modify_4 { uint32_t clear_mask; uint32_t set_mask; }; + +# +# Get exclusive access to underlying device +# +METHOD void device_lock { + device_t dev; +} DEFAULT clkdev_default_device_lock; + +# +# Release exclusive access to underlying device +# +METHOD void device_unlock { + device_t dev; +} DEFAULT clkdev_default_device_unlock;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201603151528.u2FFSOi5071554>