Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Authors: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *          Fabien Dessenne <fabien.dessenne@st.com> for STMicroelectronics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/mailbox_controller.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/pm_wakeirq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define IPCC_XCR		0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define XCR_RXOIE		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define XCR_TXOIE		BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define IPCC_XMR		0x004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define IPCC_XSCR		0x008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define IPCC_XTOYSR		0x00c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define IPCC_PROC_OFFST		0x010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define IPCC_HWCFGR		0x3f0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define IPCFGR_CHAN_MASK	GENMASK(7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define IPCC_VER		0x3f4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define VER_MINREV_MASK		GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define VER_MAJREV_MASK		GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define RX_BIT_MASK		GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define RX_BIT_CHAN(chan)	BIT(chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define TX_BIT_SHIFT		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define TX_BIT_MASK		GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define TX_BIT_CHAN(chan)	BIT(TX_BIT_SHIFT + (chan))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define STM32_MAX_PROCS		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	IPCC_IRQ_RX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	IPCC_IRQ_TX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	IPCC_IRQ_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) struct stm32_ipcc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	struct mbox_controller controller;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	void __iomem *reg_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	void __iomem *reg_proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	spinlock_t lock; /* protect access to IPCC registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	int irqs[IPCC_IRQ_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	u32 proc_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	u32 n_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	u32 xcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	u32 xmr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) static inline void stm32_ipcc_set_bits(spinlock_t *lock, void __iomem *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 				       u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	spin_lock_irqsave(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	writel_relaxed(readl_relaxed(reg) | mask, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	spin_unlock_irqrestore(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) static inline void stm32_ipcc_clr_bits(spinlock_t *lock, void __iomem *reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 				       u32 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	spin_lock_irqsave(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	writel_relaxed(readl_relaxed(reg) & ~mask, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	spin_unlock_irqrestore(lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) static irqreturn_t stm32_ipcc_rx_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	struct stm32_ipcc *ipcc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	struct device *dev = ipcc->controller.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	u32 status, mr, tosr, chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	int proc_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	/* read 'channel occupied' status from other proc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	proc_offset = ipcc->proc_id ? -IPCC_PROC_OFFST : IPCC_PROC_OFFST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	tosr = readl_relaxed(ipcc->reg_proc + proc_offset + IPCC_XTOYSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	mr = readl_relaxed(ipcc->reg_proc + IPCC_XMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	/* search for unmasked 'channel occupied' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	status = tosr & FIELD_GET(RX_BIT_MASK, ~mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	for (chan = 0; chan < ipcc->n_chans; chan++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		if (!(status & (1 << chan)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		dev_dbg(dev, "%s: chan:%d rx\n", __func__, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		mbox_chan_received_data(&ipcc->controller.chans[chan], NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XSCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 				    RX_BIT_CHAN(chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static irqreturn_t stm32_ipcc_tx_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	struct stm32_ipcc *ipcc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct device *dev = ipcc->controller.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	u32 status, mr, tosr, chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	irqreturn_t ret = IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	tosr = readl_relaxed(ipcc->reg_proc + IPCC_XTOYSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	mr = readl_relaxed(ipcc->reg_proc + IPCC_XMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	/* search for unmasked 'channel free' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	status = ~tosr & FIELD_GET(TX_BIT_MASK, ~mr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	for (chan = 0; chan < ipcc->n_chans ; chan++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		if (!(status & (1 << chan)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		dev_dbg(dev, "%s: chan:%d tx\n", __func__, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		/* mask 'tx channel free' interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				    TX_BIT_CHAN(chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		mbox_chan_txdone(&ipcc->controller.chans[chan], 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		ret = IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int stm32_ipcc_send_data(struct mbox_chan *link, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	unsigned int chan = (unsigned int)link->con_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct stm32_ipcc *ipcc = container_of(link->mbox, struct stm32_ipcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 					       controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	dev_dbg(ipcc->controller.dev, "%s: chan:%d\n", __func__, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	/* set channel n occupied */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XSCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			    TX_BIT_CHAN(chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	/* unmask 'tx channel free' interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	stm32_ipcc_clr_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			    TX_BIT_CHAN(chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) static int stm32_ipcc_startup(struct mbox_chan *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	unsigned int chan = (unsigned int)link->con_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	struct stm32_ipcc *ipcc = container_of(link->mbox, struct stm32_ipcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 					       controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	ret = clk_prepare_enable(ipcc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		dev_err(ipcc->controller.dev, "can not enable the clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	/* unmask 'rx channel occupied' interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	stm32_ipcc_clr_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			    RX_BIT_CHAN(chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void stm32_ipcc_shutdown(struct mbox_chan *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	unsigned int chan = (unsigned int)link->con_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	struct stm32_ipcc *ipcc = container_of(link->mbox, struct stm32_ipcc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 					       controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	/* mask rx/tx interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			    RX_BIT_CHAN(chan) | TX_BIT_CHAN(chan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	clk_disable_unprepare(ipcc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static const struct mbox_chan_ops stm32_ipcc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	.send_data	= stm32_ipcc_send_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	.startup	= stm32_ipcc_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	.shutdown	= stm32_ipcc_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int stm32_ipcc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	struct stm32_ipcc *ipcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	u32 ip_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	static const char * const irq_name[] = {"rx", "tx"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	irq_handler_t irq_thread[] = {stm32_ipcc_rx_irq, stm32_ipcc_tx_irq};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (!np) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		dev_err(dev, "No DT found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	ipcc = devm_kzalloc(dev, sizeof(*ipcc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	if (!ipcc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	spin_lock_init(&ipcc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	/* proc_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (of_property_read_u32(np, "st,proc-id", &ipcc->proc_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		dev_err(dev, "Missing st,proc-id\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (ipcc->proc_id >= STM32_MAX_PROCS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		dev_err(dev, "Invalid proc_id (%d)\n", ipcc->proc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	/* regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	ipcc->reg_base = devm_ioremap_resource(dev, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	if (IS_ERR(ipcc->reg_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		return PTR_ERR(ipcc->reg_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	ipcc->reg_proc = ipcc->reg_base + ipcc->proc_id * IPCC_PROC_OFFST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	/* clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	ipcc->clk = devm_clk_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	if (IS_ERR(ipcc->clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		return PTR_ERR(ipcc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	ret = clk_prepare_enable(ipcc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		dev_err(dev, "can not enable the clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	/* irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	for (i = 0; i < IPCC_IRQ_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		ipcc->irqs[i] = platform_get_irq_byname(pdev, irq_name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		if (ipcc->irqs[i] < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			if (ipcc->irqs[i] != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				dev_err(dev, "no IRQ specified %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 					irq_name[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			ret = ipcc->irqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		ret = devm_request_threaded_irq(dev, ipcc->irqs[i], NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 						irq_thread[i], IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 						dev_name(dev), ipcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			dev_err(dev, "failed to request irq %d (%d)\n", i, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			goto err_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	/* mask and enable rx/tx irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XMR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 			    RX_BIT_MASK | TX_BIT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	stm32_ipcc_set_bits(&ipcc->lock, ipcc->reg_proc + IPCC_XCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			    XCR_RXOIE | XCR_TXOIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	/* wakeup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	if (of_property_read_bool(np, "wakeup-source")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		device_set_wakeup_capable(dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		ret = dev_pm_set_wake_irq(dev, ipcc->irqs[IPCC_IRQ_RX]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			dev_err(dev, "Failed to set wake up irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			goto err_init_wkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	/* mailbox controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	ipcc->n_chans = readl_relaxed(ipcc->reg_base + IPCC_HWCFGR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	ipcc->n_chans &= IPCFGR_CHAN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	ipcc->controller.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	ipcc->controller.txdone_irq = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	ipcc->controller.ops = &stm32_ipcc_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	ipcc->controller.num_chans = ipcc->n_chans;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	ipcc->controller.chans = devm_kcalloc(dev, ipcc->controller.num_chans,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 					      sizeof(*ipcc->controller.chans),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 					      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	if (!ipcc->controller.chans) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		goto err_irq_wkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	for (i = 0; i < ipcc->controller.num_chans; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		ipcc->controller.chans[i].con_priv = (void *)i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	ret = devm_mbox_controller_register(dev, &ipcc->controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		goto err_irq_wkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	platform_set_drvdata(pdev, ipcc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	ip_ver = readl_relaxed(ipcc->reg_base + IPCC_VER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	dev_info(dev, "ipcc rev:%ld.%ld enabled, %d chans, proc %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		 FIELD_GET(VER_MAJREV_MASK, ip_ver),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		 FIELD_GET(VER_MINREV_MASK, ip_ver),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		 ipcc->controller.num_chans, ipcc->proc_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	clk_disable_unprepare(ipcc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) err_irq_wkp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (of_property_read_bool(np, "wakeup-source"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		dev_pm_clear_wake_irq(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) err_init_wkp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	device_set_wakeup_capable(dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) err_clk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	clk_disable_unprepare(ipcc->clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int stm32_ipcc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	if (of_property_read_bool(dev->of_node, "wakeup-source"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		dev_pm_clear_wake_irq(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	device_set_wakeup_capable(dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int stm32_ipcc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	struct stm32_ipcc *ipcc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	ipcc->xmr = readl_relaxed(ipcc->reg_proc + IPCC_XMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	ipcc->xcr = readl_relaxed(ipcc->reg_proc + IPCC_XCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) static int stm32_ipcc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	struct stm32_ipcc *ipcc = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	writel_relaxed(ipcc->xmr, ipcc->reg_proc + IPCC_XMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	writel_relaxed(ipcc->xcr, ipcc->reg_proc + IPCC_XCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) static SIMPLE_DEV_PM_OPS(stm32_ipcc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 			 stm32_ipcc_suspend, stm32_ipcc_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static const struct of_device_id stm32_ipcc_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	{ .compatible = "st,stm32mp1-ipcc" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) MODULE_DEVICE_TABLE(of, stm32_ipcc_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static struct platform_driver stm32_ipcc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		.name = "stm32-ipcc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		.pm = &stm32_ipcc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		.of_match_table = stm32_ipcc_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	.probe		= stm32_ipcc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	.remove		= stm32_ipcc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) module_platform_driver(stm32_ipcc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) MODULE_DESCRIPTION("STM32 IPCC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) MODULE_LICENSE("GPL v2");