Files
twx-linux/include/linux/clk.h
T
Greg Kroah-Hartman 0ddb73d446 Merge 5.10.166 into android12-5.10-lts
Changes in 5.10.166
	clk: generalize devm_clk_get() a bit
	clk: Provide new devm_clk helpers for prepared and enabled clocks
	memory: atmel-sdramc: Fix missing clk_disable_unprepare in atmel_ramc_probe()
	memory: mvebu-devbus: Fix missing clk_disable_unprepare in mvebu_devbus_probe()
	ARM: dts: imx6ul-pico-dwarf: Use 'clock-frequency'
	ARM: dts: imx7d-pico: Use 'clock-frequency'
	ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts'
	arm64: dts: imx8mm-beacon: Fix ecspi2 pinmux
	ARM: imx: add missing of_node_put()
	HID: intel_ish-hid: Add check for ishtp_dma_tx_map
	EDAC/highbank: Fix memory leak in highbank_mc_probe()
	firmware: arm_scmi: Harden shared memory access in fetch_response
	firmware: arm_scmi: Harden shared memory access in fetch_notification
	tomoyo: fix broken dependency on *.conf.default
	RDMA/core: Fix ib block iterator counter overflow
	IB/hfi1: Reject a zero-length user expected buffer
	IB/hfi1: Reserve user expected TIDs
	IB/hfi1: Fix expected receive setup error exit issues
	IB/hfi1: Immediately remove invalid memory from hardware
	IB/hfi1: Remove user expected buffer invalidate race
	affs: initialize fsdata in affs_truncate()
	PM: AVS: qcom-cpr: Fix an error handling path in cpr_probe()
	phy: ti: fix Kconfig warning and operator precedence
	ARM: dts: at91: sam9x60: fix the ddr clock for sam9x60
	amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent
	amd-xgbe: Delay AN timeout during KR training
	bpf: Fix pointer-leak due to insufficient speculative store bypass mitigation
	phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in rockchip_usb2phy_power_on()
	net: nfc: Fix use-after-free in local_cleanup()
	net: wan: Add checks for NULL for utdm in undo_uhdlc_init and unmap_si_regs
	gpio: mxc: Always set GPIOs used as interrupt source to INPUT mode
	wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid
	net/sched: sch_taprio: fix possible use-after-free
	l2tp: Serialize access to sk_user_data with sk_callback_lock
	l2tp: Don't sleep and disable BH under writer-side sk_callback_lock
	l2tp: convert l2tp_tunnel_list to idr
	l2tp: close all race conditions in l2tp_tunnel_register()
	net: usb: sr9700: Handle negative len
	net: mdio: validate parameter addr in mdiobus_get_phy()
	HID: check empty report_list in hid_validate_values()
	HID: check empty report_list in bigben_probe()
	net: stmmac: fix invalid call to mdiobus_get_phy()
	HID: revert CHERRY_MOUSE_000C quirk
	usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait
	usb: gadget: f_fs: Ensure ep0req is dequeued before free_request
	net: mlx5: eliminate anonymous module_init & module_exit
	drm/panfrost: fix GENERIC_ATOMIC64 dependency
	dmaengine: Fix double increment of client_count in dma_chan_get()
	net: macb: fix PTP TX timestamp failure due to packet padding
	l2tp: prevent lockdep issue in l2tp_tunnel_register()
	HID: betop: check shape of output reports
	dmaengine: xilinx_dma: call of_node_put() when breaking out of for_each_child_of_node()
	nvme-pci: fix timeout request state check
	tcp: avoid the lookup process failing to get sk in ehash table
	w1: fix deadloop in __w1_remove_master_device()
	w1: fix WARNING after calling w1_process()
	driver core: Fix test_async_probe_init saves device in wrong array
	net: dsa: microchip: ksz9477: port map correction in ALU table entry register
	tcp: fix rate_app_limited to default to 1
	scsi: iscsi: Fix multiple iSCSI session unbind events sent to userspace
	cpufreq: Add Tegra234 to cpufreq-dt-platdev blocklist
	kcsan: test: don't put the expect array on the stack
	ASoC: fsl_micfil: Correct the number of steps on SX controls
	drm: Add orientation quirk for Lenovo ideapad D330-10IGL
	s390/debug: add _ASM_S390_ prefix to header guard
	cpufreq: armada-37xx: stop using 0 as NULL pointer
	ASoC: fsl_ssi: Rename AC'97 streams to avoid collisions with AC'97 CODEC
	ASoC: fsl-asoc-card: Fix naming of AC'97 CODEC widgets
	spi: spidev: remove debug messages that access spidev->spi without locking
	KVM: s390: interrupt: use READ_ONCE() before cmpxchg()
	scsi: hisi_sas: Set a port invalid only if there are no devices attached when refreshing port id
	platform/x86: touchscreen_dmi: Add info for the CSL Panther Tab HD
	platform/x86: asus-nb-wmi: Add alternate mapping for KEY_SCREENLOCK
	lockref: stop doing cpu_relax in the cmpxchg loop
	Revert "selftests/bpf: check null propagation only neither reg is PTR_TO_BTF_ID"
	netfilter: conntrack: do not renew entry stuck in tcp SYN_SENT state
	x86: ACPI: cstate: Optimize C3 entry on AMD CPUs
	fs: reiserfs: remove useless new_opts in reiserfs_remount
	sysctl: add a new register_sysctl_init() interface
	kernel/panic: move panic sysctls to its own file
	panic: unset panic_on_warn inside panic()
	ubsan: no need to unset panic_on_warn in ubsan_epilogue()
	kasan: no need to unset panic_on_warn in end_report()
	exit: Add and use make_task_dead.
	objtool: Add a missing comma to avoid string concatenation
	hexagon: Fix function name in die()
	h8300: Fix build errors from do_exit() to make_task_dead() transition
	csky: Fix function name in csky_alignment() and die()
	ia64: make IA64_MCA_RECOVERY bool instead of tristate
	panic: Separate sysctl logic from CONFIG_SMP
	exit: Put an upper limit on how often we can oops
	exit: Expose "oops_count" to sysfs
	exit: Allow oops_limit to be disabled
	panic: Consolidate open-coded panic_on_warn checks
	panic: Introduce warn_limit
	panic: Expose "warn_count" to sysfs
	docs: Fix path paste-o for /sys/kernel/warn_count
	exit: Use READ_ONCE() for all oops/warn limit reads
	Bluetooth: hci_sync: cancel cmd_timer if hci_open failed
	xhci: Set HCD flag to defer primary roothub registration
	scsi: hpsa: Fix allocation size for scsi_host_alloc()
	module: Don't wait for GOING modules
	tracing: Make sure trace_printk() can output as soon as it can be used
	trace_events_hist: add check for return value of 'create_hist_field'
	ftrace/scripts: Update the instructions for ftrace-bisect.sh
	cifs: Fix oops due to uncleared server->smbd_conn in reconnect
	KVM: x86/vmx: Do not skip segment attributes if unusable bit is set
	thermal: intel: int340x: Protect trip temperature from concurrent updates
	ARM: 9280/1: mm: fix warning on phys_addr_t to void pointer assignment
	EDAC/device: Respect any driver-supplied workqueue polling value
	EDAC/qcom: Do not pass llcc_driv_data as edac_device_ctl_info's pvt_info
	units: Add Watt units
	units: Add SI metric prefix definitions
	i2c: designware: Use DIV_ROUND_CLOSEST() macro
	i2c: designware: use casting of u64 in clock multiplication to avoid overflow
	netlink: prevent potential spectre v1 gadgets
	net: fix UaF in netns ops registration error path
	netfilter: nft_set_rbtree: Switch to node list walk for overlap detection
	netfilter: nft_set_rbtree: skip elements in transaction from garbage collection
	netlink: annotate data races around nlk->portid
	netlink: annotate data races around dst_portid and dst_group
	netlink: annotate data races around sk_state
	ipv4: prevent potential spectre v1 gadget in ip_metrics_convert()
	ipv4: prevent potential spectre v1 gadget in fib_metrics_match()
	netfilter: conntrack: fix vtag checks for ABORT/SHUTDOWN_COMPLETE
	netrom: Fix use-after-free of a listening socket.
	net/sched: sch_taprio: do not schedule in taprio_reset()
	sctp: fail if no bound addresses can be used for a given scope
	net: ravb: Fix possible hang if RIS2_QFF1 happen
	thermal: intel: int340x: Add locking to int340x_thermal_get_trip_type()
	net/tg3: resolve deadlock in tg3_reset_task() during EEH
	net: mdio-mux-meson-g12a: force internal PHY off on mux switch
	tools: gpio: fix -c option of gpio-event-mon
	Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode"
	nouveau: explicitly wait on the fence in nouveau_bo_move_m2mf
	nfsd: Ensure knfsd shuts down when the "nfsd" pseudofs is unmounted
	Revert "selftests/ftrace: Update synthetic event syntax errors"
	block: fix and cleanup bio_check_ro
	x86/i8259: Mark legacy PIC interrupts with IRQ_LEVEL
	netfilter: conntrack: unify established states for SCTP paths
	perf/x86/amd: fix potential integer overflow on shift of a int
	clk: Fix pointer casting to prevent oops in devm_clk_release()
	Linux 5.10.166

Change-Id: Ibf582f7504221c6ee1648da95c49b45e3678708c
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2023-02-17 12:18:56 +00:00

1116 lines
32 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* linux/include/linux/clk.h
*
* Copyright (C) 2004 ARM Limited.
* Written by Deep Blue Solutions Limited.
* Copyright (C) 2011-2012 Linaro Ltd <mturquette@linaro.org>
*/
#ifndef __LINUX_CLK_H
#define __LINUX_CLK_H
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/notifier.h>
struct device;
struct clk;
struct device_node;
struct of_phandle_args;
/**
* DOC: clk notifier callback types
*
* PRE_RATE_CHANGE - called immediately before the clk rate is changed,
* to indicate that the rate change will proceed. Drivers must
* immediately terminate any operations that will be affected by the
* rate change. Callbacks may either return NOTIFY_DONE, NOTIFY_OK,
* NOTIFY_STOP or NOTIFY_BAD.
*
* ABORT_RATE_CHANGE: called if the rate change failed for some reason
* after PRE_RATE_CHANGE. In this case, all registered notifiers on
* the clk will be called with ABORT_RATE_CHANGE. Callbacks must
* always return NOTIFY_DONE or NOTIFY_OK.
*
* POST_RATE_CHANGE - called after the clk rate change has successfully
* completed. Callbacks must always return NOTIFY_DONE or NOTIFY_OK.
*
*/
#define PRE_RATE_CHANGE BIT(0)
#define POST_RATE_CHANGE BIT(1)
#define ABORT_RATE_CHANGE BIT(2)
/**
* struct clk_notifier - associate a clk with a notifier
* @clk: struct clk * to associate the notifier with
* @notifier_head: a blocking_notifier_head for this clk
* @node: linked list pointers
*
* A list of struct clk_notifier is maintained by the notifier code.
* An entry is created whenever code registers the first notifier on a
* particular @clk. Future notifiers on that @clk are added to the
* @notifier_head.
*/
struct clk_notifier {
struct clk *clk;
struct srcu_notifier_head notifier_head;
struct list_head node;
};
/**
* struct clk_notifier_data - rate data to pass to the notifier callback
* @clk: struct clk * being changed
* @old_rate: previous rate of this clk
* @new_rate: new rate of this clk
*
* For a pre-notifier, old_rate is the clk's rate before this rate
* change, and new_rate is what the rate will be in the future. For a
* post-notifier, old_rate and new_rate are both set to the clk's
* current rate (this was done to optimize the implementation).
*/
struct clk_notifier_data {
struct clk *clk;
unsigned long old_rate;
unsigned long new_rate;
};
/**
* struct clk_bulk_data - Data used for bulk clk operations.
*
* @id: clock consumer ID
* @clk: struct clk * to store the associated clock
*
* The CLK APIs provide a series of clk_bulk_() API calls as
* a convenience to consumers which require multiple clks. This
* structure is used to manage data for these calls.
*/
struct clk_bulk_data {
const char *id;
struct clk *clk;
};
#ifdef CONFIG_COMMON_CLK
/**
* clk_notifier_register: register a clock rate-change notifier callback
* @clk: clock whose rate we are interested in
* @nb: notifier block with callback function pointer
*
* ProTip: debugging across notifier chains can be frustrating. Make sure that
* your notifier callback function prints a nice big warning in case of
* failure.
*/
int clk_notifier_register(struct clk *clk, struct notifier_block *nb);
/**
* clk_notifier_unregister: unregister a clock rate-change notifier callback
* @clk: clock whose rate we are no longer interested in
* @nb: notifier block which will be unregistered
*/
int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);
/**
* devm_clk_notifier_register - register a managed rate-change notifier callback
* @dev: device for clock "consumer"
* @clk: clock whose rate we are interested in
* @nb: notifier block with callback function pointer
*
* Returns 0 on success, -EERROR otherwise
*/
int devm_clk_notifier_register(struct device *dev, struct clk *clk,
struct notifier_block *nb);
/**
* clk_get_accuracy - obtain the clock accuracy in ppb (parts per billion)
* for a clock source.
* @clk: clock source
*
* This gets the clock source accuracy expressed in ppb.
* A perfect clock returns 0.
*/
long clk_get_accuracy(struct clk *clk);
/**
* clk_set_phase - adjust the phase shift of a clock signal
* @clk: clock signal source
* @degrees: number of degrees the signal is shifted
*
* Shifts the phase of a clock signal by the specified degrees. Returns 0 on
* success, -EERROR otherwise.
*/
int clk_set_phase(struct clk *clk, int degrees);
/**
* clk_get_phase - return the phase shift of a clock signal
* @clk: clock signal source
*
* Returns the phase shift of a clock node in degrees, otherwise returns
* -EERROR.
*/
int clk_get_phase(struct clk *clk);
/**
* clk_set_duty_cycle - adjust the duty cycle ratio of a clock signal
* @clk: clock signal source
* @num: numerator of the duty cycle ratio to be applied
* @den: denominator of the duty cycle ratio to be applied
*
* Adjust the duty cycle of a clock signal by the specified ratio. Returns 0 on
* success, -EERROR otherwise.
*/
int clk_set_duty_cycle(struct clk *clk, unsigned int num, unsigned int den);
/**
* clk_get_duty_cycle - return the duty cycle ratio of a clock signal
* @clk: clock signal source
* @scale: scaling factor to be applied to represent the ratio as an integer
*
* Returns the duty cycle ratio multiplied by the scale provided, otherwise
* returns -EERROR.
*/
int clk_get_scaled_duty_cycle(struct clk *clk, unsigned int scale);
/**
* clk_is_match - check if two clk's point to the same hardware clock
* @p: clk compared against q
* @q: clk compared against p
*
* Returns true if the two struct clk pointers both point to the same hardware
* clock node. Put differently, returns true if @p and @q
* share the same &struct clk_core object.
*
* Returns false otherwise. Note that two NULL clks are treated as matching.
*/
bool clk_is_match(const struct clk *p, const struct clk *q);
#else
static inline int clk_notifier_register(struct clk *clk,
struct notifier_block *nb)
{
return -ENOTSUPP;
}
static inline int clk_notifier_unregister(struct clk *clk,
struct notifier_block *nb)
{
return -ENOTSUPP;
}
static inline int devm_clk_notifier_register(struct device *dev,
struct clk *clk,
struct notifier_block *nb)
{
return -ENOTSUPP;
}
static inline long clk_get_accuracy(struct clk *clk)
{
return -ENOTSUPP;
}
static inline long clk_set_phase(struct clk *clk, int phase)
{
return -ENOTSUPP;
}
static inline long clk_get_phase(struct clk *clk)
{
return -ENOTSUPP;
}
static inline int clk_set_duty_cycle(struct clk *clk, unsigned int num,
unsigned int den)
{
return -ENOTSUPP;
}
static inline unsigned int clk_get_scaled_duty_cycle(struct clk *clk,
unsigned int scale)
{
return 0;
}
static inline bool clk_is_match(const struct clk *p, const struct clk *q)
{
return p == q;
}
#endif
/**
* clk_prepare - prepare a clock source
* @clk: clock source
*
* This prepares the clock source for use.
*
* Must not be called from within atomic context.
*/
#ifdef CONFIG_HAVE_CLK_PREPARE
int clk_prepare(struct clk *clk);
int __must_check clk_bulk_prepare(int num_clks,
const struct clk_bulk_data *clks);
#else
static inline int clk_prepare(struct clk *clk)
{
might_sleep();
return 0;
}
static inline int __must_check
clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks)
{
might_sleep();
return 0;
}
#endif
/**
* clk_unprepare - undo preparation of a clock source
* @clk: clock source
*
* This undoes a previously prepared clock. The caller must balance
* the number of prepare and unprepare calls.
*
* Must not be called from within atomic context.
*/
#ifdef CONFIG_HAVE_CLK_PREPARE
void clk_unprepare(struct clk *clk);
void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks);
#else
static inline void clk_unprepare(struct clk *clk)
{
might_sleep();
}
static inline void clk_bulk_unprepare(int num_clks,
const struct clk_bulk_data *clks)
{
might_sleep();
}
#endif
#ifdef CONFIG_HAVE_CLK
/**
* clk_get - lookup and obtain a reference to a clock producer.
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Returns a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* Drivers must assume that the clock source is not enabled.
*
* clk_get should not be called from within interrupt context.
*/
struct clk *clk_get(struct device *dev, const char *id);
/**
* clk_bulk_get - lookup and obtain a number of references to clock producer.
* @dev: device for clock "consumer"
* @num_clks: the number of clk_bulk_data
* @clks: the clk_bulk_data table of consumer
*
* This helper function allows drivers to get several clk consumers in one
* operation. If any of the clk cannot be acquired then any clks
* that were obtained will be freed before returning to the caller.
*
* Returns 0 if all clocks specified in clk_bulk_data table are obtained
* successfully, or valid IS_ERR() condition containing errno.
* The implementation uses @dev and @clk_bulk_data.id to determine the
* clock consumer, and thereby the clock producer.
* The clock returned is stored in each @clk_bulk_data.clk field.
*
* Drivers must assume that the clock source is not enabled.
*
* clk_bulk_get should not be called from within interrupt context.
*/
int __must_check clk_bulk_get(struct device *dev, int num_clks,
struct clk_bulk_data *clks);
/**
* clk_bulk_get_all - lookup and obtain all available references to clock
* producer.
* @dev: device for clock "consumer"
* @clks: pointer to the clk_bulk_data table of consumer
*
* This helper function allows drivers to get all clk consumers in one
* operation. If any of the clk cannot be acquired then any clks
* that were obtained will be freed before returning to the caller.
*
* Returns a positive value for the number of clocks obtained while the
* clock references are stored in the clk_bulk_data table in @clks field.
* Returns 0 if there're none and a negative value if something failed.
*
* Drivers must assume that the clock source is not enabled.
*
* clk_bulk_get should not be called from within interrupt context.
*/
int __must_check clk_bulk_get_all(struct device *dev,
struct clk_bulk_data **clks);
/**
* clk_bulk_get_optional - lookup and obtain a number of references to clock producer
* @dev: device for clock "consumer"
* @num_clks: the number of clk_bulk_data
* @clks: the clk_bulk_data table of consumer
*
* Behaves the same as clk_bulk_get() except where there is no clock producer.
* In this case, instead of returning -ENOENT, the function returns 0 and
* NULL for a clk for which a clock producer could not be determined.
*/
int __must_check clk_bulk_get_optional(struct device *dev, int num_clks,
struct clk_bulk_data *clks);
/**
* devm_clk_bulk_get - managed get multiple clk consumers
* @dev: device for clock "consumer"
* @num_clks: the number of clk_bulk_data
* @clks: the clk_bulk_data table of consumer
*
* Return 0 on success, an errno on failure.
*
* This helper function allows drivers to get several clk
* consumers in one operation with management, the clks will
* automatically be freed when the device is unbound.
*/
int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
struct clk_bulk_data *clks);
/**
* devm_clk_bulk_get_optional - managed get multiple optional consumer clocks
* @dev: device for clock "consumer"
* @num_clks: the number of clk_bulk_data
* @clks: pointer to the clk_bulk_data table of consumer
*
* Behaves the same as devm_clk_bulk_get() except where there is no clock
* producer. In this case, instead of returning -ENOENT, the function returns
* NULL for given clk. It is assumed all clocks in clk_bulk_data are optional.
*
* Returns 0 if all clocks specified in clk_bulk_data table are obtained
* successfully or for any clk there was no clk provider available, otherwise
* returns valid IS_ERR() condition containing errno.
* The implementation uses @dev and @clk_bulk_data.id to determine the
* clock consumer, and thereby the clock producer.
* The clock returned is stored in each @clk_bulk_data.clk field.
*
* Drivers must assume that the clock source is not enabled.
*
* clk_bulk_get should not be called from within interrupt context.
*/
int __must_check devm_clk_bulk_get_optional(struct device *dev, int num_clks,
struct clk_bulk_data *clks);
/**
* devm_clk_bulk_get_all - managed get multiple clk consumers
* @dev: device for clock "consumer"
* @clks: pointer to the clk_bulk_data table of consumer
*
* Returns a positive value for the number of clocks obtained while the
* clock references are stored in the clk_bulk_data table in @clks field.
* Returns 0 if there're none and a negative value if something failed.
*
* This helper function allows drivers to get several clk
* consumers in one operation with management, the clks will
* automatically be freed when the device is unbound.
*/
int __must_check devm_clk_bulk_get_all(struct device *dev,
struct clk_bulk_data **clks);
/**
* devm_clk_get - lookup and obtain a managed reference to a clock producer.
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Returns a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* Drivers must assume that the clock source is not enabled.
*
* devm_clk_get should not be called from within interrupt context.
*
* The clock will automatically be freed when the device is unbound
* from the bus.
*/
struct clk *devm_clk_get(struct device *dev, const char *id);
/**
* devm_clk_get_prepared - devm_clk_get() + clk_prepare()
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Context: May sleep.
*
* Return: a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* The returned clk (if valid) is prepared. Drivers must however assume
* that the clock is not enabled.
*
* The clock will automatically be unprepared and freed when the device
* is unbound from the bus.
*/
struct clk *devm_clk_get_prepared(struct device *dev, const char *id);
/**
* devm_clk_get_enabled - devm_clk_get() + clk_prepare_enable()
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Context: May sleep.
*
* Return: a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* The returned clk (if valid) is prepared and enabled.
*
* The clock will automatically be disabled, unprepared and freed
* when the device is unbound from the bus.
*/
struct clk *devm_clk_get_enabled(struct device *dev, const char *id);
/**
* devm_clk_get_optional - lookup and obtain a managed reference to an optional
* clock producer.
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Behaves the same as devm_clk_get() except where there is no clock producer.
* In this case, instead of returning -ENOENT, the function returns NULL.
*/
struct clk *devm_clk_get_optional(struct device *dev, const char *id);
/**
* devm_clk_get_optional_prepared - devm_clk_get_optional() + clk_prepare()
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Context: May sleep.
*
* Return: a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. If no such clk is found, it returns NULL
* which serves as a dummy clk. That's the only difference compared
* to devm_clk_get_prepared().
*
* The returned clk (if valid) is prepared. Drivers must however
* assume that the clock is not enabled.
*
* The clock will automatically be unprepared and freed when the
* device is unbound from the bus.
*/
struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id);
/**
* devm_clk_get_optional_enabled - devm_clk_get_optional() +
* clk_prepare_enable()
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Context: May sleep.
*
* Return: a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. If no such clk is found, it returns NULL
* which serves as a dummy clk. That's the only difference compared
* to devm_clk_get_enabled().
*
* The returned clk (if valid) is prepared and enabled.
*
* The clock will automatically be disabled, unprepared and freed
* when the device is unbound from the bus.
*/
struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id);
/**
* devm_get_clk_from_child - lookup and obtain a managed reference to a
* clock producer from child node.
* @dev: device for clock "consumer"
* @np: pointer to clock consumer node
* @con_id: clock consumer ID
*
* This function parses the clocks, and uses them to look up the
* struct clk from the registered list of clock providers by using
* @np and @con_id
*
* The clock will automatically be freed when the device is unbound
* from the bus.
*/
struct clk *devm_get_clk_from_child(struct device *dev,
struct device_node *np, const char *con_id);
/**
* clk_rate_exclusive_get - get exclusivity over the rate control of a
* producer
* @clk: clock source
*
* This function allows drivers to get exclusive control over the rate of a
* provider. It prevents any other consumer to execute, even indirectly,
* opereation which could alter the rate of the provider or cause glitches
*
* If exlusivity is claimed more than once on clock, even by the same driver,
* the rate effectively gets locked as exclusivity can't be preempted.
*
* Must not be called from within atomic context.
*
* Returns success (0) or negative errno.
*/
int clk_rate_exclusive_get(struct clk *clk);
/**
* clk_rate_exclusive_put - release exclusivity over the rate control of a
* producer
* @clk: clock source
*
* This function allows drivers to release the exclusivity it previously got
* from clk_rate_exclusive_get()
*
* The caller must balance the number of clk_rate_exclusive_get() and
* clk_rate_exclusive_put() calls.
*
* Must not be called from within atomic context.
*/
void clk_rate_exclusive_put(struct clk *clk);
/**
* clk_enable - inform the system when the clock source should be running.
* @clk: clock source
*
* If the clock can not be enabled/disabled, this should return success.
*
* May be called from atomic contexts.
*
* Returns success (0) or negative errno.
*/
int clk_enable(struct clk *clk);
/**
* clk_bulk_enable - inform the system when the set of clks should be running.
* @num_clks: the number of clk_bulk_data
* @clks: the clk_bulk_data table of consumer
*
* May be called from atomic contexts.
*
* Returns success (0) or negative errno.
*/
int __must_check clk_bulk_enable(int num_clks,
const struct clk_bulk_data *clks);
/**
* clk_disable - inform the system when the clock source is no longer required.
* @clk: clock source
*
* Inform the system that a clock source is no longer required by
* a driver and may be shut down.
*
* May be called from atomic contexts.
*
* Implementation detail: if the clock source is shared between
* multiple drivers, clk_enable() calls must be balanced by the
* same number of clk_disable() calls for the clock source to be
* disabled.
*/
void clk_disable(struct clk *clk);
/**
* clk_bulk_disable - inform the system when the set of clks is no
* longer required.
* @num_clks: the number of clk_bulk_data
* @clks: the clk_bulk_data table of consumer
*
* Inform the system that a set of clks is no longer required by
* a driver and may be shut down.
*
* May be called from atomic contexts.
*
* Implementation detail: if the set of clks is shared between
* multiple drivers, clk_bulk_enable() calls must be balanced by the
* same number of clk_bulk_disable() calls for the clock source to be
* disabled.
*/
void clk_bulk_disable(int num_clks, const struct clk_bulk_data *clks);
/**
* clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
* This is only valid once the clock source has been enabled.
* @clk: clock source
*/
unsigned long clk_get_rate(struct clk *clk);
/**
* clk_put - "free" the clock source
* @clk: clock source
*
* Note: drivers must ensure that all clk_enable calls made on this
* clock source are balanced by clk_disable calls prior to calling
* this function.
*
* clk_put should not be called from within interrupt context.
*/
void clk_put(struct clk *clk);
/**
* clk_bulk_put - "free" the clock source
* @num_clks: the number of clk_bulk_data
* @clks: the clk_bulk_data table of consumer
*
* Note: drivers must ensure that all clk_bulk_enable calls made on this
* clock source are balanced by clk_bulk_disable calls prior to calling
* this function.
*
* clk_bulk_put should not be called from within interrupt context.
*/
void clk_bulk_put(int num_clks, struct clk_bulk_data *clks);
/**
* clk_bulk_put_all - "free" all the clock source
* @num_clks: the number of clk_bulk_data
* @clks: the clk_bulk_data table of consumer
*
* Note: drivers must ensure that all clk_bulk_enable calls made on this
* clock source are balanced by clk_bulk_disable calls prior to calling
* this function.
*
* clk_bulk_put_all should not be called from within interrupt context.
*/
void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks);
/**
* devm_clk_put - "free" a managed clock source
* @dev: device used to acquire the clock
* @clk: clock source acquired with devm_clk_get()
*
* Note: drivers must ensure that all clk_enable calls made on this
* clock source are balanced by clk_disable calls prior to calling
* this function.
*
* clk_put should not be called from within interrupt context.
*/
void devm_clk_put(struct device *dev, struct clk *clk);
/*
* The remaining APIs are optional for machine class support.
*/
/**
* clk_round_rate - adjust a rate to the exact rate a clock can provide
* @clk: clock source
* @rate: desired clock rate in Hz
*
* This answers the question "if I were to pass @rate to clk_set_rate(),
* what clock rate would I end up with?" without changing the hardware
* in any way. In other words:
*
* rate = clk_round_rate(clk, r);
*
* and:
*
* clk_set_rate(clk, r);
* rate = clk_get_rate(clk);
*
* are equivalent except the former does not modify the clock hardware
* in any way.
*
* Returns rounded clock rate in Hz, or negative errno.
*/
long clk_round_rate(struct clk *clk, unsigned long rate);
/**
* clk_set_rate - set the clock rate for a clock source
* @clk: clock source
* @rate: desired clock rate in Hz
*
* Updating the rate starts at the top-most affected clock and then
* walks the tree down to the bottom-most clock that needs updating.
*
* Returns success (0) or negative errno.
*/
int clk_set_rate(struct clk *clk, unsigned long rate);
/**
* clk_set_rate_exclusive- set the clock rate and claim exclusivity over
* clock source
* @clk: clock source
* @rate: desired clock rate in Hz
*
* This helper function allows drivers to atomically set the rate of a producer
* and claim exclusivity over the rate control of the producer.
*
* It is essentially a combination of clk_set_rate() and
* clk_rate_exclusite_get(). Caller must balance this call with a call to
* clk_rate_exclusive_put()
*
* Returns success (0) or negative errno.
*/
int clk_set_rate_exclusive(struct clk *clk, unsigned long rate);
/**
* clk_has_parent - check if a clock is a possible parent for another
* @clk: clock source
* @parent: parent clock source
*
* This function can be used in drivers that need to check that a clock can be
* the parent of another without actually changing the parent.
*
* Returns true if @parent is a possible parent for @clk, false otherwise.
*/
bool clk_has_parent(struct clk *clk, struct clk *parent);
/**
* clk_set_rate_range - set a rate range for a clock source
* @clk: clock source
* @min: desired minimum clock rate in Hz, inclusive
* @max: desired maximum clock rate in Hz, inclusive
*
* Returns success (0) or negative errno.
*/
int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max);
/**
* clk_set_min_rate - set a minimum clock rate for a clock source
* @clk: clock source
* @rate: desired minimum clock rate in Hz, inclusive
*
* Returns success (0) or negative errno.
*/
int clk_set_min_rate(struct clk *clk, unsigned long rate);
/**
* clk_set_max_rate - set a maximum clock rate for a clock source
* @clk: clock source
* @rate: desired maximum clock rate in Hz, inclusive
*
* Returns success (0) or negative errno.
*/
int clk_set_max_rate(struct clk *clk, unsigned long rate);
/**
* clk_set_parent - set the parent clock source for this clock
* @clk: clock source
* @parent: parent clock source
*
* Returns success (0) or negative errno.
*/
int clk_set_parent(struct clk *clk, struct clk *parent);
/**
* clk_get_parent - get the parent clock source for this clock
* @clk: clock source
*
* Returns struct clk corresponding to parent clock source, or
* valid IS_ERR() condition containing errno.
*/
struct clk *clk_get_parent(struct clk *clk);
/**
* clk_get_sys - get a clock based upon the device name
* @dev_id: device name
* @con_id: connection ID
*
* Returns a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev_id and @con_id to determine the clock consumer, and
* thereby the clock producer. In contrast to clk_get() this function
* takes the device name instead of the device itself for identification.
*
* Drivers must assume that the clock source is not enabled.
*
* clk_get_sys should not be called from within interrupt context.
*/
struct clk *clk_get_sys(const char *dev_id, const char *con_id);
/**
* clk_save_context - save clock context for poweroff
*
* Saves the context of the clock register for powerstates in which the
* contents of the registers will be lost. Occurs deep within the suspend
* code so locking is not necessary.
*/
int clk_save_context(void);
/**
* clk_restore_context - restore clock context after poweroff
*
* This occurs with all clocks enabled. Occurs deep within the resume code
* so locking is not necessary.
*/
void clk_restore_context(void);
#else /* !CONFIG_HAVE_CLK */
static inline struct clk *clk_get(struct device *dev, const char *id)
{
return NULL;
}
static inline int __must_check clk_bulk_get(struct device *dev, int num_clks,
struct clk_bulk_data *clks)
{
return 0;
}
static inline int __must_check clk_bulk_get_optional(struct device *dev,
int num_clks, struct clk_bulk_data *clks)
{
return 0;
}
static inline int __must_check clk_bulk_get_all(struct device *dev,
struct clk_bulk_data **clks)
{
return 0;
}
static inline struct clk *devm_clk_get(struct device *dev, const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_prepared(struct device *dev,
const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_enabled(struct device *dev,
const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_optional(struct device *dev,
const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_optional_prepared(struct device *dev,
const char *id)
{
return NULL;
}
static inline struct clk *devm_clk_get_optional_enabled(struct device *dev,
const char *id)
{
return NULL;
}
static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks,
struct clk_bulk_data *clks)
{
return 0;
}
static inline int __must_check devm_clk_bulk_get_optional(struct device *dev,
int num_clks, struct clk_bulk_data *clks)
{
return 0;
}
static inline int __must_check devm_clk_bulk_get_all(struct device *dev,
struct clk_bulk_data **clks)
{
return 0;
}
static inline struct clk *devm_get_clk_from_child(struct device *dev,
struct device_node *np, const char *con_id)
{
return NULL;
}
static inline void clk_put(struct clk *clk) {}
static inline void clk_bulk_put(int num_clks, struct clk_bulk_data *clks) {}
static inline void clk_bulk_put_all(int num_clks, struct clk_bulk_data *clks) {}
static inline void devm_clk_put(struct device *dev, struct clk *clk) {}
static inline int clk_rate_exclusive_get(struct clk *clk)
{
return 0;
}
static inline void clk_rate_exclusive_put(struct clk *clk) {}
static inline int clk_enable(struct clk *clk)
{
return 0;
}
static inline int __must_check clk_bulk_enable(int num_clks,
const struct clk_bulk_data *clks)
{
return 0;
}
static inline void clk_disable(struct clk *clk) {}
static inline void clk_bulk_disable(int num_clks,
const struct clk_bulk_data *clks) {}
static inline unsigned long clk_get_rate(struct clk *clk)
{
return 0;
}
static inline int clk_set_rate(struct clk *clk, unsigned long rate)
{
return 0;
}
static inline int clk_set_rate_exclusive(struct clk *clk, unsigned long rate)
{
return 0;
}
static inline long clk_round_rate(struct clk *clk, unsigned long rate)
{
return 0;
}
static inline bool clk_has_parent(struct clk *clk, struct clk *parent)
{
return true;
}
static inline int clk_set_rate_range(struct clk *clk, unsigned long min,
unsigned long max)
{
return 0;
}
static inline int clk_set_min_rate(struct clk *clk, unsigned long rate)
{
return 0;
}
static inline int clk_set_max_rate(struct clk *clk, unsigned long rate)
{
return 0;
}
static inline int clk_set_parent(struct clk *clk, struct clk *parent)
{
return 0;
}
static inline struct clk *clk_get_parent(struct clk *clk)
{
return NULL;
}
static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id)
{
return NULL;
}
static inline int clk_save_context(void)
{
return 0;
}
static inline void clk_restore_context(void) {}
#endif
/* clk_prepare_enable helps cases using clk_enable in non-atomic context. */
static inline int clk_prepare_enable(struct clk *clk)
{
int ret;
ret = clk_prepare(clk);
if (ret)
return ret;
ret = clk_enable(clk);
if (ret)
clk_unprepare(clk);
return ret;
}
/* clk_disable_unprepare helps cases using clk_disable in non-atomic context. */
static inline void clk_disable_unprepare(struct clk *clk)
{
clk_disable(clk);
clk_unprepare(clk);
}
static inline int __must_check
clk_bulk_prepare_enable(int num_clks, const struct clk_bulk_data *clks)
{
int ret;
ret = clk_bulk_prepare(num_clks, clks);
if (ret)
return ret;
ret = clk_bulk_enable(num_clks, clks);
if (ret)
clk_bulk_unprepare(num_clks, clks);
return ret;
}
static inline void clk_bulk_disable_unprepare(int num_clks,
const struct clk_bulk_data *clks)
{
clk_bulk_disable(num_clks, clks);
clk_bulk_unprepare(num_clks, clks);
}
/**
* clk_get_optional - lookup and obtain a reference to an optional clock
* producer.
* @dev: device for clock "consumer"
* @id: clock consumer ID
*
* Behaves the same as clk_get() except where there is no clock producer. In
* this case, instead of returning -ENOENT, the function returns NULL.
*/
static inline struct clk *clk_get_optional(struct device *dev, const char *id)
{
struct clk *clk = clk_get(dev, id);
if (clk == ERR_PTR(-ENOENT))
return NULL;
return clk;
}
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
struct clk *of_clk_get(struct device_node *np, int index);
struct clk *of_clk_get_by_name(struct device_node *np, const char *name);
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec);
#else
static inline struct clk *of_clk_get(struct device_node *np, int index)
{
return ERR_PTR(-ENOENT);
}
static inline struct clk *of_clk_get_by_name(struct device_node *np,
const char *name)
{
return ERR_PTR(-ENOENT);
}
static inline struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
{
return ERR_PTR(-ENOENT);
}
#endif
#endif