2f6c3deee2
* 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>
394 lines
9.8 KiB
C
394 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");
|