// SPDX-License-Identifier: GPL-2.0
/*
 * Apple ANS NVM Express device driver
 * Copyright The Asahi Linux Contributors
 *
 * Based on the pci.c NVM Express device driver
 * Copyright (c) 2011-2014, Intel Corporation.
 * and on the rdma.c NVMe over Fabrics RDMA host code.
 * Copyright (c) 2015-2016 HGST, a Western Digital Company.
 */

#include <linux/async.h>
#include <linux/blkdev.h>
#include <linux/blk-mq.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/interrupt.h>
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/jiffies.h>
#include <linux/mempool.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/once.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/soc/apple/rtkit.h>
#include <linux/soc/apple/sart.h>
#include <linux/reset.h>
#include <linux/time64.h>

#include "nvme.h"

#define APPLE_ANS_BOOT_TIMEOUT	  USEC_PER_SEC

#define APPLE_ANS_COPROC_CPU_CONTROL	 0x44
#define APPLE_ANS_COPROC_CPU_CONTROL_RUN BIT(4)

#define APPLE_ANS_ACQ_DB  0x1004
#define APPLE_ANS_IOCQ_DB 0x100c

#define APPLE_ANS_MAX_PEND_CMDS_CTRL 0x1210

#define APPLE_ANS_BOOT_STATUS	 0x1300
#define APPLE_ANS_BOOT_STATUS_OK 0xde71ce55

#define APPLE_ANS_UNKNOWN_CTRL	 0x24008
#define APPLE_ANS_PRP_NULL_CHECK BIT(11)

#define APPLE_ANS_LINEAR_SQ_CTRL 0x24908
#define APPLE_ANS_LINEAR_SQ_EN	 BIT(0)

#define APPLE_ANS_LINEAR_ASQ_DB	 0x2490c
#define APPLE_ANS_LINEAR_IOSQ_DB 0x24910

#define APPLE_NVMMU_NUM_TCBS	  0x28100
#define APPLE_NVMMU_ASQ_TCB_BASE  0x28108
#define APPLE_NVMMU_IOSQ_TCB_BASE 0x28110
#define APPLE_NVMMU_TCB_INVAL	  0x28118
#define APPLE_NVMMU_TCB_STAT	  0x28120

/*
 * This controller is a bit weird in the way command tags works: Both the
 * admin and the IO queue share the same tag space. Additionally, tags
 * cannot be higher than 0x40 which effectively limits the combined
 * queue depth to 0x40. Instead of wasting half of that on the admin queue
 * which gets much less traffic we instead reduce its size here.
 * The controller also doesn't support async event such that no space must
 * be reserved for NVME_NR_AEN_COMMANDS.
 */
#define APPLE_NVME_AQ_DEPTH	   2
#define APPLE_NVME_AQ_MQ_TAG_DEPTH (APPLE_NVME_AQ_DEPTH - 1)

#define APPLE_NVME_IOSQES	7

/*
 * These can be higher, but we need to ensure that any command doesn't
 * require an sg allocation that needs more than a page of data.
 */
#define NVME_MAX_KB_SZ 4096
#define NVME_MAX_SEGS  127

/*
 * This controller comes with an embedded IOMMU known as NVMMU.
 * The NVMMU is pointed to an array of TCBs indexed by the command tag.
 * Each command must be configured inside this structure before it's allowed
 * to execute, including commands that don't require DMA transfers.
 *
 * An exception to this are Apple's vendor-specific commands (opcode 0xD8 on the
 * admin queue): Those commands must still be added to the NVMMU but the DMA
 * buffers cannot be represented as PRPs and must instead be allowed using SART.
 *
 * Programming the PRPs to the same values as those in the submission queue
 * looks rather silly at first. This hardware is however designed for a kernel
 * that runs the NVMMU code in a higher exception level than the NVMe driver.
 * In that setting the NVMe driver first programs the submission queue entry
 * and then executes a hypercall to the code that is allowed to program the
 * NVMMU. The NVMMU driver then creates a shadow copy of the PRPs while
 * verifying that they don't point to kernel text, data, pagetables, or similar
 * protected areas before programming the TCB to point to this shadow copy.
 * Since Linux doesn't do any of that we may as well just point both the queue
 * and the TCB PRP pointer to the same memory.
 */
struct apple_nvmmu_tcb {
	u8 opcode;

#define APPLE_ANS_TCB_DMA_FROM_DEVICE BIT(0)
#define APPLE_ANS_TCB_DMA_TO_DEVICE   BIT(1)
	u8 dma_flags;

	u8 command_id;
	u8 _unk0;
	__le16 length;
	u8 _unk1[18];
	__le64 prp1;
	__le64 prp2;
	u8 _unk2[16];
	u8 aes_iv[8];
	u8 _aes_unk[64];
};

/*
 * The Apple NVMe controller only supports a single admin and a single IO queue
 * which are both limited to 64 entries and share a single interrupt.
 *
 * The completion queue works as usual. The submission "queue" instead is
 * an array indexed by the command tag on this hardware. Commands must also be
 * present in the NVMMU's tcb array. They are triggered by writing their tag to
 * a MMIO register.
 */
struct apple_nvme_queue {
	struct nvme_command *sqes;
	struct nvme_completion *cqes;
	struct apple_nvmmu_tcb *tcbs;

	dma_addr_t sq_dma_addr;
	dma_addr_t cq_dma_addr;
	dma_addr_t tcb_dma_addr;

	u32 __iomem *sq_db;
	u32 __iomem *cq_db;

	u16 sq_tail;
	u16 cq_head;
	u8 cq_phase;

	bool is_adminq;
	bool enabled;
};

/*
 * The apple_nvme_iod describes the data in an I/O.
 *
 * The sg pointer contains the list of PRP chunk allocations in addition
 * to the actual struct scatterlist.
 */
struct apple_nvme_iod {
	struct nvme_request req;
	struct nvme_command cmd;
	struct apple_nvme_queue *q;
	int npages; /* In the PRP list. 0 means small pool in use */
	int nents; /* Used in scatterlist */
	dma_addr_t first_dma;
	unsigned int dma_len; /* length of single DMA segment mapping */
	struct scatterlist *sg;
};

struct apple_nvme_hw {
	bool has_lsq_nvmmu;
	u32 max_queue_depth;
};

struct apple_nvme {
	struct device *dev;

	void __iomem *mmio_coproc;
	void __iomem *mmio_nvme;
	const struct apple_nvme_hw *hw;

	struct device **pd_dev;
	struct device_link **pd_link;
	int pd_count;

	struct apple_sart *sart;
	struct apple_rtkit *rtk;
	struct reset_control *reset;

	struct dma_pool *prp_page_pool;
	struct dma_pool *prp_small_pool;
	mempool_t *iod_mempool;

	struct nvme_ctrl ctrl;
	struct work_struct remove_work;

	struct apple_nvme_queue adminq;
	struct apple_nvme_queue ioq;

	struct blk_mq_tag_set admin_tagset;
	struct blk_mq_tag_set tagset;

	int irq;
	spinlock_t lock;
};

static_assert(sizeof(struct nvme_command) == 64);
static_assert(sizeof(struct apple_nvmmu_tcb) == 128);

static inline struct apple_nvme *ctrl_to_apple_nvme(struct nvme_ctrl *ctrl)
{
	return container_of(ctrl, struct apple_nvme, ctrl);
}

static inline struct apple_nvme *queue_to_apple_nvme(struct apple_nvme_queue *q)
{
	if (q->is_adminq)
		return container_of(q, struct apple_nvme, adminq);

	return container_of(q, struct apple_nvme, ioq);
}

static unsigned int apple_nvme_queue_depth(struct apple_nvme_queue *q)
{
	struct apple_nvme *anv = queue_to_apple_nvme(q);

	if (q->is_adminq && anv->hw->has_lsq_nvmmu)
		return APPLE_NVME_AQ_DEPTH;

	return anv->hw->max_queue_depth;
}

static void apple_nvme_rtkit_crashed(void *cookie, const void *crashlog, size_t crashlog_size)
{
	struct apple_nvme *anv = cookie;

	dev_warn(anv->dev, "RTKit crashed; unable to recover without a reboot");
	nvme_reset_ctrl(&anv->ctrl);
}

static int apple_nvme_sart_dma_setup(void *cookie,
				     struct apple_rtkit_shmem *bfr)
{
	struct apple_nvme *anv = cookie;
	int ret;

	if (bfr->iova)
		return -EINVAL;
	if (!bfr->size)
		return -EINVAL;

	bfr->buffer =
		dma_alloc_coherent(anv->dev, bfr->size, &bfr->iova, GFP_KERNEL);
	if (!bfr->buffer)
		return -ENOMEM;

	ret = apple_sart_add_allowed_region(anv->sart, bfr->iova, bfr->size);
	if (ret) {
		dma_free_coherent(anv->dev, bfr->size, bfr->buffer, bfr->iova);
		bfr->buffer = NULL;
		return -ENOMEM;
	}

	return 0;
}

static void apple_nvme_sart_dma_destroy(void *cookie,
					struct apple_rtkit_shmem *bfr)
{
	struct apple_nvme *anv = cookie;

	apple_sart_remove_allowed_region(anv->sart, bfr->iova, bfr->size);
	dma_free_coherent(anv->dev, bfr->size, bfr->buffer, bfr->iova);
}

static const struct apple_rtkit_ops apple_nvme_rtkit_ops = {
	.crashed = apple_nvme_rtkit_crashed,
	.shmem_setup = apple_nvme_sart_dma_setup,
	.shmem_destroy = apple_nvme_sart_dma_destroy,
};

static void apple_nvmmu_inval(struct apple_nvme_queue *q, unsigned int tag)
{
	struct apple_nvme *anv = queue_to_apple_nvme(q);

	writel(tag, anv->mmio_nvme + APPLE_NVMMU_TCB_INVAL);
	if (readl(anv->mmio_nvme + APPLE_NVMMU_TCB_STAT))
		dev_warn_ratelimited(anv->dev,
				     "NVMMU TCB invalidation failed\n");
}

static void apple_nvme_submit_cmd_t8015(struct apple_nvme_queue *q,
				  struct nvme_command *cmd)
{
	struct apple_nvme *anv = queue_to_apple_nvme(q);

	spin_lock_irq(&anv->lock);

	if (q->is_adminq)
		memcpy(&q->sqes[q->sq_tail], cmd, sizeof(*cmd));
	else
		memcpy((void *)q->sqes + (q->sq_tail << APPLE_NVME_IOSQES),
			cmd, sizeof(*cmd));

	if (++q->sq_tail == anv->hw->max_queue_depth)
		q->sq_tail = 0;

	writel(q->sq_tail, q->sq_db);
	spin_unlock_irq(&anv->lock);
}


static void apple_nvme_submit_cmd_t8103(struct apple_nvme_queue *q,
				  struct nvme_command *cmd)
{
	struct apple_nvme *anv = queue_to_apple_nvme(q);
	u32 tag = nvme_tag_from_cid(cmd->common.command_id);
	struct apple_nvmmu_tcb *tcb = &q->tcbs[tag];

	tcb->opcode = cmd->common.opcode;
	tcb->prp1 = cmd->common.dptr.prp1;
	tcb->prp2 = cmd->common.dptr.prp2;
	tcb->length = cmd->rw.length;
	tcb->command_id = tag;

	if (nvme_is_write(cmd))
		tcb->dma_flags = APPLE_ANS_TCB_DMA_TO_DEVICE;
	else
		tcb->dma_flags = APPLE_ANS_TCB_DMA_FROM_DEVICE;

	memcpy(&q->sqes[tag], cmd, sizeof(*cmd));

	/*
	 * This lock here doesn't make much sense at a first glance but
	 * removing it will result in occasional missed completion
	 * interrupts even though the commands still appear on the CQ.
	 * It's unclear why this happens but our best guess is that
	 * there is a bug in the firmware triggered when a new command
	 * is issued while we're inside the irq handler between the
	 * NVMMU invalidation (and making the tag available again)
	 * and the final CQ update.
	 */
	spin_lock_irq(&anv->lock);
	writel(tag, q->sq_db);
	spin_unlock_irq(&anv->lock);
}

/*
 * From pci.c:
 * Will slightly overestimate the number of pages needed.  This is OK
 * as it only leads to a small amount of wasted memory for the lifetime of
 * the I/O.
 */
static inline size_t apple_nvme_iod_alloc_size(void)
{
	const unsigned int nprps = DIV_ROUND_UP(
		NVME_MAX_KB_SZ + NVME_CTRL_PAGE_SIZE, NVME_CTRL_PAGE_SIZE);
	const int npages = DIV_ROUND_UP(8 * nprps, PAGE_SIZE - 8);
	const size_t alloc_size = sizeof(__le64 *) * npages +
				  sizeof(struct scatterlist) * NVME_MAX_SEGS;

	return alloc_size;
}

static void **apple_nvme_iod_list(struct request *req)
{
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);

	return (void **)(iod->sg + blk_rq_nr_phys_segments(req));
}

static void apple_nvme_free_prps(struct apple_nvme *anv, struct request *req)
{
	const int last_prp = NVME_CTRL_PAGE_SIZE / sizeof(__le64) - 1;
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);
	dma_addr_t dma_addr = iod->first_dma;
	int i;

	for (i = 0; i < iod->npages; i++) {
		__le64 *prp_list = apple_nvme_iod_list(req)[i];
		dma_addr_t next_dma_addr = le64_to_cpu(prp_list[last_prp]);

		dma_pool_free(anv->prp_page_pool, prp_list, dma_addr);
		dma_addr = next_dma_addr;
	}
}

static void apple_nvme_unmap_data(struct apple_nvme *anv, struct request *req)
{
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);

	if (iod->dma_len) {
		dma_unmap_page(anv->dev, iod->first_dma, iod->dma_len,
			       rq_dma_dir(req));
		return;
	}

	WARN_ON_ONCE(!iod->nents);

	dma_unmap_sg(anv->dev, iod->sg, iod->nents, rq_dma_dir(req));
	if (iod->npages == 0)
		dma_pool_free(anv->prp_small_pool, apple_nvme_iod_list(req)[0],
			      iod->first_dma);
	else
		apple_nvme_free_prps(anv, req);
	mempool_free(iod->sg, anv->iod_mempool);
}

static void apple_nvme_print_sgl(struct scatterlist *sgl, int nents)
{
	int i;
	struct scatterlist *sg;

	for_each_sg(sgl, sg, nents, i) {
		dma_addr_t phys = sg_phys(sg);

		pr_warn("sg[%d] phys_addr:%pad offset:%d length:%d dma_address:%pad dma_length:%d\n",
			i, &phys, sg->offset, sg->length, &sg_dma_address(sg),
			sg_dma_len(sg));
	}
}

static blk_status_t apple_nvme_setup_prps(struct apple_nvme *anv,
					  struct request *req,
					  struct nvme_rw_command *cmnd)
{
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);
	struct dma_pool *pool;
	int length = blk_rq_payload_bytes(req);
	struct scatterlist *sg = iod->sg;
	int dma_len = sg_dma_len(sg);
	u64 dma_addr = sg_dma_address(sg);
	int offset = dma_addr & (NVME_CTRL_PAGE_SIZE - 1);
	__le64 *prp_list;
	void **list = apple_nvme_iod_list(req);
	dma_addr_t prp_dma;
	int nprps, i;

	length -= (NVME_CTRL_PAGE_SIZE - offset);
	if (length <= 0) {
		iod->first_dma = 0;
		goto done;
	}

	dma_len -= (NVME_CTRL_PAGE_SIZE - offset);
	if (dma_len) {
		dma_addr += (NVME_CTRL_PAGE_SIZE - offset);
	} else {
		sg = sg_next(sg);
		dma_addr = sg_dma_address(sg);
		dma_len = sg_dma_len(sg);
	}

	if (length <= NVME_CTRL_PAGE_SIZE) {
		iod->first_dma = dma_addr;
		goto done;
	}

	nprps = DIV_ROUND_UP(length, NVME_CTRL_PAGE_SIZE);
	if (nprps <= (256 / 8)) {
		pool = anv->prp_small_pool;
		iod->npages = 0;
	} else {
		pool = anv->prp_page_pool;
		iod->npages = 1;
	}

	prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
	if (!prp_list) {
		iod->first_dma = dma_addr;
		iod->npages = -1;
		return BLK_STS_RESOURCE;
	}
	list[0] = prp_list;
	iod->first_dma = prp_dma;
	i = 0;
	for (;;) {
		if (i == NVME_CTRL_PAGE_SIZE >> 3) {
			__le64 *old_prp_list = prp_list;

			prp_list = dma_pool_alloc(pool, GFP_ATOMIC, &prp_dma);
			if (!prp_list)
				goto free_prps;
			list[iod->npages++] = prp_list;
			prp_list[0] = old_prp_list[i - 1];
			old_prp_list[i - 1] = cpu_to_le64(prp_dma);
			i = 1;
		}
		prp_list[i++] = cpu_to_le64(dma_addr);
		dma_len -= NVME_CTRL_PAGE_SIZE;
		dma_addr += NVME_CTRL_PAGE_SIZE;
		length -= NVME_CTRL_PAGE_SIZE;
		if (length <= 0)
			break;
		if (dma_len > 0)
			continue;
		if (unlikely(dma_len < 0))
			goto bad_sgl;
		sg = sg_next(sg);
		dma_addr = sg_dma_address(sg);
		dma_len = sg_dma_len(sg);
	}
done:
	cmnd->dptr.prp1 = cpu_to_le64(sg_dma_address(iod->sg));
	cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma);
	return BLK_STS_OK;
free_prps:
	apple_nvme_free_prps(anv, req);
	return BLK_STS_RESOURCE;
bad_sgl:
	WARN(DO_ONCE(apple_nvme_print_sgl, iod->sg, iod->nents),
	     "Invalid SGL for payload:%d nents:%d\n", blk_rq_payload_bytes(req),
	     iod->nents);
	return BLK_STS_IOERR;
}

static blk_status_t apple_nvme_setup_prp_simple(struct apple_nvme *anv,
						struct request *req,
						struct nvme_rw_command *cmnd,
						struct bio_vec *bv)
{
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);
	unsigned int offset = bv->bv_offset & (NVME_CTRL_PAGE_SIZE - 1);
	unsigned int first_prp_len = NVME_CTRL_PAGE_SIZE - offset;

	iod->first_dma = dma_map_bvec(anv->dev, bv, rq_dma_dir(req), 0);
	if (dma_mapping_error(anv->dev, iod->first_dma))
		return BLK_STS_RESOURCE;
	iod->dma_len = bv->bv_len;

	cmnd->dptr.prp1 = cpu_to_le64(iod->first_dma);
	if (bv->bv_len > first_prp_len)
		cmnd->dptr.prp2 = cpu_to_le64(iod->first_dma + first_prp_len);
	return BLK_STS_OK;
}

static blk_status_t apple_nvme_map_data(struct apple_nvme *anv,
					struct request *req,
					struct nvme_command *cmnd)
{
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);
	blk_status_t ret = BLK_STS_RESOURCE;
	int nr_mapped;

	if (blk_rq_nr_phys_segments(req) == 1) {
		struct bio_vec bv = req_bvec(req);

		if (bv.bv_offset + bv.bv_len <= NVME_CTRL_PAGE_SIZE * 2)
			return apple_nvme_setup_prp_simple(anv, req, &cmnd->rw,
							   &bv);
	}

	iod->dma_len = 0;
	iod->sg = mempool_alloc(anv->iod_mempool, GFP_ATOMIC);
	if (!iod->sg)
		return BLK_STS_RESOURCE;
	sg_init_table(iod->sg, blk_rq_nr_phys_segments(req));
	iod->nents = blk_rq_map_sg(req, iod->sg);
	if (!iod->nents)
		goto out_free_sg;

	nr_mapped = dma_map_sg_attrs(anv->dev, iod->sg, iod->nents,
				     rq_dma_dir(req), DMA_ATTR_NO_WARN);
	if (!nr_mapped)
		goto out_free_sg;

	ret = apple_nvme_setup_prps(anv, req, &cmnd->rw);
	if (ret != BLK_STS_OK)
		goto out_unmap_sg;
	return BLK_STS_OK;

out_unmap_sg:
	dma_unmap_sg(anv->dev, iod->sg, iod->nents, rq_dma_dir(req));
out_free_sg:
	mempool_free(iod->sg, anv->iod_mempool);
	return ret;
}

static __always_inline void apple_nvme_unmap_rq(struct request *req)
{
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);
	struct apple_nvme *anv = queue_to_apple_nvme(iod->q);

	if (blk_rq_nr_phys_segments(req))
		apple_nvme_unmap_data(anv, req);
}

static void apple_nvme_complete_rq(struct request *req)
{
	apple_nvme_unmap_rq(req);
	nvme_complete_rq(req);
}

static void apple_nvme_complete_batch(struct io_comp_batch *iob)
{
	nvme_complete_batch(iob, apple_nvme_unmap_rq);
}

static inline bool apple_nvme_cqe_pending(struct apple_nvme_queue *q)
{
	struct nvme_completion *hcqe = &q->cqes[q->cq_head];

	return (le16_to_cpu(READ_ONCE(hcqe->status)) & 1) == q->cq_phase;
}

static inline struct blk_mq_tags *
apple_nvme_queue_tagset(struct apple_nvme *anv, struct apple_nvme_queue *q)
{
	if (q->is_adminq)
		return anv->admin_tagset.tags[0];
	else
		return anv->tagset.tags[0];
}

static inline void apple_nvme_handle_cqe(struct apple_nvme_queue *q,
					 struct io_comp_batch *iob, u16 idx)
{
	struct apple_nvme *anv = queue_to_apple_nvme(q);
	struct nvme_completion *cqe = &q->cqes[idx];
	__u16 command_id = READ_ONCE(cqe->command_id);
	struct request *req;

	if (anv->hw->has_lsq_nvmmu)
		apple_nvmmu_inval(q, command_id);

	req = nvme_find_rq(apple_nvme_queue_tagset(anv, q), command_id);
	if (unlikely(!req)) {
		dev_warn(anv->dev, "invalid id %d completed", command_id);
		return;
	}

	if (!nvme_try_complete_req(req, cqe->status, cqe->result) &&
	    !blk_mq_add_to_batch(req, iob,
				 nvme_req(req)->status != NVME_SC_SUCCESS,
				 apple_nvme_complete_batch))
		apple_nvme_complete_rq(req);
}

static inline void apple_nvme_update_cq_head(struct apple_nvme_queue *q)
{
	u32 tmp = q->cq_head + 1;

	if (tmp == apple_nvme_queue_depth(q)) {
		q->cq_head = 0;
		q->cq_phase ^= 1;
	} else {
		q->cq_head = tmp;
	}
}

static bool apple_nvme_poll_cq(struct apple_nvme_queue *q,
			       struct io_comp_batch *iob)
{
	bool found = false;

	while (apple_nvme_cqe_pending(q)) {
		found = true;

		/*
		 * load-load control dependency between phase and the rest of
		 * the cqe requires a full read memory barrier
		 */
		dma_rmb();
		apple_nvme_handle_cqe(q, iob, q->cq_head);
		apple_nvme_update_cq_head(q);
	}

	if (found)
		writel(q->cq_head, q->cq_db);

	return found;
}

static bool apple_nvme_handle_cq(struct apple_nvme_queue *q, bool force)
{
	bool found;
	DEFINE_IO_COMP_BATCH(iob);

	if (!READ_ONCE(q->enabled) && !force)
		return false;

	found = apple_nvme_poll_cq(q, &iob);

	if (!rq_list_empty(&iob.req_list))
		apple_nvme_complete_batch(&iob);

	return found;
}

static irqreturn_t apple_nvme_irq(int irq, void *data)
{
	struct apple_nvme *anv = data;
	bool handled = false;
	unsigned long flags;

	spin_lock_irqsave(&anv->lock, flags);
	if (apple_nvme_handle_cq(&anv->ioq, false))
		handled = true;
	if (apple_nvme_handle_cq(&anv->adminq, false))
		handled = true;
	spin_unlock_irqrestore(&anv->lock, flags);

	if (handled)
		return IRQ_HANDLED;
	return IRQ_NONE;
}

static int apple_nvme_create_cq(struct apple_nvme *anv)
{
	struct nvme_command c = {};

	/*
	 * Note: we (ab)use the fact that the prp fields survive if no data
	 * is attached to the request.
	 */
	c.create_cq.opcode = nvme_admin_create_cq;
	c.create_cq.prp1 = cpu_to_le64(anv->ioq.cq_dma_addr);
	c.create_cq.cqid = cpu_to_le16(1);
	c.create_cq.qsize = cpu_to_le16(anv->hw->max_queue_depth - 1);
	c.create_cq.cq_flags = cpu_to_le16(NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED);
	c.create_cq.irq_vector = cpu_to_le16(0);

	return nvme_submit_sync_cmd(anv->ctrl.admin_q, &c, NULL, 0);
}

static int apple_nvme_remove_cq(struct apple_nvme *anv)
{
	struct nvme_command c = {};

	c.delete_queue.opcode = nvme_admin_delete_cq;
	c.delete_queue.qid = cpu_to_le16(1);

	return nvme_submit_sync_cmd(anv->ctrl.admin_q, &c, NULL, 0);
}

static int apple_nvme_create_sq(struct apple_nvme *anv)
{
	struct nvme_command c = {};

	/*
	 * Note: we (ab)use the fact that the prp fields survive if no data
	 * is attached to the request.
	 */
	c.create_sq.opcode = nvme_admin_create_sq;
	c.create_sq.prp1 = cpu_to_le64(anv->ioq.sq_dma_addr);
	c.create_sq.sqid = cpu_to_le16(1);
	c.create_sq.qsize = cpu_to_le16(anv->hw->max_queue_depth - 1);
	c.create_sq.sq_flags = cpu_to_le16(NVME_QUEUE_PHYS_CONTIG);
	c.create_sq.cqid = cpu_to_le16(1);

	return nvme_submit_sync_cmd(anv->ctrl.admin_q, &c, NULL, 0);
}

static int apple_nvme_remove_sq(struct apple_nvme *anv)
{
	struct nvme_command c = {};

	c.delete_queue.opcode = nvme_admin_delete_sq;
	c.delete_queue.qid = cpu_to_le16(1);

	return nvme_submit_sync_cmd(anv->ctrl.admin_q, &c, NULL, 0);
}

static blk_status_t apple_nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
					const struct blk_mq_queue_data *bd)
{
	struct nvme_ns *ns = hctx->queue->queuedata;
	struct apple_nvme_queue *q = hctx->driver_data;
	struct apple_nvme *anv = queue_to_apple_nvme(q);
	struct request *req = bd->rq;
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);
	struct nvme_command *cmnd = &iod->cmd;
	blk_status_t ret;

	iod->npages = -1;
	iod->nents = 0;

	/*
	 * We should not need to do this, but we're still using this to
	 * ensure we can drain requests on a dying queue.
	 */
	if (unlikely(!READ_ONCE(q->enabled)))
		return BLK_STS_IOERR;

	if (!nvme_check_ready(&anv->ctrl, req, true))
		return nvme_fail_nonready_command(&anv->ctrl, req);

	ret = nvme_setup_cmd(ns, req);
	if (ret)
		return ret;

	if (blk_rq_nr_phys_segments(req)) {
		ret = apple_nvme_map_data(anv, req, cmnd);
		if (ret)
			goto out_free_cmd;
	}

	nvme_start_request(req);

	if (anv->hw->has_lsq_nvmmu)
		apple_nvme_submit_cmd_t8103(q, cmnd);
	else
		apple_nvme_submit_cmd_t8015(q, cmnd);

	return BLK_STS_OK;

out_free_cmd:
	nvme_cleanup_cmd(req);
	return ret;
}

static int apple_nvme_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
				unsigned int hctx_idx)
{
	hctx->driver_data = data;
	return 0;
}

static int apple_nvme_init_request(struct blk_mq_tag_set *set,
				   struct request *req, unsigned int hctx_idx,
				   unsigned int numa_node)
{
	struct apple_nvme_queue *q = set->driver_data;
	struct apple_nvme *anv = queue_to_apple_nvme(q);
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);
	struct nvme_request *nreq = nvme_req(req);

	iod->q = q;
	nreq->ctrl = &anv->ctrl;
	nreq->cmd = &iod->cmd;

	return 0;
}

static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown)
{
	enum nvme_ctrl_state state = nvme_ctrl_state(&anv->ctrl);
	u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS);
	bool dead = false, freeze = false;
	unsigned long flags;

	if (apple_rtkit_is_crashed(anv->rtk))
		dead = true;
	if (!(csts & NVME_CSTS_RDY))
		dead = true;
	if (csts & NVME_CSTS_CFS)
		dead = true;

	if (state == NVME_CTRL_LIVE ||
	    state == NVME_CTRL_RESETTING) {
		freeze = true;
		nvme_start_freeze(&anv->ctrl);
	}

	/*
	 * Give the controller a chance to complete all entered requests if
	 * doing a safe shutdown.
	 */
	if (!dead && shutdown && freeze)
		nvme_wait_freeze_timeout(&anv->ctrl, NVME_IO_TIMEOUT);

	nvme_quiesce_io_queues(&anv->ctrl);

	if (!dead) {
		if (READ_ONCE(anv->ioq.enabled)) {
			apple_nvme_remove_sq(anv);
			apple_nvme_remove_cq(anv);
		}

		/*
		 * Always disable the NVMe controller after shutdown.
		 * We need to do this to bring it back up later anyway, and we
		 * can't do it while the firmware is not running (e.g. in the
		 * resume reset path before RTKit is initialized), so for Apple
		 * controllers it makes sense to unconditionally do it here.
		 * Additionally, this sequence of events is reliable, while
		 * others (like disabling after bringing back the firmware on
		 * resume) seem to run into trouble under some circumstances.
		 *
		 * Both U-Boot and m1n1 also use this convention (i.e. an ANS
		 * NVMe controller is handed off with firmware shut down, in an
		 * NVMe disabled state, after a clean shutdown).
		 */
		if (shutdown)
			nvme_disable_ctrl(&anv->ctrl, shutdown);
		nvme_disable_ctrl(&anv->ctrl, false);
	}

	WRITE_ONCE(anv->ioq.enabled, false);
	WRITE_ONCE(anv->adminq.enabled, false);
	mb(); /* ensure that nvme_queue_rq() sees that enabled is cleared */
	nvme_quiesce_admin_queue(&anv->ctrl);

	/* last chance to complete any requests before nvme_cancel_request */
	spin_lock_irqsave(&anv->lock, flags);
	apple_nvme_handle_cq(&anv->ioq, true);
	apple_nvme_handle_cq(&anv->adminq, true);
	spin_unlock_irqrestore(&anv->lock, flags);

	nvme_cancel_tagset(&anv->ctrl);
	nvme_cancel_admin_tagset(&anv->ctrl);

	/*
	 * The driver will not be starting up queues again if shutting down so
	 * must flush all entered requests to their failed completion to avoid
	 * deadlocking blk-mq hot-cpu notifier.
	 */
	if (shutdown) {
		nvme_unquiesce_io_queues(&anv->ctrl);
		nvme_unquiesce_admin_queue(&anv->ctrl);
	}
}

static enum blk_eh_timer_return apple_nvme_timeout(struct request *req)
{
	struct apple_nvme_iod *iod = blk_mq_rq_to_pdu(req);
	struct apple_nvme_queue *q = iod->q;
	struct apple_nvme *anv = queue_to_apple_nvme(q);
	unsigned long flags;
	u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS);

	if (nvme_ctrl_state(&anv->ctrl) != NVME_CTRL_LIVE) {
		/*
		 * From rdma.c:
		 * If we are resetting, connecting or deleting we should
		 * complete immediately because we may block controller
		 * teardown or setup sequence
		 * - ctrl disable/shutdown fabrics requests
		 * - connect requests
		 * - initialization admin requests
		 * - I/O requests that entered after unquiescing and
		 *   the controller stopped responding
		 *
		 * All other requests should be cancelled by the error
		 * recovery work, so it's fine that we fail it here.
		 */
		dev_warn(anv->dev,
			 "I/O %d(aq:%d) timeout while not in live state\n",
			 req->tag, q->is_adminq);
		if (blk_mq_request_started(req) &&
		    !blk_mq_request_completed(req)) {
			nvme_req(req)->status = NVME_SC_HOST_ABORTED_CMD;
			nvme_req(req)->flags |= NVME_REQ_CANCELLED;
			blk_mq_complete_request(req);
		}
		return BLK_EH_DONE;
	}

	/* check if we just missed an interrupt if we're still alive */
	if (!apple_rtkit_is_crashed(anv->rtk) && !(csts & NVME_CSTS_CFS)) {
		spin_lock_irqsave(&anv->lock, flags);
		apple_nvme_handle_cq(q, false);
		spin_unlock_irqrestore(&anv->lock, flags);
		if (blk_mq_request_completed(req)) {
			dev_warn(anv->dev,
				 "I/O %d(aq:%d) timeout: completion polled\n",
				 req->tag, q->is_adminq);
			return BLK_EH_DONE;
		}
	}

	/*
	 * aborting commands isn't supported which leaves a full reset as our
	 * only option here
	 */
	dev_warn(anv->dev, "I/O %d(aq:%d) timeout: resetting controller\n",
		 req->tag, q->is_adminq);
	nvme_req(req)->flags |= NVME_REQ_CANCELLED;
	apple_nvme_disable(anv, false);
	nvme_reset_ctrl(&anv->ctrl);
	return BLK_EH_DONE;
}

static int apple_nvme_poll(struct blk_mq_hw_ctx *hctx,
			   struct io_comp_batch *iob)
{
	struct apple_nvme_queue *q = hctx->driver_data;
	struct apple_nvme *anv = queue_to_apple_nvme(q);
	bool found;
	unsigned long flags;

	spin_lock_irqsave(&anv->lock, flags);
	found = apple_nvme_poll_cq(q, iob);
	spin_unlock_irqrestore(&anv->lock, flags);

	return found;
}

static const struct blk_mq_ops apple_nvme_mq_admin_ops = {
	.queue_rq = apple_nvme_queue_rq,
	.complete = apple_nvme_complete_rq,
	.init_hctx = apple_nvme_init_hctx,
	.init_request = apple_nvme_init_request,
	.timeout = apple_nvme_timeout,
};

static const struct blk_mq_ops apple_nvme_mq_ops = {
	.queue_rq = apple_nvme_queue_rq,
	.complete = apple_nvme_complete_rq,
	.init_hctx = apple_nvme_init_hctx,
	.init_request = apple_nvme_init_request,
	.timeout = apple_nvme_timeout,
	.poll = apple_nvme_poll,
};

static void apple_nvme_init_queue(struct apple_nvme_queue *q)
{
	unsigned int depth = apple_nvme_queue_depth(q);
	struct apple_nvme *anv = queue_to_apple_nvme(q);

	q->cq_head = 0;
	q->cq_phase = 1;
	if (anv->hw->has_lsq_nvmmu)
		memset(q->tcbs, 0, anv->hw->max_queue_depth
			* sizeof(struct apple_nvmmu_tcb));
	memset(q->cqes, 0, depth * sizeof(struct nvme_completion));
	WRITE_ONCE(q->enabled, true);
	wmb(); /* ensure the first interrupt sees the initialization */
}

static void apple_nvme_reset_work(struct work_struct *work)
{
	unsigned int nr_io_queues = 1;
	int ret;
	u32 boot_status, aqa;
	struct apple_nvme *anv =
		container_of(work, struct apple_nvme, ctrl.reset_work);
	enum nvme_ctrl_state state = nvme_ctrl_state(&anv->ctrl);

	if (state != NVME_CTRL_RESETTING) {
		dev_warn(anv->dev, "ctrl state %d is not RESETTING\n", state);
		ret = -ENODEV;
		goto out;
	}

	/* there's unfortunately no known way to recover if RTKit crashed :( */
	if (apple_rtkit_is_crashed(anv->rtk)) {
		dev_err(anv->dev,
			"RTKit has crashed without any way to recover.");
		ret = -EIO;
		goto out;
	}

	/* RTKit must be shut down cleanly for the (soft)-reset to work */
	if (apple_rtkit_is_running(anv->rtk)) {
		/* reset the controller if it is enabled */
		if (anv->ctrl.ctrl_config & NVME_CC_ENABLE)
			apple_nvme_disable(anv, false);
		dev_dbg(anv->dev, "Trying to shut down RTKit before reset.");
		ret = apple_rtkit_shutdown(anv->rtk);
		if (ret)
			goto out;

		writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
	}

	/*
	 * Only do the soft-reset if the CPU is not running, which means either we
	 * or the previous stage shut it down cleanly.
	 */
	if (!(readl(anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL) &
		APPLE_ANS_COPROC_CPU_CONTROL_RUN)) {

		ret = reset_control_assert(anv->reset);
		if (ret)
			goto out;

		ret = apple_rtkit_reinit(anv->rtk);
		if (ret)
			goto out;

		ret = reset_control_deassert(anv->reset);
		if (ret)
			goto out;

		writel(APPLE_ANS_COPROC_CPU_CONTROL_RUN,
		       anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);

		ret = apple_rtkit_boot(anv->rtk);
	} else {
		ret = apple_rtkit_wake(anv->rtk);
	}

	if (ret) {
		dev_err(anv->dev, "ANS did not boot");
		goto out;
	}

	ret = readl_poll_timeout(anv->mmio_nvme + APPLE_ANS_BOOT_STATUS,
				 boot_status,
				 boot_status == APPLE_ANS_BOOT_STATUS_OK,
				 USEC_PER_MSEC, APPLE_ANS_BOOT_TIMEOUT);
	if (ret) {
		dev_err(anv->dev, "ANS did not initialize");
		goto out;
	}

	dev_dbg(anv->dev, "ANS booted successfully.");

	/*
	 * Limit the max command size to prevent iod->sg allocations going
	 * over a single page.
	 */
	anv->ctrl.max_hw_sectors = min_t(u32, NVME_MAX_KB_SZ << 1,
					 dma_max_mapping_size(anv->dev) >> 9);
	anv->ctrl.max_segments = NVME_MAX_SEGS;

	dma_set_max_seg_size(anv->dev, 0xffffffff);

	if (anv->hw->has_lsq_nvmmu) {
		/*
		 * Enable NVMMU and linear submission queues which is required
		 * since T6000.
		 */
		writel(APPLE_ANS_LINEAR_SQ_EN,
			anv->mmio_nvme + APPLE_ANS_LINEAR_SQ_CTRL);

		/* Allow as many pending command as possible for both queues */
		writel(anv->hw->max_queue_depth
			| (anv->hw->max_queue_depth << 16), anv->mmio_nvme
			+ APPLE_ANS_MAX_PEND_CMDS_CTRL);

		/* Setup the NVMMU for the maximum admin and IO queue depth */
		writel(anv->hw->max_queue_depth - 1,
			anv->mmio_nvme + APPLE_NVMMU_NUM_TCBS);

		/*
		 * This is probably a chicken bit: without it all commands
		 * where any PRP is set to zero (including those that don't use
		 * that field) fail and the co-processor complains about
		 * "completed with err BAD_CMD-" or a "NULL_PRP_PTR_ERR" in the
		 * syslog
		 */
		writel(readl(anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL) &
			~APPLE_ANS_PRP_NULL_CHECK,
			anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL);
	}

	/* Setup the admin queue */
	if (anv->hw->has_lsq_nvmmu)
		aqa = APPLE_NVME_AQ_DEPTH - 1;
	else
		aqa = anv->hw->max_queue_depth - 1;
	aqa |= aqa << 16;
	writel(aqa, anv->mmio_nvme + NVME_REG_AQA);
	writeq(anv->adminq.sq_dma_addr, anv->mmio_nvme + NVME_REG_ASQ);
	writeq(anv->adminq.cq_dma_addr, anv->mmio_nvme + NVME_REG_ACQ);

	if (anv->hw->has_lsq_nvmmu) {
		/* Setup NVMMU for both queues */
		writeq(anv->adminq.tcb_dma_addr,
			anv->mmio_nvme + APPLE_NVMMU_ASQ_TCB_BASE);
		writeq(anv->ioq.tcb_dma_addr,
			anv->mmio_nvme + APPLE_NVMMU_IOSQ_TCB_BASE);
	}

	anv->ctrl.sqsize =
		anv->hw->max_queue_depth - 1; /* 0's based queue depth */
	anv->ctrl.cap = readq(anv->mmio_nvme + NVME_REG_CAP);

	dev_dbg(anv->dev, "Enabling controller now");
	ret = nvme_enable_ctrl(&anv->ctrl);
	if (ret)
		goto out;

	dev_dbg(anv->dev, "Starting admin queue");
	apple_nvme_init_queue(&anv->adminq);
	nvme_unquiesce_admin_queue(&anv->ctrl);

	if (!nvme_change_ctrl_state(&anv->ctrl, NVME_CTRL_CONNECTING)) {
		dev_warn(anv->ctrl.device,
			 "failed to mark controller CONNECTING\n");
		ret = -ENODEV;
		goto out;
	}

	ret = nvme_init_ctrl_finish(&anv->ctrl, false);
	if (ret)
		goto out;

	dev_dbg(anv->dev, "Creating IOCQ");
	ret = apple_nvme_create_cq(anv);
	if (ret)
		goto out;
	dev_dbg(anv->dev, "Creating IOSQ");
	ret = apple_nvme_create_sq(anv);
	if (ret)
		goto out_remove_cq;

	apple_nvme_init_queue(&anv->ioq);
	nr_io_queues = 1;
	ret = nvme_set_queue_count(&anv->ctrl, &nr_io_queues);
	if (ret)
		goto out_remove_sq;
	if (nr_io_queues != 1) {
		ret = -ENXIO;
		goto out_remove_sq;
	}

	anv->ctrl.queue_count = nr_io_queues + 1;

	nvme_unquiesce_io_queues(&anv->ctrl);
	nvme_wait_freeze(&anv->ctrl);
	blk_mq_update_nr_hw_queues(&anv->tagset, 1);
	nvme_unfreeze(&anv->ctrl);

	if (!nvme_change_ctrl_state(&anv->ctrl, NVME_CTRL_LIVE)) {
		dev_warn(anv->ctrl.device,
			 "failed to mark controller live state\n");
		ret = -ENODEV;
		goto out_remove_sq;
	}

	nvme_start_ctrl(&anv->ctrl);

	dev_dbg(anv->dev, "ANS boot and NVMe init completed.");
	return;

out_remove_sq:
	apple_nvme_remove_sq(anv);
out_remove_cq:
	apple_nvme_remove_cq(anv);
out:
	dev_warn(anv->ctrl.device, "Reset failure status: %d\n", ret);
	nvme_change_ctrl_state(&anv->ctrl, NVME_CTRL_DELETING);
	nvme_get_ctrl(&anv->ctrl);
	apple_nvme_disable(anv, false);
	nvme_mark_namespaces_dead(&anv->ctrl);
	if (!queue_work(nvme_wq, &anv->remove_work))
		nvme_put_ctrl(&anv->ctrl);
}

static void apple_nvme_remove_dead_ctrl_work(struct work_struct *work)
{
	struct apple_nvme *anv =
		container_of(work, struct apple_nvme, remove_work);

	nvme_put_ctrl(&anv->ctrl);
	device_release_driver(anv->dev);
}

static int apple_nvme_reg_read32(struct nvme_ctrl *ctrl, u32 off, u32 *val)
{
	*val = readl(ctrl_to_apple_nvme(ctrl)->mmio_nvme + off);
	return 0;
}

static int apple_nvme_reg_write32(struct nvme_ctrl *ctrl, u32 off, u32 val)
{
	writel(val, ctrl_to_apple_nvme(ctrl)->mmio_nvme + off);
	return 0;
}

static int apple_nvme_reg_read64(struct nvme_ctrl *ctrl, u32 off, u64 *val)
{
	*val = readq(ctrl_to_apple_nvme(ctrl)->mmio_nvme + off);
	return 0;
}

static int apple_nvme_get_address(struct nvme_ctrl *ctrl, char *buf, int size)
{
	struct device *dev = ctrl_to_apple_nvme(ctrl)->dev;

	return snprintf(buf, size, "%s\n", dev_name(dev));
}

static void apple_nvme_free_ctrl(struct nvme_ctrl *ctrl)
{
	struct apple_nvme *anv = ctrl_to_apple_nvme(ctrl);

	if (anv->ctrl.admin_q)
		blk_put_queue(anv->ctrl.admin_q);
	put_device(anv->dev);
}

static const struct nvme_ctrl_ops nvme_ctrl_ops = {
	.name = "apple-nvme",
	.module = THIS_MODULE,
	.flags = 0,
	.reg_read32 = apple_nvme_reg_read32,
	.reg_write32 = apple_nvme_reg_write32,
	.reg_read64 = apple_nvme_reg_read64,
	.free_ctrl = apple_nvme_free_ctrl,
	.get_address = apple_nvme_get_address,
	.get_virt_boundary = nvme_get_virt_boundary,
};

static void apple_nvme_async_probe(void *data, async_cookie_t cookie)
{
	struct apple_nvme *anv = data;

	flush_work(&anv->ctrl.reset_work);
	flush_work(&anv->ctrl.scan_work);
	nvme_put_ctrl(&anv->ctrl);
}

static void devm_apple_nvme_put_tag_set(void *data)
{
	blk_mq_free_tag_set(data);
}

static int apple_nvme_alloc_tagsets(struct apple_nvme *anv)
{
	int ret;

	anv->admin_tagset.ops = &apple_nvme_mq_admin_ops;
	anv->admin_tagset.nr_hw_queues = 1;
	anv->admin_tagset.queue_depth = APPLE_NVME_AQ_MQ_TAG_DEPTH;
	anv->admin_tagset.timeout = NVME_ADMIN_TIMEOUT;
	anv->admin_tagset.numa_node = NUMA_NO_NODE;
	anv->admin_tagset.cmd_size = sizeof(struct apple_nvme_iod);
	anv->admin_tagset.driver_data = &anv->adminq;

	ret = blk_mq_alloc_tag_set(&anv->admin_tagset);
	if (ret)
		return ret;
	ret = devm_add_action_or_reset(anv->dev, devm_apple_nvme_put_tag_set,
				       &anv->admin_tagset);
	if (ret)
		return ret;

	anv->tagset.ops = &apple_nvme_mq_ops;
	anv->tagset.nr_hw_queues = 1;
	anv->tagset.nr_maps = 1;
	/*
	 * Tags are used as an index to the NVMMU and must be unique across
	 * both queues. The admin queue gets the first APPLE_NVME_AQ_DEPTH which
	 * must be marked as reserved in the IO queue.
	 */
	if (anv->hw->has_lsq_nvmmu)
		anv->tagset.reserved_tags = APPLE_NVME_AQ_DEPTH;
	anv->tagset.queue_depth = anv->hw->max_queue_depth - 1;
	anv->tagset.timeout = NVME_IO_TIMEOUT;
	anv->tagset.numa_node = NUMA_NO_NODE;
	anv->tagset.cmd_size = sizeof(struct apple_nvme_iod);
	anv->tagset.driver_data = &anv->ioq;

	ret = blk_mq_alloc_tag_set(&anv->tagset);
	if (ret)
		return ret;
	ret = devm_add_action_or_reset(anv->dev, devm_apple_nvme_put_tag_set,
					&anv->tagset);
	if (ret)
		return ret;

	anv->ctrl.admin_tagset = &anv->admin_tagset;
	anv->ctrl.tagset = &anv->tagset;

	return 0;
}

static int apple_nvme_queue_alloc(struct apple_nvme *anv,
				  struct apple_nvme_queue *q)
{
	unsigned int depth = apple_nvme_queue_depth(q);
	size_t iosq_size;

	q->cqes = dmam_alloc_coherent(anv->dev,
				      depth * sizeof(struct nvme_completion),
				      &q->cq_dma_addr, GFP_KERNEL);
	if (!q->cqes)
		return -ENOMEM;

	if (anv->hw->has_lsq_nvmmu)
		iosq_size = depth * sizeof(struct nvme_command);
	else
		iosq_size = depth << APPLE_NVME_IOSQES;

	q->sqes = dmam_alloc_coherent(anv->dev, iosq_size,
				      &q->sq_dma_addr, GFP_KERNEL);
	if (!q->sqes)
		return -ENOMEM;

	if (anv->hw->has_lsq_nvmmu) {
		/*
		 * We need the maximum queue depth here because the NVMMU only
		 * has a single depth configuration shared between both queues.
		 */
		q->tcbs = dmam_alloc_coherent(anv->dev,
			anv->hw->max_queue_depth *
				sizeof(struct apple_nvmmu_tcb),
			&q->tcb_dma_addr, GFP_KERNEL);
		if (!q->tcbs)
			return -ENOMEM;
	}

	/*
	 * initialize phase to make sure the allocated and empty memory
	 * doesn't look like a full cq already.
	 */
	q->cq_phase = 1;
	return 0;
}

static void apple_nvme_detach_genpd(struct apple_nvme *anv)
{
	int i;

	if (anv->pd_count <= 1)
		return;

	for (i = anv->pd_count - 1; i >= 0; i--) {
		if (anv->pd_link[i])
			device_link_del(anv->pd_link[i]);
		if (!IS_ERR_OR_NULL(anv->pd_dev[i]))
			dev_pm_domain_detach(anv->pd_dev[i], true);
	}
}

static int apple_nvme_attach_genpd(struct apple_nvme *anv)
{
	struct device *dev = anv->dev;
	int i;

	anv->pd_count = of_count_phandle_with_args(
		dev->of_node, "power-domains", "#power-domain-cells");
	if (anv->pd_count <= 1)
		return 0;

	anv->pd_dev = devm_kcalloc(dev, anv->pd_count, sizeof(*anv->pd_dev),
				   GFP_KERNEL);
	if (!anv->pd_dev)
		return -ENOMEM;

	anv->pd_link = devm_kcalloc(dev, anv->pd_count, sizeof(*anv->pd_link),
				    GFP_KERNEL);
	if (!anv->pd_link)
		return -ENOMEM;

	for (i = 0; i < anv->pd_count; i++) {
		anv->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
		if (IS_ERR(anv->pd_dev[i])) {
			apple_nvme_detach_genpd(anv);
			return PTR_ERR(anv->pd_dev[i]);
		}

		anv->pd_link[i] = device_link_add(dev, anv->pd_dev[i],
						  DL_FLAG_STATELESS |
						  DL_FLAG_PM_RUNTIME |
						  DL_FLAG_RPM_ACTIVE);
		if (!anv->pd_link[i]) {
			apple_nvme_detach_genpd(anv);
			return -EINVAL;
		}
	}

	return 0;
}

static void devm_apple_nvme_mempool_destroy(void *data)
{
	mempool_destroy(data);
}

static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct apple_nvme *anv;
	int ret;

	anv = devm_kzalloc(dev, sizeof(*anv), GFP_KERNEL);
	if (!anv)
		return ERR_PTR(-ENOMEM);

	anv->dev = get_device(dev);
	anv->adminq.is_adminq = true;
	platform_set_drvdata(pdev, anv);

	anv->hw = of_device_get_match_data(&pdev->dev);
	if (!anv->hw) {
		ret = -ENODEV;
		goto put_dev;
	}

	ret = apple_nvme_attach_genpd(anv);
	if (ret < 0) {
		dev_err_probe(dev, ret, "Failed to attach power domains");
		goto put_dev;
	}
	if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) {
		ret = -ENXIO;
		goto put_dev;
	}

	anv->irq = platform_get_irq(pdev, 0);
	if (anv->irq < 0) {
		ret = anv->irq;
		goto put_dev;
	}
	if (!anv->irq) {
		ret = -ENXIO;
		goto put_dev;
	}

	anv->mmio_coproc = devm_platform_ioremap_resource_byname(pdev, "ans");
	if (IS_ERR(anv->mmio_coproc)) {
		ret = PTR_ERR(anv->mmio_coproc);
		goto put_dev;
	}
	anv->mmio_nvme = devm_platform_ioremap_resource_byname(pdev, "nvme");
	if (IS_ERR(anv->mmio_nvme)) {
		ret = PTR_ERR(anv->mmio_nvme);
		goto put_dev;
	}

	if (anv->hw->has_lsq_nvmmu) {
		anv->adminq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_ASQ_DB;
		anv->adminq.cq_db = anv->mmio_nvme + APPLE_ANS_ACQ_DB;
		anv->ioq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_IOSQ_DB;
		anv->ioq.cq_db = anv->mmio_nvme + APPLE_ANS_IOCQ_DB;
	} else {
		anv->adminq.sq_db = anv->mmio_nvme + NVME_REG_DBS;
		anv->adminq.cq_db = anv->mmio_nvme + APPLE_ANS_ACQ_DB;
		anv->ioq.sq_db = anv->mmio_nvme + NVME_REG_DBS + 8;
		anv->ioq.cq_db = anv->mmio_nvme + APPLE_ANS_IOCQ_DB;
	}

	anv->sart = devm_apple_sart_get(dev);
	if (IS_ERR(anv->sart)) {
		ret = dev_err_probe(dev, PTR_ERR(anv->sart),
				    "Failed to initialize SART");
		goto put_dev;
	}

	anv->reset = devm_reset_control_array_get_exclusive(anv->dev);
	if (IS_ERR(anv->reset)) {
		ret = dev_err_probe(dev, PTR_ERR(anv->reset),
				    "Failed to get reset control");
		goto put_dev;
	}

	INIT_WORK(&anv->ctrl.reset_work, apple_nvme_reset_work);
	INIT_WORK(&anv->remove_work, apple_nvme_remove_dead_ctrl_work);
	spin_lock_init(&anv->lock);

	ret = apple_nvme_queue_alloc(anv, &anv->adminq);
	if (ret)
		goto put_dev;
	ret = apple_nvme_queue_alloc(anv, &anv->ioq);
	if (ret)
		goto put_dev;

	anv->prp_page_pool = dmam_pool_create("prp list page", anv->dev,
					      NVME_CTRL_PAGE_SIZE,
					      NVME_CTRL_PAGE_SIZE, 0);
	if (!anv->prp_page_pool) {
		ret = -ENOMEM;
		goto put_dev;
	}

	anv->prp_small_pool =
		dmam_pool_create("prp list 256", anv->dev, 256, 256, 0);
	if (!anv->prp_small_pool) {
		ret = -ENOMEM;
		goto put_dev;
	}

	WARN_ON_ONCE(apple_nvme_iod_alloc_size() > PAGE_SIZE);
	anv->iod_mempool =
		mempool_create_kmalloc_pool(1, apple_nvme_iod_alloc_size());
	if (!anv->iod_mempool) {
		ret = -ENOMEM;
		goto put_dev;
	}
	ret = devm_add_action_or_reset(anv->dev,
			devm_apple_nvme_mempool_destroy, anv->iod_mempool);
	if (ret)
		goto put_dev;

	ret = apple_nvme_alloc_tagsets(anv);
	if (ret)
		goto put_dev;

	ret = devm_request_irq(anv->dev, anv->irq, apple_nvme_irq, 0,
			       "nvme-apple", anv);
	if (ret) {
		dev_err_probe(dev, ret, "Failed to request IRQ");
		goto put_dev;
	}

	anv->rtk =
		devm_apple_rtkit_init(dev, anv, NULL, 0, &apple_nvme_rtkit_ops);
	if (IS_ERR(anv->rtk)) {
		ret = dev_err_probe(dev, PTR_ERR(anv->rtk),
				    "Failed to initialize RTKit");
		goto put_dev;
	}

	ret = nvme_init_ctrl(&anv->ctrl, anv->dev, &nvme_ctrl_ops,
			     NVME_QUIRK_SKIP_CID_GEN | NVME_QUIRK_IDENTIFY_CNS);
	if (ret) {
		dev_err_probe(dev, ret, "Failed to initialize nvme_ctrl");
		goto put_dev;
	}

	return anv;
put_dev:
	apple_nvme_detach_genpd(anv);
	put_device(anv->dev);
	return ERR_PTR(ret);
}

static int apple_nvme_probe(struct platform_device *pdev)
{
	struct apple_nvme *anv;
	int ret;

	anv = apple_nvme_alloc(pdev);
	if (IS_ERR(anv))
		return PTR_ERR(anv);

	ret = nvme_add_ctrl(&anv->ctrl);
	if (ret)
		goto out_put_ctrl;

	anv->ctrl.admin_q = blk_mq_alloc_queue(&anv->admin_tagset, NULL, NULL);
	if (IS_ERR(anv->ctrl.admin_q)) {
		ret = -ENOMEM;
		anv->ctrl.admin_q = NULL;
		goto out_uninit_ctrl;
	}

	nvme_reset_ctrl(&anv->ctrl);
	async_schedule(apple_nvme_async_probe, anv);

	return 0;

out_uninit_ctrl:
	nvme_uninit_ctrl(&anv->ctrl);
out_put_ctrl:
	nvme_put_ctrl(&anv->ctrl);
	apple_nvme_detach_genpd(anv);
	return ret;
}

static void apple_nvme_remove(struct platform_device *pdev)
{
	struct apple_nvme *anv = platform_get_drvdata(pdev);

	nvme_change_ctrl_state(&anv->ctrl, NVME_CTRL_DELETING);
	flush_work(&anv->ctrl.reset_work);
	nvme_stop_ctrl(&anv->ctrl);
	nvme_remove_namespaces(&anv->ctrl);
	apple_nvme_disable(anv, true);
	nvme_uninit_ctrl(&anv->ctrl);

	if (apple_rtkit_is_running(anv->rtk)) {
		apple_rtkit_shutdown(anv->rtk);

		writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
	}

	apple_nvme_detach_genpd(anv);
}

static void apple_nvme_shutdown(struct platform_device *pdev)
{
	struct apple_nvme *anv = platform_get_drvdata(pdev);

	apple_nvme_disable(anv, true);
	if (apple_rtkit_is_running(anv->rtk)) {
		apple_rtkit_shutdown(anv->rtk);

		writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
	}
}

static int apple_nvme_resume(struct device *dev)
{
	struct apple_nvme *anv = dev_get_drvdata(dev);

	return nvme_reset_ctrl(&anv->ctrl);
}

static int apple_nvme_suspend(struct device *dev)
{
	struct apple_nvme *anv = dev_get_drvdata(dev);
	int ret = 0;

	apple_nvme_disable(anv, true);

	if (apple_rtkit_is_running(anv->rtk)) {
		ret = apple_rtkit_shutdown(anv->rtk);

		writel(0, anv->mmio_coproc + APPLE_ANS_COPROC_CPU_CONTROL);
	}

	return ret;
}

static DEFINE_SIMPLE_DEV_PM_OPS(apple_nvme_pm_ops, apple_nvme_suspend,
				apple_nvme_resume);

static const struct apple_nvme_hw apple_nvme_t8015_hw = {
	.has_lsq_nvmmu = false,
	.max_queue_depth = 16,
};

static const struct apple_nvme_hw apple_nvme_t8103_hw = {
	.has_lsq_nvmmu = true,
	.max_queue_depth = 64,
};

static const struct of_device_id apple_nvme_of_match[] = {
	{ .compatible = "apple,t8015-nvme-ans2", .data = &apple_nvme_t8015_hw },
	{ .compatible = "apple,t8103-nvme-ans2", .data = &apple_nvme_t8103_hw },
	{ .compatible = "apple,nvme-ans2", .data = &apple_nvme_t8103_hw },
	{},
};
MODULE_DEVICE_TABLE(of, apple_nvme_of_match);

static struct platform_driver apple_nvme_driver = {
	.driver = {
		.name = "nvme-apple",
		.of_match_table = apple_nvme_of_match,
		.pm = pm_sleep_ptr(&apple_nvme_pm_ops),
	},
	.probe = apple_nvme_probe,
	.remove = apple_nvme_remove,
	.shutdown = apple_nvme_shutdown,
};
module_platform_driver(apple_nvme_driver);

MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");
MODULE_DESCRIPTION("Apple ANS NVM Express device driver");
MODULE_LICENSE("GPL");
