cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pinctrl-qdf2xxx.c (4908B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
      4 *
      5 * GPIO and pin control functions on this SOC are handled by the "TLMM"
      6 * device.  The driver which controls this device is pinctrl-msm.c.  Each
      7 * SOC with a TLMM is expected to create a client driver that registers
      8 * with pinctrl-msm.c.  This means that all TLMM drivers are pin control
      9 * drivers.
     10 *
     11 * This pin control driver is intended to be used only an ACPI-enabled
     12 * system.  As such, UEFI will handle all pin control configuration, so
     13 * this driver does not provide pin control functions.  It is effectively
     14 * a GPIO-only driver.  The alternative is to duplicate the GPIO code of
     15 * pinctrl-msm.c into another driver.
     16 */
     17
     18#include <linux/module.h>
     19#include <linux/platform_device.h>
     20#include <linux/pinctrl/pinctrl.h>
     21#include <linux/acpi.h>
     22
     23#include "pinctrl-msm.h"
     24
     25/* A maximum of 256 allows us to use a u8 array to hold the GPIO numbers */
     26#define MAX_GPIOS	256
     27
     28/* maximum size of each gpio name (enough room for "gpioXXX" + null) */
     29#define NAME_SIZE	8
     30
     31static int qdf2xxx_pinctrl_probe(struct platform_device *pdev)
     32{
     33	struct msm_pinctrl_soc_data *pinctrl;
     34	struct pinctrl_pin_desc *pins;
     35	struct msm_pingroup *groups;
     36	char (*names)[NAME_SIZE];
     37	unsigned int i;
     38	u32 num_gpios;
     39	unsigned int avail_gpios; /* The number of GPIOs we support */
     40	u8 gpios[MAX_GPIOS];      /* An array of supported GPIOs */
     41	int ret;
     42
     43	/* Query the number of GPIOs from ACPI */
     44	ret = device_property_read_u32(&pdev->dev, "num-gpios", &num_gpios);
     45	if (ret < 0) {
     46		dev_err(&pdev->dev, "missing 'num-gpios' property\n");
     47		return ret;
     48	}
     49	if (!num_gpios || num_gpios > MAX_GPIOS) {
     50		dev_err(&pdev->dev, "invalid 'num-gpios' property\n");
     51		return -ENODEV;
     52	}
     53
     54	/* The number of GPIOs in the approved list */
     55	ret = device_property_count_u8(&pdev->dev, "gpios");
     56	if (ret < 0) {
     57		dev_err(&pdev->dev, "missing 'gpios' property\n");
     58		return ret;
     59	}
     60	/*
     61	 * The number of available GPIOs should be non-zero, and no
     62	 * more than the total number of GPIOS.
     63	 */
     64	if (!ret || ret > num_gpios) {
     65		dev_err(&pdev->dev, "invalid 'gpios' property\n");
     66		return -ENODEV;
     67	}
     68	avail_gpios = ret;
     69
     70	ret = device_property_read_u8_array(&pdev->dev, "gpios", gpios,
     71					    avail_gpios);
     72	if (ret < 0) {
     73		dev_err(&pdev->dev, "could not read list of GPIOs\n");
     74		return ret;
     75	}
     76
     77	pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL);
     78	pins = devm_kcalloc(&pdev->dev, num_gpios,
     79		sizeof(struct pinctrl_pin_desc), GFP_KERNEL);
     80	groups = devm_kcalloc(&pdev->dev, num_gpios,
     81		sizeof(struct msm_pingroup), GFP_KERNEL);
     82	names = devm_kcalloc(&pdev->dev, avail_gpios, NAME_SIZE, GFP_KERNEL);
     83
     84	if (!pinctrl || !pins || !groups || !names)
     85		return -ENOMEM;
     86
     87	/*
     88	 * Initialize the array.  GPIOs not listed in the 'gpios' array
     89	 * still need a number, but nothing else.
     90	 */
     91	for (i = 0; i < num_gpios; i++) {
     92		pins[i].number = i;
     93		groups[i].pins = &pins[i].number;
     94	}
     95
     96	/* Populate the entries that are meant to be exposed as GPIOs. */
     97	for (i = 0; i < avail_gpios; i++) {
     98		unsigned int gpio = gpios[i];
     99
    100		groups[gpio].npins = 1;
    101		snprintf(names[i], NAME_SIZE, "gpio%u", gpio);
    102		pins[gpio].name = names[i];
    103		groups[gpio].name = names[i];
    104
    105		groups[gpio].ctl_reg = 0x10000 * gpio;
    106		groups[gpio].io_reg = 0x04 + 0x10000 * gpio;
    107		groups[gpio].intr_cfg_reg = 0x08 + 0x10000 * gpio;
    108		groups[gpio].intr_status_reg = 0x0c + 0x10000 * gpio;
    109		groups[gpio].intr_target_reg = 0x08 + 0x10000 * gpio;
    110
    111		groups[gpio].mux_bit = 2;
    112		groups[gpio].pull_bit = 0;
    113		groups[gpio].drv_bit = 6;
    114		groups[gpio].oe_bit = 9;
    115		groups[gpio].in_bit = 0;
    116		groups[gpio].out_bit = 1;
    117		groups[gpio].intr_enable_bit = 0;
    118		groups[gpio].intr_status_bit = 0;
    119		groups[gpio].intr_target_bit = 5;
    120		groups[gpio].intr_target_kpss_val = 1;
    121		groups[gpio].intr_raw_status_bit = 4;
    122		groups[gpio].intr_polarity_bit = 1;
    123		groups[gpio].intr_detection_bit = 2;
    124		groups[gpio].intr_detection_width = 2;
    125	}
    126
    127	pinctrl->pins = pins;
    128	pinctrl->groups = groups;
    129	pinctrl->npins = num_gpios;
    130	pinctrl->ngroups = num_gpios;
    131	pinctrl->ngpios = num_gpios;
    132
    133	return msm_pinctrl_probe(pdev, pinctrl);
    134}
    135
    136static const struct acpi_device_id qdf2xxx_acpi_ids[] = {
    137	{"QCOM8002"},
    138	{},
    139};
    140MODULE_DEVICE_TABLE(acpi, qdf2xxx_acpi_ids);
    141
    142static struct platform_driver qdf2xxx_pinctrl_driver = {
    143	.driver = {
    144		.name = "qdf2xxx-pinctrl",
    145		.acpi_match_table = ACPI_PTR(qdf2xxx_acpi_ids),
    146	},
    147	.probe = qdf2xxx_pinctrl_probe,
    148	.remove = msm_pinctrl_remove,
    149};
    150
    151static int __init qdf2xxx_pinctrl_init(void)
    152{
    153	return platform_driver_register(&qdf2xxx_pinctrl_driver);
    154}
    155arch_initcall(qdf2xxx_pinctrl_init);
    156
    157static void __exit qdf2xxx_pinctrl_exit(void)
    158{
    159	platform_driver_unregister(&qdf2xxx_pinctrl_driver);
    160}
    161module_exit(qdf2xxx_pinctrl_exit);
    162
    163MODULE_DESCRIPTION("Qualcomm Technologies QDF2xxx pin control driver");
    164MODULE_LICENSE("GPL v2");