linux/drivers/bus/mhi/ep/main.c

// SPDX-License-Identifier: GPL-2.0
/*
 * MHI Endpoint bus stack
 *
 * Copyright (C) 2022 Linaro Ltd.
 * Author: Manivannan Sadhasivam <[email protected]>
 */

#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/dma-direction.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/mhi_ep.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include "internal.h"

#define M0_WAIT_DELAY_MS
#define M0_WAIT_COUNT

static DEFINE_IDA(mhi_ep_cntrl_ida);

static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
static int mhi_ep_destroy_device(struct device *dev, void *data);

static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx,
			     struct mhi_ring_element *el, bool bei)
{}

static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring,
					struct mhi_ring_element *tre, u32 len, enum mhi_ev_ccs code)
{}

int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state)
{}

int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env)
{}

static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ev_ccs code)
{}

static int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ring_element *el)
{}

bool mhi_ep_queue_is_empty(struct mhi_ep_device *mhi_dev, enum dma_data_direction dir)
{}
EXPORT_SYMBOL_GPL();

static void mhi_ep_read_completion(struct mhi_ep_buf_info *buf_info)
{}

static int mhi_ep_read_channel(struct mhi_ep_cntrl *mhi_cntrl,
			       struct mhi_ep_ring *ring)
{}

static int mhi_ep_process_ch_ring(struct mhi_ep_ring *ring)
{}

static void mhi_ep_skb_completion(struct mhi_ep_buf_info *buf_info)
{}

/* TODO: Handle partially formed TDs */
int mhi_ep_queue_skb(struct mhi_ep_device *mhi_dev, struct sk_buff *skb)
{}
EXPORT_SYMBOL_GPL();

static int mhi_ep_cache_host_cfg(struct mhi_ep_cntrl *mhi_cntrl)
{}

static void mhi_ep_free_host_cfg(struct mhi_ep_cntrl *mhi_cntrl)
{}

static void mhi_ep_enable_int(struct mhi_ep_cntrl *mhi_cntrl)
{}

static int mhi_ep_enable(struct mhi_ep_cntrl *mhi_cntrl)
{}

static void mhi_ep_cmd_ring_worker(struct work_struct *work)
{}

static void mhi_ep_ch_ring_worker(struct work_struct *work)
{}

static void mhi_ep_state_worker(struct work_struct *work)
{}

static void mhi_ep_queue_channel_db(struct mhi_ep_cntrl *mhi_cntrl, unsigned long ch_int,
				    u32 ch_idx)
{}

/*
 * Channel interrupt statuses are contained in 4 registers each of 32bit length.
 * For checking all interrupts, we need to loop through each registers and then
 * check for bits set.
 */
static void mhi_ep_check_channel_interrupt(struct mhi_ep_cntrl *mhi_cntrl)
{}

static void mhi_ep_process_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl,
					 enum mhi_state state)
{}

/*
 * Interrupt handler that services interrupts raised by the host writing to
 * MHICTRL and Command ring doorbell (CRDB) registers for state change and
 * channel interrupts.
 */
static irqreturn_t mhi_ep_irq(int irq, void *data)
{}

static void mhi_ep_abort_transfer(struct mhi_ep_cntrl *mhi_cntrl)
{}

static void mhi_ep_reset_worker(struct work_struct *work)
{}

/*
 * We don't need to do anything special other than setting the MHI SYS_ERR
 * state. The host will reset all contexts and issue MHI RESET so that we
 * could also recover from error state.
 */
void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl)
{}

int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl)
{}
EXPORT_SYMBOL_GPL();

void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl)
{}
EXPORT_SYMBOL_GPL();

void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl)
{}

void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl)
{}

static void mhi_ep_release_device(struct device *dev)
{}

static struct mhi_ep_device *mhi_ep_alloc_device(struct mhi_ep_cntrl *mhi_cntrl,
						 enum mhi_device_type dev_type)
{}

/*
 * MHI channels are always defined in pairs with UL as the even numbered
 * channel and DL as odd numbered one. This function gets UL channel (primary)
 * as the ch_id and always looks after the next entry in channel list for
 * the corresponding DL channel (secondary).
 */
static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id)
{}

static int mhi_ep_destroy_device(struct device *dev, void *data)
{}

static int mhi_ep_chan_init(struct mhi_ep_cntrl *mhi_cntrl,
			    const struct mhi_ep_cntrl_config *config)
{}

/*
 * Allocate channel and command rings here. Event rings will be allocated
 * in mhi_ep_power_up() as the config comes from the host.
 */
int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl,
				const struct mhi_ep_cntrl_config *config)
{}
EXPORT_SYMBOL_GPL();

/*
 * It is expected that the controller drivers will power down the MHI EP stack
 * using "mhi_ep_power_down()" before calling this function to unregister themselves.
 */
void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl)
{}
EXPORT_SYMBOL_GPL();

static int mhi_ep_driver_probe(struct device *dev)
{}

static int mhi_ep_driver_remove(struct device *dev)
{}

int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module *owner)
{}
EXPORT_SYMBOL_GPL();

void mhi_ep_driver_unregister(struct mhi_ep_driver *mhi_drv)
{}
EXPORT_SYMBOL_GPL();

static int mhi_ep_uevent(const struct device *dev, struct kobj_uevent_env *env)
{}

static int mhi_ep_match(struct device *dev, const struct device_driver *drv)
{
	struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev);
	const struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(drv);
	const struct mhi_device_id *id;

	/*
	 * If the device is a controller type then there is no client driver
	 * associated with it
	 */
	if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER)
		return 0;

	for (id = mhi_drv->id_table; id->chan[0]; id++)
		if (!strcmp(mhi_dev->name, id->chan)) {
			mhi_dev->id = id;
			return 1;
		}

	return 0;
};

struct bus_type mhi_ep_bus_type =;

static int __init mhi_ep_init(void)
{}

static void __exit mhi_ep_exit(void)
{}

postcore_initcall(mhi_ep_init);
module_exit(mhi_ep_exit);

MODULE_LICENSE();
MODULE_DESCRIPTION();
MODULE_AUTHOR();