android_kernel_samsung_sm8650/drivers/regulator/fixed.c
jianzhou 2f6c3deee2 Merge keystone/android14-6.1-keystone-qcom-release.6.1.23 (4ab5627) into msm-pineapple
* 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>
2023-04-27 23:12:59 -07:00

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(&regulator_fixed_voltage_driver);
}
subsys_initcall(regulator_fixed_voltage_init);
static void __exit regulator_fixed_voltage_exit(void)
{
platform_driver_unregister(&regulator_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");