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 --- |