Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752898AbbLKS2Y (ORCPT ); Fri, 11 Dec 2015 13:28:24 -0500 Received: from mail-bn1bn0102.outbound.protection.outlook.com ([157.56.110.102]:23264 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752073AbbLKS1O (ORCPT ); Fri, 11 Dec 2015 13:27:14 -0500 Authentication-Results: spf=permerror (sender IP is 192.88.168.50) smtp.mailfrom=freescale.com; freescale.mail.onmicrosoft.com; dkim=none (message not signed) header.d=none;freescale.mail.onmicrosoft.com; dmarc=none action=none header.from=freescale.com; From: "J. German Rivera" To: , , , CC: , , , , , , , , , , , , , , "J. German Rivera" Subject: [PATCH v4 10/11] staging: fsl-mc: Added DPRC interrupt handler Date: Fri, 11 Dec 2015 12:09:48 -0600 Message-ID: <1449857389-2506-11-git-send-email-German.Rivera@freescale.com> X-Mailer: git-send-email 2.3.3 In-Reply-To: <1449857389-2506-1-git-send-email-German.Rivera@freescale.com> References: <1449857389-2506-1-git-send-email-German.Rivera@freescale.com> X-EOPAttributedMessage: 0 X-Microsoft-Exchange-Diagnostics: 1;BY2FFO11FD008;1:dD4FsfMfbfTqh6JTQ9zxrHfhgUFiQUDgbLOXZ/FVBpxtRgcJgK/VRFx8DRd5A4VvVybrJfxGmu80ixbVD1dZ5Q9PvdHJmRL3+T7SjDWn8ybjtYnYwxc0joGmIoyG1/KY9x6voVxQPobVy0uodBYg+MC0cgzsAr76U3/y47StgWp1BUnbSOV0vSH9BryEzeg9wmd0NeV5dfGksOjhbLUS8Nz7+XIWLmunoZ70ENbxq5zOBZOlfMzhfSsINCDaWUOjtYBACQa2qDMZjK+ZjLpYyBSjc55TIDyYe0NpbNGkj4i/SjNhsiA89MnmdHnpi/EUFsMgQa1Hca2YG+Q05OH3SavbuWcPyeLD2HPrIMLNfJCX/NGfwmNFC/Jzd/3xUGwC7zow5ih+lFlDUEOl7rnZ3oH+IqPxmok9FtTdCeZqVUn7H3JyZOTkC18x4zJnqN1X X-Forefront-Antispam-Report: CIP:192.88.168.50;CTRY:US;IPV:NLI;EFV:NLI;SFV:NSPM;SFS:(10019020)(6009001)(2980300002)(448002)(189002)(199003)(2201001)(1096002)(104016004)(5001960100002)(92566002)(86362001)(19580405001)(97736004)(189998001)(81156007)(85326001)(50986999)(11100500001)(47776003)(107886002)(87936001)(50226001)(5008740100001)(575784001)(76176999)(6806005)(4001430100002)(5001770100001)(1220700001)(586003)(50466002)(19580395003)(2950100001)(36756003)(5003940100001)(106466001)(229853001)(77096005)(48376002);DIR:OUT;SFP:1102;SCL:1;SRVR:CY1PR0301MB1307;H:tx30smr01.am.freescale.net;FPR:;SPF:PermError;PTR:InfoDomainNonexistent;MX:1;A:1;LANG:en; MIME-Version: 1.0 Content-Type: text/plain X-Microsoft-Exchange-Diagnostics: 1;CY1PR0301MB1307;2:ERHqbQUNgZH5CnjWjqbgnFhe38jc5x4kAHjlWH4aPntGwTjoX8G3nNcpLY5bWYLSw+zx9ICE/iiwygWSey56NaXYFaZp7lrAzoiTB5MBmflaaKmDzLpoqFVrq9DnWeYh4Eqs4QDlA/rz0/gRL5zhyg==;3:H/8UwsAjQ7n5LYAEXMPSxC3xNT9jC2jL1zbR2fJHeZ/v093Y2aB62vSWye3/M1GjN8AtqYTYOHNGV4ggwny8FJCSpP2c3A01BC9YtcPGJ4nBlGx90otfeNZB19r6L9CvSxIyWLrKCLlORRokrfsrTBUJAiF5XLQsyeQxMg89R7q5FJy3SUGgyleVSxWeP6XbAUZeG0porxLAbhoYcPOf7mHYRadPNTpK/2WGYMIUD90=;25:o83PMM+DJAi8ZtPaJI16aoFCxw31NGRFGWMkkGxqXL1jy36Sk5pQDjAV0hXSsUOQkueSAyr3Z9JKdyBtuqAbBsqfnbLIC3oQp1Qpk3qy0KIwwtj+gespl5uR6gGKQzJrix/LF11wcyY4hX92RKGDSQYPJExMeeFmcKCJkcieE6DzLclJyIeAx5wapkRmO0yqW2XizeftMEDqjM0RikiLw+TJWgbPj4NCiU6EyfEv9Fsqb9x4bPVaeLr8Qo/E9ji3mJvnHduoCR2g0gxacdXdRQ== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0301MB1307; X-Microsoft-Exchange-Diagnostics: 1;CY1PR0301MB1307;20:1lpk2dueNAzx53nEQ+nPjMNg2ZFfmvQHMWYmMyPoOaNcQRHP9/qKcCLr19TPwVm4S4j5VlJmMk9eSDd8lu+tgOnlF7GyGKd9jEI992LWwH/HZkwnC9ZTI6FXb54B4qpP9BMhFsNdKQL+0gucEo1xssE13/ridAH9Ux+TkDgfnSYlhNE0BB2jku2Z+x7MAcAbaZZ8CPhJxTFXm1qkb10ocpOw8oOQq3WqhZiwrbL6w+Cu6yiyq6sNmG3KFGVIe+on1tGnaW3CdvhZwRLDYGLRTQ3e5vdGruUfeiLN7h2sHB9jqLXkUeVyZuEEQBde6dAHlKVeBmC2rYF9JRFW+abO95bRFjfMxdk0vZBCx5T97jI=;4:7FKgTwbYLCO5CzOJ3KzGzobf7oijJRTRqv+MduEd8eX6fuh8PR3+1w2SQ1NDthbChjd1mecLrsj0sL/ldkp5BjhoolnZ9DQKSkY1aGOay2uBRe85ZowlMQL5FB1SApXW0XRwZaWf7hwTYZ+IIcKdbyd9IzWQDk/fZLJHgNVwbIrU8TkddstbWtsXdimWf68BrrUsQ1YekWIsjYo+iY64yd62WQYUHLQZfbkivsgf8MrsUH5ik/Fw0rpWUXXLXa3h9C5ybpYzNc81rv31NFulSLALmW/DtD5AnA+gbrnqUKR2n5aCfY42EOnfFvQgeRaf0NCeHZxlmlhsB7pY7nwoI4LIWlgiirQwZl+LeV/7VMFjH7y75bmsCQfJ8bnzfAXdTgFPfmguRnWXteKJv0t+25ILwoth3B4epoRBaL/dJ0235SXSRaLa3erVqcB3A8py X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(101931422205132); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(520078)(8121501046)(3002001)(10201501046);SRVR:CY1PR0301MB1307;BCL:0;PCL:0;RULEID:;SRVR:CY1PR0301MB1307; X-Forefront-PRVS: 0787459938 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CY1PR0301MB1307;23:WwFa8+HbS+Sy37QuzET9JNzeNW8f5bytbazCQj4?= =?us-ascii?Q?F1EEZAf5uZjNN8UFk8tl/0Yg9dIowOCSchGJAx3oARZksxAIfuWbR8v29mgF?= =?us-ascii?Q?1sQk5a+XFKlBbK4Ht2fRYe3PK3oZ9zhUk5pY4xViqZ4XMzV6W2epWREiRQZL?= =?us-ascii?Q?DralCY3N24AyDL+voyk2ZlVSMqW5eKDFJBL8rkvRFvVhFNZqqmjvc3g5fQJi?= =?us-ascii?Q?iJdAjKzdcqrkHKs4gU0lDAb3QtTURE17Pgciy37hRGqWLFirK/TBUSOfMMvp?= =?us-ascii?Q?VU4HowJmI/mvpwu+kUdqHGcUuq62zDmfVaOpFTSjtgAtCFGqD699kx/EKbqY?= =?us-ascii?Q?ACquxGtpoxo7A8tue3dNx9+THOL3tDjLZ3YOmC22vwjUgs0xlOSF8qM3l40T?= =?us-ascii?Q?+5aB8c+o6RMsKn/z/d4utqOEl+Y6V5Lohx0HX0MT9Za0dZpXNWoG8UBXdgCn?= =?us-ascii?Q?tPHOiOcDzmJJq18qX7ty1F+vD+4wdVK2jSb21brcBRnYga7subyalDQ2XhXY?= =?us-ascii?Q?iQARktLKThEYQsrgjt258O3cLuPTYbYcyjykCil7jORPaBw9dGlPguWXQ1Oq?= =?us-ascii?Q?bUAe2PGPGrCE7Bvc/l05p/DLo2WSV+2Iq3dJo9jP+E4Tr6IzL0B3JxrEQU3K?= =?us-ascii?Q?0ouydFmYMQc/8kKIYskgQh5RqMGSz6S687y8BZGjgb5Q53Y0A4S+n2USUqtE?= =?us-ascii?Q?AkmigjE9J1Yc0M7DFFRNkZqLEJrkWybwTkLRflVNYvYNnz21u3UYFWLwfs5+?= =?us-ascii?Q?paGg0EBvo39Wgxnk7KvitQ5CkwrdmffkFHQRhW8CetDERo8xemw5KTFFidyX?= =?us-ascii?Q?ZJhF2NsO8IOT/THBvd38lYDCsP2kBYhoYKX/igxgUq2PojQ2+gqVVKAPc3e0?= =?us-ascii?Q?4fNHBtCLr+s9odKIKtszibAnhrHa4lww3gNQRP90nEYUVoXLJTEQGKiNsQjN?= =?us-ascii?Q?F7boZ0YWsHrwaMoqMpkpht75fneAMlHPGyV7gSJPcZyplfFeWWrigUrTQu6i?= =?us-ascii?Q?xhSNv1SeV5gRDQ34AWMQa9G4wkWtDnsJ4pSUtEHwd/W/Jj5uMzecCk//XGzt?= =?us-ascii?Q?6DK0pjXg=3D?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR0301MB1307;5:6TdWuOJOKMoKYBrP9rDF+BLwee90doCBWBT43FIlE6Nz0RurXdUIC0B7xG1iG/iVq6D7Vla5JDSxlAOZnRb0bRv40TyuuqXWWudWrrMkoj6+qlpZmR9H9uy3xQZY09fQauZ5pWcuB+2FtS7+CHQ4BQ==;24:EYfniKKreIqk21yrJdEs9WtWZlwrISmgI+VVK8QqWFnPFuNZmOXOq1ZGkiTzg6wvFXQ8YwDX5DV9Qm7MEwamA2CZJy8Vyig9dBiX5k3vJmw= X-OriginatorOrg: freescale.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Dec 2015 18:27:09.2398 (UTC) X-MS-Exchange-CrossTenant-Id: 710a03f5-10f6-4d38-9ff4-a80b81da590d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=710a03f5-10f6-4d38-9ff4-a80b81da590d;Ip=[192.88.168.50];Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR0301MB1307 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7863 Lines: 313 The interrupt handler for DPRC IRQs is added. DPRC IRQs are generated for hot plug events related to DPAA2 objects in a given DPRC. These events include, creating/destroying DPAA2 objects in the DPRC, changing the "plugged" state of DPAA2 objects and moving objects between DPRCs. Signed-off-by: J. German Rivera --- CHANGE HISTORY Changes in v4: none Changes in v3: none Changes in v2: none drivers/staging/fsl-mc/bus/dprc-driver.c | 247 +++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) diff --git a/drivers/staging/fsl-mc/bus/dprc-driver.c b/drivers/staging/fsl-mc/bus/dprc-driver.c index 42b2494..52c6fce 100644 --- a/drivers/staging/fsl-mc/bus/dprc-driver.c +++ b/drivers/staging/fsl-mc/bus/dprc-driver.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "dprc-cmd.h" struct dprc_child_objs { @@ -386,6 +387,230 @@ error: EXPORT_SYMBOL_GPL(dprc_scan_container); /** + * dprc_irq0_handler - Regular ISR for DPRC interrupt 0 + * + * @irq: IRQ number of the interrupt being handled + * @arg: Pointer to device structure + */ +static irqreturn_t dprc_irq0_handler(int irq_num, void *arg) +{ + return IRQ_WAKE_THREAD; +} + +/** + * dprc_irq0_handler_thread - Handler thread function for DPRC interrupt 0 + * + * @irq: IRQ number of the interrupt being handled + * @arg: Pointer to device structure + */ +static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg) +{ + int error; + u32 status; + struct device *dev = (struct device *)arg; + struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); + struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev); + struct fsl_mc_io *mc_io = mc_dev->mc_io; + struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc; + + dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n", + irq_num, smp_processor_id()); + + if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC))) + return IRQ_HANDLED; + + mutex_lock(&mc_bus->scan_mutex); + if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num)) + goto out; + + error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0, + &status); + if (error < 0) { + dev_err(dev, + "dprc_get_irq_status() failed: %d\n", error); + goto out; + } + + error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0, + status); + if (error < 0) { + dev_err(dev, + "dprc_clear_irq_status() failed: %d\n", error); + goto out; + } + + if (status & (DPRC_IRQ_EVENT_OBJ_ADDED | + DPRC_IRQ_EVENT_OBJ_REMOVED | + DPRC_IRQ_EVENT_CONTAINER_DESTROYED | + DPRC_IRQ_EVENT_OBJ_DESTROYED | + DPRC_IRQ_EVENT_OBJ_CREATED)) { + unsigned int irq_count; + + error = dprc_scan_objects(mc_dev, &irq_count); + if (error < 0) { + /* + * If the error is -ENXIO, we ignore it, as it indicates + * that the object scan was aborted, as we detected that + * an object was removed from the DPRC in the MC, while + * we were scanning the DPRC. + */ + if (error != -ENXIO) { + dev_err(dev, "dprc_scan_objects() failed: %d\n", + error); + } + + goto out; + } + + if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) { + dev_warn(dev, + "IRQs needed (%u) exceed IRQs preallocated (%u)\n", + irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS); + } + } + +out: + mutex_unlock(&mc_bus->scan_mutex); + return IRQ_HANDLED; +} + +/* + * Disable and clear interrupt for a given DPRC object + */ +static int disable_dprc_irq(struct fsl_mc_device *mc_dev) +{ + int error; + struct fsl_mc_io *mc_io = mc_dev->mc_io; + + WARN_ON(mc_dev->obj_desc.irq_count != 1); + + /* + * Disable generation of interrupt, while we configure it: + */ + error = dprc_set_irq_enable(mc_io, 0, mc_dev->mc_handle, 0, 0); + if (error < 0) { + dev_err(&mc_dev->dev, + "Disabling DPRC IRQ failed: dprc_set_irq_enable() failed: %d\n", + error); + return error; + } + + /* + * Disable all interrupt causes for the interrupt: + */ + error = dprc_set_irq_mask(mc_io, 0, mc_dev->mc_handle, 0, 0x0); + if (error < 0) { + dev_err(&mc_dev->dev, + "Disabling DPRC IRQ failed: dprc_set_irq_mask() failed: %d\n", + error); + return error; + } + + /* + * Clear any leftover interrupts: + */ + error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0, ~0x0U); + if (error < 0) { + dev_err(&mc_dev->dev, + "Disabling DPRC IRQ failed: dprc_clear_irq_status() failed: %d\n", + error); + return error; + } + + return 0; +} + +static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev) +{ + int error; + struct fsl_mc_device_irq *irq = mc_dev->irqs[0]; + + WARN_ON(mc_dev->obj_desc.irq_count != 1); + + /* + * NOTE: devm_request_threaded_irq() invokes the device-specific + * function that programs the MSI physically in the device + */ + error = devm_request_threaded_irq(&mc_dev->dev, + irq->msi_desc->irq, + dprc_irq0_handler, + dprc_irq0_handler_thread, + IRQF_NO_SUSPEND | IRQF_ONESHOT, + "FSL MC DPRC irq0", + &mc_dev->dev); + if (error < 0) { + dev_err(&mc_dev->dev, + "devm_request_threaded_irq() failed: %d\n", + error); + return error; + } + + return 0; +} + +static int enable_dprc_irq(struct fsl_mc_device *mc_dev) +{ + int error; + + /* + * Enable all interrupt causes for the interrupt: + */ + error = dprc_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle, 0, + ~0x0u); + if (error < 0) { + dev_err(&mc_dev->dev, + "Enabling DPRC IRQ failed: dprc_set_irq_mask() failed: %d\n", + error); + + return error; + } + + /* + * Enable generation of the interrupt: + */ + error = dprc_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle, 0, 1); + if (error < 0) { + dev_err(&mc_dev->dev, + "Enabling DPRC IRQ failed: dprc_set_irq_enable() failed: %d\n", + error); + + return error; + } + + return 0; +} + +/* + * Setup interrupt for a given DPRC device + */ +static int dprc_setup_irq(struct fsl_mc_device *mc_dev) +{ + int error; + + error = fsl_mc_allocate_irqs(mc_dev); + if (error < 0) + return error; + + error = disable_dprc_irq(mc_dev); + if (error < 0) + goto error_free_irqs; + + error = register_dprc_irq_handler(mc_dev); + if (error < 0) + goto error_free_irqs; + + error = enable_dprc_irq(mc_dev); + if (error < 0) + goto error_free_irqs; + + return 0; + +error_free_irqs: + fsl_mc_free_irqs(mc_dev); + return error; +} + +/** * dprc_probe - callback invoked when a DPRC is being bound to this driver * * @mc_dev: Pointer to fsl-mc device representing a DPRC @@ -476,6 +701,13 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) if (error < 0) goto error_cleanup_open; + /* + * Configure interrupt for the DPRC object associated with this MC bus: + */ + error = dprc_setup_irq(mc_dev); + if (error < 0) + goto error_cleanup_open; + dev_info(&mc_dev->dev, "DPRC device bound to driver"); return 0; @@ -494,6 +726,15 @@ error_cleanup_msi_domain: return error; } +/* + * Tear down interrupt for a given DPRC object + */ +static void dprc_teardown_irq(struct fsl_mc_device *mc_dev) +{ + (void)disable_dprc_irq(mc_dev); + fsl_mc_free_irqs(mc_dev); +} + /** * dprc_remove - callback invoked when a DPRC is being unbound from this driver * @@ -514,6 +755,12 @@ static int dprc_remove(struct fsl_mc_device *mc_dev) if (WARN_ON(!mc_dev->mc_io)) return -EINVAL; + if (WARN_ON(!mc_bus->irq_resources)) + return -EINVAL; + + if (dev_get_msi_domain(&mc_dev->dev)) + dprc_teardown_irq(mc_dev); + device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove); dprc_cleanup_all_resource_pools(mc_dev); error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle); -- 2.3.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/