1/* 2 * Intel MIC Platform Software Stack (MPSS) 3 * 4 * Copyright(c) 2013 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, version 2, as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * The full GNU General Public License is included in this distribution in 16 * the file called "COPYING". 17 * 18 * Disclaimer: The codes contained in these modules may be specific to 19 * the Intel Software Development Platform codenamed: Knights Ferry, and 20 * the Intel product codenamed: Knights Corner, and are not backward 21 * compatible with other Intel products. Additionally, Intel will NOT 22 * support the codes or instruction set in future products. 23 * 24 * Intel MIC Card driver. 25 * 26 */ 27#include <linux/module.h> 28#include <linux/pci.h> 29#include <linux/interrupt.h> 30#include <linux/reboot.h> 31 32#include <linux/mic_common.h> 33#include "../common/mic_dev.h" 34#include "mic_device.h" 35#include "mic_virtio.h" 36 37static struct mic_driver *g_drv; 38static struct mic_irq *shutdown_cookie; 39 40static void mic_notify_host(u8 state) 41{ 42 struct mic_driver *mdrv = g_drv; 43 struct mic_bootparam __iomem *bootparam = mdrv->dp; 44 45 iowrite8(state, &bootparam->shutdown_status); 46 dev_dbg(mdrv->dev, "%s %d system_state %d\n", 47 __func__, __LINE__, state); 48 mic_send_intr(&mdrv->mdev, ioread8(&bootparam->c2h_shutdown_db)); 49} 50 51static int mic_panic_event(struct notifier_block *this, unsigned long event, 52 void *ptr) 53{ 54 struct mic_driver *mdrv = g_drv; 55 struct mic_bootparam __iomem *bootparam = mdrv->dp; 56 57 iowrite8(-1, &bootparam->h2c_config_db); 58 iowrite8(-1, &bootparam->h2c_shutdown_db); 59 mic_notify_host(MIC_CRASHED); 60 return NOTIFY_DONE; 61} 62 63static struct notifier_block mic_panic = { 64 .notifier_call = mic_panic_event, 65}; 66 67static irqreturn_t mic_shutdown_isr(int irq, void *data) 68{ 69 struct mic_driver *mdrv = g_drv; 70 struct mic_bootparam __iomem *bootparam = mdrv->dp; 71 72 mic_ack_interrupt(&g_drv->mdev); 73 if (ioread8(&bootparam->shutdown_card)) 74 orderly_poweroff(true); 75 return IRQ_HANDLED; 76} 77 78static int mic_shutdown_init(void) 79{ 80 int rc = 0; 81 struct mic_driver *mdrv = g_drv; 82 struct mic_bootparam __iomem *bootparam = mdrv->dp; 83 int shutdown_db; 84 85 shutdown_db = mic_next_card_db(); 86 shutdown_cookie = mic_request_card_irq(mic_shutdown_isr, NULL, 87 "Shutdown", mdrv, shutdown_db); 88 if (IS_ERR(shutdown_cookie)) 89 rc = PTR_ERR(shutdown_cookie); 90 else 91 iowrite8(shutdown_db, &bootparam->h2c_shutdown_db); 92 return rc; 93} 94 95static void mic_shutdown_uninit(void) 96{ 97 struct mic_driver *mdrv = g_drv; 98 struct mic_bootparam __iomem *bootparam = mdrv->dp; 99 100 iowrite8(-1, &bootparam->h2c_shutdown_db); 101 mic_free_card_irq(shutdown_cookie, mdrv); 102} 103 104static int __init mic_dp_init(void) 105{ 106 struct mic_driver *mdrv = g_drv; 107 struct mic_device *mdev = &mdrv->mdev; 108 struct mic_bootparam __iomem *bootparam; 109 u64 lo, hi, dp_dma_addr; 110 u32 magic; 111 112 lo = mic_read_spad(&mdrv->mdev, MIC_DPLO_SPAD); 113 hi = mic_read_spad(&mdrv->mdev, MIC_DPHI_SPAD); 114 115 dp_dma_addr = lo | (hi << 32); 116 mdrv->dp = mic_card_map(mdev, dp_dma_addr, MIC_DP_SIZE); 117 if (!mdrv->dp) { 118 dev_err(mdrv->dev, "Cannot remap Aperture BAR\n"); 119 return -ENOMEM; 120 } 121 bootparam = mdrv->dp; 122 magic = ioread32(&bootparam->magic); 123 if (MIC_MAGIC != magic) { 124 dev_err(mdrv->dev, "bootparam magic mismatch 0x%x\n", magic); 125 return -EIO; 126 } 127 return 0; 128} 129 130/* Uninitialize the device page */ 131static void mic_dp_uninit(void) 132{ 133 mic_card_unmap(&g_drv->mdev, g_drv->dp); 134} 135 136/** 137 * mic_request_card_irq - request an irq. 138 * 139 * @handler: interrupt handler passed to request_threaded_irq. 140 * @thread_fn: thread fn. passed to request_threaded_irq. 141 * @name: The ASCII name of the callee requesting the irq. 142 * @data: private data that is returned back when calling the 143 * function handler. 144 * @index: The doorbell index of the requester. 145 * 146 * returns: The cookie that is transparent to the caller. Passed 147 * back when calling mic_free_irq. An appropriate error code 148 * is returned on failure. Caller needs to use IS_ERR(return_val) 149 * to check for failure and PTR_ERR(return_val) to obtained the 150 * error code. 151 * 152 */ 153struct mic_irq * 154mic_request_card_irq(irq_handler_t handler, 155 irq_handler_t thread_fn, const char *name, 156 void *data, int index) 157{ 158 int rc = 0; 159 unsigned long cookie; 160 struct mic_driver *mdrv = g_drv; 161 162 rc = request_threaded_irq(mic_db_to_irq(mdrv, index), handler, 163 thread_fn, 0, name, data); 164 if (rc) { 165 dev_err(mdrv->dev, "request_threaded_irq failed rc = %d\n", rc); 166 goto err; 167 } 168 mdrv->irq_info.irq_usage_count[index]++; 169 cookie = index; 170 return (struct mic_irq *)cookie; 171err: 172 return ERR_PTR(rc); 173} 174 175/** 176 * mic_free_card_irq - free irq. 177 * 178 * @cookie: cookie obtained during a successful call to mic_request_threaded_irq 179 * @data: private data specified by the calling function during the 180 * mic_request_threaded_irq 181 * 182 * returns: none. 183 */ 184void mic_free_card_irq(struct mic_irq *cookie, void *data) 185{ 186 int index; 187 struct mic_driver *mdrv = g_drv; 188 189 index = (unsigned long)cookie & 0xFFFFU; 190 free_irq(mic_db_to_irq(mdrv, index), data); 191 mdrv->irq_info.irq_usage_count[index]--; 192} 193 194/** 195 * mic_next_card_db - Get the doorbell with minimum usage count. 196 * 197 * Returns the irq index. 198 */ 199int mic_next_card_db(void) 200{ 201 int i; 202 int index = 0; 203 struct mic_driver *mdrv = g_drv; 204 205 for (i = 0; i < mdrv->intr_info.num_intr; i++) { 206 if (mdrv->irq_info.irq_usage_count[i] < 207 mdrv->irq_info.irq_usage_count[index]) 208 index = i; 209 } 210 211 return index; 212} 213 214/** 215 * mic_init_irq - Initialize irq information. 216 * 217 * Returns 0 in success. Appropriate error code on failure. 218 */ 219static int mic_init_irq(void) 220{ 221 struct mic_driver *mdrv = g_drv; 222 223 mdrv->irq_info.irq_usage_count = kzalloc((sizeof(u32) * 224 mdrv->intr_info.num_intr), 225 GFP_KERNEL); 226 if (!mdrv->irq_info.irq_usage_count) 227 return -ENOMEM; 228 return 0; 229} 230 231/** 232 * mic_uninit_irq - Uninitialize irq information. 233 * 234 * None. 235 */ 236static void mic_uninit_irq(void) 237{ 238 struct mic_driver *mdrv = g_drv; 239 240 kfree(mdrv->irq_info.irq_usage_count); 241} 242 243/* 244 * mic_driver_init - MIC driver initialization tasks. 245 * 246 * Returns 0 in success. Appropriate error code on failure. 247 */ 248int __init mic_driver_init(struct mic_driver *mdrv) 249{ 250 int rc; 251 252 g_drv = mdrv; 253 /* 254 * Unloading the card module is not supported. The MIC card module 255 * handles fundamental operations like host/card initiated shutdowns 256 * and informing the host about card crashes and cannot be unloaded. 257 */ 258 if (!try_module_get(mdrv->dev->driver->owner)) { 259 rc = -ENODEV; 260 goto done; 261 } 262 rc = mic_dp_init(); 263 if (rc) 264 goto put; 265 rc = mic_init_irq(); 266 if (rc) 267 goto dp_uninit; 268 rc = mic_shutdown_init(); 269 if (rc) 270 goto irq_uninit; 271 rc = mic_devices_init(mdrv); 272 if (rc) 273 goto shutdown_uninit; 274 mic_create_card_debug_dir(mdrv); 275 atomic_notifier_chain_register(&panic_notifier_list, &mic_panic); 276done: 277 return rc; 278shutdown_uninit: 279 mic_shutdown_uninit(); 280irq_uninit: 281 mic_uninit_irq(); 282dp_uninit: 283 mic_dp_uninit(); 284put: 285 module_put(mdrv->dev->driver->owner); 286 return rc; 287} 288 289/* 290 * mic_driver_uninit - MIC driver uninitialization tasks. 291 * 292 * Returns None 293 */ 294void mic_driver_uninit(struct mic_driver *mdrv) 295{ 296 mic_delete_card_debug_dir(mdrv); 297 mic_devices_uninit(mdrv); 298 /* 299 * Inform the host about the shutdown status i.e. poweroff/restart etc. 300 * The module cannot be unloaded so the only code path to call 301 * mic_devices_uninit(..) is the shutdown callback. 302 */ 303 mic_notify_host(system_state); 304 mic_shutdown_uninit(); 305 mic_uninit_irq(); 306 mic_dp_uninit(); 307 module_put(mdrv->dev->driver->owner); 308} 309