cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mailbox-sti.c (13198B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * STi Mailbox
      4 *
      5 * Copyright (C) 2015 ST Microelectronics
      6 *
      7 * Author: Lee Jones <lee.jones@linaro.org> for ST Microelectronics
      8 *
      9 * Based on the original driver written by;
     10 *   Alexandre Torgue, Olivier Lebreton and Loic Pallardy
     11 */
     12
     13#include <linux/err.h>
     14#include <linux/interrupt.h>
     15#include <linux/io.h>
     16#include <linux/kernel.h>
     17#include <linux/mailbox_controller.h>
     18#include <linux/module.h>
     19#include <linux/of.h>
     20#include <linux/of_device.h>
     21#include <linux/platform_device.h>
     22#include <linux/slab.h>
     23
     24#include "mailbox.h"
     25
     26#define STI_MBOX_INST_MAX	4      /* RAM saving: Max supported instances */
     27#define STI_MBOX_CHAN_MAX	20     /* RAM saving: Max supported channels  */
     28
     29#define STI_IRQ_VAL_OFFSET	0x04   /* Read interrupt status	              */
     30#define STI_IRQ_SET_OFFSET	0x24   /* Generate a Tx channel interrupt     */
     31#define STI_IRQ_CLR_OFFSET	0x44   /* Clear pending Rx interrupts	      */
     32#define STI_ENA_VAL_OFFSET	0x64   /* Read enable status		      */
     33#define STI_ENA_SET_OFFSET	0x84   /* Enable a channel		      */
     34#define STI_ENA_CLR_OFFSET	0xa4   /* Disable a channel		      */
     35
     36#define MBOX_BASE(mdev, inst)   ((mdev)->base + ((inst) * 4))
     37
     38/**
     39 * struct sti_mbox_device - STi Mailbox device data
     40 *
     41 * @dev:	Device to which it is attached
     42 * @mbox:	Representation of a communication channel controller
     43 * @base:	Base address of the register mapping region
     44 * @name:	Name of the mailbox
     45 * @enabled:	Local copy of enabled channels
     46 * @lock:	Mutex protecting enabled status
     47 *
     48 * An IP Mailbox is currently composed of 4 instances
     49 * Each instance is currently composed of 32 channels
     50 * This means that we have 128 channels per Mailbox
     51 * A channel an be used for TX or RX
     52 */
     53struct sti_mbox_device {
     54	struct device		*dev;
     55	struct mbox_controller	*mbox;
     56	void __iomem		*base;
     57	const char		*name;
     58	u32			enabled[STI_MBOX_INST_MAX];
     59	spinlock_t		lock;
     60};
     61
     62/**
     63 * struct sti_mbox_pdata - STi Mailbox platform specific configuration
     64 *
     65 * @num_inst:	Maximum number of instances in one HW Mailbox
     66 * @num_chan:	Maximum number of channel per instance
     67 */
     68struct sti_mbox_pdata {
     69	unsigned int		num_inst;
     70	unsigned int		num_chan;
     71};
     72
     73/**
     74 * struct sti_channel - STi Mailbox allocated channel information
     75 *
     76 * @mdev:	Pointer to parent Mailbox device
     77 * @instance:	Instance number channel resides in
     78 * @channel:	Channel number pertaining to this container
     79 */
     80struct sti_channel {
     81	struct sti_mbox_device	*mdev;
     82	unsigned int		instance;
     83	unsigned int		channel;
     84};
     85
     86static inline bool sti_mbox_channel_is_enabled(struct mbox_chan *chan)
     87{
     88	struct sti_channel *chan_info = chan->con_priv;
     89	struct sti_mbox_device *mdev = chan_info->mdev;
     90	unsigned int instance = chan_info->instance;
     91	unsigned int channel = chan_info->channel;
     92
     93	return mdev->enabled[instance] & BIT(channel);
     94}
     95
     96static inline
     97struct mbox_chan *sti_mbox_to_channel(struct mbox_controller *mbox,
     98				      unsigned int instance,
     99				      unsigned int channel)
    100{
    101	struct sti_channel *chan_info;
    102	int i;
    103
    104	for (i = 0; i < mbox->num_chans; i++) {
    105		chan_info = mbox->chans[i].con_priv;
    106		if (chan_info &&
    107		    chan_info->instance == instance &&
    108		    chan_info->channel == channel)
    109			return &mbox->chans[i];
    110	}
    111
    112	dev_err(mbox->dev,
    113		"Channel not registered: instance: %d channel: %d\n",
    114		instance, channel);
    115
    116	return NULL;
    117}
    118
    119static void sti_mbox_enable_channel(struct mbox_chan *chan)
    120{
    121	struct sti_channel *chan_info = chan->con_priv;
    122	struct sti_mbox_device *mdev = chan_info->mdev;
    123	unsigned int instance = chan_info->instance;
    124	unsigned int channel = chan_info->channel;
    125	unsigned long flags;
    126	void __iomem *base = MBOX_BASE(mdev, instance);
    127
    128	spin_lock_irqsave(&mdev->lock, flags);
    129	mdev->enabled[instance] |= BIT(channel);
    130	writel_relaxed(BIT(channel), base + STI_ENA_SET_OFFSET);
    131	spin_unlock_irqrestore(&mdev->lock, flags);
    132}
    133
    134static void sti_mbox_disable_channel(struct mbox_chan *chan)
    135{
    136	struct sti_channel *chan_info = chan->con_priv;
    137	struct sti_mbox_device *mdev = chan_info->mdev;
    138	unsigned int instance = chan_info->instance;
    139	unsigned int channel = chan_info->channel;
    140	unsigned long flags;
    141	void __iomem *base = MBOX_BASE(mdev, instance);
    142
    143	spin_lock_irqsave(&mdev->lock, flags);
    144	mdev->enabled[instance] &= ~BIT(channel);
    145	writel_relaxed(BIT(channel), base + STI_ENA_CLR_OFFSET);
    146	spin_unlock_irqrestore(&mdev->lock, flags);
    147}
    148
    149static void sti_mbox_clear_irq(struct mbox_chan *chan)
    150{
    151	struct sti_channel *chan_info = chan->con_priv;
    152	struct sti_mbox_device *mdev = chan_info->mdev;
    153	unsigned int instance = chan_info->instance;
    154	unsigned int channel = chan_info->channel;
    155	void __iomem *base = MBOX_BASE(mdev, instance);
    156
    157	writel_relaxed(BIT(channel), base + STI_IRQ_CLR_OFFSET);
    158}
    159
    160static struct mbox_chan *sti_mbox_irq_to_channel(struct sti_mbox_device *mdev,
    161						 unsigned int instance)
    162{
    163	struct mbox_controller *mbox = mdev->mbox;
    164	struct mbox_chan *chan = NULL;
    165	unsigned int channel;
    166	unsigned long bits;
    167	void __iomem *base = MBOX_BASE(mdev, instance);
    168
    169	bits = readl_relaxed(base + STI_IRQ_VAL_OFFSET);
    170	if (!bits)
    171		/* No IRQs fired in specified instance */
    172		return NULL;
    173
    174	/* An IRQ has fired, find the associated channel */
    175	for (channel = 0; bits; channel++) {
    176		if (!test_and_clear_bit(channel, &bits))
    177			continue;
    178
    179		chan = sti_mbox_to_channel(mbox, instance, channel);
    180		if (chan) {
    181			dev_dbg(mbox->dev,
    182				"IRQ fired on instance: %d channel: %d\n",
    183				instance, channel);
    184			break;
    185		}
    186	}
    187
    188	return chan;
    189}
    190
    191static irqreturn_t sti_mbox_thread_handler(int irq, void *data)
    192{
    193	struct sti_mbox_device *mdev = data;
    194	struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
    195	struct mbox_chan *chan;
    196	unsigned int instance;
    197
    198	for (instance = 0; instance < pdata->num_inst; instance++) {
    199keep_looking:
    200		chan = sti_mbox_irq_to_channel(mdev, instance);
    201		if (!chan)
    202			continue;
    203
    204		mbox_chan_received_data(chan, NULL);
    205		sti_mbox_clear_irq(chan);
    206		sti_mbox_enable_channel(chan);
    207		goto keep_looking;
    208	}
    209
    210	return IRQ_HANDLED;
    211}
    212
    213static irqreturn_t sti_mbox_irq_handler(int irq, void *data)
    214{
    215	struct sti_mbox_device *mdev = data;
    216	struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
    217	struct sti_channel *chan_info;
    218	struct mbox_chan *chan;
    219	unsigned int instance;
    220	int ret = IRQ_NONE;
    221
    222	for (instance = 0; instance < pdata->num_inst; instance++) {
    223		chan = sti_mbox_irq_to_channel(mdev, instance);
    224		if (!chan)
    225			continue;
    226		chan_info = chan->con_priv;
    227
    228		if (!sti_mbox_channel_is_enabled(chan)) {
    229			dev_warn(mdev->dev,
    230				 "Unexpected IRQ: %s\n"
    231				 "  instance: %d: channel: %d [enabled: %x]\n",
    232				 mdev->name, chan_info->instance,
    233				 chan_info->channel, mdev->enabled[instance]);
    234
    235			/* Only handle IRQ if no other valid IRQs were found */
    236			if (ret == IRQ_NONE)
    237				ret = IRQ_HANDLED;
    238			continue;
    239		}
    240
    241		sti_mbox_disable_channel(chan);
    242		ret = IRQ_WAKE_THREAD;
    243	}
    244
    245	if (ret == IRQ_NONE)
    246		dev_err(mdev->dev, "Spurious IRQ - was a channel requested?\n");
    247
    248	return ret;
    249}
    250
    251static bool sti_mbox_tx_is_ready(struct mbox_chan *chan)
    252{
    253	struct sti_channel *chan_info = chan->con_priv;
    254	struct sti_mbox_device *mdev = chan_info->mdev;
    255	unsigned int instance = chan_info->instance;
    256	unsigned int channel = chan_info->channel;
    257	void __iomem *base = MBOX_BASE(mdev, instance);
    258
    259	if (!(readl_relaxed(base + STI_ENA_VAL_OFFSET) & BIT(channel))) {
    260		dev_dbg(mdev->dev, "Mbox: %s: inst: %d, chan: %d disabled\n",
    261			mdev->name, instance, channel);
    262		return false;
    263	}
    264
    265	if (readl_relaxed(base + STI_IRQ_VAL_OFFSET) & BIT(channel)) {
    266		dev_dbg(mdev->dev, "Mbox: %s: inst: %d, chan: %d not ready\n",
    267			mdev->name, instance, channel);
    268		return false;
    269	}
    270
    271	return true;
    272}
    273
    274static int sti_mbox_send_data(struct mbox_chan *chan, void *data)
    275{
    276	struct sti_channel *chan_info = chan->con_priv;
    277	struct sti_mbox_device *mdev = chan_info->mdev;
    278	unsigned int instance = chan_info->instance;
    279	unsigned int channel = chan_info->channel;
    280	void __iomem *base = MBOX_BASE(mdev, instance);
    281
    282	/* Send event to co-processor */
    283	writel_relaxed(BIT(channel), base + STI_IRQ_SET_OFFSET);
    284
    285	dev_dbg(mdev->dev,
    286		"Sent via Mailbox %s: instance: %d channel: %d\n",
    287		mdev->name, instance, channel);
    288
    289	return 0;
    290}
    291
    292static int sti_mbox_startup_chan(struct mbox_chan *chan)
    293{
    294	sti_mbox_clear_irq(chan);
    295	sti_mbox_enable_channel(chan);
    296
    297	return 0;
    298}
    299
    300static void sti_mbox_shutdown_chan(struct mbox_chan *chan)
    301{
    302	struct sti_channel *chan_info = chan->con_priv;
    303	struct mbox_controller *mbox = chan_info->mdev->mbox;
    304	int i;
    305
    306	for (i = 0; i < mbox->num_chans; i++)
    307		if (chan == &mbox->chans[i])
    308			break;
    309
    310	if (mbox->num_chans == i) {
    311		dev_warn(mbox->dev, "Request to free non-existent channel\n");
    312		return;
    313	}
    314
    315	/* Reset channel */
    316	sti_mbox_disable_channel(chan);
    317	sti_mbox_clear_irq(chan);
    318	chan->con_priv = NULL;
    319}
    320
    321static struct mbox_chan *sti_mbox_xlate(struct mbox_controller *mbox,
    322					const struct of_phandle_args *spec)
    323{
    324	struct sti_mbox_device *mdev = dev_get_drvdata(mbox->dev);
    325	struct sti_mbox_pdata *pdata = dev_get_platdata(mdev->dev);
    326	struct sti_channel *chan_info;
    327	struct mbox_chan *chan = NULL;
    328	unsigned int instance  = spec->args[0];
    329	unsigned int channel   = spec->args[1];
    330	int i;
    331
    332	/* Bounds checking */
    333	if (instance >= pdata->num_inst || channel  >= pdata->num_chan) {
    334		dev_err(mbox->dev,
    335			"Invalid channel requested instance: %d channel: %d\n",
    336			instance, channel);
    337		return ERR_PTR(-EINVAL);
    338	}
    339
    340	for (i = 0; i < mbox->num_chans; i++) {
    341		chan_info = mbox->chans[i].con_priv;
    342
    343		/* Is requested channel free? */
    344		if (chan_info &&
    345		    mbox->dev == chan_info->mdev->dev &&
    346		    instance == chan_info->instance &&
    347		    channel == chan_info->channel) {
    348
    349			dev_err(mbox->dev, "Channel in use\n");
    350			return ERR_PTR(-EBUSY);
    351		}
    352
    353		/*
    354		 * Find the first free slot, then continue checking
    355		 * to see if requested channel is in use
    356		 */
    357		if (!chan && !chan_info)
    358			chan = &mbox->chans[i];
    359	}
    360
    361	if (!chan) {
    362		dev_err(mbox->dev, "No free channels left\n");
    363		return ERR_PTR(-EBUSY);
    364	}
    365
    366	chan_info = devm_kzalloc(mbox->dev, sizeof(*chan_info), GFP_KERNEL);
    367	if (!chan_info)
    368		return ERR_PTR(-ENOMEM);
    369
    370	chan_info->mdev		= mdev;
    371	chan_info->instance	= instance;
    372	chan_info->channel	= channel;
    373
    374	chan->con_priv = chan_info;
    375
    376	dev_info(mbox->dev,
    377		 "Mbox: %s: Created channel: instance: %d channel: %d\n",
    378		 mdev->name, instance, channel);
    379
    380	return chan;
    381}
    382
    383static const struct mbox_chan_ops sti_mbox_ops = {
    384	.startup	= sti_mbox_startup_chan,
    385	.shutdown	= sti_mbox_shutdown_chan,
    386	.send_data	= sti_mbox_send_data,
    387	.last_tx_done	= sti_mbox_tx_is_ready,
    388};
    389
    390static const struct sti_mbox_pdata mbox_stih407_pdata = {
    391	.num_inst	= 4,
    392	.num_chan	= 32,
    393};
    394
    395static const struct of_device_id sti_mailbox_match[] = {
    396	{
    397		.compatible = "st,stih407-mailbox",
    398		.data = (void *)&mbox_stih407_pdata
    399	},
    400	{ }
    401};
    402MODULE_DEVICE_TABLE(of, sti_mailbox_match);
    403
    404static int sti_mbox_probe(struct platform_device *pdev)
    405{
    406	const struct of_device_id *match;
    407	struct mbox_controller *mbox;
    408	struct sti_mbox_device *mdev;
    409	struct device_node *np = pdev->dev.of_node;
    410	struct mbox_chan *chans;
    411	int irq;
    412	int ret;
    413
    414	match = of_match_device(sti_mailbox_match, &pdev->dev);
    415	if (!match) {
    416		dev_err(&pdev->dev, "No configuration found\n");
    417		return -ENODEV;
    418	}
    419	pdev->dev.platform_data = (struct sti_mbox_pdata *) match->data;
    420
    421	mdev = devm_kzalloc(&pdev->dev, sizeof(*mdev), GFP_KERNEL);
    422	if (!mdev)
    423		return -ENOMEM;
    424
    425	platform_set_drvdata(pdev, mdev);
    426
    427	mdev->base = devm_platform_ioremap_resource(pdev, 0);
    428	if (IS_ERR(mdev->base))
    429		return PTR_ERR(mdev->base);
    430
    431	ret = of_property_read_string(np, "mbox-name", &mdev->name);
    432	if (ret)
    433		mdev->name = np->full_name;
    434
    435	mbox = devm_kzalloc(&pdev->dev, sizeof(*mbox), GFP_KERNEL);
    436	if (!mbox)
    437		return -ENOMEM;
    438
    439	chans = devm_kcalloc(&pdev->dev,
    440			     STI_MBOX_CHAN_MAX, sizeof(*chans), GFP_KERNEL);
    441	if (!chans)
    442		return -ENOMEM;
    443
    444	mdev->dev		= &pdev->dev;
    445	mdev->mbox		= mbox;
    446
    447	spin_lock_init(&mdev->lock);
    448
    449	/* STi Mailbox does not have a Tx-Done or Tx-Ready IRQ */
    450	mbox->txdone_irq	= false;
    451	mbox->txdone_poll	= true;
    452	mbox->txpoll_period	= 100;
    453	mbox->ops		= &sti_mbox_ops;
    454	mbox->dev		= mdev->dev;
    455	mbox->of_xlate		= sti_mbox_xlate;
    456	mbox->chans		= chans;
    457	mbox->num_chans		= STI_MBOX_CHAN_MAX;
    458
    459	ret = devm_mbox_controller_register(&pdev->dev, mbox);
    460	if (ret)
    461		return ret;
    462
    463	/* It's okay for Tx Mailboxes to not supply IRQs */
    464	irq = platform_get_irq(pdev, 0);
    465	if (irq < 0) {
    466		dev_info(&pdev->dev,
    467			 "%s: Registered Tx only Mailbox\n", mdev->name);
    468		return 0;
    469	}
    470
    471	ret = devm_request_threaded_irq(&pdev->dev, irq,
    472					sti_mbox_irq_handler,
    473					sti_mbox_thread_handler,
    474					IRQF_ONESHOT, mdev->name, mdev);
    475	if (ret) {
    476		dev_err(&pdev->dev, "Can't claim IRQ %d\n", irq);
    477		return -EINVAL;
    478	}
    479
    480	dev_info(&pdev->dev, "%s: Registered Tx/Rx Mailbox\n", mdev->name);
    481
    482	return 0;
    483}
    484
    485static struct platform_driver sti_mbox_driver = {
    486	.probe = sti_mbox_probe,
    487	.driver = {
    488		.name = "sti-mailbox",
    489		.of_match_table = sti_mailbox_match,
    490	},
    491};
    492module_platform_driver(sti_mbox_driver);
    493
    494MODULE_LICENSE("GPL");
    495MODULE_DESCRIPTION("STMicroelectronics Mailbox Controller");
    496MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org");
    497MODULE_ALIAS("platform:mailbox-sti");