linux/drivers/pinctrl/qcom/pinctrl-msm.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2013, Sony Mobile Communications AB.
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/firmware/qcom/qcom_scm.h>
#include <linux/reboot.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinmux.h>

#include <linux/soc/qcom/irq.h>

#include "../core.h"
#include "../pinconf.h"
#include "../pinctrl-utils.h"

#include "pinctrl-msm.h"

#define MAX_NR_GPIO
#define MAX_NR_TILES
#define PS_HOLD_OFFSET

/**
 * struct msm_pinctrl - state for a pinctrl-msm device
 * @dev:            device handle.
 * @pctrl:          pinctrl handle.
 * @chip:           gpiochip handle.
 * @desc:           pin controller descriptor
 * @restart_nb:     restart notifier block.
 * @irq:            parent irq for the TLMM irq_chip.
 * @intr_target_use_scm: route irq to application cpu using scm calls
 * @lock:           Spinlock to protect register resources as well
 *                  as msm_pinctrl data structures.
 * @enabled_irqs:   Bitmap of currently enabled irqs.
 * @dual_edge_irqs: Bitmap of irqs that need sw emulated dual edge
 *                  detection.
 * @skip_wake_irqs: Skip IRQs that are handled by wakeup interrupt controller
 * @disabled_for_mux: These IRQs were disabled because we muxed away.
 * @ever_gpio:      This bit is set the first time we mux a pin to gpio_func.
 * @soc:            Reference to soc_data of platform specific data.
 * @regs:           Base addresses for the TLMM tiles.
 * @phys_base:      Physical base address
 */
struct msm_pinctrl {};

#define MSM_ACCESSOR(name)

MSM_ACCESSOR()
MSM_ACCESSOR()
MSM_ACCESSOR()
MSM_ACCESSOR()
MSM_ACCESSOR()

static void msm_ack_intr_status(struct msm_pinctrl *pctrl,
				const struct msm_pingroup *g)
{}

static int msm_get_groups_count(struct pinctrl_dev *pctldev)
{}

static const char *msm_get_group_name(struct pinctrl_dev *pctldev,
				      unsigned group)
{}

static int msm_get_group_pins(struct pinctrl_dev *pctldev,
			      unsigned group,
			      const unsigned **pins,
			      unsigned *num_pins)
{}

static const struct pinctrl_ops msm_pinctrl_ops =;

static int msm_pinmux_request(struct pinctrl_dev *pctldev, unsigned offset)
{}

static int msm_get_functions_count(struct pinctrl_dev *pctldev)
{}

static const char *msm_get_function_name(struct pinctrl_dev *pctldev,
					 unsigned function)
{}

static int msm_get_function_groups(struct pinctrl_dev *pctldev,
				   unsigned function,
				   const char * const **groups,
				   unsigned * const num_groups)
{}

static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
			      unsigned function,
			      unsigned group)
{}

static int msm_pinmux_request_gpio(struct pinctrl_dev *pctldev,
				   struct pinctrl_gpio_range *range,
				   unsigned offset)
{}

static const struct pinmux_ops msm_pinmux_ops =;

static int msm_config_reg(struct msm_pinctrl *pctrl,
			  const struct msm_pingroup *g,
			  unsigned param,
			  unsigned *mask,
			  unsigned *bit)
{}

#define MSM_NO_PULL
#define MSM_PULL_DOWN
#define MSM_KEEPER
#define MSM_PULL_UP_NO_KEEPER
#define MSM_PULL_UP
#define MSM_I2C_STRONG_PULL_UP

static unsigned msm_regval_to_drive(u32 val)
{}

static int msm_config_group_get(struct pinctrl_dev *pctldev,
				unsigned int group,
				unsigned long *config)
{}

static int msm_config_group_set(struct pinctrl_dev *pctldev,
				unsigned group,
				unsigned long *configs,
				unsigned num_configs)
{}

static const struct pinconf_ops msm_pinconf_ops =;

static int msm_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{}

static int msm_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value)
{}

static int msm_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
{}

static int msm_gpio_get(struct gpio_chip *chip, unsigned offset)
{}

static void msm_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{}

#ifdef CONFIG_DEBUG_FS

static void msm_gpio_dbg_show_one(struct seq_file *s,
				  struct pinctrl_dev *pctldev,
				  struct gpio_chip *chip,
				  unsigned offset,
				  unsigned gpio)
{}

static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
{}

#else
#define msm_gpio_dbg_show
#endif

static int msm_gpio_init_valid_mask(struct gpio_chip *gc,
				    unsigned long *valid_mask,
				    unsigned int ngpios)
{}

static const struct gpio_chip msm_gpio_template =;

/* For dual-edge interrupts in software, since some hardware has no
 * such support:
 *
 * At appropriate moments, this function may be called to flip the polarity
 * settings of both-edge irq lines to try and catch the next edge.
 *
 * The attempt is considered successful if:
 * - the status bit goes high, indicating that an edge was caught, or
 * - the input value of the gpio doesn't change during the attempt.
 * If the value changes twice during the process, that would cause the first
 * test to fail but would force the second, as two opposite
 * transitions would cause a detection no matter the polarity setting.
 *
 * The do-loop tries to sledge-hammer closed the timing hole between
 * the initial value-read and the polarity-write - if the line value changes
 * during that window, an interrupt is lost, the new polarity setting is
 * incorrect, and the first success test will fail, causing a retry.
 *
 * Algorithm comes from Google's msmgpio driver.
 */
static void msm_gpio_update_dual_edge_pos(struct msm_pinctrl *pctrl,
					  const struct msm_pingroup *g,
					  struct irq_data *d)
{}

static void msm_gpio_irq_mask(struct irq_data *d)
{}

static void msm_gpio_irq_unmask(struct irq_data *d)
{}

static void msm_gpio_irq_enable(struct irq_data *d)
{}

static void msm_gpio_irq_disable(struct irq_data *d)
{}

/**
 * msm_gpio_update_dual_edge_parent() - Prime next edge for IRQs handled by parent.
 * @d: The irq dta.
 *
 * This is much like msm_gpio_update_dual_edge_pos() but for IRQs that are
 * normally handled by the parent irqchip.  The logic here is slightly
 * different due to what's easy to do with our parent, but in principle it's
 * the same.
 */
static void msm_gpio_update_dual_edge_parent(struct irq_data *d)
{}

static void msm_gpio_irq_ack(struct irq_data *d)
{}

static void msm_gpio_irq_eoi(struct irq_data *d)
{}

static bool msm_gpio_needs_dual_edge_parent_workaround(struct irq_data *d,
						       unsigned int type)
{}

static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{}

static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{}

static int msm_gpio_irq_reqres(struct irq_data *d)
{}

static void msm_gpio_irq_relres(struct irq_data *d)
{}

static int msm_gpio_irq_set_affinity(struct irq_data *d,
				const struct cpumask *dest, bool force)
{}

static int msm_gpio_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
{}

static void msm_gpio_irq_handler(struct irq_desc *desc)
{}

static int msm_gpio_wakeirq(struct gpio_chip *gc,
			    unsigned int child,
			    unsigned int child_type,
			    unsigned int *parent,
			    unsigned int *parent_type)
{}

static bool msm_gpio_needs_valid_mask(struct msm_pinctrl *pctrl)
{}

static const struct irq_chip msm_gpio_irq_chip =;

static int msm_gpio_init(struct msm_pinctrl *pctrl)
{}

static int msm_ps_hold_restart(struct notifier_block *nb, unsigned long action,
			       void *data)
{}

static struct msm_pinctrl *poweroff_pctrl;

static void msm_ps_hold_poweroff(void)
{}

static void msm_pinctrl_setup_pm_reset(struct msm_pinctrl *pctrl)
{}

static __maybe_unused int msm_pinctrl_suspend(struct device *dev)
{}

static __maybe_unused int msm_pinctrl_resume(struct device *dev)
{}

SIMPLE_DEV_PM_OPS(msm_pinctrl_dev_pm_ops, msm_pinctrl_suspend,
		  msm_pinctrl_resume);

EXPORT_SYMBOL();

int msm_pinctrl_probe(struct platform_device *pdev,
		      const struct msm_pinctrl_soc_data *soc_data)
{}
EXPORT_SYMBOL();

void msm_pinctrl_remove(struct platform_device *pdev)
{}
EXPORT_SYMBOL();

MODULE_DESCRIPTION();
MODULE_LICENSE();