brintos

brintos / linux-shallow public Read only

0
0
Text · 21.8 KiB · 9cd5247 Raw
877 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2015, Sony Mobile Communications AB.4 * Copyright (c) 2013, The Linux Foundation. All rights reserved.5 */6 7#include <linux/gpio/driver.h>8#include <linux/interrupt.h>9#include <linux/module.h>10#include <linux/of.h>11#include <linux/of_irq.h>12#include <linux/platform_device.h>13#include <linux/regmap.h>14#include <linux/seq_file.h>15#include <linux/slab.h>16 17#include <linux/pinctrl/pinconf-generic.h>18#include <linux/pinctrl/pinconf.h>19#include <linux/pinctrl/pinctrl.h>20#include <linux/pinctrl/pinmux.h>21 22#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>23 24#include "../core.h"25#include "../pinctrl-utils.h"26 27/* mode */28#define PM8XXX_GPIO_MODE_ENABLED	BIT(0)29#define PM8XXX_GPIO_MODE_INPUT		030#define PM8XXX_GPIO_MODE_OUTPUT		231 32/* output buffer */33#define PM8XXX_GPIO_PUSH_PULL		034#define PM8XXX_GPIO_OPEN_DRAIN		135 36/* bias */37#define PM8XXX_GPIO_BIAS_PU_30		038#define PM8XXX_GPIO_BIAS_PU_1P5		139#define PM8XXX_GPIO_BIAS_PU_31P5	240#define PM8XXX_GPIO_BIAS_PU_1P5_30	341#define PM8XXX_GPIO_BIAS_PD		442#define PM8XXX_GPIO_BIAS_NP		543 44/* GPIO registers */45#define SSBI_REG_ADDR_GPIO_BASE		0x15046#define SSBI_REG_ADDR_GPIO(n)		(SSBI_REG_ADDR_GPIO_BASE + n)47 48#define PM8XXX_BANK_WRITE		BIT(7)49 50#define PM8XXX_MAX_GPIOS               4451 52#define PM8XXX_GPIO_PHYSICAL_OFFSET	153 54/* custom pinconf parameters */55#define PM8XXX_QCOM_DRIVE_STRENGH      (PIN_CONFIG_END + 1)56#define PM8XXX_QCOM_PULL_UP_STRENGTH   (PIN_CONFIG_END + 2)57 58/**59 * struct pm8xxx_pin_data - dynamic configuration for a pin60 * @reg:               address of the control register61 * @power_source:      logical selected voltage source, mapping in static data62 *                     is used translate to register values63 * @mode:              operating mode for the pin (input/output)64 * @open_drain:        output buffer configured as open-drain (vs push-pull)65 * @output_value:      configured output value66 * @bias:              register view of configured bias67 * @pull_up_strength:  placeholder for selected pull up strength68 *                     only used to configure bias when pull up is selected69 * @output_strength:   selector of output-strength70 * @disable:           pin disabled / configured as tristate71 * @function:          pinmux selector72 * @inverted:          pin logic is inverted73 */74struct pm8xxx_pin_data {75	unsigned reg;76	u8 power_source;77	u8 mode;78	bool open_drain;79	bool output_value;80	u8 bias;81	u8 pull_up_strength;82	u8 output_strength;83	bool disable;84	u8 function;85	bool inverted;86};87 88struct pm8xxx_gpio {89	struct device *dev;90	struct regmap *regmap;91	struct pinctrl_dev *pctrl;92	struct gpio_chip chip;93 94	struct pinctrl_desc desc;95	unsigned npins;96};97 98static const struct pinconf_generic_params pm8xxx_gpio_bindings[] = {99	{"qcom,drive-strength",		PM8XXX_QCOM_DRIVE_STRENGH,	0},100	{"qcom,pull-up-strength",	PM8XXX_QCOM_PULL_UP_STRENGTH,	0},101};102 103#ifdef CONFIG_DEBUG_FS104static const struct pin_config_item pm8xxx_conf_items[ARRAY_SIZE(pm8xxx_gpio_bindings)] = {105	PCONFDUMP(PM8XXX_QCOM_DRIVE_STRENGH, "drive-strength", NULL, true),106	PCONFDUMP(PM8XXX_QCOM_PULL_UP_STRENGTH,  "pull up strength", NULL, true),107};108#endif109 110static const char * const pm8xxx_groups[PM8XXX_MAX_GPIOS] = {111	"gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", "gpio8",112	"gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", "gpio15",113	"gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", "gpio22",114	"gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", "gpio29",115	"gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", "gpio36",116	"gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", "gpio43",117	"gpio44",118};119 120static const char * const pm8xxx_gpio_functions[] = {121	PMIC_GPIO_FUNC_NORMAL, PMIC_GPIO_FUNC_PAIRED,122	PMIC_GPIO_FUNC_FUNC1, PMIC_GPIO_FUNC_FUNC2,123	PMIC_GPIO_FUNC_DTEST1, PMIC_GPIO_FUNC_DTEST2,124	PMIC_GPIO_FUNC_DTEST3, PMIC_GPIO_FUNC_DTEST4,125};126 127static int pm8xxx_read_bank(struct pm8xxx_gpio *pctrl,128			    struct pm8xxx_pin_data *pin, int bank)129{130	unsigned int val = bank << 4;131	int ret;132 133	ret = regmap_write(pctrl->regmap, pin->reg, val);134	if (ret) {135		dev_err(pctrl->dev, "failed to select bank %d\n", bank);136		return ret;137	}138 139	ret = regmap_read(pctrl->regmap, pin->reg, &val);140	if (ret) {141		dev_err(pctrl->dev, "failed to read register %d\n", bank);142		return ret;143	}144 145	return val;146}147 148static int pm8xxx_write_bank(struct pm8xxx_gpio *pctrl,149			     struct pm8xxx_pin_data *pin,150			     int bank,151			     u8 val)152{153	int ret;154 155	val |= PM8XXX_BANK_WRITE;156	val |= bank << 4;157 158	ret = regmap_write(pctrl->regmap, pin->reg, val);159	if (ret)160		dev_err(pctrl->dev, "failed to write register\n");161 162	return ret;163}164 165static int pm8xxx_get_groups_count(struct pinctrl_dev *pctldev)166{167	struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);168 169	return pctrl->npins;170}171 172static const char *pm8xxx_get_group_name(struct pinctrl_dev *pctldev,173					 unsigned group)174{175	return pm8xxx_groups[group];176}177 178 179static int pm8xxx_get_group_pins(struct pinctrl_dev *pctldev,180				 unsigned group,181				 const unsigned **pins,182				 unsigned *num_pins)183{184	struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);185 186	*pins = &pctrl->desc.pins[group].number;187	*num_pins = 1;188 189	return 0;190}191 192static const struct pinctrl_ops pm8xxx_pinctrl_ops = {193	.get_groups_count	= pm8xxx_get_groups_count,194	.get_group_name		= pm8xxx_get_group_name,195	.get_group_pins         = pm8xxx_get_group_pins,196	.dt_node_to_map		= pinconf_generic_dt_node_to_map_group,197	.dt_free_map		= pinctrl_utils_free_map,198};199 200static int pm8xxx_get_functions_count(struct pinctrl_dev *pctldev)201{202	return ARRAY_SIZE(pm8xxx_gpio_functions);203}204 205static const char *pm8xxx_get_function_name(struct pinctrl_dev *pctldev,206					    unsigned function)207{208	return pm8xxx_gpio_functions[function];209}210 211static int pm8xxx_get_function_groups(struct pinctrl_dev *pctldev,212				      unsigned function,213				      const char * const **groups,214				      unsigned * const num_groups)215{216	struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);217 218	*groups = pm8xxx_groups;219	*num_groups = pctrl->npins;220	return 0;221}222 223static int pm8xxx_pinmux_set_mux(struct pinctrl_dev *pctldev,224				 unsigned function,225				 unsigned group)226{227	struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);228	struct pm8xxx_pin_data *pin = pctrl->desc.pins[group].drv_data;229	u8 val;230 231	pin->function = function;232	val = pin->function << 1;233 234	pm8xxx_write_bank(pctrl, pin, 4, val);235 236	return 0;237}238 239static const struct pinmux_ops pm8xxx_pinmux_ops = {240	.get_functions_count	= pm8xxx_get_functions_count,241	.get_function_name	= pm8xxx_get_function_name,242	.get_function_groups	= pm8xxx_get_function_groups,243	.set_mux		= pm8xxx_pinmux_set_mux,244};245 246static int pm8xxx_pin_config_get(struct pinctrl_dev *pctldev,247				 unsigned int offset,248				 unsigned long *config)249{250	struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);251	struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;252	unsigned param = pinconf_to_config_param(*config);253	unsigned arg;254 255	switch (param) {256	case PIN_CONFIG_BIAS_DISABLE:257		if (pin->bias != PM8XXX_GPIO_BIAS_NP)258			return -EINVAL;259		arg = 1;260		break;261	case PIN_CONFIG_BIAS_PULL_DOWN:262		if (pin->bias != PM8XXX_GPIO_BIAS_PD)263			return -EINVAL;264		arg = 1;265		break;266	case PIN_CONFIG_BIAS_PULL_UP:267		if (pin->bias > PM8XXX_GPIO_BIAS_PU_1P5_30)268			return -EINVAL;269		arg = 1;270		break;271	case PM8XXX_QCOM_PULL_UP_STRENGTH:272		arg = pin->pull_up_strength;273		break;274	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:275		if (!pin->disable)276			return -EINVAL;277		arg = 1;278		break;279	case PIN_CONFIG_INPUT_ENABLE:280		if (pin->mode != PM8XXX_GPIO_MODE_INPUT)281			return -EINVAL;282		arg = 1;283		break;284	case PIN_CONFIG_OUTPUT:285		if (pin->mode & PM8XXX_GPIO_MODE_OUTPUT)286			arg = pin->output_value;287		else288			arg = 0;289		break;290	case PIN_CONFIG_POWER_SOURCE:291		arg = pin->power_source;292		break;293	case PM8XXX_QCOM_DRIVE_STRENGH:294		arg = pin->output_strength;295		break;296	case PIN_CONFIG_DRIVE_PUSH_PULL:297		if (pin->open_drain)298			return -EINVAL;299		arg = 1;300		break;301	case PIN_CONFIG_DRIVE_OPEN_DRAIN:302		if (!pin->open_drain)303			return -EINVAL;304		arg = 1;305		break;306	default:307		return -EINVAL;308	}309 310	*config = pinconf_to_config_packed(param, arg);311 312	return 0;313}314 315static int pm8xxx_pin_config_set(struct pinctrl_dev *pctldev,316				 unsigned int offset,317				 unsigned long *configs,318				 unsigned num_configs)319{320	struct pm8xxx_gpio *pctrl = pinctrl_dev_get_drvdata(pctldev);321	struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;322	unsigned param;323	unsigned arg;324	unsigned i;325	u8 banks = 0;326	u8 val;327 328	for (i = 0; i < num_configs; i++) {329		param = pinconf_to_config_param(configs[i]);330		arg = pinconf_to_config_argument(configs[i]);331 332		switch (param) {333		case PIN_CONFIG_BIAS_DISABLE:334			pin->bias = PM8XXX_GPIO_BIAS_NP;335			banks |= BIT(2);336			pin->disable = 0;337			banks |= BIT(3);338			break;339		case PIN_CONFIG_BIAS_PULL_DOWN:340			pin->bias = PM8XXX_GPIO_BIAS_PD;341			banks |= BIT(2);342			pin->disable = 0;343			banks |= BIT(3);344			break;345		case PM8XXX_QCOM_PULL_UP_STRENGTH:346			if (arg > PM8XXX_GPIO_BIAS_PU_1P5_30) {347				dev_err(pctrl->dev, "invalid pull-up strength\n");348				return -EINVAL;349			}350			pin->pull_up_strength = arg;351			fallthrough;352		case PIN_CONFIG_BIAS_PULL_UP:353			pin->bias = pin->pull_up_strength;354			banks |= BIT(2);355			pin->disable = 0;356			banks |= BIT(3);357			break;358		case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:359			pin->disable = 1;360			banks |= BIT(3);361			break;362		case PIN_CONFIG_INPUT_ENABLE:363			pin->mode = PM8XXX_GPIO_MODE_INPUT;364			banks |= BIT(0) | BIT(1);365			break;366		case PIN_CONFIG_OUTPUT:367			pin->mode = PM8XXX_GPIO_MODE_OUTPUT;368			pin->output_value = !!arg;369			banks |= BIT(0) | BIT(1);370			break;371		case PIN_CONFIG_POWER_SOURCE:372			pin->power_source = arg;373			banks |= BIT(0);374			break;375		case PM8XXX_QCOM_DRIVE_STRENGH:376			if (arg > PMIC_GPIO_STRENGTH_LOW) {377				dev_err(pctrl->dev, "invalid drive strength\n");378				return -EINVAL;379			}380			pin->output_strength = arg;381			banks |= BIT(3);382			break;383		case PIN_CONFIG_DRIVE_PUSH_PULL:384			pin->open_drain = 0;385			banks |= BIT(1);386			break;387		case PIN_CONFIG_DRIVE_OPEN_DRAIN:388			pin->open_drain = 1;389			banks |= BIT(1);390			break;391		default:392			dev_err(pctrl->dev,393				"unsupported config parameter: %x\n",394				param);395			return -EINVAL;396		}397	}398 399	if (banks & BIT(0)) {400		val = pin->power_source << 1;401		val |= PM8XXX_GPIO_MODE_ENABLED;402		pm8xxx_write_bank(pctrl, pin, 0, val);403	}404 405	if (banks & BIT(1)) {406		val = pin->mode << 2;407		val |= pin->open_drain << 1;408		val |= pin->output_value;409		pm8xxx_write_bank(pctrl, pin, 1, val);410	}411 412	if (banks & BIT(2)) {413		val = pin->bias << 1;414		pm8xxx_write_bank(pctrl, pin, 2, val);415	}416 417	if (banks & BIT(3)) {418		val = pin->output_strength << 2;419		val |= pin->disable;420		pm8xxx_write_bank(pctrl, pin, 3, val);421	}422 423	if (banks & BIT(4)) {424		val = pin->function << 1;425		pm8xxx_write_bank(pctrl, pin, 4, val);426	}427 428	if (banks & BIT(5)) {429		val = 0;430		if (!pin->inverted)431			val |= BIT(3);432		pm8xxx_write_bank(pctrl, pin, 5, val);433	}434 435	return 0;436}437 438static const struct pinconf_ops pm8xxx_pinconf_ops = {439	.is_generic = true,440	.pin_config_group_get = pm8xxx_pin_config_get,441	.pin_config_group_set = pm8xxx_pin_config_set,442};443 444static const struct pinctrl_desc pm8xxx_pinctrl_desc = {445	.name = "pm8xxx_gpio",446	.pctlops = &pm8xxx_pinctrl_ops,447	.pmxops = &pm8xxx_pinmux_ops,448	.confops = &pm8xxx_pinconf_ops,449	.owner = THIS_MODULE,450};451 452static int pm8xxx_gpio_direction_input(struct gpio_chip *chip,453				       unsigned offset)454{455	struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);456	struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;457	u8 val;458 459	pin->mode = PM8XXX_GPIO_MODE_INPUT;460	val = pin->mode << 2;461 462	pm8xxx_write_bank(pctrl, pin, 1, val);463 464	return 0;465}466 467static int pm8xxx_gpio_direction_output(struct gpio_chip *chip,468					unsigned offset,469					int value)470{471	struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);472	struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;473	u8 val;474 475	pin->mode = PM8XXX_GPIO_MODE_OUTPUT;476	pin->output_value = !!value;477 478	val = pin->mode << 2;479	val |= pin->open_drain << 1;480	val |= pin->output_value;481 482	pm8xxx_write_bank(pctrl, pin, 1, val);483 484	return 0;485}486 487static int pm8xxx_gpio_get(struct gpio_chip *chip, unsigned offset)488{489	struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);490	struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;491	int ret, irq;492	bool state;493 494	if (pin->mode == PM8XXX_GPIO_MODE_OUTPUT)495		return pin->output_value;496 497	irq = chip->to_irq(chip, offset);498	if (irq >= 0) {499		ret = irq_get_irqchip_state(irq, IRQCHIP_STATE_LINE_LEVEL,500					    &state);501		if (!ret)502			ret = !!state;503	} else504		ret = -EINVAL;505 506	return ret;507}508 509static void pm8xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int value)510{511	struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);512	struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;513	u8 val;514 515	pin->output_value = !!value;516 517	val = pin->mode << 2;518	val |= pin->open_drain << 1;519	val |= pin->output_value;520 521	pm8xxx_write_bank(pctrl, pin, 1, val);522}523 524static int pm8xxx_gpio_of_xlate(struct gpio_chip *chip,525				const struct of_phandle_args *gpio_desc,526				u32 *flags)527{528	if (chip->of_gpio_n_cells < 2)529		return -EINVAL;530 531	if (flags)532		*flags = gpio_desc->args[1];533 534	return gpio_desc->args[0] - PM8XXX_GPIO_PHYSICAL_OFFSET;535}536 537 538#ifdef CONFIG_DEBUG_FS539 540static void pm8xxx_gpio_dbg_show_one(struct seq_file *s,541				  struct pinctrl_dev *pctldev,542				  struct gpio_chip *chip,543				  unsigned offset,544				  unsigned gpio)545{546	struct pm8xxx_gpio *pctrl = gpiochip_get_data(chip);547	struct pm8xxx_pin_data *pin = pctrl->desc.pins[offset].drv_data;548 549	static const char * const modes[] = {550		"in", "both", "out", "off"551	};552	static const char * const biases[] = {553		"pull-up 30uA", "pull-up 1.5uA", "pull-up 31.5uA",554		"pull-up 1.5uA + 30uA boost", "pull-down 10uA", "no pull"555	};556	static const char * const buffer_types[] = {557		"push-pull", "open-drain"558	};559	static const char * const strengths[] = {560		"no", "high", "medium", "low"561	};562 563	seq_printf(s, " gpio%-2d:", offset + PM8XXX_GPIO_PHYSICAL_OFFSET);564	if (pin->disable) {565		seq_puts(s, " ---");566	} else {567		seq_printf(s, " %-4s", modes[pin->mode]);568		seq_printf(s, " %-7s", pm8xxx_gpio_functions[pin->function]);569		seq_printf(s, " VIN%d", pin->power_source);570		seq_printf(s, " %-27s", biases[pin->bias]);571		seq_printf(s, " %-10s", buffer_types[pin->open_drain]);572		seq_printf(s, " %-4s", pin->output_value ? "high" : "low");573		seq_printf(s, " %-7s", strengths[pin->output_strength]);574		if (pin->inverted)575			seq_puts(s, " inverted");576	}577}578 579static void pm8xxx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)580{581	unsigned gpio = chip->base;582	unsigned i;583 584	for (i = 0; i < chip->ngpio; i++, gpio++) {585		pm8xxx_gpio_dbg_show_one(s, NULL, chip, i, gpio);586		seq_puts(s, "\n");587	}588}589 590#else591#define pm8xxx_gpio_dbg_show NULL592#endif593 594static const struct gpio_chip pm8xxx_gpio_template = {595	.direction_input = pm8xxx_gpio_direction_input,596	.direction_output = pm8xxx_gpio_direction_output,597	.get = pm8xxx_gpio_get,598	.set = pm8xxx_gpio_set,599	.of_xlate = pm8xxx_gpio_of_xlate,600	.dbg_show = pm8xxx_gpio_dbg_show,601	.owner = THIS_MODULE,602};603 604static int pm8xxx_pin_populate(struct pm8xxx_gpio *pctrl,605			       struct pm8xxx_pin_data *pin)606{607	int val;608 609	val = pm8xxx_read_bank(pctrl, pin, 0);610	if (val < 0)611		return val;612 613	pin->power_source = (val >> 1) & 0x7;614 615	val = pm8xxx_read_bank(pctrl, pin, 1);616	if (val < 0)617		return val;618 619	pin->mode = (val >> 2) & 0x3;620	pin->open_drain = !!(val & BIT(1));621	pin->output_value = val & BIT(0);622 623	val = pm8xxx_read_bank(pctrl, pin, 2);624	if (val < 0)625		return val;626 627	pin->bias = (val >> 1) & 0x7;628	if (pin->bias <= PM8XXX_GPIO_BIAS_PU_1P5_30)629		pin->pull_up_strength = pin->bias;630	else631		pin->pull_up_strength = PM8XXX_GPIO_BIAS_PU_30;632 633	val = pm8xxx_read_bank(pctrl, pin, 3);634	if (val < 0)635		return val;636 637	pin->output_strength = (val >> 2) & 0x3;638	pin->disable = val & BIT(0);639 640	val = pm8xxx_read_bank(pctrl, pin, 4);641	if (val < 0)642		return val;643 644	pin->function = (val >> 1) & 0x7;645 646	val = pm8xxx_read_bank(pctrl, pin, 5);647	if (val < 0)648		return val;649 650	pin->inverted = !(val & BIT(3));651 652	return 0;653}654 655static void pm8xxx_irq_disable(struct irq_data *d)656{657	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);658 659	gpiochip_disable_irq(gc, irqd_to_hwirq(d));660}661 662static void pm8xxx_irq_enable(struct irq_data *d)663{664	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);665 666	gpiochip_enable_irq(gc, irqd_to_hwirq(d));667}668 669static const struct irq_chip pm8xxx_irq_chip = {670	.name = "ssbi-gpio",671	.irq_mask_ack = irq_chip_mask_ack_parent,672	.irq_unmask = irq_chip_unmask_parent,673	.irq_disable = pm8xxx_irq_disable,674	.irq_enable = pm8xxx_irq_enable,675	.irq_set_type = irq_chip_set_type_parent,676	.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE |677		IRQCHIP_IMMUTABLE,678	GPIOCHIP_IRQ_RESOURCE_HELPERS,679};680 681static int pm8xxx_domain_translate(struct irq_domain *domain,682				   struct irq_fwspec *fwspec,683				   unsigned long *hwirq,684				   unsigned int *type)685{686	struct pm8xxx_gpio *pctrl = container_of(domain->host_data,687						 struct pm8xxx_gpio, chip);688 689	if (fwspec->param_count != 2 || fwspec->param[0] < 1 ||690	    fwspec->param[0] > pctrl->chip.ngpio)691		return -EINVAL;692 693	*hwirq = fwspec->param[0] - PM8XXX_GPIO_PHYSICAL_OFFSET;694	*type = fwspec->param[1];695 696	return 0;697}698 699static unsigned int pm8xxx_child_offset_to_irq(struct gpio_chip *chip,700					       unsigned int offset)701{702	return offset + PM8XXX_GPIO_PHYSICAL_OFFSET;703}704 705static int pm8xxx_child_to_parent_hwirq(struct gpio_chip *chip,706					unsigned int child_hwirq,707					unsigned int child_type,708					unsigned int *parent_hwirq,709					unsigned int *parent_type)710{711	*parent_hwirq = child_hwirq + 0xc0;712	*parent_type = child_type;713 714	return 0;715}716 717static const struct of_device_id pm8xxx_gpio_of_match[] = {718	{ .compatible = "qcom,pm8018-gpio", .data = (void *) 6 },719	{ .compatible = "qcom,pm8038-gpio", .data = (void *) 12 },720	{ .compatible = "qcom,pm8058-gpio", .data = (void *) 44 },721	{ .compatible = "qcom,pm8917-gpio", .data = (void *) 38 },722	{ .compatible = "qcom,pm8921-gpio", .data = (void *) 44 },723	{ },724};725MODULE_DEVICE_TABLE(of, pm8xxx_gpio_of_match);726 727static int pm8xxx_gpio_probe(struct platform_device *pdev)728{729	struct pm8xxx_pin_data *pin_data;730	struct irq_domain *parent_domain;731	struct device_node *parent_node;732	struct pinctrl_pin_desc *pins;733	struct gpio_irq_chip *girq;734	struct pm8xxx_gpio *pctrl;735	int ret, i;736 737	pctrl = devm_kzalloc(&pdev->dev, sizeof(*pctrl), GFP_KERNEL);738	if (!pctrl)739		return -ENOMEM;740 741	pctrl->dev = &pdev->dev;742	pctrl->npins = (uintptr_t) device_get_match_data(&pdev->dev);743 744	pctrl->regmap = dev_get_regmap(pdev->dev.parent, NULL);745	if (!pctrl->regmap) {746		dev_err(&pdev->dev, "parent regmap unavailable\n");747		return -ENXIO;748	}749 750	pctrl->desc = pm8xxx_pinctrl_desc;751	pctrl->desc.npins = pctrl->npins;752 753	pins = devm_kcalloc(&pdev->dev,754			    pctrl->desc.npins,755			    sizeof(struct pinctrl_pin_desc),756			    GFP_KERNEL);757	if (!pins)758		return -ENOMEM;759 760	pin_data = devm_kcalloc(&pdev->dev,761				pctrl->desc.npins,762				sizeof(struct pm8xxx_pin_data),763				GFP_KERNEL);764	if (!pin_data)765		return -ENOMEM;766 767	for (i = 0; i < pctrl->desc.npins; i++) {768		pin_data[i].reg = SSBI_REG_ADDR_GPIO(i);769 770		ret = pm8xxx_pin_populate(pctrl, &pin_data[i]);771		if (ret)772			return ret;773 774		pins[i].number = i;775		pins[i].name = pm8xxx_groups[i];776		pins[i].drv_data = &pin_data[i];777	}778	pctrl->desc.pins = pins;779 780	pctrl->desc.num_custom_params = ARRAY_SIZE(pm8xxx_gpio_bindings);781	pctrl->desc.custom_params = pm8xxx_gpio_bindings;782#ifdef CONFIG_DEBUG_FS783	pctrl->desc.custom_conf_items = pm8xxx_conf_items;784#endif785 786	pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl);787	if (IS_ERR(pctrl->pctrl)) {788		dev_err(&pdev->dev, "couldn't register pm8xxx gpio driver\n");789		return PTR_ERR(pctrl->pctrl);790	}791 792	pctrl->chip = pm8xxx_gpio_template;793	pctrl->chip.base = -1;794	pctrl->chip.parent = &pdev->dev;795	pctrl->chip.of_gpio_n_cells = 2;796	pctrl->chip.label = dev_name(pctrl->dev);797	pctrl->chip.ngpio = pctrl->npins;798 799	parent_node = of_irq_find_parent(pctrl->dev->of_node);800	if (!parent_node)801		return -ENXIO;802 803	parent_domain = irq_find_host(parent_node);804	of_node_put(parent_node);805	if (!parent_domain)806		return -ENXIO;807 808	girq = &pctrl->chip.irq;809	gpio_irq_chip_set_chip(girq, &pm8xxx_irq_chip);810	girq->default_type = IRQ_TYPE_NONE;811	girq->handler = handle_level_irq;812	girq->fwnode = dev_fwnode(pctrl->dev);813	girq->parent_domain = parent_domain;814	girq->child_to_parent_hwirq = pm8xxx_child_to_parent_hwirq;815	girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell;816	girq->child_offset_to_irq = pm8xxx_child_offset_to_irq;817	girq->child_irq_domain_ops.translate = pm8xxx_domain_translate;818 819	ret = gpiochip_add_data(&pctrl->chip, pctrl);820	if (ret) {821		dev_err(&pdev->dev, "failed register gpiochip\n");822		return ret;823	}824 825	/*826	 * For DeviceTree-supported systems, the gpio core checks the827	 * pinctrl's device node for the "gpio-ranges" property.828	 * If it is present, it takes care of adding the pin ranges829	 * for the driver. In this case the driver can skip ahead.830	 *831	 * In order to remain compatible with older, existing DeviceTree832	 * files which don't set the "gpio-ranges" property or systems that833	 * utilize ACPI the driver has to call gpiochip_add_pin_range().834	 */835	if (!of_property_read_bool(pctrl->dev->of_node, "gpio-ranges")) {836		ret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),837					     0, 0, pctrl->chip.ngpio);838		if (ret) {839			dev_err(pctrl->dev, "failed to add pin range\n");840			goto unregister_gpiochip;841		}842	}843 844	platform_set_drvdata(pdev, pctrl);845 846	dev_dbg(&pdev->dev, "Qualcomm pm8xxx gpio driver probed\n");847 848	return 0;849 850unregister_gpiochip:851	gpiochip_remove(&pctrl->chip);852 853	return ret;854}855 856static void pm8xxx_gpio_remove(struct platform_device *pdev)857{858	struct pm8xxx_gpio *pctrl = platform_get_drvdata(pdev);859 860	gpiochip_remove(&pctrl->chip);861}862 863static struct platform_driver pm8xxx_gpio_driver = {864	.driver = {865		.name = "qcom-ssbi-gpio",866		.of_match_table = pm8xxx_gpio_of_match,867	},868	.probe = pm8xxx_gpio_probe,869	.remove_new = pm8xxx_gpio_remove,870};871 872module_platform_driver(pm8xxx_gpio_driver);873 874MODULE_AUTHOR("Bjorn Andersson <bjorn.andersson@sonymobile.com>");875MODULE_DESCRIPTION("Qualcomm PM8xxx GPIO driver");876MODULE_LICENSE("GPL v2");877