apple-admac.c (072431595a57bc6605c29724afce5f9ef8114915) apple-admac.c (6aed75d7ccb3288029287c50fc594a4314698be0)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Driver for Audio DMA Controller (ADMAC) on t8103 (M1) and other Apple chips
4 *
5 * Copyright (C) The Asahi Linux Contributors
6 */
7
8#include <linux/bits.h>
9#include <linux/bitfield.h>
10#include <linux/device.h>
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/of_device.h>
14#include <linux/of_dma.h>
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Driver for Audio DMA Controller (ADMAC) on t8103 (M1) and other Apple chips
4 *
5 * Copyright (C) The Asahi Linux Contributors
6 */
7
8#include <linux/bits.h>
9#include <linux/bitfield.h>
10#include <linux/device.h>
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/of_device.h>
14#include <linux/of_dma.h>
15#include <linux/interrupt.h>
15#include <linux/reset.h>
16#include <linux/spinlock.h>
16#include <linux/spinlock.h>
17#include <linux/interrupt.h>
17
18#include "dmaengine.h"
19
20#define NCHANNELS_MAX 64
21#define IRQ_NOUTPUTS 4
22
23#define RING_WRITE_SLOT GENMASK(1, 0)
24#define RING_READ_SLOT GENMASK(5, 4)

--- 65 unchanged lines hidden (view full) ---

90
91 struct list_head to_free;
92};
93
94struct admac_data {
95 struct dma_device dma;
96 struct device *dev;
97 __iomem void *base;
18
19#include "dmaengine.h"
20
21#define NCHANNELS_MAX 64
22#define IRQ_NOUTPUTS 4
23
24#define RING_WRITE_SLOT GENMASK(1, 0)
25#define RING_READ_SLOT GENMASK(5, 4)

--- 65 unchanged lines hidden (view full) ---

91
92 struct list_head to_free;
93};
94
95struct admac_data {
96 struct dma_device dma;
97 struct device *dev;
98 __iomem void *base;
99 struct reset_control *rstc;
98
99 int irq;
100 int irq_index;
101 int nchannels;
102 struct admac_chan channels[];
103};
104
105struct admac_tx {

--- 621 unchanged lines hidden (view full) ---

727 return dev_err_probe(&pdev->dev, irq, "no usable interrupt\n");
728 ad->irq = irq;
729
730 ad->base = devm_platform_ioremap_resource(pdev, 0);
731 if (IS_ERR(ad->base))
732 return dev_err_probe(&pdev->dev, PTR_ERR(ad->base),
733 "unable to obtain MMIO resource\n");
734
100
101 int irq;
102 int irq_index;
103 int nchannels;
104 struct admac_chan channels[];
105};
106
107struct admac_tx {

--- 621 unchanged lines hidden (view full) ---

729 return dev_err_probe(&pdev->dev, irq, "no usable interrupt\n");
730 ad->irq = irq;
731
732 ad->base = devm_platform_ioremap_resource(pdev, 0);
733 if (IS_ERR(ad->base))
734 return dev_err_probe(&pdev->dev, PTR_ERR(ad->base),
735 "unable to obtain MMIO resource\n");
736
737 ad->rstc = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
738 if (IS_ERR(ad->rstc))
739 return PTR_ERR(ad->rstc);
740
735 dma = &ad->dma;
736
737 dma_cap_set(DMA_PRIVATE, dma->cap_mask);
738 dma_cap_set(DMA_CYCLIC, dma->cap_mask);
739
740 dma->dev = &pdev->dev;
741 dma->device_alloc_chan_resources = admac_alloc_chan_resources;
742 dma->device_free_chan_resources = admac_free_chan_resources;

--- 22 unchanged lines hidden (view full) ---

765 spin_lock_init(&adchan->lock);
766 INIT_LIST_HEAD(&adchan->submitted);
767 INIT_LIST_HEAD(&adchan->issued);
768 INIT_LIST_HEAD(&adchan->to_free);
769 list_add_tail(&adchan->chan.device_node, &dma->channels);
770 tasklet_setup(&adchan->tasklet, admac_chan_tasklet);
771 }
772
741 dma = &ad->dma;
742
743 dma_cap_set(DMA_PRIVATE, dma->cap_mask);
744 dma_cap_set(DMA_CYCLIC, dma->cap_mask);
745
746 dma->dev = &pdev->dev;
747 dma->device_alloc_chan_resources = admac_alloc_chan_resources;
748 dma->device_free_chan_resources = admac_free_chan_resources;

--- 22 unchanged lines hidden (view full) ---

771 spin_lock_init(&adchan->lock);
772 INIT_LIST_HEAD(&adchan->submitted);
773 INIT_LIST_HEAD(&adchan->issued);
774 INIT_LIST_HEAD(&adchan->to_free);
775 list_add_tail(&adchan->chan.device_node, &dma->channels);
776 tasklet_setup(&adchan->tasklet, admac_chan_tasklet);
777 }
778
773 err = request_irq(irq, admac_interrupt, 0, dev_name(&pdev->dev), ad);
779 err = reset_control_reset(ad->rstc);
774 if (err)
775 return dev_err_probe(&pdev->dev, err,
780 if (err)
781 return dev_err_probe(&pdev->dev, err,
776 "unable to register interrupt\n");
782 "unable to trigger reset\n");
777
783
784 err = request_irq(irq, admac_interrupt, 0, dev_name(&pdev->dev), ad);
785 if (err) {
786 dev_err_probe(&pdev->dev, err,
787 "unable to register interrupt\n");
788 goto free_reset;
789 }
790
778 err = dma_async_device_register(&ad->dma);
779 if (err) {
780 dev_err_probe(&pdev->dev, err, "failed to register DMA device\n");
781 goto free_irq;
782 }
783
784 err = of_dma_controller_register(pdev->dev.of_node, admac_dma_of_xlate, ad);
785 if (err) {
786 dma_async_device_unregister(&ad->dma);
787 dev_err_probe(&pdev->dev, err, "failed to register with OF\n");
788 goto free_irq;
789 }
790
791 return 0;
792
793free_irq:
794 free_irq(ad->irq, ad);
791 err = dma_async_device_register(&ad->dma);
792 if (err) {
793 dev_err_probe(&pdev->dev, err, "failed to register DMA device\n");
794 goto free_irq;
795 }
796
797 err = of_dma_controller_register(pdev->dev.of_node, admac_dma_of_xlate, ad);
798 if (err) {
799 dma_async_device_unregister(&ad->dma);
800 dev_err_probe(&pdev->dev, err, "failed to register with OF\n");
801 goto free_irq;
802 }
803
804 return 0;
805
806free_irq:
807 free_irq(ad->irq, ad);
808free_reset:
809 reset_control_rearm(ad->rstc);
795 return err;
796}
797
798static int admac_remove(struct platform_device *pdev)
799{
800 struct admac_data *ad = platform_get_drvdata(pdev);
801
802 of_dma_controller_free(pdev->dev.of_node);
803 dma_async_device_unregister(&ad->dma);
804 free_irq(ad->irq, ad);
810 return err;
811}
812
813static int admac_remove(struct platform_device *pdev)
814{
815 struct admac_data *ad = platform_get_drvdata(pdev);
816
817 of_dma_controller_free(pdev->dev.of_node);
818 dma_async_device_unregister(&ad->dma);
819 free_irq(ad->irq, ad);
820 reset_control_rearm(ad->rstc);
805
806 return 0;
807}
808
809static const struct of_device_id admac_of_match[] = {
810 { .compatible = "apple,admac", },
811 { }
812};

--- 15 unchanged lines hidden ---
821
822 return 0;
823}
824
825static const struct of_device_id admac_of_match[] = {
826 { .compatible = "apple,admac", },
827 { }
828};

--- 15 unchanged lines hidden ---