Received: by 2002:a05:6a10:413:0:0:0:0 with SMTP id 19csp2133217pxp; Sun, 13 Mar 2022 09:36:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw2gxynyUeO/Jf5fWcrF9XnwxkQI7CPjngoPpW7njSAAX1rzXRW8W7cIr0cLsX+T1SPpIt4 X-Received: by 2002:a05:6a00:c93:b0:4f7:c76:921f with SMTP id a19-20020a056a000c9300b004f70c76921fmr20246512pfv.73.1647189393553; Sun, 13 Mar 2022 09:36:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1647189393; cv=none; d=google.com; s=arc-20160816; b=aORCfnd9gP+JtR2BP/Hxo/Tmhn8uU4QXjUx6L2fuuk2cSWUH9qLLK8hW+Zcx7FHxsn KjqfT7X/w2BEUAXQJyvTCXA7KtPMIuMHZlARmW0ScQinfslEmUmYmiN4Y8XFbH+x84Hl 8bImGS9WFJKKDGF6Ch8i6Zcg7kX5MC3mwyWvcKryq8jq4phiBs2TbV1P5DK9RqJP+BrY Ebkr0Nts3EUjqz9xuXE3pJKocQCubK3GT7NtMlD+JdqfAITw71IgklUkLXl8KNIuj+uw og1xhyb+AMchuIUf6f0tCOhV/hn4G6fV4CVswpeoOwrz8zfeHArbJT6iWRcSVBB5omg6 1ilQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id; bh=kb0de6HldLnd4xohCrVDNj13OM4MWv/wQJJZL01v2vo=; b=j2CALjHOasxa2XzMFjUFWb0Vx12huiclQuBADIRV3OMwkJcicE8JtPPFaIzexJC0+o 1o6k+l2EUBdiTMm1VV4ehCPnEjt7bBp8NTJAK0ky6+mol6s8N4oUOWWWQ6BGZyAFWZV3 AfAodSHSbZCR5j2VmscvXae4mrbOJ+KLS8XX6t7pzRLfNOwr3JCyM0bYPI8yPEEgoU7S q82MpZxwJQQqII2u0cbP44edPTf19SoEJySrr2MV5NxL3EUY6TdyOKN8EHISL//vF7aZ TB7LsU1ETuvIKky7xIv0nWYhFM7yjpRly2cvcMw/5EMh1n5o+v7PQJrC/xwskIKTyuig h1Wg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j12-20020a170903024c00b001514c2da722si15975081plh.349.2022.03.13.09.36.16; Sun, 13 Mar 2022 09:36:33 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234196AbiCMJop (ORCPT + 99 others); Sun, 13 Mar 2022 05:44:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233001AbiCMJoo (ORCPT ); Sun, 13 Mar 2022 05:44:44 -0400 Received: from mail-ed1-f45.google.com (mail-ed1-f45.google.com [209.85.208.45]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 83BC05E169; Sun, 13 Mar 2022 01:43:36 -0800 (PST) Received: by mail-ed1-f45.google.com with SMTP id c20so15970922edr.8; Sun, 13 Mar 2022 01:43:36 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:message-id:date:mime-version:user-agent:subject :content-language:to:cc:references:from:in-reply-to :content-transfer-encoding; bh=kb0de6HldLnd4xohCrVDNj13OM4MWv/wQJJZL01v2vo=; b=nsz+/mW60ek1IhhY7qM4gsomgiwuqbE4PVSD0MgZegeYA/W+sYSDvosAQbsm5MzdUx b2QrfOPzasq3i6QhM6xVRQm3IwMcDWhxJb9Jks1UdG3uSCeYWFEPgWI0XCI5uwivGpIv Rmk13hRvIvzHNBskNfNIpoTQgGL7Bj+Z6uOcngI7WisrgdFTKdOhPxkfSri3CWE4YlCH NxINOG7VRiWfAYGJniCVDSrXR3kV1KEx6EFreq9EOyxmYaucSia2QsStyPQLy9jzXY1B KmPPUYfmd1xKqi4wWTJawjgV+HEYBYg0iA5Kg/HJVKbTo7RxJsMoOwnz7KcTA7DMdFvC DJjg== X-Gm-Message-State: AOAM531E5DT9HRoMzHYAVpcV7ZM5eSGiReIFKqInr4KoCFdzDosC2kmv uPo6f/U5RVy90qBer6HTu+3cMeqtha4= X-Received: by 2002:a50:d4d2:0:b0:410:9fa2:60d6 with SMTP id e18-20020a50d4d2000000b004109fa260d6mr16062652edj.35.1647164614932; Sun, 13 Mar 2022 01:43:34 -0800 (PST) Received: from [192.168.0.150] (xdsl-188-155-174-239.adslplus.ch. [188.155.174.239]) by smtp.googlemail.com with ESMTPSA id re21-20020a170906d8d500b006daf3718d0csm5353269ejb.143.2022.03.13.01.43.33 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sun, 13 Mar 2022 01:43:34 -0800 (PST) Message-ID: <00362767-080a-aa7f-672f-22b83ab35e61@kernel.org> Date: Sun, 13 Mar 2022 10:43:33 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0 Subject: Re: [PATCH v11 2/2] misc: Add iop driver for Sunplus SP7021 Content-Language: en-US To: Tony Huang , robh+dt@kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, derek.kiernan@xilinx.com, dragan.cvetic@xilinx.com, arnd@arndb.de, gregkh@linuxfoundation.org Cc: wells.lu@sunplus.com, tony.huang@sunplus.com References: <07f507a84a9e39d3cd8393f41d1292c250e07642.1647095774.git.tonyhuang.sunplus@gmail.com> From: Krzysztof Kozlowski In-Reply-To: <07f507a84a9e39d3cd8393f41d1292c250e07642.1647095774.git.tonyhuang.sunplus@gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00, FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS, NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 12/03/2022 17:16, Tony Huang wrote: > This driver is load 8051 bin code. > The IOP core is DQ8051, so also named IOP8051. > Need Install DQ8051, The DQ8051 bin file generated by keil C. > We will provide users with 8051 normal and power off source code. > Path: https://sunplus.atlassian.net/wiki/spaces/doc/pages/610172933/ > How+to+use+I+O+processor+8051+of+SP7021#5.-Write-C-or-assembly-source- > files-for-IOP > Users can follow the operation steps to generate normal.bin and > poweroff.bin. > Path: https://sunplus.atlassian.net/wiki/spaces/doc/pages/466190338 > /26.+IOP8051 26.5?How To Create 8051 bin file > > PMC in power management purpose: > Add sp_iop_poweroff() function. pm_power_off=sp_iop_poweroff. > When the power off command is executed. > The 8051 has a register(DEF_PWR_EN_0=0) to control the power-on and > power-off of the system. > > Signed-off-by: Tony Huang > --- > Changes in v11: > - Addressed comments from Arnd Bergmann. How did you address Arnd's comments about splitting the driver to proper parts? drivers/clk and drivers/power/reset? > - Addressed comments from krzysztof. > > MAINTAINERS | 1 + > drivers/misc/Kconfig | 23 +++ > drivers/misc/Makefile | 1 + > drivers/misc/sunplus_iop.c | 411 +++++++++++++++++++++++++++++++++++++++++++++ The driver looks like SoC specific driver. Why did you put it in drivers/misc/, not in usual place - drivers/soc/? sp_iop_poweroff is still here. > 4 files changed, 436 insertions(+) > create mode 100644 drivers/misc/sunplus_iop.c > > diff --git a/MAINTAINERS b/MAINTAINERS > index d64c8ed..c282e95 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -18246,6 +18246,7 @@ SUNPLUS IOP DRIVER > M: Tony Huang > S: Maintained > F: Documentation/devicetree/bindings/misc/sunplus,iop.yaml > +F: drivers/misc/sunplus_iop.c > > SUPERH > M: Yoshinori Sato > diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig > index 0f5a49f..e5f32d8 100644 > --- a/drivers/misc/Kconfig > +++ b/drivers/misc/Kconfig > @@ -470,6 +470,29 @@ config HISI_HIKEY_USB > switching between the dual-role USB-C port and the USB-A host ports > using only one USB controller. > > +config SUNPLUS_IOP > + tristate "Sunplus IOP support" > + default ARCH_SUNPLUS > + help > + This driver is load 8051 bin code. > + The IOP core is DQ8051, so also named IOP8051. > + Need Install DQ8051, The DQ8051 bin file generated by keil C. > + We will provide users with 8051 normal and power off source code. > + Path: https://sunplus.atlassian.net/wiki/spaces/doc/pages/610172933/ > + How+to+use+I+O+processor+8051+of+SP7021#5.-Write-C-or-assembly-source-files-for-IOP > + Users can follow the operation steps to generate normal.bin and poweroff.bin. > + Path: https://sunplus.atlassian.net/wiki/spaces/doc/pages/466190338/26.+IOP8051 > + 26.5?How To Create 8051 bin file > + > + PMC in power management purpose: > + Add sp_iop_poweroff() function. pm_power_off=sp_iop_poweroff. > + When the power off command is executed. > + The 8051 has a register(DEF_PWR_EN_0=0) to control the power-on and > + power-off of the system. > + > + This driver can also be built as a module. If so, the module > + will be called sunplus_iop. > + > source "drivers/misc/c2port/Kconfig" > source "drivers/misc/eeprom/Kconfig" > source "drivers/misc/cb710/Kconfig" > diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile > index a086197..eafeab6 100644 > --- a/drivers/misc/Makefile > +++ b/drivers/misc/Makefile > @@ -52,6 +52,7 @@ obj-$(CONFIG_DW_XDATA_PCIE) += dw-xdata-pcie.o > obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o > obj-$(CONFIG_OCXL) += ocxl/ > obj-$(CONFIG_BCM_VK) += bcm-vk/ > +obj-$(CONFIG_SUNPLUS_IOP) += sunplus_iop.o > obj-y += cardreader/ > obj-$(CONFIG_PVPANIC) += pvpanic/ > obj-$(CONFIG_HABANA_AI) += habanalabs/ > diff --git a/drivers/misc/sunplus_iop.c b/drivers/misc/sunplus_iop.c > new file mode 100644 > index 0000000..5bdce5e > --- /dev/null > +++ b/drivers/misc/sunplus_iop.c > @@ -0,0 +1,411 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * The IOP driver for Sunplus SP7021 > + * > + * Copyright (C) 2021 Sunplus Technology Inc. > + * > + * All Rights Reserved. > + */ > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* IOP register offset */ > +#define IOP_CONTROL 0x00 > +#define IOP_DATA0 0x20 > +#define IOP_DATA1 0x24 > +#define IOP_DATA2 0x28 > +#define IOP_DATA3 0x2c > +#define IOP_DATA4 0x30 > +#define IOP_DATA5 0x34 > +#define IOP_DATA6 0x38 > +#define IOP_DATA7 0x3c > +#define IOP_DATA8 0x40 > +#define IOP_DATA9 0x44 > +#define IOP_DATA10 0x48 > +#define IOP_DATA11 0x4c > +#define IOP_BASE_ADR_L 0x50 > +#define IOP_BASE_ADR_H 0x54 > + > +/* PMC register offset */ > +#define IOP_PMC_TIMER 0x00 > +#define IOP_PMC_CTRL 0x04 > +#define IOP_XTAL27M_PASSWORD_I 0x08 > +#define IOP_XTAL27M_PASSWORD_II 0x0c > +#define IOP_XTAL32K_PASSWORD_I 0x10 > +#define IOP_XTAL32K_PASSWORD_II 0x14 > +#define IOP_CLK27M_PASSWORD_I 0x18 > +#define IOP_CLK27M_PASSWORD_II 0x1c > +#define IOP_PMC_TIMER2 0x20 > + > +/* Max size of poweroff.bin that can be received */ > +#define POWEROFF_CODE_MAX_SIZE 0x4000 > + > +/* 8051 informs linux kerenl. 8051 has been switched to poweroff.bin code. */ > +#define IOP_READY 0x0004 > +#define RISC_READY 0x0008 > + > +/* System linux kernel tells 8051 which gpio pin to wake-up through. */ > +#define WAKEUP_PIN 0xFE02 > + > +/* > + * There are 3 power domains in SP7021, AO domain, IOP domain, > + * Default domain. Default domain is linux kernel system. > + * System linux kernel tells 8051 to execute power off. > + */ > +#define DEFAULT_DOMAIN_POWEROFF 0x5331 /* AO&IOP domain on, Default domain off */ > +#define DEFAULT_AND_IOP_DOMAIN_POWEROFF 0x5333 /* AO domain on, IOP&Default domain off */ > + > +struct sp_iop { > + struct device *dev; > + struct clk *iopclk; > + struct reset_control *rstc; > + void __iomem *iop_regs; > + void __iomem *pmc_regs; > + void __iomem *moon0_regs; > + int irq; > + int gpio_wakeup; > + resource_size_t iop_mem_start; > + resource_size_t iop_mem_size; > + unsigned char bin_code_mode; > +}; > + > +static struct sp_iop *iop_poweroff; > + > +static void sp_iop_load_normal_code(struct sp_iop *iop) > +{ > + const struct firmware *fw; > + void __iomem *iop_kernel_base; > + unsigned int reg, err; > + > + err = request_firmware(&fw, "normal.bin", iop->dev); > + if (err) > + dev_err(iop->dev, "get bin file error\n"); > + > + iop_kernel_base = ioremap(iop->iop_mem_start, fw->size); > + memset(iop_kernel_base, 0, fw->size); > + memcpy(iop_kernel_base, fw->data, fw->size); > + release_firmware(fw); > + > + clk_prepare_enable(iop->iopclk); where do you disable the clock? > + > + reg = readl(iop->iop_regs + IOP_CONTROL); > + reg |= 0x01; > + writel(reg, iop->iop_regs + IOP_CONTROL); > + (...) > +static int sp_iop_get_resources(struct platform_device *pdev, struct sp_iop *p_sp_iop_info) > +{ > + struct resource *r; > + > + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iop"); > + p_sp_iop_info->iop_regs = devm_ioremap_resource(&pdev->dev, r); > + if (IS_ERR(p_sp_iop_info->iop_regs)) { > + dev_err(&pdev->dev, "ioremap fail\n"); > + return PTR_ERR(p_sp_iop_info->iop_regs); > + } > + > + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iop_pmc"); > + p_sp_iop_info->pmc_regs = devm_ioremap_resource(&pdev->dev, r); > + if (IS_ERR(p_sp_iop_info->pmc_regs)) { > + dev_err(&pdev->dev, "ioremap fail\n"); > + return PTR_ERR(p_sp_iop_info->pmc_regs); > + } > + > + r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "moon0"); > + p_sp_iop_info->moon0_regs = devm_ioremap_resource(&pdev->dev, r); > + if (IS_ERR(p_sp_iop_info->moon0_regs)) { > + dev_err(&pdev->dev, "ioremap fail\n"); > + return PTR_ERR(p_sp_iop_info->moon0_regs); > + } > + return 0; https://lore.kernel.org/all/16d98dfa-66f9-f9a4-08c9-d68d78c33b23@canonical.com/ You received a comment about adding blank lines before return. This has to be done everywhere. > +} > + > +static int sp_iop_platform_driver_probe(struct platform_device *pdev) Do not add "platform_driver" suffix to functions. "_probe" is enough. > +{ > + int ret = -ENXIO; > + int rc; > + struct sp_iop *iop; > + struct device_node *memnp; > + struct resource mem_res; > + > + iop = devm_kzalloc(&pdev->dev, sizeof(struct sp_iop), GFP_KERNEL); > + if (!iop) { > + ret = -ENOMEM; > + goto fail_kmalloc; > + } > + > + ret = sp_iop_get_resources(pdev, iop); > + > + /* Get reserve address. */ > + memnp = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); > + if (!memnp) { > + dev_err(&pdev->dev, "no memory-region node\n"); > + return -EINVAL; > + } > + > + rc = of_address_to_resource(memnp, 0, &mem_res); > + of_node_put(memnp); > + if (rc) { > + dev_err(&pdev->dev, "failed to translate memory-region to a resource\n"); > + return -EINVAL; > + } > + > + iop->dev = &pdev->dev; > + iop->iop_mem_start = mem_res.start; > + iop->iop_mem_size = resource_size(&mem_res); > + iop->iopclk = devm_clk_get(&pdev->dev, NULL); > + if (IS_ERR(iop->iopclk)) > + return dev_err_probe(&pdev->dev, PTR_ERR(iop->iopclk), > + "devm_clk_get fail\n"); Clocks are not documented but required in bindings? > + > + /* > + * 8051 has two bin files, normal.bin and poweroff.bin in rootfs. > + * Normally, 8051 executes normal.bin code. Normal.bin code size can exceed 16K. > + */ > + sp_iop_load_normal_code(iop); > + > + platform_set_drvdata(pdev, iop); > + iop->gpio_wakeup = of_get_named_gpio(pdev->dev.of_node, "iop-wakeup", 0); It's not in the bindings. Do not add undocumented properties. Everything has to be in the bindings. I don't see usage of generic wakeup-gpios, so this all looks untested. You didn't run this code, did you? > + iop_poweroff = iop; > + pm_power_off = sp_iop_poweroff; > + > + return 0; > + > +fail_kmalloc: > + return ret; > +} > + > +static int sp_iop_remove(struct platform_device *pdev) > +{ > + pm_power_off = NULL; > + return 0; > +} > + > +static const struct of_device_id sp_iop_of_match[] = { > + { .compatible = "sunplus,sp7021-iop" }, > + { /* sentinel */ }, > +}; > + > +MODULE_DEVICE_TABLE(of, sp_iop_of_match); > + > +static struct platform_driver sp_iop_platform_driver = { > + .probe = sp_iop_platform_driver_probe, > + .remove = sp_iop_remove, > + .driver = { > + .name = "sunplus,sp7021-iop", > + .of_match_table = sp_iop_of_match, > + } > +}; > + > +module_platform_driver(sp_iop_platform_driver); > + > +MODULE_AUTHOR("Tony Huang "); > +MODULE_DESCRIPTION("Sunplus IOP Driver"); > +MODULE_LICENSE("GPL v2"); Best regards, Krzysztof