1fa74a025SManivannan Sadhasivam // SPDX-License-Identifier: GPL-2.0-only 2fa74a025SManivannan Sadhasivam /* 3fa74a025SManivannan Sadhasivam * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. 4fa74a025SManivannan Sadhasivam */ 5fa74a025SManivannan Sadhasivam 6fa74a025SManivannan Sadhasivam #include <linux/bitfield.h> 7fa74a025SManivannan Sadhasivam #include <linux/interrupt.h> 8fa74a025SManivannan Sadhasivam #include <linux/irq.h> 9fa74a025SManivannan Sadhasivam #include <linux/irqdomain.h> 10fa74a025SManivannan Sadhasivam #include <linux/mailbox_controller.h> 11fa74a025SManivannan Sadhasivam #include <linux/module.h> 12fa74a025SManivannan Sadhasivam #include <linux/platform_device.h> 13fa74a025SManivannan Sadhasivam 14fa74a025SManivannan Sadhasivam #include <dt-bindings/mailbox/qcom-ipcc.h> 15fa74a025SManivannan Sadhasivam 16fa74a025SManivannan Sadhasivam /* IPCC Register offsets */ 17fa74a025SManivannan Sadhasivam #define IPCC_REG_SEND_ID 0x0c 18fa74a025SManivannan Sadhasivam #define IPCC_REG_RECV_ID 0x10 19fa74a025SManivannan Sadhasivam #define IPCC_REG_RECV_SIGNAL_ENABLE 0x14 20fa74a025SManivannan Sadhasivam #define IPCC_REG_RECV_SIGNAL_DISABLE 0x18 21fa74a025SManivannan Sadhasivam #define IPCC_REG_RECV_SIGNAL_CLEAR 0x1c 22fa74a025SManivannan Sadhasivam #define IPCC_REG_CLIENT_CLEAR 0x38 23fa74a025SManivannan Sadhasivam 24fa74a025SManivannan Sadhasivam #define IPCC_SIGNAL_ID_MASK GENMASK(15, 0) 25fa74a025SManivannan Sadhasivam #define IPCC_CLIENT_ID_MASK GENMASK(31, 16) 26fa74a025SManivannan Sadhasivam 27fa74a025SManivannan Sadhasivam #define IPCC_NO_PENDING_IRQ GENMASK(31, 0) 28fa74a025SManivannan Sadhasivam 29fa74a025SManivannan Sadhasivam /** 30fa74a025SManivannan Sadhasivam * struct qcom_ipcc_chan_info - Per-mailbox-channel info 31fa74a025SManivannan Sadhasivam * @client_id: The client-id to which the interrupt has to be triggered 32fa74a025SManivannan Sadhasivam * @signal_id: The signal-id to which the interrupt has to be triggered 33fa74a025SManivannan Sadhasivam */ 34fa74a025SManivannan Sadhasivam struct qcom_ipcc_chan_info { 35fa74a025SManivannan Sadhasivam u16 client_id; 36fa74a025SManivannan Sadhasivam u16 signal_id; 37fa74a025SManivannan Sadhasivam }; 38fa74a025SManivannan Sadhasivam 39fa74a025SManivannan Sadhasivam /** 40fa74a025SManivannan Sadhasivam * struct qcom_ipcc - Holder for the mailbox driver 41fa74a025SManivannan Sadhasivam * @dev: Device associated with this instance 42fa74a025SManivannan Sadhasivam * @base: Base address of the IPCC frame associated to APSS 43fa74a025SManivannan Sadhasivam * @irq_domain: The irq_domain associated with this instance 44fa74a025SManivannan Sadhasivam * @chan: The mailbox channels array 45fa74a025SManivannan Sadhasivam * @mchan: The per-mailbox channel info array 46fa74a025SManivannan Sadhasivam * @mbox: The mailbox controller 47fa74a025SManivannan Sadhasivam * @irq: Summary irq 48fa74a025SManivannan Sadhasivam */ 49fa74a025SManivannan Sadhasivam struct qcom_ipcc { 50fa74a025SManivannan Sadhasivam struct device *dev; 51fa74a025SManivannan Sadhasivam void __iomem *base; 52fa74a025SManivannan Sadhasivam struct irq_domain *irq_domain; 53*e9d50e4bSHuang Yiwei struct mbox_chan *chans; 54*e9d50e4bSHuang Yiwei struct qcom_ipcc_chan_info *mchan; 55fa74a025SManivannan Sadhasivam struct mbox_controller mbox; 56*e9d50e4bSHuang Yiwei int num_chans; 57fa74a025SManivannan Sadhasivam int irq; 58fa74a025SManivannan Sadhasivam }; 59fa74a025SManivannan Sadhasivam 60fa74a025SManivannan Sadhasivam static inline struct qcom_ipcc *to_qcom_ipcc(struct mbox_controller *mbox) 61fa74a025SManivannan Sadhasivam { 62fa74a025SManivannan Sadhasivam return container_of(mbox, struct qcom_ipcc, mbox); 63fa74a025SManivannan Sadhasivam } 64fa74a025SManivannan Sadhasivam 65fa74a025SManivannan Sadhasivam static inline u32 qcom_ipcc_get_hwirq(u16 client_id, u16 signal_id) 66fa74a025SManivannan Sadhasivam { 67fa74a025SManivannan Sadhasivam return FIELD_PREP(IPCC_CLIENT_ID_MASK, client_id) | 68fa74a025SManivannan Sadhasivam FIELD_PREP(IPCC_SIGNAL_ID_MASK, signal_id); 69fa74a025SManivannan Sadhasivam } 70fa74a025SManivannan Sadhasivam 71fa74a025SManivannan Sadhasivam static irqreturn_t qcom_ipcc_irq_fn(int irq, void *data) 72fa74a025SManivannan Sadhasivam { 73fa74a025SManivannan Sadhasivam struct qcom_ipcc *ipcc = data; 74fa74a025SManivannan Sadhasivam u32 hwirq; 75fa74a025SManivannan Sadhasivam int virq; 76fa74a025SManivannan Sadhasivam 77fa74a025SManivannan Sadhasivam for (;;) { 78fa74a025SManivannan Sadhasivam hwirq = readl(ipcc->base + IPCC_REG_RECV_ID); 79fa74a025SManivannan Sadhasivam if (hwirq == IPCC_NO_PENDING_IRQ) 80fa74a025SManivannan Sadhasivam break; 81fa74a025SManivannan Sadhasivam 82fa74a025SManivannan Sadhasivam virq = irq_find_mapping(ipcc->irq_domain, hwirq); 83fa74a025SManivannan Sadhasivam writel(hwirq, ipcc->base + IPCC_REG_RECV_SIGNAL_CLEAR); 84fa74a025SManivannan Sadhasivam generic_handle_irq(virq); 85fa74a025SManivannan Sadhasivam } 86fa74a025SManivannan Sadhasivam 87fa74a025SManivannan Sadhasivam return IRQ_HANDLED; 88fa74a025SManivannan Sadhasivam } 89fa74a025SManivannan Sadhasivam 90fa74a025SManivannan Sadhasivam static void qcom_ipcc_mask_irq(struct irq_data *irqd) 91fa74a025SManivannan Sadhasivam { 92fa74a025SManivannan Sadhasivam struct qcom_ipcc *ipcc = irq_data_get_irq_chip_data(irqd); 93fa74a025SManivannan Sadhasivam irq_hw_number_t hwirq = irqd_to_hwirq(irqd); 94fa74a025SManivannan Sadhasivam 95fa74a025SManivannan Sadhasivam writel(hwirq, ipcc->base + IPCC_REG_RECV_SIGNAL_DISABLE); 96fa74a025SManivannan Sadhasivam } 97fa74a025SManivannan Sadhasivam 98fa74a025SManivannan Sadhasivam static void qcom_ipcc_unmask_irq(struct irq_data *irqd) 99fa74a025SManivannan Sadhasivam { 100fa74a025SManivannan Sadhasivam struct qcom_ipcc *ipcc = irq_data_get_irq_chip_data(irqd); 101fa74a025SManivannan Sadhasivam irq_hw_number_t hwirq = irqd_to_hwirq(irqd); 102fa74a025SManivannan Sadhasivam 103fa74a025SManivannan Sadhasivam writel(hwirq, ipcc->base + IPCC_REG_RECV_SIGNAL_ENABLE); 104fa74a025SManivannan Sadhasivam } 105fa74a025SManivannan Sadhasivam 106fa74a025SManivannan Sadhasivam static struct irq_chip qcom_ipcc_irq_chip = { 107fa74a025SManivannan Sadhasivam .name = "ipcc", 108fa74a025SManivannan Sadhasivam .irq_mask = qcom_ipcc_mask_irq, 109fa74a025SManivannan Sadhasivam .irq_unmask = qcom_ipcc_unmask_irq, 110fa74a025SManivannan Sadhasivam .flags = IRQCHIP_SKIP_SET_WAKE, 111fa74a025SManivannan Sadhasivam }; 112fa74a025SManivannan Sadhasivam 113fa74a025SManivannan Sadhasivam static int qcom_ipcc_domain_map(struct irq_domain *d, unsigned int irq, 114fa74a025SManivannan Sadhasivam irq_hw_number_t hw) 115fa74a025SManivannan Sadhasivam { 116fa74a025SManivannan Sadhasivam struct qcom_ipcc *ipcc = d->host_data; 117fa74a025SManivannan Sadhasivam 118fa74a025SManivannan Sadhasivam irq_set_chip_and_handler(irq, &qcom_ipcc_irq_chip, handle_level_irq); 119fa74a025SManivannan Sadhasivam irq_set_chip_data(irq, ipcc); 120fa74a025SManivannan Sadhasivam irq_set_noprobe(irq); 121fa74a025SManivannan Sadhasivam 122fa74a025SManivannan Sadhasivam return 0; 123fa74a025SManivannan Sadhasivam } 124fa74a025SManivannan Sadhasivam 125fa74a025SManivannan Sadhasivam static int qcom_ipcc_domain_xlate(struct irq_domain *d, 126fa74a025SManivannan Sadhasivam struct device_node *node, const u32 *intspec, 127fa74a025SManivannan Sadhasivam unsigned int intsize, 128fa74a025SManivannan Sadhasivam unsigned long *out_hwirq, 129fa74a025SManivannan Sadhasivam unsigned int *out_type) 130fa74a025SManivannan Sadhasivam { 131fa74a025SManivannan Sadhasivam if (intsize != 3) 132fa74a025SManivannan Sadhasivam return -EINVAL; 133fa74a025SManivannan Sadhasivam 134fa74a025SManivannan Sadhasivam *out_hwirq = qcom_ipcc_get_hwirq(intspec[0], intspec[1]); 135fa74a025SManivannan Sadhasivam *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 136fa74a025SManivannan Sadhasivam 137fa74a025SManivannan Sadhasivam return 0; 138fa74a025SManivannan Sadhasivam } 139fa74a025SManivannan Sadhasivam 140fa74a025SManivannan Sadhasivam static const struct irq_domain_ops qcom_ipcc_irq_ops = { 141fa74a025SManivannan Sadhasivam .map = qcom_ipcc_domain_map, 142fa74a025SManivannan Sadhasivam .xlate = qcom_ipcc_domain_xlate, 143fa74a025SManivannan Sadhasivam }; 144fa74a025SManivannan Sadhasivam 145fa74a025SManivannan Sadhasivam static int qcom_ipcc_mbox_send_data(struct mbox_chan *chan, void *data) 146fa74a025SManivannan Sadhasivam { 147fa74a025SManivannan Sadhasivam struct qcom_ipcc *ipcc = to_qcom_ipcc(chan->mbox); 148fa74a025SManivannan Sadhasivam struct qcom_ipcc_chan_info *mchan = chan->con_priv; 149fa74a025SManivannan Sadhasivam u32 hwirq; 150fa74a025SManivannan Sadhasivam 151fa74a025SManivannan Sadhasivam hwirq = qcom_ipcc_get_hwirq(mchan->client_id, mchan->signal_id); 152fa74a025SManivannan Sadhasivam writel(hwirq, ipcc->base + IPCC_REG_SEND_ID); 153fa74a025SManivannan Sadhasivam 154fa74a025SManivannan Sadhasivam return 0; 155fa74a025SManivannan Sadhasivam } 156fa74a025SManivannan Sadhasivam 157d6fbfdbcSSibi Sankar static void qcom_ipcc_mbox_shutdown(struct mbox_chan *chan) 158d6fbfdbcSSibi Sankar { 159d6fbfdbcSSibi Sankar chan->con_priv = NULL; 160d6fbfdbcSSibi Sankar } 161d6fbfdbcSSibi Sankar 162fa74a025SManivannan Sadhasivam static struct mbox_chan *qcom_ipcc_mbox_xlate(struct mbox_controller *mbox, 163fa74a025SManivannan Sadhasivam const struct of_phandle_args *ph) 164fa74a025SManivannan Sadhasivam { 165fa74a025SManivannan Sadhasivam struct qcom_ipcc *ipcc = to_qcom_ipcc(mbox); 166fa74a025SManivannan Sadhasivam struct qcom_ipcc_chan_info *mchan; 167fa74a025SManivannan Sadhasivam struct mbox_chan *chan; 168*e9d50e4bSHuang Yiwei struct device *dev; 169*e9d50e4bSHuang Yiwei int chan_id; 170*e9d50e4bSHuang Yiwei 171*e9d50e4bSHuang Yiwei dev = ipcc->dev; 172fa74a025SManivannan Sadhasivam 173fa74a025SManivannan Sadhasivam if (ph->args_count != 2) 174fa74a025SManivannan Sadhasivam return ERR_PTR(-EINVAL); 175fa74a025SManivannan Sadhasivam 176*e9d50e4bSHuang Yiwei for (chan_id = 0; chan_id < mbox->num_chans; chan_id++) { 177*e9d50e4bSHuang Yiwei chan = &ipcc->chans[chan_id]; 178*e9d50e4bSHuang Yiwei mchan = chan->con_priv; 179*e9d50e4bSHuang Yiwei 180*e9d50e4bSHuang Yiwei if (!mchan) 181*e9d50e4bSHuang Yiwei break; 182*e9d50e4bSHuang Yiwei else if (mchan->client_id == ph->args[0] && 183*e9d50e4bSHuang Yiwei mchan->signal_id == ph->args[1]) 184*e9d50e4bSHuang Yiwei return ERR_PTR(-EBUSY); 185*e9d50e4bSHuang Yiwei } 186*e9d50e4bSHuang Yiwei 187*e9d50e4bSHuang Yiwei if (chan_id >= mbox->num_chans) 188*e9d50e4bSHuang Yiwei return ERR_PTR(-EBUSY); 189*e9d50e4bSHuang Yiwei 190*e9d50e4bSHuang Yiwei mchan = devm_kzalloc(dev, sizeof(*mchan), GFP_KERNEL); 191*e9d50e4bSHuang Yiwei if (!mchan) 192*e9d50e4bSHuang Yiwei return ERR_PTR(-ENOMEM); 193*e9d50e4bSHuang Yiwei 194fa74a025SManivannan Sadhasivam mchan->client_id = ph->args[0]; 195fa74a025SManivannan Sadhasivam mchan->signal_id = ph->args[1]; 196fa74a025SManivannan Sadhasivam chan->con_priv = mchan; 197fa74a025SManivannan Sadhasivam 198*e9d50e4bSHuang Yiwei return chan; 199fa74a025SManivannan Sadhasivam } 200fa74a025SManivannan Sadhasivam 201fa74a025SManivannan Sadhasivam static const struct mbox_chan_ops ipcc_mbox_chan_ops = { 202fa74a025SManivannan Sadhasivam .send_data = qcom_ipcc_mbox_send_data, 203d6fbfdbcSSibi Sankar .shutdown = qcom_ipcc_mbox_shutdown, 204fa74a025SManivannan Sadhasivam }; 205fa74a025SManivannan Sadhasivam 206*e9d50e4bSHuang Yiwei static int qcom_ipcc_setup_mbox(struct qcom_ipcc *ipcc, 207*e9d50e4bSHuang Yiwei struct device_node *controller_dn) 208fa74a025SManivannan Sadhasivam { 209*e9d50e4bSHuang Yiwei struct of_phandle_args curr_ph; 210*e9d50e4bSHuang Yiwei struct device_node *client_dn; 211fa74a025SManivannan Sadhasivam struct mbox_controller *mbox; 212fa74a025SManivannan Sadhasivam struct device *dev = ipcc->dev; 213*e9d50e4bSHuang Yiwei int i, j, ret; 214*e9d50e4bSHuang Yiwei 215*e9d50e4bSHuang Yiwei /* 216*e9d50e4bSHuang Yiwei * Find out the number of clients interested in this mailbox 217*e9d50e4bSHuang Yiwei * and create channels accordingly. 218*e9d50e4bSHuang Yiwei */ 219*e9d50e4bSHuang Yiwei ipcc->num_chans = 0; 220*e9d50e4bSHuang Yiwei for_each_node_with_property(client_dn, "mboxes") { 221*e9d50e4bSHuang Yiwei if (!of_device_is_available(client_dn)) 222*e9d50e4bSHuang Yiwei continue; 223*e9d50e4bSHuang Yiwei i = of_count_phandle_with_args(client_dn, 224*e9d50e4bSHuang Yiwei "mboxes", "#mbox-cells"); 225*e9d50e4bSHuang Yiwei for (j = 0; j < i; j++) { 226*e9d50e4bSHuang Yiwei ret = of_parse_phandle_with_args(client_dn, "mboxes", 227*e9d50e4bSHuang Yiwei "#mbox-cells", j, &curr_ph); 228*e9d50e4bSHuang Yiwei of_node_put(curr_ph.np); 229*e9d50e4bSHuang Yiwei if (!ret && curr_ph.np == controller_dn) { 230*e9d50e4bSHuang Yiwei ipcc->num_chans++; 231*e9d50e4bSHuang Yiwei break; 232*e9d50e4bSHuang Yiwei } 233*e9d50e4bSHuang Yiwei } 234*e9d50e4bSHuang Yiwei } 235*e9d50e4bSHuang Yiwei 236*e9d50e4bSHuang Yiwei /* If no clients are found, skip registering as a mbox controller */ 237*e9d50e4bSHuang Yiwei if (!ipcc->num_chans) 238*e9d50e4bSHuang Yiwei return 0; 239*e9d50e4bSHuang Yiwei 240*e9d50e4bSHuang Yiwei ipcc->chans = devm_kcalloc(dev, ipcc->num_chans, 241*e9d50e4bSHuang Yiwei sizeof(struct mbox_chan), GFP_KERNEL); 242*e9d50e4bSHuang Yiwei if (!ipcc->chans) 243*e9d50e4bSHuang Yiwei return -ENOMEM; 244fa74a025SManivannan Sadhasivam 245fa74a025SManivannan Sadhasivam mbox = &ipcc->mbox; 246fa74a025SManivannan Sadhasivam mbox->dev = dev; 247*e9d50e4bSHuang Yiwei mbox->num_chans = ipcc->num_chans; 248*e9d50e4bSHuang Yiwei mbox->chans = ipcc->chans; 249fa74a025SManivannan Sadhasivam mbox->ops = &ipcc_mbox_chan_ops; 250fa74a025SManivannan Sadhasivam mbox->of_xlate = qcom_ipcc_mbox_xlate; 251fa74a025SManivannan Sadhasivam mbox->txdone_irq = false; 252fa74a025SManivannan Sadhasivam mbox->txdone_poll = false; 253fa74a025SManivannan Sadhasivam 254fa74a025SManivannan Sadhasivam return devm_mbox_controller_register(dev, mbox); 255fa74a025SManivannan Sadhasivam } 256fa74a025SManivannan Sadhasivam 257fa74a025SManivannan Sadhasivam static int qcom_ipcc_probe(struct platform_device *pdev) 258fa74a025SManivannan Sadhasivam { 259fa74a025SManivannan Sadhasivam struct qcom_ipcc *ipcc; 260fa74a025SManivannan Sadhasivam int ret; 261fa74a025SManivannan Sadhasivam 262fa74a025SManivannan Sadhasivam ipcc = devm_kzalloc(&pdev->dev, sizeof(*ipcc), GFP_KERNEL); 263fa74a025SManivannan Sadhasivam if (!ipcc) 264fa74a025SManivannan Sadhasivam return -ENOMEM; 265fa74a025SManivannan Sadhasivam 266fa74a025SManivannan Sadhasivam ipcc->dev = &pdev->dev; 267fa74a025SManivannan Sadhasivam 268fa74a025SManivannan Sadhasivam ipcc->base = devm_platform_ioremap_resource(pdev, 0); 269fa74a025SManivannan Sadhasivam if (IS_ERR(ipcc->base)) 270fa74a025SManivannan Sadhasivam return PTR_ERR(ipcc->base); 271fa74a025SManivannan Sadhasivam 272fa74a025SManivannan Sadhasivam ipcc->irq = platform_get_irq(pdev, 0); 273fa74a025SManivannan Sadhasivam if (ipcc->irq < 0) 274fa74a025SManivannan Sadhasivam return ipcc->irq; 275fa74a025SManivannan Sadhasivam 276fa74a025SManivannan Sadhasivam ipcc->irq_domain = irq_domain_add_tree(pdev->dev.of_node, 277fa74a025SManivannan Sadhasivam &qcom_ipcc_irq_ops, ipcc); 278fa74a025SManivannan Sadhasivam if (!ipcc->irq_domain) 279fa74a025SManivannan Sadhasivam return -ENOMEM; 280fa74a025SManivannan Sadhasivam 281*e9d50e4bSHuang Yiwei ret = qcom_ipcc_setup_mbox(ipcc, pdev->dev.of_node); 282fa74a025SManivannan Sadhasivam if (ret) 283fa74a025SManivannan Sadhasivam goto err_mbox; 284fa74a025SManivannan Sadhasivam 285fa74a025SManivannan Sadhasivam ret = devm_request_irq(&pdev->dev, ipcc->irq, qcom_ipcc_irq_fn, 286fa74a025SManivannan Sadhasivam IRQF_TRIGGER_HIGH, "ipcc", ipcc); 287fa74a025SManivannan Sadhasivam if (ret < 0) { 288fa74a025SManivannan Sadhasivam dev_err(&pdev->dev, "Failed to register the irq: %d\n", ret); 289*e9d50e4bSHuang Yiwei goto err_req_irq; 290fa74a025SManivannan Sadhasivam } 291fa74a025SManivannan Sadhasivam 292fa74a025SManivannan Sadhasivam enable_irq_wake(ipcc->irq); 293fa74a025SManivannan Sadhasivam platform_set_drvdata(pdev, ipcc); 294fa74a025SManivannan Sadhasivam 295fa74a025SManivannan Sadhasivam return 0; 296fa74a025SManivannan Sadhasivam 297*e9d50e4bSHuang Yiwei err_req_irq: 298*e9d50e4bSHuang Yiwei if (ipcc->num_chans) 299*e9d50e4bSHuang Yiwei mbox_controller_unregister(&ipcc->mbox); 300fa74a025SManivannan Sadhasivam err_mbox: 301fa74a025SManivannan Sadhasivam irq_domain_remove(ipcc->irq_domain); 302fa74a025SManivannan Sadhasivam 303fa74a025SManivannan Sadhasivam return ret; 304fa74a025SManivannan Sadhasivam } 305fa74a025SManivannan Sadhasivam 306fa74a025SManivannan Sadhasivam static int qcom_ipcc_remove(struct platform_device *pdev) 307fa74a025SManivannan Sadhasivam { 308fa74a025SManivannan Sadhasivam struct qcom_ipcc *ipcc = platform_get_drvdata(pdev); 309fa74a025SManivannan Sadhasivam 310fa74a025SManivannan Sadhasivam disable_irq_wake(ipcc->irq); 311fa74a025SManivannan Sadhasivam irq_domain_remove(ipcc->irq_domain); 312fa74a025SManivannan Sadhasivam 313fa74a025SManivannan Sadhasivam return 0; 314fa74a025SManivannan Sadhasivam } 315fa74a025SManivannan Sadhasivam 316fa74a025SManivannan Sadhasivam static const struct of_device_id qcom_ipcc_of_match[] = { 317fa74a025SManivannan Sadhasivam { .compatible = "qcom,ipcc"}, 318fa74a025SManivannan Sadhasivam {} 319fa74a025SManivannan Sadhasivam }; 320fa74a025SManivannan Sadhasivam MODULE_DEVICE_TABLE(of, qcom_ipcc_of_match); 321fa74a025SManivannan Sadhasivam 322fa74a025SManivannan Sadhasivam static struct platform_driver qcom_ipcc_driver = { 323fa74a025SManivannan Sadhasivam .probe = qcom_ipcc_probe, 324fa74a025SManivannan Sadhasivam .remove = qcom_ipcc_remove, 325fa74a025SManivannan Sadhasivam .driver = { 326fa74a025SManivannan Sadhasivam .name = "qcom-ipcc", 327fa74a025SManivannan Sadhasivam .of_match_table = qcom_ipcc_of_match, 3288d7e5908SAmit Pundir .suppress_bind_attrs = true, 329fa74a025SManivannan Sadhasivam }, 330fa74a025SManivannan Sadhasivam }; 331fa74a025SManivannan Sadhasivam 332fa74a025SManivannan Sadhasivam static int __init qcom_ipcc_init(void) 333fa74a025SManivannan Sadhasivam { 334fa74a025SManivannan Sadhasivam return platform_driver_register(&qcom_ipcc_driver); 335fa74a025SManivannan Sadhasivam } 336fa74a025SManivannan Sadhasivam arch_initcall(qcom_ipcc_init); 337fa74a025SManivannan Sadhasivam 338fa74a025SManivannan Sadhasivam MODULE_AUTHOR("Venkata Narendra Kumar Gutta <vnkgutta@codeaurora.org>"); 339fa74a025SManivannan Sadhasivam MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>"); 340fa74a025SManivannan Sadhasivam MODULE_DESCRIPTION("Qualcomm Technologies, Inc. IPCC driver"); 341fa74a025SManivannan Sadhasivam MODULE_LICENSE("GPL v2"); 342