From patchwork Sat Jul 28 06:58:39 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haojian Zhuang X-Patchwork-Id: 1251371 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 4729A3FC5A for ; Sat, 28 Jul 2012 07:07:01 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Sv12g-0007l2-2S; Sat, 28 Jul 2012 07:02:26 +0000 Received: from mail-pb0-f49.google.com ([209.85.160.49]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Sv0zx-0007di-Rt for linux-arm-kernel@lists.infradead.org; Sat, 28 Jul 2012 06:59:38 +0000 Received: by mail-pb0-f49.google.com with SMTP id rq13so6832454pbb.36 for ; Fri, 27 Jul 2012 23:59:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=2tPbesp4AlwV5OAU5FCGIzYlcEQORNWJCTHXF3LM/24=; b=CTsfeeHRhwFWgPwgLZrxktsWuiZWOqmRp/1nEwaAKYT6rdqBghf6pn19t49367tyLv GwS6x60DARRxl5sBRBfIARSbNdv1sPdSp6t/MLkKw2T5XUcwiJqN8nC0wN8d4cbYd0wK 5V0LaUtaI0oMjZaGGwU80ELEtVh7o6bMQDVhiKrAVybYl18BuERVmQdhTs3hH+4jn0IC EYp2tG+CDXj5kDHpACa1NjOW62Vzv2qC3sJIzc4/x2RyVcLus0QlGlRnbSyXRUv+N6Zz Z/OEZxonDiiyhE/mGEYmBLXQ1+x5QjsMSQlRx2gEo/zzjI0qSJwznZHJx6TwBrom9Rts fgFw== Received: by 10.68.196.193 with SMTP id io1mr19945684pbc.17.1343458777365; Fri, 27 Jul 2012 23:59:37 -0700 (PDT) Received: from localhost ([221.239.195.16]) by mx.google.com with ESMTPS id pj10sm3448445pbb.46.2012.07.27.23.59.32 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 27 Jul 2012 23:59:36 -0700 (PDT) From: Haojian Zhuang To: linux-arm-kernel@lists.infradead.org, grant.likely@secretlab.ca, linus.walleij@stericsson.com, arnd@arndb.de Subject: [PATCH 3/6] pinctrl: support dt in pxa series Date: Sat, 28 Jul 2012 14:58:39 +0800 Message-Id: <1343458722-17127-4-git-send-email-haojian.zhuang@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1343458722-17127-1-git-send-email-haojian.zhuang@gmail.com> References: <1343458722-17127-1-git-send-email-haojian.zhuang@gmail.com> X-Spam-Note: CRM114 invocation failed X-Spam-Note: SpamAssassin invocation failed Cc: Haojian Zhuang X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add DT support in PXA168/PXA910/MMP2 pinctrl driver. Signed-off-by: Haojian Zhuang Acked-by: Linus Walleij --- drivers/pinctrl/pinctrl-mmp2.c | 10 ++- drivers/pinctrl/pinctrl-pxa168.c | 10 ++- drivers/pinctrl/pinctrl-pxa3xx.c | 136 ++++++++++++++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-pxa910.c | 10 ++- 4 files changed, 163 insertions(+), 3 deletions(-) diff --git a/drivers/pinctrl/pinctrl-mmp2.c b/drivers/pinctrl/pinctrl-mmp2.c index 2cfed55..25b9cd3 100644 --- a/drivers/pinctrl/pinctrl-mmp2.c +++ b/drivers/pinctrl/pinctrl-mmp2.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "pinctrl-pxa3xx.h" @@ -696,10 +697,16 @@ static int __devexit mmp2_pinmux_remove(struct platform_device *pdev) return pxa3xx_pinctrl_unregister(pdev); } +static struct of_device_id mmp2_pinctrl_of_match[] __devinitdata = { + { .compatible = "marvell,mmp2-pinmux", }, + { }, +}; + static struct platform_driver mmp2_pinmux_driver = { .driver = { .name = "mmp2-pinmux", .owner = THIS_MODULE, + .of_match_table = mmp2_pinctrl_of_match, }, .probe = mmp2_pinmux_probe, .remove = __devexit_p(mmp2_pinmux_remove), @@ -718,5 +725,6 @@ static void __exit mmp2_pinmux_exit(void) module_exit(mmp2_pinmux_exit); MODULE_AUTHOR("Haojian Zhuang "); -MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_DESCRIPTION("MMP2 pin control driver"); MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, mmp2_pinctrl_of_match); diff --git a/drivers/pinctrl/pinctrl-pxa168.c b/drivers/pinctrl/pinctrl-pxa168.c index c1997fa..959a13d 100644 --- a/drivers/pinctrl/pinctrl-pxa168.c +++ b/drivers/pinctrl/pinctrl-pxa168.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "pinctrl-pxa3xx.h" @@ -625,10 +626,16 @@ static int __devexit pxa168_pinmux_remove(struct platform_device *pdev) return pxa3xx_pinctrl_unregister(pdev); } +static struct of_device_id pxa168_pinctrl_of_match[] __devinitdata = { + { .compatible = "marvell,pxa168-pinmux", }, + { }, +}; + static struct platform_driver pxa168_pinmux_driver = { .driver = { .name = "pxa168-pinmux", .owner = THIS_MODULE, + .of_match_table = pxa168_pinctrl_of_match, }, .probe = pxa168_pinmux_probe, .remove = __devexit_p(pxa168_pinmux_remove), @@ -647,5 +654,6 @@ static void __exit pxa168_pinmux_exit(void) module_exit(pxa168_pinmux_exit); MODULE_AUTHOR("Haojian Zhuang "); -MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_DESCRIPTION("PXA168 pin control driver"); MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, pxa168_pinctrl_of_match); diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c index cae74db..125839f 100644 --- a/drivers/pinctrl/pinctrl-pxa3xx.c +++ b/drivers/pinctrl/pinctrl-pxa3xx.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -54,10 +55,145 @@ static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev, return 0; } +static int pxa3xx_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev, + struct device_node *np_config, + struct pinctrl_map **map, + unsigned *num_maps) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrl_dev); + struct device_node *np; + struct property *prop; + const char *func, *group; + int ret, count = 0, i = 0, pin_num, size; + u32 ds, cfg; + + /* verify subnode */ + for_each_child_of_node(np_config, np) { + ret = of_property_read_string(np, "marvell,function", &func); + if (ret < 0) + return ret; + ret = of_property_count_strings(np, "marvell,pins"); + if (ret < 0) + return ret; + count += ret; + pin_num = ret; + + if (!of_property_read_u32(np, "marvell,drive-strength", &ds)) + count += pin_num; + + if (of_find_property(np, "marvell,pull-up", &size) + || of_find_property(np, "marvell,pull-down", &size)) + count += pin_num; + + if (of_find_property(np, "marvell,lowpower-pull-up", &size) + || of_find_property(np, "marvell,lowpower-pull-down", + &size) + || of_find_property(np, "marvell,lowpower-drive-high", + &size) + || of_find_property(np, "marvell,lowpower-drive-low", + &size) + || of_find_property(np, "marvell,lowpower-float", &size) + || of_find_property(np, "marvell,lowpower-zero", &size)) + count += pin_num; + } + + if (!count) { + dev_err(info->dev, "No child nodes passed via DT\n"); + return -ENODEV; + } + + *map = kzalloc(sizeof(**map) * count, GFP_KERNEL); + if (!*map) + return -ENOMEM; + + for_each_child_of_node(np_config, np) { + of_property_read_string(np, "marvell,function", &func); + of_property_for_each_string(np, "marvell,pins", prop, group) { + (*map)[i].type = PIN_MAP_TYPE_MUX_GROUP; + (*map)[i].data.mux.group = group; + (*map)[i].data.mux.function = func; + i++; + + cfg = 0; + if (of_find_property(np, "marvell,pull-up", &size)) + cfg = PXA3XX_PINCONF_PULL_UP; + else if (of_find_property(np, + "marvell,pull-down", &size)) + cfg = PXA3XX_PINCONF_PULL_DOWN; + if (cfg) { + (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; + (*map)[i].data.configs.configs = + kmemdup(&cfg, sizeof(cfg), GFP_KERNEL); + (*map)[i].data.configs.group_or_pin = group; + (*map)[i].data.configs.num_configs = 1; + i++; + } + + cfg = 0; + if (of_find_property(np, "marvell,lowpower-pull-up", + &size)) + cfg = PXA3XX_PINCONF_LOWPOWER_PULL_UP; + else if (of_find_property(np, + "marvell,lowpower-pull-down", &size)) + cfg = PXA3XX_PINCONF_LOWPOWER_PULL_DOWN; + else if (of_find_property(np, + "marvell,lowpower-drive-high", &size)) + cfg = PXA3XX_PINCONF_LOWPOWER_DRIVE_HIGH; + else if (of_find_property(np, + "marvell,lowpower-drive-low", &size)) + cfg = PXA3XX_PINCONF_LOWPOWER_DRIVE_LOW; + else if (of_find_property(np, + "marvell,lowpower-float", &size)) + cfg = PXA3XX_PINCONF_LOWPOWER_FLOAT; + else if (of_find_property(np, + "marvell,lowpower-zero", &size)) + cfg = PXA3XX_PINCONF_LOWPOWER_ZERO; + if (cfg) { + (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; + (*map)[i].data.configs.configs = + kmemdup(&cfg, sizeof(cfg), GFP_KERNEL); + (*map)[i].data.configs.group_or_pin = group; + (*map)[i].data.configs.num_configs = 1; + i++; + } + + cfg = 0; + if (!of_property_read_u32(np, + "marvell,drive-strength", &ds)) + cfg = PXA3XX_PINCONF_DRIVE_STRENGTH + | (ds << PXA3XX_PINCONF_DS_SHIFT); + if (cfg) { + (*map)[i].type = PIN_MAP_TYPE_CONFIGS_GROUP; + (*map)[i].data.configs.configs = + kmemdup(&cfg, sizeof(cfg), GFP_KERNEL); + (*map)[i].data.configs.group_or_pin = group; + (*map)[i].data.configs.num_configs = 1; + i++; + } + } + } + *num_maps = count; + return 0; +} + +static void pxa3xx_pinctrl_dt_free_map(struct pinctrl_dev *pctrl_dev, + struct pinctrl_map *map, + unsigned num_maps) +{ + int i; + + for (i = 0; i < num_maps; i++) + if (map[i].type == PIN_MAP_TYPE_CONFIGS_GROUP) + kfree(map[i].data.configs.configs); + kfree(map); +} + static struct pinctrl_ops pxa3xx_pctrl_ops = { .get_groups_count = pxa3xx_get_groups_count, .get_group_name = pxa3xx_get_group_name, .get_group_pins = pxa3xx_get_group_pins, + .dt_node_to_map = pxa3xx_pinctrl_dt_node_to_map, + .dt_free_map = pxa3xx_pinctrl_dt_free_map, }; static int pxa3xx_pmx_get_funcs_count(struct pinctrl_dev *pctrldev) diff --git a/drivers/pinctrl/pinctrl-pxa910.c b/drivers/pinctrl/pinctrl-pxa910.c index 4164a6b..ccda259 100644 --- a/drivers/pinctrl/pinctrl-pxa910.c +++ b/drivers/pinctrl/pinctrl-pxa910.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "pinctrl-pxa3xx.h" @@ -985,10 +986,16 @@ static int __devexit pxa910_pinmux_remove(struct platform_device *pdev) return pxa3xx_pinctrl_unregister(pdev); } +static struct of_device_id pxa910_pinctrl_of_match[] __devinitdata = { + { .compatible = "marvell,pxa910-pinmux", }, + { }, +}; + static struct platform_driver pxa910_pinmux_driver = { .driver = { .name = "pxa910-pinmux", .owner = THIS_MODULE, + .of_match_table = pxa910_pinctrl_of_match, }, .probe = pxa910_pinmux_probe, .remove = __devexit_p(pxa910_pinmux_remove), @@ -1007,5 +1014,6 @@ static void __exit pxa910_pinmux_exit(void) module_exit(pxa910_pinmux_exit); MODULE_AUTHOR("Haojian Zhuang "); -MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_DESCRIPTION("PXA910 pin control driver"); MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, pxa910_pinctrl_of_match);