* refs/heads/tmp-4ab5627:
ANDROID: Update symbol list for mtk
ANDROID: module: Add vendor hooks
ANDROID: kernel: Add restricted vendor hook in creds
ANDROID: enable CONFIG_USB_XHCI_PCI_RENESAS in gki_defconfig
ANDROID: Add utf8_data_table for case-folding support
UPSTREAM: usb: typec: altmodes/displayport: Add hpd sysfs attribute
ANDROID: vendor_hooks: Add vendor hook for tcpm logs
ANDROID: usb: typec: tcpm: Add vendor hook to modify port src caps
ANDROID: usb: typec: tcpm: Add vendor hook to store partner source capabilities
ANDROID: usb: typec: tcpm: vendor hook for timer adjustments
ANDROID: usb: typec: tcpci: Add vendor hook to mask vbus present
ANDROID: usb: typec: tcpci: Add vendor hooks for tcpci interface
UPSTREAM: scsi: ufs: mcq: Use active_reqs to check busy in clock scaling
FROMLIST: xfrm: Skip checking of already-verified secpath entries
Revert "Fix XFRM-I support for nested ESP tunnels"
FROMLIST: xfrm: Ensure policy checked for nested ESP tunnels
ANDROID: Update the ABI symbol list for typec mux
ANDROID: Update the ABI symbol list for typec port management
ANDROID: ABI: Add __irq_set_handler and irq_set_handler_data in QCOM symbol list
FROMGIT: soc: qcom: geni-se: Update Tx and Rx fifo depth based on QUP HW version
FROMGIT: soc: qcom: geni-se: Move qcom-geni-se.h to linux/soc/qcom/geni-se.h
ANDROID: CONFIG_PKVM_MODULE_PATH to /lib/modules/
ANDROID: KVM: arm64: Add a fallback for pKVM module loading
ANDROID: KVM: arm64: Add a custom module path for pKVM module loading
ANDROID: update the pixel symbol list
ANDROID: Add ufs symbol for mtk
ANDROID: scsi: ufs: Add hook to influence the UFS clock scaling policy
UPSTREAM: mm: multi-gen LRU: simplify lru_gen_look_around()
UPSTREAM: mm: multi-gen LRU: improve walk_pmd_range()
UPSTREAM: mm: multi-gen LRU: improve lru_gen_exit_memcg()
UPSTREAM: mm: multi-gen LRU: section for memcg LRU
UPSTREAM: mm: multi-gen LRU: section for Bloom filters
UPSTREAM: mm: multi-gen LRU: section for rmap/PT walk feedback
UPSTREAM: mm: multi-gen LRU: section for working set protection
UPSTREAM: mm: support POSIX_FADV_NOREUSE
UPSTREAM: mm: add vma_has_recency()
ANDROID: 4/12/2023 KMI update
ANDROID: ABI: remove stale symbol
ANDROID: fuse: Support errors from fuse daemon in canonical path
ANDROID: abi_gki_aarch64_qcom: Add memremap_pages and memunmap_pages
ANDROID: Enable CONFIG_ZONE_DEVICE
Revert "Revert "block/io_uring: pass in issue_flags for uring_cmd task_work handling""
Revert "Revert "net: mdio: fix owner field for mdio buses registered using device-tree""
FROMGIT: wifi: cfg80211/mac80211: report link ID on control port RX
UPSTREAM: iommu: Rename iommu-sva-lib.{c,h}
UPSTREAM: iommu: Per-domain I/O page fault handling
UPSTREAM: iommu: Prepare IOMMU domain for IOPF
UPSTREAM: iommu: Remove SVA related callbacks from iommu ops
UPSTREAM: iommu/sva: Refactoring iommu_sva_bind/unbind_device()
UPSTREAM: arm-smmu-v3/sva: Add SVA domain support
UPSTREAM: iommu/vt-d: Add SVA domain support
UPSTREAM: iommu: Add IOMMU SVA domain support
UPSTREAM: iommu: Add attach/detach_dev_pasid iommu interfaces
UPSTREAM: PCI: Enable PASID only when ACS RR & UF enabled on upstream path
UPSTREAM: iommu: Remove SVM_FLAG_SUPERVISOR_MODE support
UPSTREAM: iommu: Add max_pasids field in struct dev_iommu
UPSTREAM: iommu: Add max_pasids field in struct iommu_device
ANDROID: GKI: fscrypt: add ABI padding to struct fscrypt_operations
ANDROID: abi_gki_aarch64_qcom: Add sock_gen_put
ANDROID: arm64: Implement hypervisor workaround for SoCs with DMA beyond the PoC
ANDROID: GKI: add symbol list file for xiaomi
ANDROID: Add initial symbols list for imx
ANDROID: Add initial symbol list for mtk
ANDROID: virt: gunyah: Move arch_is_gh_guest under RM probe
ANDROID: GKI: Enable CONFIG_USB_CONFIGFS_F_UAC2
ANDROID: Update the pixel symbol list
BACKPORT: FROMLIST: Revert "scsi: ufs: core: Initialize devfreq synchronously"
ANDROID: abi_gki_aarch64_qcom: update abi
ANDROID: abi_gki_aarch64_qcom: Further update symbol list
ANDROID: GKI: Convert 80211 modules as unprotected
ANDROID: ABI: Update QCOM symbol list
Revert "FROMGIT: scsi: ufs: ufs-qcom: Add support for reinitializing the UFS device"
Revert "FROMGIT: scsi: ufs: ufs-qcom: Add support for finding max gear on new platforms"
Revert "block/io_uring: pass in issue_flags for uring_cmd task_work handling"
ANDROID: abi_gki_aarch64_qcom: Add of_icc_get_from_provider
FROMLIST: staging: greybus: drop loopback test files
ANDROID: KVM: arm64: Prevent pKVM module loading after IOMMU init
ANDROID: KVM: arm64: Factor out logic for setting SVE vector length at hyp
ANDROID: KVM: arm64: Fix pKVM module loading close
ANDROID: KVM: arm64: Handle permission issue while loading pKVM module
Linux 6.1.23
Revert "cpuidle, intel_idle: Fix CPUIDLE_FLAG_IRQ_ENABLE *again*"
x86/PVH: avoid 32-bit build warning when obtaining VGA console info
hsr: ratelimit only when errors are printed
drm/amdkfd: Get prange->offset after svm_range_vram_node_new
usb: ucsi: Fix ucsi->connector race
libbpf: Fix btf_dump's packed struct determination
selftests/bpf: Add few corner cases to test padding handling of btf_dump
libbpf: Fix BTF-to-C converter's padding logic
selftests/bpf: Test btf dump for struct with padding only fields
net: dsa: mv88e6xxx: replace VTU violation prints with trace points
net: dsa: mv88e6xxx: replace ATU violation prints with trace points
net: dsa: mv88e6xxx: read FID when handling ATU violations
KVM: arm64: Disable interrupts while walking userspace PTs
KVM: arm64: PMU: Fix GET_ONE_REG for vPMC regs to return the current value
drm/i915: Move CSC load back into .color_commit_arm() when PSR is enabled on skl/glk
drm/i915: Disable DC states for all commits
drm/i915/dpt: Treat the DPT BO as a framebuffer
drm/i915/gem: Flush lmem contents after construction
drm/amd/display: Take FEC Overhead into Timeslot Calculation
drm/amd/display: Add DSC Support for Synaptics Cascaded MST Hub
drm/amdgpu: allow more APUs to do mode2 reset when go to S4
drm/etnaviv: fix reference leak when mmaping imported buffer
s390: reintroduce expoline dependence to scripts
s390/uaccess: add missing earlyclobber annotations to __clear_user()
dt-bindings: mtd: jedec,spi-nor: Document CPOL/CPHA support
rcu: Fix rcu_torture_read ftrace event
xtensa: fix KASAN report for show_stack
ALSA: hda/realtek: Add quirk for Lenovo ZhaoYang CF4620Z
ALSA: hda/realtek: Add quirks for some Clevo laptops
ALSA: usb-audio: Fix regression on detection of Roland VS-100
ALSA: hda/conexant: Partial revert of a quirk for Lenovo
NFSv4: Fix hangs when recovering open state after a server reboot
powerpc/64s: Fix __pte_needs_flush() false positive warning
powerpc/pseries/vas: Ignore VAS update for DLPAR if copy/paste is not enabled
powerpc: Don't try to copy PPR for task with NULL pt_regs
platform/x86: ideapad-laptop: Stop sending KEY_TOUCHPAD_TOGGLE
pinctrl: at91-pio4: fix domain name assignment
pinctrl: amd: Disable and mask interrupts on resume
modpost: Fix processing of CRCs on 32-bit build machines
net: phy: dp83869: fix default value for tx-/rx-internal-delay
xen/netback: don't do grant copy across page boundary
can: j1939: prevent deadlock by moving j1939_sk_errqueue()
dm: fix __send_duplicate_bios() to always allow for splitting IO
zonefs: Always invalidate last cached page on append write
vmxnet3: use gro callback when UPT is enabled
io_uring: fix poll/netmsg alloc caches
io_uring/rsrc: fix rogue rsrc node grabbing
io_uring/poll: clear single/double poll flags on poll arming
block/io_uring: pass in issue_flags for uring_cmd task_work handling
zonefs: Do not propagate iomap_dio_rw() ENOTBLK error to user space
btrfs: scan device in non-exclusive mode
btrfs: fix race between quota disable and quota assign ioctls
btrfs: fix deadlock when aborting transaction during relocation with scrub
Input: goodix - add Lenovo Yoga Book X90F to nine_bytes_report DMI table
Input: i8042 - add quirk for Fujitsu Lifebook A574/H
cifs: fix DFS traversal oops without CONFIG_CIFS_DFS_UPCALL
cifs: prevent infinite recursion in CIFSGetDFSRefer()
Input: focaltech - use explicitly signed char type
Input: alps - fix compatibility with -funsigned-char
Input: i8042 - add TUXEDO devices to i8042 quirk tables for partial fix
iommu/vt-d: Allow zero SAGAW if second-stage not supported
Input: xpad - fix incorrectly applied patch for MAP_PROFILE_BUTTON
pinctrl: ocelot: Fix alt mode for ocelot
net: ethernet: mtk_eth_soc: add missing ppe cache flush when deleting a flow
net: ethernet: mtk_eth_soc: fix flow block refcounting logic
net: dsa: mv88e6xxx: Enable IGMP snooping on user ports only
bnxt_en: Add missing 200G link speed reporting
bnxt_en: Fix typo in PCI id to device description string mapping
bnxt_en: Fix reporting of test result in ethtool selftest
i40e: fix registers dump after run ethtool adapter self test
net: ipa: compute DMA pool size properly
ALSA: ymfpci: Fix BUG_ON in probe function
ALSA: ymfpci: Create card with device-managed snd_devm_card_new()
ice: fix invalid check for empty list in ice_sched_assoc_vsi_to_agg()
ice: add profile conflict check for AVF FDIR
ice: Fix ice_cfg_rdma_fltr() to only update relevant fields
smsc911x: avoid PHY being resumed when interface is not up
net: mvpp2: parser fix PPPoE
net: mvpp2: parser fix QinQ
net: mvpp2: classifier flow fix fragmentation flags
loop: LOOP_CONFIGURE: send uevents for partitions
ACPI: bus: Rework system-level device notification handling
s390/vfio-ap: fix memory leak in vfio_ap device driver
can: bcm: bcm_tx_setup(): fix KMSAN uninit-value in vfs_write
platform/x86/intel/pmc: Alder Lake PCH slp_s0_residency fix
drm/i915/tc: Fix the ICL PHY ownership check in TC-cold state
net: stmmac: don't reject VLANs when IFF_PROMISC is set
net/net_failover: fix txq exceeding warning
regulator: Handle deferred clk
r8169: fix RTL8168H and RTL8107E rx crc error
net: dsa: microchip: ksz8: fix MDB configuration with non-zero VID
net: dsa: microchip: ksz8863_smi: fix bulk access
net: dsa: microchip: ksz8: ksz8_fdb_dump: avoid extracting ghost entry from empty dynamic MAC table.
net: dsa: microchip: ksz8: fix offset for the timestamp filed
net: dsa: microchip: ksz8: fix ksz8_fdb_dump() to extract all 1024 entries
net: dsa: microchip: ksz8: fix ksz8_fdb_dump()
ptp_qoriq: fix memory leak in probe()
net: dsa: realtek: fix out-of-bounds access
scsi: mpt3sas: Don't print sense pool info twice
scsi: megaraid_sas: Fix crash after a double completion
sfc: ef10: don't overwrite offload features at NIC reset
SUNRPC: fix shutdown of NFS TCP client socket
mtd: rawnand: meson: invalidate cache on polling ECC bit
platform/surface: aggregator: Add missing fwnode_handle_put()
platform/x86: think-lmi: Add possible_values for ThinkStation
platform/x86: think-lmi: only display possible_values if available
platform/x86: think-lmi: use correct possible_values delimiters
platform/x86: think-lmi: add missing type attribute
PCI: dwc: Fix PORT_LINK_CONTROL update when CDM check enabled
ALSA: usb-audio: Fix recursive locking at XRUN during syncing
mips: bmips: BCM6358: disable RAC flush for TP1
riscv/kvm: Fix VM hang in case of timer delta being zero.
ca8210: Fix unsigned mac_len comparison with zero in ca8210_skb_tx()
mtd: nand: mxic-ecc: Fix mxic_ecc_data_xfer_wait_for_completion() when irq is used
mtd: rawnand: meson: initialize struct with zeroes
btrfs: use temporary variable for space_info in btrfs_update_block_group
btrfs: fix uninitialized variable warning in btrfs_update_block_group
tracing: Fix wrong return in kprobe_event_gen_test.c
tools/power turbostat: fix decoding of HWP_STATUS
tools/power turbostat: Fix /dev/cpu_dma_latency warnings
fbdev: au1200fb: Fix potential divide by zero
fbdev: lxfb: Fix potential divide by zero
fbdev: intelfb: Fix potential divide by zero
fbdev: nvidia: Fix potential divide by zero
net/mlx5e: Lower maximum allowed MTU in XSK to match XDP prerequisites
drm/amdkfd: Fixed kfd_process cleanup on module exit.
nvme-pci: add NVME_QUIRK_BOGUS_NID for Lexar NM620
sched_getaffinity: don't assume 'cpumask_size()' is fully initialized
ACPI: tools: pfrut: Check if the input of level and type is in the right numeric range
fbdev: tgafb: Fix potential divide by zero
ALSA: hda/ca0132: fixup buffer overrun at tuning_ctl_set()
ALSA: asihpi: check pao in control_message()
net: hsr: Don't log netdev_err message on unknown prp dst node
drm/amdkfd: fix potential kgd_mem UAFs
drm/amdkfd: fix a potential double free in pqm_create_queue
drm/amdkfd: Fix BO offset for multi-VMA page migration
x86/PVH: obtain VGA console info in Dom0
md: avoid signed overflow in slot_store()
ASoC: SOF: IPC4: update gain ipc msg definition to align with fw
ASoC: SOF: Intel: pci-tng: revert invalid bar size setting
ASoC: SOF: ipc4-topology: Fix incorrect sample rate print unit
ASoC: SOF: ipc3: Check for upper size limit for the received message
ACPI: video: Add backlight=native DMI quirk for Dell Vostro 15 3535
zstd: Fix definition of assert()
ASoC: Intel: avs: nau8825: Adjust clock control
ASoC: Intel: avs: ssm4567: Remove nau8825 bits
ASoC: Intel: avs: da7219: Explicitly define codec format
ASoC: Intel: avs: max98357a: Explicitly define codec format
ASoC: codecs: tx-macro: Fix for KASAN: slab-out-of-bounds
xfrm: Zero padding when dumping algos and encap
cifs: fix missing unload_nls() in smb2_reconnect()
arm64: efi: Set NX compat flag in PE/COFF header
net: mscc: ocelot: fix stats region batching
tracing: Do not let histogram values have some modifiers
tracing: Add .graph suffix option to histogram value
tracing: Add .percent suffix option to histogram values
tty: serial: fsl_lpuart: fix race on RX DMA shutdown
tty: serial: fsl_lpuart: switch to new dmaengine_terminate_* API
drm/msm/disp/dpu: fix sc7280_pp base offset
drm/msm/dpu: correct sm8250 and sm8350 scaler
drm/msm/dpu: Refactor sc7280_pp location
ARM: dts: aspeed: p10bmc: Update battery node name
riscv: ftrace: Fixup panic by disabling preemption
net: ethernet: ti: am65-cpsw/cpts: Fix CPTS release action
btrfs: zoned: count fresh BG region as zone unusable
btrfs: rename BTRFS_FS_NO_OVERCOMMIT to BTRFS_FS_ACTIVE_ZONE_TRACKING
kcsan: avoid passing -g for test
kernel: kcsan: kcsan_test: build without structleak plugin
fsverity: don't drop pagecache at end of FS_IOC_ENABLE_VERITY
zonefs: Fix error message in zonefs_file_dio_append()
zonefs: Separate zone information from inode information
zonefs: Reduce struct zonefs_inode_info size
zonefs: Simplify IO error handling
zonefs: Reorganize code
cifs: avoid race conditions with parallel reconnects
cifs: prevent data race in cifs_reconnect_tcon()
cifs: update ip_addr for ses only for primary chan setup
thunderbolt: Limit USB3 bandwidth of certain Intel USB4 host routers
ANDROID: usb: f_accessory: Check buffer size when initialised via composite
ANDROID: MGLRU: Avoid reactivation of anon pages on swap full
FROMGIT: f2fs: fix null pointer panic in tracepoint in __replace_atomic_write_block
ANDROID: incremental fs: Evict inodes before freeing mount data
ANDROID: fsnotify: Notify lower fs of open
ANDROID: fuse-bpf: Run bpf with migration disabled
ANDROID: fuse-bpf: Do not change bpf program in lookups
FROMGIT: ASoC: codecs: lpass: fix the order or clks turn off during suspend
ANDROID: GKI: Add a filegroup instead of _aarch64_additional_kmi symbol list
UPSTREAM: wifi: nl80211: fix puncturing bitmap policy
Conflicts:
Documentation/devicetree/bindings
Documentation/devicetree/bindings/mtd/jedec,spi-nor.yaml
drivers/ufs/host/ufs-qcom.c
Change-Id: I7004221a9c748e28c3860cb57e3da9049a25481a
Signed-off-by: jianzhou <quic_jianzhou@quicinc.com>
393 lines
9.8 KiB
C
393 lines
9.8 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* fixed.c
|
|
*
|
|
* Copyright 2008 Wolfson Microelectronics PLC.
|
|
*
|
|
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
|
|
*
|
|
* Copyright (c) 2009 Nokia Corporation
|
|
* Roger Quadros <ext-roger.quadros@nokia.com>
|
|
*
|
|
* This is useful for systems with mixed controllable and
|
|
* non-controllable regulators, as well as for allowing testing on
|
|
* systems with no controllable regulators.
|
|
*/
|
|
|
|
#include <linux/err.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/module.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/pm_domain.h>
|
|
#include <linux/pm_opp.h>
|
|
#include <linux/regulator/driver.h>
|
|
#include <linux/regulator/fixed.h>
|
|
#include <linux/gpio/consumer.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_device.h>
|
|
#include <linux/regulator/of_regulator.h>
|
|
#ifdef QTI_FIXED_REGULATOR
|
|
#include <linux/regulator/debug-regulator.h>
|
|
#include <linux/regulator/proxy-consumer.h>
|
|
#endif
|
|
#include <linux/regulator/machine.h>
|
|
#include <linux/clk.h>
|
|
|
|
|
|
struct fixed_voltage_data {
|
|
struct regulator_desc desc;
|
|
struct regulator_dev *dev;
|
|
|
|
struct clk *enable_clock;
|
|
unsigned int enable_counter;
|
|
int performance_state;
|
|
};
|
|
|
|
struct fixed_dev_type {
|
|
bool has_enable_clock;
|
|
bool has_performance_state;
|
|
};
|
|
|
|
static int reg_clock_enable(struct regulator_dev *rdev)
|
|
{
|
|
struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
|
|
int ret = 0;
|
|
|
|
ret = clk_prepare_enable(priv->enable_clock);
|
|
if (ret)
|
|
return ret;
|
|
|
|
priv->enable_counter++;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int reg_clock_disable(struct regulator_dev *rdev)
|
|
{
|
|
struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
|
|
|
|
clk_disable_unprepare(priv->enable_clock);
|
|
priv->enable_counter--;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int reg_domain_enable(struct regulator_dev *rdev)
|
|
{
|
|
struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
|
|
struct device *dev = rdev->dev.parent;
|
|
int ret;
|
|
|
|
ret = dev_pm_genpd_set_performance_state(dev, priv->performance_state);
|
|
if (ret)
|
|
return ret;
|
|
|
|
priv->enable_counter++;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int reg_domain_disable(struct regulator_dev *rdev)
|
|
{
|
|
struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
|
|
struct device *dev = rdev->dev.parent;
|
|
int ret;
|
|
|
|
ret = dev_pm_genpd_set_performance_state(dev, 0);
|
|
if (ret)
|
|
return ret;
|
|
|
|
priv->enable_counter--;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int reg_is_enabled(struct regulator_dev *rdev)
|
|
{
|
|
struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
|
|
|
|
return priv->enable_counter > 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* of_get_fixed_voltage_config - extract fixed_voltage_config structure info
|
|
* @dev: device requesting for fixed_voltage_config
|
|
* @desc: regulator description
|
|
*
|
|
* Populates fixed_voltage_config structure by extracting data from device
|
|
* tree node, returns a pointer to the populated structure of NULL if memory
|
|
* alloc fails.
|
|
*/
|
|
static struct fixed_voltage_config *
|
|
of_get_fixed_voltage_config(struct device *dev,
|
|
const struct regulator_desc *desc)
|
|
{
|
|
struct fixed_voltage_config *config;
|
|
struct device_node *np = dev->of_node;
|
|
struct regulator_init_data *init_data;
|
|
|
|
config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
|
|
GFP_KERNEL);
|
|
if (!config)
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
config->init_data = of_get_regulator_init_data(dev, dev->of_node, desc);
|
|
if (!config->init_data)
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
init_data = config->init_data;
|
|
init_data->constraints.apply_uV = 0;
|
|
|
|
config->supply_name = init_data->constraints.name;
|
|
if (init_data->constraints.min_uV == init_data->constraints.max_uV) {
|
|
config->microvolts = init_data->constraints.min_uV;
|
|
} else {
|
|
dev_err(dev,
|
|
"Fixed regulator specified with variable voltages\n");
|
|
return ERR_PTR(-EINVAL);
|
|
}
|
|
|
|
if (init_data->constraints.boot_on)
|
|
config->enabled_at_boot = true;
|
|
|
|
of_property_read_u32(np, "startup-delay-us", &config->startup_delay);
|
|
of_property_read_u32(np, "off-on-delay-us", &config->off_on_delay);
|
|
|
|
if (of_find_property(np, "vin-supply", NULL))
|
|
config->input_supply = "vin";
|
|
|
|
return config;
|
|
}
|
|
|
|
static const struct regulator_ops fixed_voltage_ops = {
|
|
};
|
|
|
|
static const struct regulator_ops fixed_voltage_clkenabled_ops = {
|
|
.enable = reg_clock_enable,
|
|
.disable = reg_clock_disable,
|
|
.is_enabled = reg_is_enabled,
|
|
};
|
|
|
|
static const struct regulator_ops fixed_voltage_domain_ops = {
|
|
.enable = reg_domain_enable,
|
|
.disable = reg_domain_disable,
|
|
.is_enabled = reg_is_enabled,
|
|
};
|
|
|
|
#ifdef QTI_FIXED_REGULATOR
|
|
static void qti_reg_fixed_voltage_init(struct device *dev,
|
|
struct regulator_dev *rdev)
|
|
{
|
|
int ret;
|
|
|
|
ret = devm_regulator_proxy_consumer_register(dev, dev->of_node);
|
|
if (ret)
|
|
dev_err(dev, "failed to register proxy consumer, ret=%d\n",
|
|
ret);
|
|
|
|
ret = devm_regulator_debug_register(dev, rdev);
|
|
if (ret)
|
|
dev_err(dev, "failed to register debug regulator, ret=%d\n",
|
|
ret);
|
|
}
|
|
#endif
|
|
|
|
static int reg_fixed_voltage_probe(struct platform_device *pdev)
|
|
{
|
|
struct device *dev = &pdev->dev;
|
|
struct fixed_voltage_config *config;
|
|
struct fixed_voltage_data *drvdata;
|
|
const struct fixed_dev_type *drvtype = of_device_get_match_data(dev);
|
|
struct regulator_config cfg = { };
|
|
enum gpiod_flags gflags;
|
|
int ret;
|
|
|
|
drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data),
|
|
GFP_KERNEL);
|
|
if (!drvdata)
|
|
return -ENOMEM;
|
|
|
|
if (pdev->dev.of_node) {
|
|
config = of_get_fixed_voltage_config(&pdev->dev,
|
|
&drvdata->desc);
|
|
if (IS_ERR(config))
|
|
return PTR_ERR(config);
|
|
} else {
|
|
config = dev_get_platdata(&pdev->dev);
|
|
}
|
|
|
|
if (!config)
|
|
return -ENOMEM;
|
|
|
|
drvdata->desc.name = devm_kstrdup(&pdev->dev,
|
|
config->supply_name,
|
|
GFP_KERNEL);
|
|
if (drvdata->desc.name == NULL) {
|
|
dev_err(&pdev->dev, "Failed to allocate supply name\n");
|
|
return -ENOMEM;
|
|
}
|
|
drvdata->desc.type = REGULATOR_VOLTAGE;
|
|
drvdata->desc.owner = THIS_MODULE;
|
|
|
|
if (drvtype && drvtype->has_enable_clock) {
|
|
drvdata->desc.ops = &fixed_voltage_clkenabled_ops;
|
|
|
|
drvdata->enable_clock = devm_clk_get(dev, NULL);
|
|
if (IS_ERR(drvdata->enable_clock)) {
|
|
dev_err(dev, "Can't get enable-clock from devicetree\n");
|
|
return PTR_ERR(drvdata->enable_clock);
|
|
}
|
|
} else if (drvtype && drvtype->has_performance_state) {
|
|
drvdata->desc.ops = &fixed_voltage_domain_ops;
|
|
|
|
drvdata->performance_state = of_get_required_opp_performance_state(dev->of_node, 0);
|
|
if (drvdata->performance_state < 0) {
|
|
dev_err(dev, "Can't get performance state from devicetree\n");
|
|
return drvdata->performance_state;
|
|
}
|
|
} else {
|
|
drvdata->desc.ops = &fixed_voltage_ops;
|
|
}
|
|
|
|
drvdata->desc.enable_time = config->startup_delay;
|
|
drvdata->desc.off_on_delay = config->off_on_delay;
|
|
|
|
if (config->input_supply) {
|
|
drvdata->desc.supply_name = devm_kstrdup(&pdev->dev,
|
|
config->input_supply,
|
|
GFP_KERNEL);
|
|
if (!drvdata->desc.supply_name)
|
|
return -ENOMEM;
|
|
}
|
|
|
|
if (config->microvolts)
|
|
drvdata->desc.n_voltages = 1;
|
|
|
|
drvdata->desc.fixed_uV = config->microvolts;
|
|
|
|
/*
|
|
* The signal will be inverted by the GPIO core if flagged so in the
|
|
* descriptor.
|
|
*/
|
|
if (config->enabled_at_boot)
|
|
gflags = GPIOD_OUT_HIGH;
|
|
else
|
|
gflags = GPIOD_OUT_LOW;
|
|
|
|
/*
|
|
* Some fixed regulators share the enable line between two
|
|
* regulators which makes it necessary to get a handle on the
|
|
* same descriptor for two different consumers. This will get
|
|
* the GPIO descriptor, but only the first call will initialize
|
|
* it so any flags such as inversion or open drain will only
|
|
* be set up by the first caller and assumed identical on the
|
|
* next caller.
|
|
*
|
|
* FIXME: find a better way to deal with this.
|
|
*/
|
|
gflags |= GPIOD_FLAGS_BIT_NONEXCLUSIVE;
|
|
|
|
/*
|
|
* Do not use devm* here: the regulator core takes over the
|
|
* lifecycle management of the GPIO descriptor.
|
|
*/
|
|
cfg.ena_gpiod = gpiod_get_optional(&pdev->dev, NULL, gflags);
|
|
if (IS_ERR(cfg.ena_gpiod))
|
|
return dev_err_probe(&pdev->dev, PTR_ERR(cfg.ena_gpiod),
|
|
"can't get GPIO\n");
|
|
|
|
cfg.dev = &pdev->dev;
|
|
cfg.init_data = config->init_data;
|
|
cfg.driver_data = drvdata;
|
|
cfg.of_node = pdev->dev.of_node;
|
|
|
|
drvdata->dev = devm_regulator_register(&pdev->dev, &drvdata->desc,
|
|
&cfg);
|
|
if (IS_ERR(drvdata->dev)) {
|
|
ret = dev_err_probe(&pdev->dev, PTR_ERR(drvdata->dev),
|
|
"Failed to register regulator: %ld\n",
|
|
PTR_ERR(drvdata->dev));
|
|
return ret;
|
|
}
|
|
|
|
platform_set_drvdata(pdev, drvdata);
|
|
|
|
#ifdef QTI_FIXED_REGULATOR
|
|
qti_reg_fixed_voltage_init(dev, drvdata->dev);
|
|
#endif
|
|
|
|
dev_dbg(&pdev->dev, "%s supplying %duV\n", drvdata->desc.name,
|
|
drvdata->desc.fixed_uV);
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if defined(CONFIG_OF)
|
|
static const struct fixed_dev_type fixed_voltage_data = {
|
|
.has_enable_clock = false,
|
|
};
|
|
|
|
static const struct fixed_dev_type fixed_clkenable_data = {
|
|
.has_enable_clock = true,
|
|
};
|
|
|
|
static const struct fixed_dev_type fixed_domain_data = {
|
|
.has_performance_state = true,
|
|
};
|
|
|
|
static const struct of_device_id fixed_of_match[] = {
|
|
#ifdef QTI_FIXED_REGULATOR
|
|
{
|
|
.compatible = "qti-regulator-fixed",
|
|
.data = &fixed_voltage_data,
|
|
},
|
|
#endif
|
|
{
|
|
.compatible = "regulator-fixed",
|
|
.data = &fixed_voltage_data,
|
|
},
|
|
{
|
|
.compatible = "regulator-fixed-clock",
|
|
.data = &fixed_clkenable_data,
|
|
},
|
|
{
|
|
.compatible = "regulator-fixed-domain",
|
|
.data = &fixed_domain_data,
|
|
},
|
|
{
|
|
},
|
|
};
|
|
MODULE_DEVICE_TABLE(of, fixed_of_match);
|
|
#endif
|
|
|
|
static struct platform_driver regulator_fixed_voltage_driver = {
|
|
.probe = reg_fixed_voltage_probe,
|
|
.driver = {
|
|
#ifdef QTI_FIXED_REGULATOR
|
|
.name = "qti-reg-fixed-voltage",
|
|
.sync_state = regulator_proxy_consumer_sync_state,
|
|
#else
|
|
.name = "reg-fixed-voltage",
|
|
#endif
|
|
.of_match_table = of_match_ptr(fixed_of_match),
|
|
},
|
|
};
|
|
|
|
static int __init regulator_fixed_voltage_init(void)
|
|
{
|
|
return platform_driver_register(®ulator_fixed_voltage_driver);
|
|
}
|
|
subsys_initcall(regulator_fixed_voltage_init);
|
|
|
|
static void __exit regulator_fixed_voltage_exit(void)
|
|
{
|
|
platform_driver_unregister(®ulator_fixed_voltage_driver);
|
|
}
|
|
module_exit(regulator_fixed_voltage_exit);
|
|
|
|
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
|
MODULE_DESCRIPTION("Fixed voltage regulator");
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_ALIAS("platform:reg-fixed-voltage");
|