From patchwork Fri Jan 2 19:51:59 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Gerlach X-Patchwork-Id: 5560611 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B36EDBF6C3 for ; Fri, 2 Jan 2015 19:55:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id A19402025A for ; Fri, 2 Jan 2015 19:55:03 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 989D420256 for ; Fri, 2 Jan 2015 19:55:02 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Y78HV-0003Wu-1z; Fri, 02 Jan 2015 19:53:09 +0000 Received: from bear.ext.ti.com ([192.94.94.41]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Y78Gz-0003Js-Oo for linux-arm-kernel@lists.infradead.org; Fri, 02 Jan 2015 19:52:39 +0000 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id t02JqAlr015758; Fri, 2 Jan 2015 13:52:10 -0600 Received: from DLEE71.ent.ti.com (dlee71.ent.ti.com [157.170.170.114]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id t02JqAeK029585; Fri, 2 Jan 2015 13:52:10 -0600 Received: from dlep32.itg.ti.com (157.170.170.100) by DLEE71.ent.ti.com (157.170.170.114) with Microsoft SMTP Server id 14.3.174.1; Fri, 2 Jan 2015 13:52:10 -0600 Received: from legion.dal.design.ti.com (legion.dal.design.ti.com [128.247.22.53]) by dlep32.itg.ti.com (8.14.3/8.13.8) with ESMTP id t02JqASR008760; Fri, 2 Jan 2015 13:52:10 -0600 Received: from localhost (dave-ubuntu.am.dhcp.ti.com [128.247.71.184]) by legion.dal.design.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id t02Jq9t19833; Fri, 2 Jan 2015 13:52:10 -0600 (CST) From: Dave Gerlach To: , , , Subject: [PATCH 3/3] remoteproc: wkup_m3: Add wkup_m3 remote proc driver Date: Fri, 2 Jan 2015 13:51:59 -0600 Message-ID: <1420228319-41085-4-git-send-email-d-gerlach@ti.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1420228319-41085-1-git-send-email-d-gerlach@ti.com> References: <1420228319-41085-1-git-send-email-d-gerlach@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150102_115237_946742_1FBF0865 X-CRM114-Status: GOOD ( 18.23 ) X-Spam-Score: -5.0 (-----) Cc: Ohad Ben-Cohen , Kevin Hilman , Arnd Bergmann , Dave Gerlach , Tony Lindgren , Benoit Cousson X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a remoteproc driver to load the firmware for and boot the wkup_m3 present on am33xx. The wkup_m3 is an integrated Cortex M3 that allows the SoC to enter the lowest possible power state by taking control from the MPU after it has gone into its own low power state and shutting off any additional peripherals. The driver expects a resource table to be present in the wkup_m3 firmware to define the required memory resources needed by the wkup_m3, at least the data memory so that the firmware can be copied to the proper place for execution. Signed-off-by: Dave Gerlach --- drivers/remoteproc/Kconfig | 12 +++ drivers/remoteproc/Makefile | 1 + drivers/remoteproc/wkup_m3_rproc.c | 175 +++++++++++++++++++++++++++++++++++++ 3 files changed, 188 insertions(+) create mode 100644 drivers/remoteproc/wkup_m3_rproc.c diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 5e343ba..7fbdb53 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -41,6 +41,18 @@ config STE_MODEM_RPROC This can be either built-in or a loadable module. If unsure say N. +config WKUP_M3_RPROC + bool "AM33xx wkup-m3 remoteproc support" + depends on SOC_AM33XX + select REMOTEPROC + help + Say y here to support AM33xx wkup-m3. + + Required for Suspend-to-ram and CPUIdle on AM33xx. Allows for + loading of firmware of CM3 PM coprocessor that is present + on AM33xx family of SoCs + If unsure say N. + config DA8XX_REMOTEPROC tristate "DA8xx/OMAP-L13x remoteproc support" depends on ARCH_DAVINCI_DA8XX diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index ac2ff75..81b04d1 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -9,4 +9,5 @@ remoteproc-y += remoteproc_virtio.o remoteproc-y += remoteproc_elf_loader.o obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o obj-$(CONFIG_STE_MODEM_RPROC) += ste_modem_rproc.o +obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o diff --git a/drivers/remoteproc/wkup_m3_rproc.c b/drivers/remoteproc/wkup_m3_rproc.c new file mode 100644 index 0000000..8686ca2 --- /dev/null +++ b/drivers/remoteproc/wkup_m3_rproc.c @@ -0,0 +1,175 @@ +/* + * AMx3 Wkup M3 Remote Processor driver + * + * Copyright (C) 2014 Texas Instruments, Inc. + * + * Dave Gerlach + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "remoteproc_internal.h" + +struct wkup_m3_rproc { + struct rproc *rproc; + struct platform_device *pdev; +}; + +static int wkup_m3_rproc_start(struct rproc *rproc) +{ + struct wkup_m3_rproc *m3_rproc = rproc->priv; + struct platform_device *pdev = m3_rproc->pdev; + struct device *dev = &pdev->dev; + struct wkup_m3_platform_data *pdata = dev->platform_data; + int ret; + + ret = pdata->deassert_reset(pdev, pdata->reset_name); + if (ret) { + dev_err(dev, "Unable to reset wkup_m3!\n"); + return -ENODEV; + } + + return 0; +} + +static int wkup_m3_rproc_stop(struct rproc *rproc) +{ + struct wkup_m3_rproc *m3_rproc = rproc->priv; + struct platform_device *pdev = m3_rproc->pdev; + struct device *dev = &pdev->dev; + struct wkup_m3_platform_data *pdata = dev->platform_data; + int ret; + + ret = pdata->assert_reset(pdev, pdata->reset_name); + if (ret) { + dev_err(dev, "Unable to assert reset of wkup_m3!\n"); + return -ENODEV; + } + return 0; +} + +static struct rproc_ops wkup_m3_rproc_ops = { + .start = wkup_m3_rproc_start, + .stop = wkup_m3_rproc_stop, +}; + +static const struct of_device_id wkup_m3_rproc_of_match[] = { + { + .compatible = "ti,am3353-wkup-m3", + .data = (void *)"am335x-pm-firmware.elf", + }, + {}, +}; + +static int wkup_m3_rproc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const char *fw_name; + struct wkup_m3_platform_data *pdata = dev->platform_data; + struct wkup_m3_rproc *m3_rproc; + const struct of_device_id *match; + struct rproc *rproc; + int ret; + + if (!(pdata && pdata->deassert_reset && pdata->assert_reset && + pdata->reset_name)) { + dev_err(dev, "Platform data missing!\n"); + return -ENODEV; + } + + match = of_match_device(wkup_m3_rproc_of_match, &pdev->dev); + if (!match) + return -ENODEV; + fw_name = (char *)match->data; + + pm_runtime_enable(&pdev->dev); + + ret = pm_runtime_get_sync(&pdev->dev); + if (IS_ERR_VALUE(ret)) { + dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); + return ret; + } + + rproc = rproc_alloc(dev, "wkup_m3", &wkup_m3_rproc_ops, + fw_name, sizeof(*m3_rproc)); + if (!rproc) + return -ENOMEM; + + m3_rproc = rproc->priv; + m3_rproc->rproc = rproc; + m3_rproc->pdev = pdev; + + dev_set_drvdata(dev, rproc); + + /* Register as a remoteproc device */ + ret = rproc_add(rproc); + if (ret) { + dev_err(dev, "rproc_add failed\n"); + goto err; + } + + return 0; + +err: + rproc_put(rproc); + pm_runtime_put_sync(&pdev->dev); + return ret; +} + +static int wkup_m3_rproc_remove(struct platform_device *pdev) +{ + struct rproc *rproc = platform_get_drvdata(pdev); + + rproc_del(rproc); + rproc_put(rproc); + pm_runtime_put_sync(&pdev->dev); + + return 0; +} + +static int wkup_m3_rpm_suspend(struct device *dev) +{ + return -EBUSY; +} + +static int wkup_m3_rpm_resume(struct device *dev) +{ + return 0; +} + +static const struct dev_pm_ops wkup_m3_rproc_pm_ops = { + SET_RUNTIME_PM_OPS(wkup_m3_rpm_suspend, wkup_m3_rpm_resume, NULL) +}; + +static struct platform_driver wkup_m3_rproc_driver = { + .probe = wkup_m3_rproc_probe, + .remove = wkup_m3_rproc_remove, + .driver = { + .name = "wkup_m3", + .of_match_table = wkup_m3_rproc_of_match, + .pm = &wkup_m3_rproc_pm_ops, + }, +}; + +module_platform_driver(wkup_m3_rproc_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("wkup m3 remote processor control driver");