1514 lines · c
1// SPDX-License-Identifier: GPL-2.0+2//3// pin-controller/pin-mux/pin-config/gpio-driver for Samsung's SoC's.4//5// Copyright (c) 2012 Samsung Electronics Co., Ltd.6// http://www.samsung.com7// Copyright (c) 2012 Linaro Ltd8// http://www.linaro.org9//10// Author: Thomas Abraham <thomas.ab@samsung.com>11//12// This driver implements the Samsung pinctrl driver. It supports setting up of13// pinmux and pinconf configurations. The gpiolib interface is also included.14// External interrupt (gpio and wakeup) support are not included in this driver15// but provides extensions to which platform specific implementation of the gpio16// and wakeup interrupts can be hooked to.17 18#include <linux/clk.h>19#include <linux/err.h>20#include <linux/gpio/driver.h>21#include <linux/init.h>22#include <linux/io.h>23#include <linux/irqdomain.h>24#include <linux/of.h>25#include <linux/platform_device.h>26#include <linux/property.h>27#include <linux/seq_file.h>28#include <linux/slab.h>29#include <linux/spinlock.h>30 31#include "../core.h"32#include "pinctrl-samsung.h"33 34/* maximum number of the memory resources */35#define SAMSUNG_PINCTRL_NUM_RESOURCES 236 37/* list of all possible config options supported */38static struct pin_config {39 const char *property;40 enum pincfg_type param;41} cfg_params[] = {42 { "samsung,pin-pud", PINCFG_TYPE_PUD },43 { "samsung,pin-drv", PINCFG_TYPE_DRV },44 { "samsung,pin-con-pdn", PINCFG_TYPE_CON_PDN },45 { "samsung,pin-pud-pdn", PINCFG_TYPE_PUD_PDN },46 { "samsung,pin-val", PINCFG_TYPE_DAT },47};48 49static int samsung_get_group_count(struct pinctrl_dev *pctldev)50{51 struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);52 53 return pmx->nr_groups;54}55 56static const char *samsung_get_group_name(struct pinctrl_dev *pctldev,57 unsigned group)58{59 struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);60 61 return pmx->pin_groups[group].name;62}63 64static int samsung_get_group_pins(struct pinctrl_dev *pctldev,65 unsigned group,66 const unsigned **pins,67 unsigned *num_pins)68{69 struct samsung_pinctrl_drv_data *pmx = pinctrl_dev_get_drvdata(pctldev);70 71 *pins = pmx->pin_groups[group].pins;72 *num_pins = pmx->pin_groups[group].num_pins;73 74 return 0;75}76 77static int reserve_map(struct device *dev, struct pinctrl_map **map,78 unsigned *reserved_maps, unsigned *num_maps,79 unsigned reserve)80{81 unsigned old_num = *reserved_maps;82 unsigned new_num = *num_maps + reserve;83 struct pinctrl_map *new_map;84 85 if (old_num >= new_num)86 return 0;87 88 new_map = krealloc(*map, sizeof(*new_map) * new_num, GFP_KERNEL);89 if (!new_map)90 return -ENOMEM;91 92 memset(new_map + old_num, 0, (new_num - old_num) * sizeof(*new_map));93 94 *map = new_map;95 *reserved_maps = new_num;96 97 return 0;98}99 100static int add_map_mux(struct pinctrl_map **map, unsigned *reserved_maps,101 unsigned *num_maps, const char *group,102 const char *function)103{104 if (WARN_ON(*num_maps == *reserved_maps))105 return -ENOSPC;106 107 (*map)[*num_maps].type = PIN_MAP_TYPE_MUX_GROUP;108 (*map)[*num_maps].data.mux.group = group;109 (*map)[*num_maps].data.mux.function = function;110 (*num_maps)++;111 112 return 0;113}114 115static int add_map_configs(struct device *dev, struct pinctrl_map **map,116 unsigned *reserved_maps, unsigned *num_maps,117 const char *group, unsigned long *configs,118 unsigned num_configs)119{120 unsigned long *dup_configs;121 122 if (WARN_ON(*num_maps == *reserved_maps))123 return -ENOSPC;124 125 dup_configs = kmemdup_array(configs, num_configs, sizeof(*dup_configs),126 GFP_KERNEL);127 if (!dup_configs)128 return -ENOMEM;129 130 (*map)[*num_maps].type = PIN_MAP_TYPE_CONFIGS_GROUP;131 (*map)[*num_maps].data.configs.group_or_pin = group;132 (*map)[*num_maps].data.configs.configs = dup_configs;133 (*map)[*num_maps].data.configs.num_configs = num_configs;134 (*num_maps)++;135 136 return 0;137}138 139static int add_config(struct device *dev, unsigned long **configs,140 unsigned *num_configs, unsigned long config)141{142 unsigned old_num = *num_configs;143 unsigned new_num = old_num + 1;144 unsigned long *new_configs;145 146 new_configs = krealloc(*configs, sizeof(*new_configs) * new_num,147 GFP_KERNEL);148 if (!new_configs)149 return -ENOMEM;150 151 new_configs[old_num] = config;152 153 *configs = new_configs;154 *num_configs = new_num;155 156 return 0;157}158 159static void samsung_dt_free_map(struct pinctrl_dev *pctldev,160 struct pinctrl_map *map,161 unsigned num_maps)162{163 int i;164 165 for (i = 0; i < num_maps; i++)166 if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP)167 kfree(map[i].data.configs.configs);168 169 kfree(map);170}171 172static int samsung_dt_subnode_to_map(struct samsung_pinctrl_drv_data *drvdata,173 struct device *dev,174 struct device_node *np,175 struct pinctrl_map **map,176 unsigned *reserved_maps,177 unsigned *num_maps)178{179 int ret, i;180 u32 val;181 unsigned long config;182 unsigned long *configs = NULL;183 unsigned num_configs = 0;184 unsigned reserve;185 struct property *prop;186 const char *group;187 bool has_func = false;188 189 ret = of_property_read_u32(np, "samsung,pin-function", &val);190 if (!ret)191 has_func = true;192 193 for (i = 0; i < ARRAY_SIZE(cfg_params); i++) {194 ret = of_property_read_u32(np, cfg_params[i].property, &val);195 if (!ret) {196 config = PINCFG_PACK(cfg_params[i].param, val);197 ret = add_config(dev, &configs, &num_configs, config);198 if (ret < 0)199 goto exit;200 /* EINVAL=missing, which is fine since it's optional */201 } else if (ret != -EINVAL) {202 dev_err(dev, "could not parse property %s\n",203 cfg_params[i].property);204 }205 }206 207 reserve = 0;208 if (has_func)209 reserve++;210 if (num_configs)211 reserve++;212 ret = of_property_count_strings(np, "samsung,pins");213 if (ret < 0) {214 dev_err(dev, "could not parse property samsung,pins\n");215 goto exit;216 }217 reserve *= ret;218 219 ret = reserve_map(dev, map, reserved_maps, num_maps, reserve);220 if (ret < 0)221 goto exit;222 223 of_property_for_each_string(np, "samsung,pins", prop, group) {224 if (has_func) {225 ret = add_map_mux(map, reserved_maps,226 num_maps, group, np->full_name);227 if (ret < 0)228 goto exit;229 }230 231 if (num_configs) {232 ret = add_map_configs(dev, map, reserved_maps,233 num_maps, group, configs,234 num_configs);235 if (ret < 0)236 goto exit;237 }238 }239 240 ret = 0;241 242exit:243 kfree(configs);244 return ret;245}246 247static int samsung_dt_node_to_map(struct pinctrl_dev *pctldev,248 struct device_node *np_config,249 struct pinctrl_map **map,250 unsigned *num_maps)251{252 struct samsung_pinctrl_drv_data *drvdata;253 unsigned reserved_maps;254 int ret;255 256 drvdata = pinctrl_dev_get_drvdata(pctldev);257 258 reserved_maps = 0;259 *map = NULL;260 *num_maps = 0;261 262 if (!of_get_child_count(np_config))263 return samsung_dt_subnode_to_map(drvdata, pctldev->dev,264 np_config, map,265 &reserved_maps,266 num_maps);267 268 for_each_child_of_node_scoped(np_config, np) {269 ret = samsung_dt_subnode_to_map(drvdata, pctldev->dev, np, map,270 &reserved_maps, num_maps);271 if (ret < 0) {272 samsung_dt_free_map(pctldev, *map, *num_maps);273 return ret;274 }275 }276 277 return 0;278}279 280#ifdef CONFIG_DEBUG_FS281/* Forward declaration which can be used by samsung_pin_dbg_show */282static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,283 unsigned long *config);284static const char * const reg_names[] = {"CON", "DAT", "PUD", "DRV", "CON_PDN",285 "PUD_PDN"};286 287static void samsung_pin_dbg_show(struct pinctrl_dev *pctldev,288 struct seq_file *s, unsigned int pin)289{290 enum pincfg_type cfg_type;291 unsigned long config;292 int ret;293 294 for (cfg_type = 0; cfg_type < PINCFG_TYPE_NUM; cfg_type++) {295 config = PINCFG_PACK(cfg_type, 0);296 ret = samsung_pinconf_get(pctldev, pin, &config);297 if (ret < 0)298 continue;299 300 seq_printf(s, " %s(0x%lx)", reg_names[cfg_type],301 PINCFG_UNPACK_VALUE(config));302 }303}304#endif305 306/* list of pinctrl callbacks for the pinctrl core */307static const struct pinctrl_ops samsung_pctrl_ops = {308 .get_groups_count = samsung_get_group_count,309 .get_group_name = samsung_get_group_name,310 .get_group_pins = samsung_get_group_pins,311 .dt_node_to_map = samsung_dt_node_to_map,312 .dt_free_map = samsung_dt_free_map,313#ifdef CONFIG_DEBUG_FS314 .pin_dbg_show = samsung_pin_dbg_show,315#endif316};317 318/* check if the selector is a valid pin function selector */319static int samsung_get_functions_count(struct pinctrl_dev *pctldev)320{321 struct samsung_pinctrl_drv_data *drvdata;322 323 drvdata = pinctrl_dev_get_drvdata(pctldev);324 return drvdata->nr_functions;325}326 327/* return the name of the pin function specified */328static const char *samsung_pinmux_get_fname(struct pinctrl_dev *pctldev,329 unsigned selector)330{331 struct samsung_pinctrl_drv_data *drvdata;332 333 drvdata = pinctrl_dev_get_drvdata(pctldev);334 return drvdata->pmx_functions[selector].name;335}336 337/* return the groups associated for the specified function selector */338static int samsung_pinmux_get_groups(struct pinctrl_dev *pctldev,339 unsigned selector, const char * const **groups,340 unsigned * const num_groups)341{342 struct samsung_pinctrl_drv_data *drvdata;343 344 drvdata = pinctrl_dev_get_drvdata(pctldev);345 *groups = drvdata->pmx_functions[selector].groups;346 *num_groups = drvdata->pmx_functions[selector].num_groups;347 return 0;348}349 350/*351 * given a pin number that is local to a pin controller, find out the pin bank352 * and the register base of the pin bank.353 */354static void pin_to_reg_bank(struct samsung_pinctrl_drv_data *drvdata,355 unsigned pin, void __iomem **reg, u32 *offset,356 struct samsung_pin_bank **bank)357{358 struct samsung_pin_bank *b;359 360 b = drvdata->pin_banks;361 362 while ((pin >= b->pin_base) &&363 ((b->pin_base + b->nr_pins - 1) < pin))364 b++;365 366 *reg = b->pctl_base + b->pctl_offset;367 *offset = pin - b->pin_base;368 if (bank)369 *bank = b;370}371 372/* enable or disable a pinmux function */373static int samsung_pinmux_setup(struct pinctrl_dev *pctldev, unsigned selector,374 unsigned group)375{376 struct samsung_pinctrl_drv_data *drvdata;377 const struct samsung_pin_bank_type *type;378 struct samsung_pin_bank *bank;379 void __iomem *reg;380 u32 mask, shift, data, pin_offset;381 unsigned long flags;382 const struct samsung_pmx_func *func;383 const struct samsung_pin_group *grp;384 int ret;385 386 drvdata = pinctrl_dev_get_drvdata(pctldev);387 func = &drvdata->pmx_functions[selector];388 grp = &drvdata->pin_groups[group];389 390 pin_to_reg_bank(drvdata, grp->pins[0], ®, &pin_offset, &bank);391 type = bank->type;392 mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;393 shift = pin_offset * type->fld_width[PINCFG_TYPE_FUNC];394 if (shift >= 32) {395 /* Some banks have two config registers */396 shift -= 32;397 reg += 4;398 }399 400 ret = clk_enable(drvdata->pclk);401 if (ret) {402 dev_err(pctldev->dev, "failed to enable clock for setup\n");403 return ret;404 }405 406 raw_spin_lock_irqsave(&bank->slock, flags);407 408 data = readl(reg + type->reg_offset[PINCFG_TYPE_FUNC]);409 data &= ~(mask << shift);410 data |= func->val << shift;411 writel(data, reg + type->reg_offset[PINCFG_TYPE_FUNC]);412 413 raw_spin_unlock_irqrestore(&bank->slock, flags);414 415 clk_disable(drvdata->pclk);416 417 return 0;418}419 420/* enable a specified pinmux by writing to registers */421static int samsung_pinmux_set_mux(struct pinctrl_dev *pctldev,422 unsigned selector,423 unsigned group)424{425 return samsung_pinmux_setup(pctldev, selector, group);426}427 428/* list of pinmux callbacks for the pinmux vertical in pinctrl core */429static const struct pinmux_ops samsung_pinmux_ops = {430 .get_functions_count = samsung_get_functions_count,431 .get_function_name = samsung_pinmux_get_fname,432 .get_function_groups = samsung_pinmux_get_groups,433 .set_mux = samsung_pinmux_set_mux,434};435 436/* set or get the pin config settings for a specified pin */437static int samsung_pinconf_rw(struct pinctrl_dev *pctldev, unsigned int pin,438 unsigned long *config, bool set)439{440 struct samsung_pinctrl_drv_data *drvdata;441 const struct samsung_pin_bank_type *type;442 struct samsung_pin_bank *bank;443 void __iomem *reg_base;444 enum pincfg_type cfg_type = PINCFG_UNPACK_TYPE(*config);445 u32 data, width, pin_offset, mask, shift;446 u32 cfg_value, cfg_reg;447 unsigned long flags;448 int ret;449 450 drvdata = pinctrl_dev_get_drvdata(pctldev);451 pin_to_reg_bank(drvdata, pin, ®_base, &pin_offset, &bank);452 type = bank->type;453 454 if (cfg_type >= PINCFG_TYPE_NUM || !type->fld_width[cfg_type])455 return -EINVAL;456 457 width = type->fld_width[cfg_type];458 cfg_reg = type->reg_offset[cfg_type];459 460 ret = clk_enable(drvdata->pclk);461 if (ret) {462 dev_err(drvdata->dev, "failed to enable clock\n");463 return ret;464 }465 466 raw_spin_lock_irqsave(&bank->slock, flags);467 468 mask = (1 << width) - 1;469 shift = pin_offset * width;470 data = readl(reg_base + cfg_reg);471 472 if (set) {473 cfg_value = PINCFG_UNPACK_VALUE(*config);474 data &= ~(mask << shift);475 data |= (cfg_value << shift);476 writel(data, reg_base + cfg_reg);477 } else {478 data >>= shift;479 data &= mask;480 *config = PINCFG_PACK(cfg_type, data);481 }482 483 raw_spin_unlock_irqrestore(&bank->slock, flags);484 485 clk_disable(drvdata->pclk);486 487 return 0;488}489 490/* set the pin config settings for a specified pin */491static int samsung_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,492 unsigned long *configs, unsigned num_configs)493{494 int i, ret;495 496 for (i = 0; i < num_configs; i++) {497 ret = samsung_pinconf_rw(pctldev, pin, &configs[i], true);498 if (ret < 0)499 return ret;500 } /* for each config */501 502 return 0;503}504 505/* get the pin config settings for a specified pin */506static int samsung_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,507 unsigned long *config)508{509 return samsung_pinconf_rw(pctldev, pin, config, false);510}511 512/* set the pin config settings for a specified pin group */513static int samsung_pinconf_group_set(struct pinctrl_dev *pctldev,514 unsigned group, unsigned long *configs,515 unsigned num_configs)516{517 struct samsung_pinctrl_drv_data *drvdata;518 const unsigned int *pins;519 unsigned int cnt;520 521 drvdata = pinctrl_dev_get_drvdata(pctldev);522 pins = drvdata->pin_groups[group].pins;523 524 for (cnt = 0; cnt < drvdata->pin_groups[group].num_pins; cnt++)525 samsung_pinconf_set(pctldev, pins[cnt], configs, num_configs);526 527 return 0;528}529 530/* get the pin config settings for a specified pin group */531static int samsung_pinconf_group_get(struct pinctrl_dev *pctldev,532 unsigned int group, unsigned long *config)533{534 struct samsung_pinctrl_drv_data *drvdata;535 const unsigned int *pins;536 537 drvdata = pinctrl_dev_get_drvdata(pctldev);538 pins = drvdata->pin_groups[group].pins;539 samsung_pinconf_get(pctldev, pins[0], config);540 return 0;541}542 543/* list of pinconfig callbacks for pinconfig vertical in the pinctrl code */544static const struct pinconf_ops samsung_pinconf_ops = {545 .pin_config_get = samsung_pinconf_get,546 .pin_config_set = samsung_pinconf_set,547 .pin_config_group_get = samsung_pinconf_group_get,548 .pin_config_group_set = samsung_pinconf_group_set,549};550 551/*552 * The samsung_gpio_set_vlaue() should be called with "bank->slock" held553 * to avoid race condition.554 */555static void samsung_gpio_set_value(struct gpio_chip *gc,556 unsigned offset, int value)557{558 struct samsung_pin_bank *bank = gpiochip_get_data(gc);559 const struct samsung_pin_bank_type *type = bank->type;560 void __iomem *reg;561 u32 data;562 563 reg = bank->pctl_base + bank->pctl_offset;564 565 data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);566 data &= ~(1 << offset);567 if (value)568 data |= 1 << offset;569 writel(data, reg + type->reg_offset[PINCFG_TYPE_DAT]);570}571 572/* gpiolib gpio_set callback function */573static void samsung_gpio_set(struct gpio_chip *gc, unsigned offset, int value)574{575 struct samsung_pin_bank *bank = gpiochip_get_data(gc);576 struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;577 unsigned long flags;578 579 if (clk_enable(drvdata->pclk)) {580 dev_err(drvdata->dev, "failed to enable clock\n");581 return;582 }583 584 raw_spin_lock_irqsave(&bank->slock, flags);585 samsung_gpio_set_value(gc, offset, value);586 raw_spin_unlock_irqrestore(&bank->slock, flags);587 588 clk_disable(drvdata->pclk);589}590 591/* gpiolib gpio_get callback function */592static int samsung_gpio_get(struct gpio_chip *gc, unsigned offset)593{594 const void __iomem *reg;595 u32 data;596 struct samsung_pin_bank *bank = gpiochip_get_data(gc);597 const struct samsung_pin_bank_type *type = bank->type;598 struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;599 int ret;600 601 reg = bank->pctl_base + bank->pctl_offset;602 603 ret = clk_enable(drvdata->pclk);604 if (ret) {605 dev_err(drvdata->dev, "failed to enable clock\n");606 return ret;607 }608 609 data = readl(reg + type->reg_offset[PINCFG_TYPE_DAT]);610 data >>= offset;611 data &= 1;612 613 clk_disable(drvdata->pclk);614 615 return data;616}617 618/*619 * The samsung_gpio_set_direction() should be called with "bank->slock" held620 * to avoid race condition.621 * The calls to gpio_direction_output() and gpio_direction_input()622 * leads to this function call.623 */624static int samsung_gpio_set_direction(struct gpio_chip *gc,625 unsigned offset, bool input)626{627 const struct samsung_pin_bank_type *type;628 struct samsung_pin_bank *bank;629 void __iomem *reg;630 u32 data, mask, shift;631 632 bank = gpiochip_get_data(gc);633 type = bank->type;634 635 reg = bank->pctl_base + bank->pctl_offset636 + type->reg_offset[PINCFG_TYPE_FUNC];637 638 mask = (1 << type->fld_width[PINCFG_TYPE_FUNC]) - 1;639 shift = offset * type->fld_width[PINCFG_TYPE_FUNC];640 if (shift >= 32) {641 /* Some banks have two config registers */642 shift -= 32;643 reg += 4;644 }645 646 data = readl(reg);647 data &= ~(mask << shift);648 if (!input)649 data |= PIN_CON_FUNC_OUTPUT << shift;650 writel(data, reg);651 652 return 0;653}654 655/* gpiolib gpio_direction_input callback function. */656static int samsung_gpio_direction_input(struct gpio_chip *gc, unsigned offset)657{658 struct samsung_pin_bank *bank = gpiochip_get_data(gc);659 struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;660 unsigned long flags;661 int ret;662 663 ret = clk_enable(drvdata->pclk);664 if (ret) {665 dev_err(drvdata->dev, "failed to enable clock\n");666 return ret;667 }668 669 raw_spin_lock_irqsave(&bank->slock, flags);670 ret = samsung_gpio_set_direction(gc, offset, true);671 raw_spin_unlock_irqrestore(&bank->slock, flags);672 673 clk_disable(drvdata->pclk);674 675 return ret;676}677 678/* gpiolib gpio_direction_output callback function. */679static int samsung_gpio_direction_output(struct gpio_chip *gc, unsigned offset,680 int value)681{682 struct samsung_pin_bank *bank = gpiochip_get_data(gc);683 struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;684 unsigned long flags;685 int ret;686 687 ret = clk_enable(drvdata->pclk);688 if (ret) {689 dev_err(drvdata->dev, "failed to enable clock\n");690 return ret;691 }692 693 raw_spin_lock_irqsave(&bank->slock, flags);694 samsung_gpio_set_value(gc, offset, value);695 ret = samsung_gpio_set_direction(gc, offset, false);696 raw_spin_unlock_irqrestore(&bank->slock, flags);697 698 clk_disable(drvdata->pclk);699 700 return ret;701}702 703/*704 * gpiod_to_irq() callback function. Creates a mapping between a GPIO pin705 * and a virtual IRQ, if not already present.706 */707static int samsung_gpio_to_irq(struct gpio_chip *gc, unsigned offset)708{709 struct samsung_pin_bank *bank = gpiochip_get_data(gc);710 unsigned int virq;711 712 if (!bank->irq_domain)713 return -ENXIO;714 715 virq = irq_create_mapping(bank->irq_domain, offset);716 717 return (virq) ? : -ENXIO;718}719 720static int samsung_add_pin_ranges(struct gpio_chip *gc)721{722 struct samsung_pin_bank *bank = gpiochip_get_data(gc);723 724 bank->grange.name = bank->name;725 bank->grange.id = bank->id;726 bank->grange.pin_base = bank->pin_base;727 bank->grange.base = gc->base;728 bank->grange.npins = bank->nr_pins;729 bank->grange.gc = &bank->gpio_chip;730 pinctrl_add_gpio_range(bank->drvdata->pctl_dev, &bank->grange);731 732 return 0;733}734 735static struct samsung_pin_group *samsung_pinctrl_create_groups(736 struct device *dev,737 struct samsung_pinctrl_drv_data *drvdata,738 unsigned int *cnt)739{740 struct pinctrl_desc *ctrldesc = &drvdata->pctl;741 struct samsung_pin_group *groups, *grp;742 const struct pinctrl_pin_desc *pdesc;743 int i;744 745 groups = devm_kcalloc(dev, ctrldesc->npins, sizeof(*groups),746 GFP_KERNEL);747 if (!groups)748 return ERR_PTR(-EINVAL);749 grp = groups;750 751 pdesc = ctrldesc->pins;752 for (i = 0; i < ctrldesc->npins; ++i, ++pdesc, ++grp) {753 grp->name = pdesc->name;754 grp->pins = &pdesc->number;755 grp->num_pins = 1;756 }757 758 *cnt = ctrldesc->npins;759 return groups;760}761 762static int samsung_pinctrl_create_function(struct device *dev,763 struct samsung_pinctrl_drv_data *drvdata,764 struct device_node *func_np,765 struct samsung_pmx_func *func)766{767 int npins;768 int ret;769 int i;770 771 if (of_property_read_u32(func_np, "samsung,pin-function", &func->val))772 return 0;773 774 npins = of_property_count_strings(func_np, "samsung,pins");775 if (npins < 1) {776 dev_err(dev, "invalid pin list in %pOFn node", func_np);777 return -EINVAL;778 }779 780 func->name = func_np->full_name;781 782 func->groups = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL);783 if (!func->groups)784 return -ENOMEM;785 786 for (i = 0; i < npins; ++i) {787 const char *gname;788 789 ret = of_property_read_string_index(func_np, "samsung,pins",790 i, &gname);791 if (ret) {792 dev_err(dev,793 "failed to read pin name %d from %pOFn node\n",794 i, func_np);795 return ret;796 }797 798 func->groups[i] = gname;799 }800 801 func->num_groups = npins;802 return 1;803}804 805static struct samsung_pmx_func *samsung_pinctrl_create_functions(806 struct device *dev,807 struct samsung_pinctrl_drv_data *drvdata,808 unsigned int *cnt)809{810 struct samsung_pmx_func *functions, *func;811 struct device_node *dev_np = dev->of_node;812 struct device_node *cfg_np;813 unsigned int func_cnt = 0;814 int ret;815 816 /*817 * Iterate over all the child nodes of the pin controller node818 * and create pin groups and pin function lists.819 */820 for_each_child_of_node(dev_np, cfg_np) {821 struct device_node *func_np;822 823 if (!of_get_child_count(cfg_np)) {824 if (!of_property_present(cfg_np,825 "samsung,pin-function"))826 continue;827 ++func_cnt;828 continue;829 }830 831 for_each_child_of_node(cfg_np, func_np) {832 if (!of_property_present(func_np,833 "samsung,pin-function"))834 continue;835 ++func_cnt;836 }837 }838 839 functions = devm_kcalloc(dev, func_cnt, sizeof(*functions),840 GFP_KERNEL);841 if (!functions)842 return ERR_PTR(-ENOMEM);843 func = functions;844 845 /*846 * Iterate over all the child nodes of the pin controller node847 * and create pin groups and pin function lists.848 */849 func_cnt = 0;850 for_each_child_of_node_scoped(dev_np, cfg_np) {851 if (!of_get_child_count(cfg_np)) {852 ret = samsung_pinctrl_create_function(dev, drvdata,853 cfg_np, func);854 if (ret < 0)855 return ERR_PTR(ret);856 if (ret > 0) {857 ++func;858 ++func_cnt;859 }860 continue;861 }862 863 for_each_child_of_node_scoped(cfg_np, func_np) {864 ret = samsung_pinctrl_create_function(dev, drvdata,865 func_np, func);866 if (ret < 0)867 return ERR_PTR(ret);868 if (ret > 0) {869 ++func;870 ++func_cnt;871 }872 }873 }874 875 *cnt = func_cnt;876 return functions;877}878 879/*880 * Parse the information about all the available pin groups and pin functions881 * from device node of the pin-controller. A pin group is formed with all882 * the pins listed in the "samsung,pins" property.883 */884 885static int samsung_pinctrl_parse_dt(struct platform_device *pdev,886 struct samsung_pinctrl_drv_data *drvdata)887{888 struct device *dev = &pdev->dev;889 struct samsung_pin_group *groups;890 struct samsung_pmx_func *functions;891 unsigned int grp_cnt = 0, func_cnt = 0;892 893 groups = samsung_pinctrl_create_groups(dev, drvdata, &grp_cnt);894 if (IS_ERR(groups)) {895 dev_err(dev, "failed to parse pin groups\n");896 return PTR_ERR(groups);897 }898 899 functions = samsung_pinctrl_create_functions(dev, drvdata, &func_cnt);900 if (IS_ERR(functions)) {901 dev_err(dev, "failed to parse pin functions\n");902 return PTR_ERR(functions);903 }904 905 drvdata->pin_groups = groups;906 drvdata->nr_groups = grp_cnt;907 drvdata->pmx_functions = functions;908 drvdata->nr_functions = func_cnt;909 910 return 0;911}912 913/* register the pinctrl interface with the pinctrl subsystem */914static int samsung_pinctrl_register(struct platform_device *pdev,915 struct samsung_pinctrl_drv_data *drvdata)916{917 struct pinctrl_desc *ctrldesc = &drvdata->pctl;918 struct pinctrl_pin_desc *pindesc, *pdesc;919 struct samsung_pin_bank *pin_bank;920 char *pin_names;921 int pin, bank, ret;922 923 ctrldesc->name = "samsung-pinctrl";924 ctrldesc->owner = THIS_MODULE;925 ctrldesc->pctlops = &samsung_pctrl_ops;926 ctrldesc->pmxops = &samsung_pinmux_ops;927 ctrldesc->confops = &samsung_pinconf_ops;928 929 pindesc = devm_kcalloc(&pdev->dev,930 drvdata->nr_pins, sizeof(*pindesc),931 GFP_KERNEL);932 if (!pindesc)933 return -ENOMEM;934 ctrldesc->pins = pindesc;935 ctrldesc->npins = drvdata->nr_pins;936 937 /* dynamically populate the pin number and pin name for pindesc */938 for (pin = 0, pdesc = pindesc; pin < ctrldesc->npins; pin++, pdesc++)939 pdesc->number = pin;940 941 /*942 * allocate space for storing the dynamically generated names for all943 * the pins which belong to this pin-controller.944 */945 pin_names = devm_kzalloc(&pdev->dev,946 array3_size(sizeof(char), PIN_NAME_LENGTH,947 drvdata->nr_pins),948 GFP_KERNEL);949 if (!pin_names)950 return -ENOMEM;951 952 /* for each pin, the name of the pin is pin-bank name + pin number */953 for (bank = 0; bank < drvdata->nr_banks; bank++) {954 pin_bank = &drvdata->pin_banks[bank];955 pin_bank->id = bank;956 for (pin = 0; pin < pin_bank->nr_pins; pin++) {957 sprintf(pin_names, "%s-%d", pin_bank->name, pin);958 pdesc = pindesc + pin_bank->pin_base + pin;959 pdesc->name = pin_names;960 pin_names += PIN_NAME_LENGTH;961 }962 }963 964 ret = samsung_pinctrl_parse_dt(pdev, drvdata);965 if (ret)966 return ret;967 968 ret = devm_pinctrl_register_and_init(&pdev->dev, ctrldesc, drvdata,969 &drvdata->pctl_dev);970 if (ret) {971 dev_err(&pdev->dev, "could not register pinctrl driver\n");972 return ret;973 }974 975 return 0;976}977 978/* unregister the pinctrl interface with the pinctrl subsystem */979static int samsung_pinctrl_unregister(struct platform_device *pdev,980 struct samsung_pinctrl_drv_data *drvdata)981{982 struct samsung_pin_bank *bank = drvdata->pin_banks;983 int i;984 985 for (i = 0; i < drvdata->nr_banks; ++i, ++bank)986 pinctrl_remove_gpio_range(drvdata->pctl_dev, &bank->grange);987 988 return 0;989}990 991static void samsung_pud_value_init(struct samsung_pinctrl_drv_data *drvdata)992{993 unsigned int *pud_val = drvdata->pud_val;994 995 pud_val[PUD_PULL_DISABLE] = EXYNOS_PIN_PUD_PULL_DISABLE;996 pud_val[PUD_PULL_DOWN] = EXYNOS_PIN_PID_PULL_DOWN;997 pud_val[PUD_PULL_UP] = EXYNOS_PIN_PID_PULL_UP;998}999 1000/*1001 * Enable or Disable the pull-down and pull-up for the gpio pins in the1002 * PUD register.1003 */1004static void samsung_gpio_set_pud(struct gpio_chip *gc, unsigned int offset,1005 unsigned int value)1006{1007 struct samsung_pin_bank *bank = gpiochip_get_data(gc);1008 const struct samsung_pin_bank_type *type = bank->type;1009 void __iomem *reg;1010 unsigned int data, mask;1011 1012 reg = bank->pctl_base + bank->pctl_offset;1013 data = readl(reg + type->reg_offset[PINCFG_TYPE_PUD]);1014 mask = (1 << type->fld_width[PINCFG_TYPE_PUD]) - 1;1015 data &= ~(mask << (offset * type->fld_width[PINCFG_TYPE_PUD]));1016 data |= value << (offset * type->fld_width[PINCFG_TYPE_PUD]);1017 writel(data, reg + type->reg_offset[PINCFG_TYPE_PUD]);1018}1019 1020/*1021 * Identify the type of PUD config based on the gpiolib request to enable1022 * or disable the PUD config.1023 */1024static int samsung_gpio_set_config(struct gpio_chip *gc, unsigned int offset,1025 unsigned long config)1026{1027 struct samsung_pin_bank *bank = gpiochip_get_data(gc);1028 struct samsung_pinctrl_drv_data *drvdata = bank->drvdata;1029 unsigned int value;1030 int ret = 0;1031 unsigned long flags;1032 1033 switch (pinconf_to_config_param(config)) {1034 case PIN_CONFIG_BIAS_DISABLE:1035 value = drvdata->pud_val[PUD_PULL_DISABLE];1036 break;1037 case PIN_CONFIG_BIAS_PULL_DOWN:1038 value = drvdata->pud_val[PUD_PULL_DOWN];1039 break;1040 case PIN_CONFIG_BIAS_PULL_UP:1041 value = drvdata->pud_val[PUD_PULL_UP];1042 break;1043 default:1044 return -ENOTSUPP;1045 }1046 1047 ret = clk_enable(drvdata->pclk);1048 if (ret) {1049 dev_err(drvdata->dev, "failed to enable clock\n");1050 return ret;1051 }1052 1053 raw_spin_lock_irqsave(&bank->slock, flags);1054 samsung_gpio_set_pud(gc, offset, value);1055 raw_spin_unlock_irqrestore(&bank->slock, flags);1056 1057 clk_disable(drvdata->pclk);1058 1059 return ret;1060}1061 1062static const struct gpio_chip samsung_gpiolib_chip = {1063 .request = gpiochip_generic_request,1064 .free = gpiochip_generic_free,1065 .set = samsung_gpio_set,1066 .get = samsung_gpio_get,1067 .direction_input = samsung_gpio_direction_input,1068 .direction_output = samsung_gpio_direction_output,1069 .to_irq = samsung_gpio_to_irq,1070 .add_pin_ranges = samsung_add_pin_ranges,1071 .set_config = samsung_gpio_set_config,1072 .owner = THIS_MODULE,1073};1074 1075/* register the gpiolib interface with the gpiolib subsystem */1076static int samsung_gpiolib_register(struct platform_device *pdev,1077 struct samsung_pinctrl_drv_data *drvdata)1078{1079 struct samsung_pin_bank *bank = drvdata->pin_banks;1080 struct gpio_chip *gc;1081 int ret;1082 int i;1083 1084 for (i = 0; i < drvdata->nr_banks; ++i, ++bank) {1085 bank->gpio_chip = samsung_gpiolib_chip;1086 1087 gc = &bank->gpio_chip;1088 gc->base = -1; /* Dynamic allocation */1089 gc->ngpio = bank->nr_pins;1090 gc->parent = &pdev->dev;1091 gc->fwnode = bank->fwnode;1092 gc->label = bank->name;1093 1094 ret = devm_gpiochip_add_data(&pdev->dev, gc, bank);1095 if (ret) {1096 dev_err(&pdev->dev, "failed to register gpio_chip %s, error code: %d\n",1097 gc->label, ret);1098 return ret;1099 }1100 }1101 1102 return 0;1103}1104 1105static const struct samsung_pin_ctrl *1106samsung_pinctrl_get_soc_data_for_of_alias(struct platform_device *pdev)1107{1108 struct device_node *node = pdev->dev.of_node;1109 const struct samsung_pinctrl_of_match_data *of_data;1110 int id;1111 1112 id = of_alias_get_id(node, "pinctrl");1113 if (id < 0) {1114 dev_err(&pdev->dev, "failed to get alias id\n");1115 return NULL;1116 }1117 1118 of_data = of_device_get_match_data(&pdev->dev);1119 if (id >= of_data->num_ctrl) {1120 dev_err(&pdev->dev, "invalid alias id %d\n", id);1121 return NULL;1122 }1123 1124 return &(of_data->ctrl[id]);1125}1126 1127static void samsung_banks_node_put(struct samsung_pinctrl_drv_data *d)1128{1129 struct samsung_pin_bank *bank;1130 unsigned int i;1131 1132 bank = d->pin_banks;1133 for (i = 0; i < d->nr_banks; ++i, ++bank)1134 fwnode_handle_put(bank->fwnode);1135}1136 1137/*1138 * Iterate over all driver pin banks to find one matching the name of node,1139 * skipping optional "-gpio" node suffix. When found, assign node to the bank.1140 */1141static void samsung_banks_node_get(struct device *dev, struct samsung_pinctrl_drv_data *d)1142{1143 const char *suffix = "-gpio-bank";1144 struct samsung_pin_bank *bank;1145 struct fwnode_handle *child;1146 /* Pin bank names are up to 4 characters */1147 char node_name[20];1148 unsigned int i;1149 size_t len;1150 1151 bank = d->pin_banks;1152 for (i = 0; i < d->nr_banks; ++i, ++bank) {1153 strscpy(node_name, bank->name, sizeof(node_name));1154 len = strlcat(node_name, suffix, sizeof(node_name));1155 if (len >= sizeof(node_name)) {1156 dev_err(dev, "Too long pin bank name '%s', ignoring\n",1157 bank->name);1158 continue;1159 }1160 1161 for_each_gpiochip_node(dev, child) {1162 struct device_node *np = to_of_node(child);1163 1164 if (of_node_name_eq(np, node_name))1165 break;1166 if (of_node_name_eq(np, bank->name))1167 break;1168 }1169 1170 if (child)1171 bank->fwnode = child;1172 else1173 dev_warn(dev, "Missing node for bank %s - invalid DTB\n",1174 bank->name);1175 /* child reference dropped in samsung_drop_banks_of_node() */1176 }1177}1178 1179/* retrieve the soc specific data */1180static const struct samsung_pin_ctrl *1181samsung_pinctrl_get_soc_data(struct samsung_pinctrl_drv_data *d,1182 struct platform_device *pdev)1183{1184 const struct samsung_pin_bank_data *bdata;1185 const struct samsung_pin_ctrl *ctrl;1186 struct samsung_pin_bank *bank;1187 struct resource *res;1188 void __iomem *virt_base[SAMSUNG_PINCTRL_NUM_RESOURCES];1189 unsigned int i;1190 1191 ctrl = samsung_pinctrl_get_soc_data_for_of_alias(pdev);1192 if (!ctrl)1193 return ERR_PTR(-ENOENT);1194 1195 d->suspend = ctrl->suspend;1196 d->resume = ctrl->resume;1197 d->nr_banks = ctrl->nr_banks;1198 d->pin_banks = devm_kcalloc(&pdev->dev, d->nr_banks,1199 sizeof(*d->pin_banks), GFP_KERNEL);1200 if (!d->pin_banks)1201 return ERR_PTR(-ENOMEM);1202 1203 if (ctrl->nr_ext_resources + 1 > SAMSUNG_PINCTRL_NUM_RESOURCES)1204 return ERR_PTR(-EINVAL);1205 1206 for (i = 0; i < ctrl->nr_ext_resources + 1; i++) {1207 res = platform_get_resource(pdev, IORESOURCE_MEM, i);1208 if (!res) {1209 dev_err(&pdev->dev, "failed to get mem%d resource\n", i);1210 return ERR_PTR(-EINVAL);1211 }1212 virt_base[i] = devm_ioremap(&pdev->dev, res->start,1213 resource_size(res));1214 if (!virt_base[i]) {1215 dev_err(&pdev->dev, "failed to ioremap %pR\n", res);1216 return ERR_PTR(-EIO);1217 }1218 }1219 1220 bank = d->pin_banks;1221 bdata = ctrl->pin_banks;1222 for (i = 0; i < ctrl->nr_banks; ++i, ++bdata, ++bank) {1223 bank->type = bdata->type;1224 bank->pctl_offset = bdata->pctl_offset;1225 bank->nr_pins = bdata->nr_pins;1226 bank->eint_func = bdata->eint_func;1227 bank->eint_type = bdata->eint_type;1228 bank->eint_mask = bdata->eint_mask;1229 bank->eint_offset = bdata->eint_offset;1230 bank->eint_con_offset = bdata->eint_con_offset;1231 bank->eint_mask_offset = bdata->eint_mask_offset;1232 bank->eint_pend_offset = bdata->eint_pend_offset;1233 bank->name = bdata->name;1234 1235 raw_spin_lock_init(&bank->slock);1236 bank->drvdata = d;1237 bank->pin_base = d->nr_pins;1238 d->nr_pins += bank->nr_pins;1239 1240 bank->eint_base = virt_base[0];1241 bank->pctl_base = virt_base[bdata->pctl_res_idx];1242 }1243 /*1244 * Legacy platforms should provide only one resource with IO memory.1245 * Store it as virt_base because legacy driver needs to access it1246 * through samsung_pinctrl_drv_data.1247 */1248 d->virt_base = virt_base[0];1249 1250 samsung_banks_node_get(&pdev->dev, d);1251 1252 return ctrl;1253}1254 1255static int samsung_pinctrl_probe(struct platform_device *pdev)1256{1257 struct samsung_pinctrl_drv_data *drvdata;1258 const struct samsung_pin_ctrl *ctrl;1259 struct device *dev = &pdev->dev;1260 int ret;1261 1262 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);1263 if (!drvdata)1264 return -ENOMEM;1265 1266 ctrl = samsung_pinctrl_get_soc_data(drvdata, pdev);1267 if (IS_ERR(ctrl)) {1268 dev_err(&pdev->dev, "driver data not available\n");1269 return PTR_ERR(ctrl);1270 }1271 drvdata->dev = dev;1272 1273 ret = platform_get_irq_optional(pdev, 0);1274 if (ret < 0 && ret != -ENXIO)1275 return ret;1276 if (ret > 0)1277 drvdata->irq = ret;1278 1279 if (ctrl->retention_data) {1280 drvdata->retention_ctrl = ctrl->retention_data->init(drvdata,1281 ctrl->retention_data);1282 if (IS_ERR(drvdata->retention_ctrl)) {1283 ret = PTR_ERR(drvdata->retention_ctrl);1284 goto err_put_banks;1285 }1286 }1287 1288 drvdata->pclk = devm_clk_get_optional_prepared(dev, "pclk");1289 if (IS_ERR(drvdata->pclk)) {1290 ret = PTR_ERR(drvdata->pclk);1291 goto err_put_banks;1292 }1293 1294 ret = samsung_pinctrl_register(pdev, drvdata);1295 if (ret)1296 goto err_put_banks;1297 1298 if (ctrl->eint_gpio_init)1299 ctrl->eint_gpio_init(drvdata);1300 if (ctrl->eint_wkup_init)1301 ctrl->eint_wkup_init(drvdata);1302 1303 if (ctrl->pud_value_init)1304 ctrl->pud_value_init(drvdata);1305 else1306 samsung_pud_value_init(drvdata);1307 1308 ret = samsung_gpiolib_register(pdev, drvdata);1309 if (ret)1310 goto err_unregister;1311 1312 ret = pinctrl_enable(drvdata->pctl_dev);1313 if (ret)1314 goto err_unregister;1315 1316 platform_set_drvdata(pdev, drvdata);1317 1318 return 0;1319 1320err_unregister:1321 samsung_pinctrl_unregister(pdev, drvdata);1322err_put_banks:1323 samsung_banks_node_put(drvdata);1324 return ret;1325}1326 1327/*1328 * samsung_pinctrl_suspend - save pinctrl state for suspend1329 *1330 * Save data for all banks handled by this device.1331 */1332static int __maybe_unused samsung_pinctrl_suspend(struct device *dev)1333{1334 struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);1335 int i;1336 1337 i = clk_enable(drvdata->pclk);1338 if (i) {1339 dev_err(drvdata->dev,1340 "failed to enable clock for saving state\n");1341 return i;1342 }1343 1344 for (i = 0; i < drvdata->nr_banks; i++) {1345 struct samsung_pin_bank *bank = &drvdata->pin_banks[i];1346 const void __iomem *reg = bank->pctl_base + bank->pctl_offset;1347 const u8 *offs = bank->type->reg_offset;1348 const u8 *widths = bank->type->fld_width;1349 enum pincfg_type type;1350 1351 /* Registers without a powerdown config aren't lost */1352 if (!widths[PINCFG_TYPE_CON_PDN])1353 continue;1354 1355 for (type = 0; type < PINCFG_TYPE_NUM; type++)1356 if (widths[type])1357 bank->pm_save[type] = readl(reg + offs[type]);1358 1359 if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {1360 /* Some banks have two config registers */1361 bank->pm_save[PINCFG_TYPE_NUM] =1362 readl(reg + offs[PINCFG_TYPE_FUNC] + 4);1363 pr_debug("Save %s @ %p (con %#010x %08x)\n",1364 bank->name, reg,1365 bank->pm_save[PINCFG_TYPE_FUNC],1366 bank->pm_save[PINCFG_TYPE_NUM]);1367 } else {1368 pr_debug("Save %s @ %p (con %#010x)\n", bank->name,1369 reg, bank->pm_save[PINCFG_TYPE_FUNC]);1370 }1371 }1372 1373 clk_disable(drvdata->pclk);1374 1375 if (drvdata->suspend)1376 drvdata->suspend(drvdata);1377 if (drvdata->retention_ctrl && drvdata->retention_ctrl->enable)1378 drvdata->retention_ctrl->enable(drvdata);1379 1380 return 0;1381}1382 1383/*1384 * samsung_pinctrl_resume - restore pinctrl state from suspend1385 *1386 * Restore one of the banks that was saved during suspend.1387 *1388 * We don't bother doing anything complicated to avoid glitching lines since1389 * we're called before pad retention is turned off.1390 */1391static int __maybe_unused samsung_pinctrl_resume(struct device *dev)1392{1393 struct samsung_pinctrl_drv_data *drvdata = dev_get_drvdata(dev);1394 int ret;1395 int i;1396 1397 /*1398 * enable clock before the callback, as we don't want to have to deal1399 * with callback cleanup on clock failures.1400 */1401 ret = clk_enable(drvdata->pclk);1402 if (ret) {1403 dev_err(drvdata->dev,1404 "failed to enable clock for restoring state\n");1405 return ret;1406 }1407 1408 if (drvdata->resume)1409 drvdata->resume(drvdata);1410 1411 for (i = 0; i < drvdata->nr_banks; i++) {1412 struct samsung_pin_bank *bank = &drvdata->pin_banks[i];1413 void __iomem *reg = bank->pctl_base + bank->pctl_offset;1414 const u8 *offs = bank->type->reg_offset;1415 const u8 *widths = bank->type->fld_width;1416 enum pincfg_type type;1417 1418 /* Registers without a powerdown config aren't lost */1419 if (!widths[PINCFG_TYPE_CON_PDN])1420 continue;1421 1422 if (widths[PINCFG_TYPE_FUNC] * bank->nr_pins > 32) {1423 /* Some banks have two config registers */1424 pr_debug("%s @ %p (con %#010x %08x => %#010x %08x)\n",1425 bank->name, reg,1426 readl(reg + offs[PINCFG_TYPE_FUNC]),1427 readl(reg + offs[PINCFG_TYPE_FUNC] + 4),1428 bank->pm_save[PINCFG_TYPE_FUNC],1429 bank->pm_save[PINCFG_TYPE_NUM]);1430 writel(bank->pm_save[PINCFG_TYPE_NUM],1431 reg + offs[PINCFG_TYPE_FUNC] + 4);1432 } else {1433 pr_debug("%s @ %p (con %#010x => %#010x)\n", bank->name,1434 reg, readl(reg + offs[PINCFG_TYPE_FUNC]),1435 bank->pm_save[PINCFG_TYPE_FUNC]);1436 }1437 for (type = 0; type < PINCFG_TYPE_NUM; type++)1438 if (widths[type])1439 writel(bank->pm_save[type], reg + offs[type]);1440 }1441 1442 clk_disable(drvdata->pclk);1443 1444 if (drvdata->retention_ctrl && drvdata->retention_ctrl->disable)1445 drvdata->retention_ctrl->disable(drvdata);1446 1447 return 0;1448}1449 1450static const struct of_device_id samsung_pinctrl_dt_match[] = {1451#ifdef CONFIG_PINCTRL_EXYNOS_ARM1452 { .compatible = "samsung,exynos3250-pinctrl",1453 .data = &exynos3250_of_data },1454 { .compatible = "samsung,exynos4210-pinctrl",1455 .data = &exynos4210_of_data },1456 { .compatible = "samsung,exynos4x12-pinctrl",1457 .data = &exynos4x12_of_data },1458 { .compatible = "samsung,exynos5250-pinctrl",1459 .data = &exynos5250_of_data },1460 { .compatible = "samsung,exynos5260-pinctrl",1461 .data = &exynos5260_of_data },1462 { .compatible = "samsung,exynos5410-pinctrl",1463 .data = &exynos5410_of_data },1464 { .compatible = "samsung,exynos5420-pinctrl",1465 .data = &exynos5420_of_data },1466 { .compatible = "samsung,s5pv210-pinctrl",1467 .data = &s5pv210_of_data },1468#endif1469#ifdef CONFIG_PINCTRL_EXYNOS_ARM641470 { .compatible = "google,gs101-pinctrl",1471 .data = &gs101_of_data },1472 { .compatible = "samsung,exynos5433-pinctrl",1473 .data = &exynos5433_of_data },1474 { .compatible = "samsung,exynos7-pinctrl",1475 .data = &exynos7_of_data },1476 { .compatible = "samsung,exynos7885-pinctrl",1477 .data = &exynos7885_of_data },1478 { .compatible = "samsung,exynos850-pinctrl",1479 .data = &exynos850_of_data },1480 { .compatible = "samsung,exynosautov9-pinctrl",1481 .data = &exynosautov9_of_data },1482 { .compatible = "samsung,exynosautov920-pinctrl",1483 .data = &exynosautov920_of_data },1484 { .compatible = "tesla,fsd-pinctrl",1485 .data = &fsd_of_data },1486#endif1487#ifdef CONFIG_PINCTRL_S3C64XX1488 { .compatible = "samsung,s3c64xx-pinctrl",1489 .data = &s3c64xx_of_data },1490#endif1491 {},1492};1493 1494static const struct dev_pm_ops samsung_pinctrl_pm_ops = {1495 SET_LATE_SYSTEM_SLEEP_PM_OPS(samsung_pinctrl_suspend,1496 samsung_pinctrl_resume)1497};1498 1499static struct platform_driver samsung_pinctrl_driver = {1500 .probe = samsung_pinctrl_probe,1501 .driver = {1502 .name = "samsung-pinctrl",1503 .of_match_table = samsung_pinctrl_dt_match,1504 .suppress_bind_attrs = true,1505 .pm = &samsung_pinctrl_pm_ops,1506 },1507};1508 1509static int __init samsung_pinctrl_drv_register(void)1510{1511 return platform_driver_register(&samsung_pinctrl_driver);1512}1513postcore_initcall(samsung_pinctrl_drv_register);1514