linux/drivers/misc/mic/host/mic_boot.c
<<
>>
Prefs
   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 * Intel MIC Host driver.
  19 *
  20 */
  21#include <linux/delay.h>
  22#include <linux/firmware.h>
  23#include <linux/pci.h>
  24
  25#include <linux/mic_common.h>
  26#include <linux/mic_bus.h>
  27#include "../common/mic_dev.h"
  28#include "mic_device.h"
  29#include "mic_smpt.h"
  30#include "mic_virtio.h"
  31
  32static inline struct mic_device *mbdev_to_mdev(struct mbus_device *mbdev)
  33{
  34        return dev_get_drvdata(mbdev->dev.parent);
  35}
  36
  37static dma_addr_t
  38mic_dma_map_page(struct device *dev, struct page *page,
  39                 unsigned long offset, size_t size, enum dma_data_direction dir,
  40                 struct dma_attrs *attrs)
  41{
  42        void *va = phys_to_virt(page_to_phys(page)) + offset;
  43        struct mic_device *mdev = dev_get_drvdata(dev->parent);
  44
  45        return mic_map_single(mdev, va, size);
  46}
  47
  48static void
  49mic_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
  50                   size_t size, enum dma_data_direction dir,
  51                   struct dma_attrs *attrs)
  52{
  53        struct mic_device *mdev = dev_get_drvdata(dev->parent);
  54        mic_unmap_single(mdev, dma_addr, size);
  55}
  56
  57static struct dma_map_ops mic_dma_ops = {
  58        .map_page = mic_dma_map_page,
  59        .unmap_page = mic_dma_unmap_page,
  60};
  61
  62static struct mic_irq *
  63_mic_request_threaded_irq(struct mbus_device *mbdev,
  64                          irq_handler_t handler, irq_handler_t thread_fn,
  65                          const char *name, void *data, int intr_src)
  66{
  67        return mic_request_threaded_irq(mbdev_to_mdev(mbdev), handler,
  68                                        thread_fn, name, data,
  69                                        intr_src, MIC_INTR_DMA);
  70}
  71
  72static void _mic_free_irq(struct mbus_device *mbdev,
  73                          struct mic_irq *cookie, void *data)
  74{
  75        return mic_free_irq(mbdev_to_mdev(mbdev), cookie, data);
  76}
  77
  78static void _mic_ack_interrupt(struct mbus_device *mbdev, int num)
  79{
  80        struct mic_device *mdev = mbdev_to_mdev(mbdev);
  81        mdev->ops->intr_workarounds(mdev);
  82}
  83
  84static struct mbus_hw_ops mbus_hw_ops = {
  85        .request_threaded_irq = _mic_request_threaded_irq,
  86        .free_irq = _mic_free_irq,
  87        .ack_interrupt = _mic_ack_interrupt,
  88};
  89
  90/**
  91 * mic_reset - Reset the MIC device.
  92 * @mdev: pointer to mic_device instance
  93 */
  94static void mic_reset(struct mic_device *mdev)
  95{
  96        int i;
  97
  98#define MIC_RESET_TO (45)
  99
 100        reinit_completion(&mdev->reset_wait);
 101        mdev->ops->reset_fw_ready(mdev);
 102        mdev->ops->reset(mdev);
 103
 104        for (i = 0; i < MIC_RESET_TO; i++) {
 105                if (mdev->ops->is_fw_ready(mdev))
 106                        goto done;
 107                /*
 108                 * Resets typically take 10s of seconds to complete.
 109                 * Since an MMIO read is required to check if the
 110                 * firmware is ready or not, a 1 second delay works nicely.
 111                 */
 112                msleep(1000);
 113        }
 114        mic_set_state(mdev, MIC_RESET_FAILED);
 115done:
 116        complete_all(&mdev->reset_wait);
 117}
 118
 119/* Initialize the MIC bootparams */
 120void mic_bootparam_init(struct mic_device *mdev)
 121{
 122        struct mic_bootparam *bootparam = mdev->dp;
 123
 124        bootparam->magic = cpu_to_le32(MIC_MAGIC);
 125        bootparam->c2h_shutdown_db = mdev->shutdown_db;
 126        bootparam->h2c_shutdown_db = -1;
 127        bootparam->h2c_config_db = -1;
 128        bootparam->shutdown_status = 0;
 129        bootparam->shutdown_card = 0;
 130}
 131
 132/**
 133 * mic_start - Start the MIC.
 134 * @mdev: pointer to mic_device instance
 135 * @buf: buffer containing boot string including firmware/ramdisk path.
 136 *
 137 * This function prepares an MIC for boot and initiates boot.
 138 * RETURNS: An appropriate -ERRNO error value on error, or zero for success.
 139 */
 140int mic_start(struct mic_device *mdev, const char *buf)
 141{
 142        int rc;
 143        mutex_lock(&mdev->mic_mutex);
 144retry:
 145        if (MIC_OFFLINE != mdev->state) {
 146                rc = -EINVAL;
 147                goto unlock_ret;
 148        }
 149        if (!mdev->ops->is_fw_ready(mdev)) {
 150                mic_reset(mdev);
 151                /*
 152                 * The state will either be MIC_OFFLINE if the reset succeeded
 153                 * or MIC_RESET_FAILED if the firmware reset failed.
 154                 */
 155                goto retry;
 156        }
 157        mdev->dma_mbdev = mbus_register_device(mdev->sdev->parent,
 158                                               MBUS_DEV_DMA_HOST, &mic_dma_ops,
 159                                               &mbus_hw_ops, mdev->mmio.va);
 160        if (IS_ERR(mdev->dma_mbdev)) {
 161                rc = PTR_ERR(mdev->dma_mbdev);
 162                goto unlock_ret;
 163        }
 164        mdev->dma_ch = mic_request_dma_chan(mdev);
 165        if (!mdev->dma_ch) {
 166                rc = -ENXIO;
 167                goto dma_remove;
 168        }
 169        rc = mdev->ops->load_mic_fw(mdev, buf);
 170        if (rc)
 171                goto dma_release;
 172        mic_smpt_restore(mdev);
 173        mic_intr_restore(mdev);
 174        mdev->intr_ops->enable_interrupts(mdev);
 175        mdev->ops->write_spad(mdev, MIC_DPLO_SPAD, mdev->dp_dma_addr);
 176        mdev->ops->write_spad(mdev, MIC_DPHI_SPAD, mdev->dp_dma_addr >> 32);
 177        mdev->ops->send_firmware_intr(mdev);
 178        mic_set_state(mdev, MIC_ONLINE);
 179        goto unlock_ret;
 180dma_release:
 181        dma_release_channel(mdev->dma_ch);
 182dma_remove:
 183        mbus_unregister_device(mdev->dma_mbdev);
 184unlock_ret:
 185        mutex_unlock(&mdev->mic_mutex);
 186        return rc;
 187}
 188
 189/**
 190 * mic_stop - Prepare the MIC for reset and trigger reset.
 191 * @mdev: pointer to mic_device instance
 192 * @force: force a MIC to reset even if it is already offline.
 193 *
 194 * RETURNS: None.
 195 */
 196void mic_stop(struct mic_device *mdev, bool force)
 197{
 198        mutex_lock(&mdev->mic_mutex);
 199        if (MIC_OFFLINE != mdev->state || force) {
 200                mic_virtio_reset_devices(mdev);
 201                if (mdev->dma_ch) {
 202                        dma_release_channel(mdev->dma_ch);
 203                        mdev->dma_ch = NULL;
 204                }
 205                mbus_unregister_device(mdev->dma_mbdev);
 206                mic_bootparam_init(mdev);
 207                mic_reset(mdev);
 208                if (MIC_RESET_FAILED == mdev->state)
 209                        goto unlock;
 210                mic_set_shutdown_status(mdev, MIC_NOP);
 211                if (MIC_SUSPENDED != mdev->state)
 212                        mic_set_state(mdev, MIC_OFFLINE);
 213        }
 214unlock:
 215        mutex_unlock(&mdev->mic_mutex);
 216}
 217
 218/**
 219 * mic_shutdown - Initiate MIC shutdown.
 220 * @mdev: pointer to mic_device instance
 221 *
 222 * RETURNS: None.
 223 */
 224void mic_shutdown(struct mic_device *mdev)
 225{
 226        struct mic_bootparam *bootparam = mdev->dp;
 227        s8 db = bootparam->h2c_shutdown_db;
 228
 229        mutex_lock(&mdev->mic_mutex);
 230        if (MIC_ONLINE == mdev->state && db != -1) {
 231                bootparam->shutdown_card = 1;
 232                mdev->ops->send_intr(mdev, db);
 233                mic_set_state(mdev, MIC_SHUTTING_DOWN);
 234        }
 235        mutex_unlock(&mdev->mic_mutex);
 236}
 237
 238/**
 239 * mic_shutdown_work - Handle shutdown interrupt from MIC.
 240 * @work: The work structure.
 241 *
 242 * This work is scheduled whenever the host has received a shutdown
 243 * interrupt from the MIC.
 244 */
 245void mic_shutdown_work(struct work_struct *work)
 246{
 247        struct mic_device *mdev = container_of(work, struct mic_device,
 248                        shutdown_work);
 249        struct mic_bootparam *bootparam = mdev->dp;
 250
 251        mutex_lock(&mdev->mic_mutex);
 252        mic_set_shutdown_status(mdev, bootparam->shutdown_status);
 253        bootparam->shutdown_status = 0;
 254
 255        /*
 256         * if state is MIC_SUSPENDED, OSPM suspend is in progress. We do not
 257         * change the state here so as to prevent users from booting the card
 258         * during and after the suspend operation.
 259         */
 260        if (MIC_SHUTTING_DOWN != mdev->state &&
 261            MIC_SUSPENDED != mdev->state)
 262                mic_set_state(mdev, MIC_SHUTTING_DOWN);
 263        mutex_unlock(&mdev->mic_mutex);
 264}
 265
 266/**
 267 * mic_reset_trigger_work - Trigger MIC reset.
 268 * @work: The work structure.
 269 *
 270 * This work is scheduled whenever the host wants to reset the MIC.
 271 */
 272void mic_reset_trigger_work(struct work_struct *work)
 273{
 274        struct mic_device *mdev = container_of(work, struct mic_device,
 275                        reset_trigger_work);
 276
 277        mic_stop(mdev, false);
 278}
 279
 280/**
 281 * mic_complete_resume - Complete MIC Resume after an OSPM suspend/hibernate
 282 * event.
 283 * @mdev: pointer to mic_device instance
 284 *
 285 * RETURNS: None.
 286 */
 287void mic_complete_resume(struct mic_device *mdev)
 288{
 289        if (mdev->state != MIC_SUSPENDED) {
 290                dev_warn(mdev->sdev->parent, "state %d should be %d\n",
 291                         mdev->state, MIC_SUSPENDED);
 292                return;
 293        }
 294
 295        /* Make sure firmware is ready */
 296        if (!mdev->ops->is_fw_ready(mdev))
 297                mic_stop(mdev, true);
 298
 299        mutex_lock(&mdev->mic_mutex);
 300        mic_set_state(mdev, MIC_OFFLINE);
 301        mutex_unlock(&mdev->mic_mutex);
 302}
 303
 304/**
 305 * mic_prepare_suspend - Handle suspend notification for the MIC device.
 306 * @mdev: pointer to mic_device instance
 307 *
 308 * RETURNS: None.
 309 */
 310void mic_prepare_suspend(struct mic_device *mdev)
 311{
 312        int rc;
 313
 314#define MIC_SUSPEND_TIMEOUT (60 * HZ)
 315
 316        mutex_lock(&mdev->mic_mutex);
 317        switch (mdev->state) {
 318        case MIC_OFFLINE:
 319                /*
 320                 * Card is already offline. Set state to MIC_SUSPENDED
 321                 * to prevent users from booting the card.
 322                 */
 323                mic_set_state(mdev, MIC_SUSPENDED);
 324                mutex_unlock(&mdev->mic_mutex);
 325                break;
 326        case MIC_ONLINE:
 327                /*
 328                 * Card is online. Set state to MIC_SUSPENDING and notify
 329                 * MIC user space daemon which will issue card
 330                 * shutdown and reset.
 331                 */
 332                mic_set_state(mdev, MIC_SUSPENDING);
 333                mutex_unlock(&mdev->mic_mutex);
 334                rc = wait_for_completion_timeout(&mdev->reset_wait,
 335                                                MIC_SUSPEND_TIMEOUT);
 336                /* Force reset the card if the shutdown completion timed out */
 337                if (!rc) {
 338                        mutex_lock(&mdev->mic_mutex);
 339                        mic_set_state(mdev, MIC_SUSPENDED);
 340                        mutex_unlock(&mdev->mic_mutex);
 341                        mic_stop(mdev, true);
 342                }
 343                break;
 344        case MIC_SHUTTING_DOWN:
 345                /*
 346                 * Card is shutting down. Set state to MIC_SUSPENDED
 347                 * to prevent further boot of the card.
 348                 */
 349                mic_set_state(mdev, MIC_SUSPENDED);
 350                mutex_unlock(&mdev->mic_mutex);
 351                rc = wait_for_completion_timeout(&mdev->reset_wait,
 352                                                MIC_SUSPEND_TIMEOUT);
 353                /* Force reset the card if the shutdown completion timed out */
 354                if (!rc)
 355                        mic_stop(mdev, true);
 356                break;
 357        default:
 358                mutex_unlock(&mdev->mic_mutex);
 359                break;
 360        }
 361}
 362
 363/**
 364 * mic_suspend - Initiate MIC suspend. Suspend merely issues card shutdown.
 365 * @mdev: pointer to mic_device instance
 366 *
 367 * RETURNS: None.
 368 */
 369void mic_suspend(struct mic_device *mdev)
 370{
 371        struct mic_bootparam *bootparam = mdev->dp;
 372        s8 db = bootparam->h2c_shutdown_db;
 373
 374        mutex_lock(&mdev->mic_mutex);
 375        if (MIC_SUSPENDING == mdev->state && db != -1) {
 376                bootparam->shutdown_card = 1;
 377                mdev->ops->send_intr(mdev, db);
 378                mic_set_state(mdev, MIC_SUSPENDED);
 379        }
 380        mutex_unlock(&mdev->mic_mutex);
 381}
 382