sound updates for 5.15-rc1

There are a few intensive changes in ALSA core side at this time that
 helped the significant code reduction.  Meanwhile we keep getting new
 stuff, so the total size still grows...
 Anyway, the below are some highlights in this development cycle.
 
 ALSA core:
 - New helpers to manage page allocations and card object with devres
 - Refactoring for memory allocation with wc-pages
 - A new PCM hardware flag SNDRV_PCM_INFO_EXPLICIT_SYNC for controlling
   the explicit sync of the stream control; it'll be used for ASoC SOF
   and non-coherent memory in future
 
 ASoC:
 - Lots of cleanups and improvements to the Intel drivers, including
   some new systems support
 - New support for AMD Vangoh, CUI CMM-4030D-261, Mediatek Mt8195,
   Renesas RZ/G2L Mediatek Mt8195, RealTek RT101P, Renesas RZ/G2L,
   Rockchip RK3568 S/PDIF
 
 USB-audio:
 - Re-organized the quirk handling and  a new option quirk_flags
 - Fix for a regression in 5.14 code change for JACK
 - Quirks for Sony WALKMAN, Digidesign mbox
 
 HD-audio:
 - Enhanced support for CS8409 codec
 - More consistent shutdown behavior with the runtime PM
 - The model option can accept the PCI or codec SSID as an alias
 - Quirks for ASUS ROG, HP Spectre x360
 
 Others:
 - Lots of code reduction in legacy drivers with devres helpers
 - FireWire MOTU 896HD support
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmEvQxUOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE9hlxAAr+mfQEuYxpBC8z/Uy/E0x+QVp3HhkiQURE3o
 fTJFHp3V4KafH5YdNRg6x0xjNka1Y4/ku4Egealy5YQph0eF5AW0y/um43b08dca
 HPy9SLDsmsRMxMUX41WBpGiT9vhVmFoo66YZ/azL+at8r9UV9lp9+pFg74KvxtbU
 dfTywI1Y/nB8kKAPlTzOFoYiYhe8WTr79m5oLX8ZyZdO1jG20XHdgbPjgesId6sP
 roKua1YsfOYyBWBtUnYx4POuAYSoe9CzJOeEUFWS/36UyP2LD5GS0YRdqHPVVmgF
 mshKZ6njwjkeOnijPLs9LJkOsN7RR1ypthPpMcRShAYMza46z1p5Eg1SlVDsogAl
 206sUgbjusulN5Yjki7AWW4l3fCAQDfZ0rQnMqEOfRNpG4lhCdfKZgK2Bg8WIC9l
 Vm1Q0ArHHLp5MhUGorRxXXo23mABS+zrDOLdjMajHFV53TPOdARGSHUbgJzDVTLE
 kcY73E4oQpphLfCeSxwDIrzOGWRozFQlvgt7/5ePbA/6BeYAyn90MZaxLEISAAx4
 x3BynyyoYBTxwWY84V6zWuDOwvb1Iat0vtm0GwUb9j2OlmperSj8gbL0hWiYam7c
 eOpym+g1oEPpm+MHQs77RUXS34fSrT2JeTEo6c0pJXQ/FvgGCV+z5kTpqYBM/Vbn
 5mARPEg=
 =fHyJ
 -----END PGP SIGNATURE-----

Merge tag 'sound-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound updates from Takashi Iwai:
 "There are a few intensive changes in ALSA core side at this time that
  helped with significant code reduction. Meanwhile we keep getting new
  stuff, so the total size still grows...

  Anyway, the below are some highlights in this development cycle.

  ALSA core:

   - New helpers to manage page allocations and card object with devres

   - Refactoring for memory allocation with wc-pages

   - A new PCM hardware flag SNDRV_PCM_INFO_EXPLICIT_SYNC for
     controlling the explicit sync of the stream control; it'll be used
     for ASoC SOF and non-coherent memory in future

  ASoC:

   - Lots of cleanups and improvements to the Intel drivers, including
     some new systems support

   - New support for AMD Vangoh, CUI CMM-4030D-261, Mediatek Mt8195,
     Renesas RZ/G2L Mediatek Mt8195, RealTek RT101P, Renesas RZ/G2L,
     Rockchip RK3568 S/PDIF

  USB-audio:

   - Re-organized the quirk handling and a new option quirk_flags

   - Fix for a regression in 5.14 code change for JACK

   - Quirks for Sony WALKMAN, Digidesign mbox

  HD-audio:

   - Enhanced support for CS8409 codec

   - More consistent shutdown behavior with the runtime PM

   - The model option can accept the PCI or codec SSID as an alias

   - Quirks for ASUS ROG, HP Spectre x360

  Others:

   - Lots of code reduction in legacy drivers with devres helpers

   - FireWire MOTU 896HD support"

* tag 'sound-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (421 commits)
  ASoC: Revert PCM trigger changes
  ALSA: usb-audio: Add lowlatency module option
  ALSA: hda/cs8409: Initialize Codec only in init fixup.
  ALSA: hda/cs8409: Ensure Type Detection is only run on startup when necessary
  ALSA: usb-audio: Work around for XRUN with low latency playback
  ALSA: pcm: fix divide error in snd_pcm_lib_ioctl
  ASoC: soc-pcm: test refcount before triggering
  ASoC: soc-pcm: protect BE dailink state changes in trigger
  ASoC: wcd9335: Disable irq on slave ports in the remove function
  ASoC: wcd9335: Fix a memory leak in the error handling path of the probe function
  ASoC: wcd9335: Fix a double irq free in the remove function
  ALSA: hda: Disable runtime resume at shutdown
  ASoC: rockchip: i2s: Add support for frame inversion
  ASoC: dt-bindings: rockchip: Add compatible strings for more SoCs
  ASoC: rockchip: i2s: Add compatible for more SoCs
  ASoC: rockchip: i2s: Make playback/capture optional
  ASoC: rockchip: i2s: Fixup config for DAIFMT_DSP_A/B
  ASoC: dt-bindings: rockchip: Document reset property for i2s
  ASoC: rockchip: i2s: Fix regmap_ops hang
  ASoC: rockchip: i2s: Improve dma data transfer efficiency
  ...
This commit is contained in:
Linus Torvalds 2021-09-01 10:29:29 -07:00
commit 0d290223a6
363 changed files with 23745 additions and 9497 deletions

View File

@ -6,6 +6,7 @@ Required properties:
"ti,da830-mcasp-audio" : for both DA830 & DA850 platforms
"ti,am33xx-mcasp-audio" : for AM33xx platforms (AM33xx, AM43xx, TI81xx)
"ti,dra7-mcasp-audio" : for DRA7xx platforms
"ti,omap4-mcasp-audio" : for OMAP4
- reg : Should contain reg specifiers for the entries in the reg-names property.
- reg-names : Should contain:

View File

@ -1,4 +1,4 @@
Invensense ICS-43432 MEMS microphone with I2S output.
Invensense ICS-43432-compatible MEMS microphone with I2S output.
There are no software configuration options for this device, indeed, the only
host connection is the I2S interface. Apart from requirements on clock
@ -8,7 +8,9 @@ contain audio data. A hardware pin determines if the device outputs data
on the left or right channel of the I2S frame.
Required properties:
- compatible : Must be "invensense,ics43432"
- compatible: should be one of the following.
"invensense,ics43432": For the Invensense ICS43432
"cui,cmm-4030d-261": For the CUI CMM-4030D-261-I2S-TR
Example:

View File

@ -0,0 +1,184 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mt8195-afe-pcm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek AFE PCM controller for mt8195
maintainers:
- Trevor Wu <trevor.wu@mediatek.com>
properties:
compatible:
const: mediatek,mt8195-audio
reg:
maxItems: 1
interrupts:
maxItems: 1
mediatek,topckgen:
$ref: "/schemas/types.yaml#/definitions/phandle"
description: The phandle of the mediatek topckgen controller
power-domains:
maxItems: 1
clocks:
items:
- description: 26M clock
- description: audio pll1 clock
- description: audio pll2 clock
- description: clock divider for i2si1_mck
- description: clock divider for i2si2_mck
- description: clock divider for i2so1_mck
- description: clock divider for i2so2_mck
- description: clock divider for dptx_mck
- description: a1sys hoping clock
- description: audio intbus clock
- description: audio hires clock
- description: audio local bus clock
- description: mux for dptx_mck
- description: mux for i2so1_mck
- description: mux for i2so2_mck
- description: mux for i2si1_mck
- description: mux for i2si2_mck
- description: audio infra 26M clock
- description: infra bus clock
clock-names:
items:
- const: clk26m
- const: apll1_ck
- const: apll2_ck
- const: apll12_div0
- const: apll12_div1
- const: apll12_div2
- const: apll12_div3
- const: apll12_div9
- const: a1sys_hp_sel
- const: aud_intbus_sel
- const: audio_h_sel
- const: audio_local_bus_sel
- const: dptx_m_sel
- const: i2so1_m_sel
- const: i2so2_m_sel
- const: i2si1_m_sel
- const: i2si2_m_sel
- const: infra_ao_audio_26m_b
- const: scp_adsp_audiodsp
mediatek,etdm-in1-chn-disabled:
$ref: /schemas/types.yaml#/definitions/uint8-array
maxItems: 24
description: Specify which input channel should be disabled.
mediatek,etdm-in2-chn-disabled:
$ref: /schemas/types.yaml#/definitions/uint8-array
maxItems: 16
description: Specify which input channel should be disabled.
patternProperties:
"^mediatek,etdm-in[1-2]-mclk-always-on-rate-hz$":
description: Specify etdm in mclk output rate for always on case.
"^mediatek,etdm-out[1-3]-mclk-always-on-rate-hz$":
description: Specify etdm out mclk output rate for always on case.
"^mediatek,etdm-in[1-2]-multi-pin-mode$":
type: boolean
description: if present, the etdm data mode is I2S.
"^mediatek,etdm-out[1-3]-multi-pin-mode$":
type: boolean
description: if present, the etdm data mode is I2S.
"^mediatek,etdm-in[1-2]-cowork-source$":
$ref: /schemas/types.yaml#/definitions/uint32
description: |
etdm modules can share the same external clock pin. Specify
which etdm clock source is required by this etdm in moudule.
enum:
- 0 # etdm1_in
- 1 # etdm2_in
- 2 # etdm1_out
- 3 # etdm2_out
"^mediatek,etdm-out[1-2]-cowork-source$":
$ref: /schemas/types.yaml#/definitions/uint32
description: |
etdm modules can share the same external clock pin. Specify
which etdm clock source is required by this etdm out moudule.
enum:
- 0 # etdm1_in
- 1 # etdm2_in
- 2 # etdm1_out
- 3 # etdm2_out
required:
- compatible
- reg
- interrupts
- mediatek,topckgen
- power-domains
- clocks
- clock-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/mt8195-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/power/mt8195-power.h>
afe: mt8195-afe-pcm@10890000 {
compatible = "mediatek,mt8195-audio";
reg = <0x10890000 0x10000>;
interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
mediatek,topckgen = <&topckgen>;
power-domains = <&spm MT8195_POWER_DOMAIN_AUDIO>;
clocks = <&clk26m>,
<&topckgen CLK_TOP_APLL1>,
<&topckgen CLK_TOP_APLL2>,
<&topckgen CLK_TOP_APLL12_DIV0>,
<&topckgen CLK_TOP_APLL12_DIV1>,
<&topckgen CLK_TOP_APLL12_DIV2>,
<&topckgen CLK_TOP_APLL12_DIV3>,
<&topckgen CLK_TOP_APLL12_DIV9>,
<&topckgen CLK_TOP_A1SYS_HP_SEL>,
<&topckgen CLK_TOP_AUD_INTBUS_SEL>,
<&topckgen CLK_TOP_AUDIO_H_SEL>,
<&topckgen CLK_TOP_AUDIO_LOCAL_BUS_SEL>,
<&topckgen CLK_TOP_DPTX_M_SEL>,
<&topckgen CLK_TOP_I2SO1_M_SEL>,
<&topckgen CLK_TOP_I2SO2_M_SEL>,
<&topckgen CLK_TOP_I2SI1_M_SEL>,
<&topckgen CLK_TOP_I2SI2_M_SEL>,
<&infracfg_ao CLK_INFRA_AO_AUDIO_26M_B>,
<&scp_adsp CLK_SCP_ADSP_AUDIODSP>;
clock-names = "clk26m",
"apll1_ck",
"apll2_ck",
"apll12_div0",
"apll12_div1",
"apll12_div2",
"apll12_div3",
"apll12_div9",
"a1sys_hp_sel",
"aud_intbus_sel",
"audio_h_sel",
"audio_local_bus_sel",
"dptx_m_sel",
"i2so1_m_sel",
"i2so2_m_sel",
"i2si1_m_sel",
"i2si2_m_sel",
"infra_ao_audio_26m_b",
"scp_adsp_audiodsp";
};
...

View File

@ -0,0 +1,47 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1019-rt5682.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek MT8195 with MT6359, RT1019 and RT5682 ASoC sound card driver
maintainers:
- Trevor Wu <trevor.wu@mediatek.com>
description:
This binding describes the MT8195 sound card.
properties:
compatible:
const: mediatek,mt8195_mt6359_rt1019_rt5682
mediatek,platform:
$ref: "/schemas/types.yaml#/definitions/phandle"
description: The phandle of MT8195 ASoC platform.
mediatek,dptx-codec:
$ref: "/schemas/types.yaml#/definitions/phandle"
description: The phandle of MT8195 Display Port Tx codec node.
mediatek,hdmi-codec:
$ref: "/schemas/types.yaml#/definitions/phandle"
description: The phandle of MT8195 HDMI codec node.
additionalProperties: false
required:
- compatible
- mediatek,platform
examples:
- |
sound: mt8195-sound {
compatible = "mediatek,mt8195_mt6359_rt1019_rt5682";
mediatek,platform = <&afe>;
pinctrl-names = "default";
pinctrl-0 = <&aud_pins_default>;
};
...

View File

@ -15,7 +15,9 @@ description: |
properties:
compatible:
const: realtek,rt1015p
enum:
- realtek,rt1015p
- realtek,rt1019p
sdb-gpios:
description:

View File

@ -0,0 +1,118 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/sound/renesas,rz-ssi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Renesas RZ/G2L ASoC Sound Serial Interface (SSIF-2)
maintainers:
- Biju Das <biju.das.jz@bp.renesas.com>
properties:
compatible:
items:
- enum:
- renesas,r9a07g044-ssi # RZ/G2{L,LC}
- const: renesas,rz-ssi
reg:
maxItems: 1
interrupts:
maxItems: 4
interrupt-names:
items:
- const: int_req
- const: dma_rx
- const: dma_tx
- const: dma_rt
clocks:
maxItems: 4
clock-names:
items:
- const: ssi
- const: ssi_sfr
- const: audio_clk1
- const: audio_clk2
power-domains:
maxItems: 1
resets:
maxItems: 1
dmas:
minItems: 1
maxItems: 2
description:
The first cell represents a phandle to dmac
The second cell specifies the encoded MID/RID values of the SSI port
connected to the DMA client and the slave channel configuration
parameters.
bits[0:9] - Specifies MID/RID value of a SSI channel as below
MID/RID value of SSI rx0 = 0x256
MID/RID value of SSI tx0 = 0x255
MID/RID value of SSI rx1 = 0x25a
MID/RID value of SSI tx1 = 0x259
MID/RID value of SSI rt2 = 0x25f
MID/RID value of SSI rx3 = 0x262
MID/RID value of SSI tx3 = 0x261
bit[10] - HIEN = 1, Detects a request in response to the rising edge
of the signal
bit[11] - LVL = 0, Detects based on the edge
bits[12:14] - AM = 2, Bus cycle mode
bit[15] - TM = 0, Single transfer mode
dma-names:
oneOf:
- items:
- const: tx
- const: rx
- items:
- const: rt
'#sound-dai-cells':
const: 0
required:
- compatible
- reg
- interrupts
- interrupt-names
- clocks
- clock-names
- resets
- '#sound-dai-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/r9a07g044-cpg.h>
ssi0: ssi@10049c00 {
compatible = "renesas,r9a07g044-ssi",
"renesas,rz-ssi";
reg = <0x10049c00 0x400>;
interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 327 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 328 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 329 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "int_req", "dma_rx", "dma_tx", "dma_rt";
clocks = <&cpg CPG_MOD R9A07G044_SSI0_PCLK2>,
<&cpg CPG_MOD R9A07G044_SSI0_PCLK_SFR>,
<&audio_clk1>,
<&audio_clk2>;
clock-names = "ssi", "ssi_sfr", "audio_clk1", "audio_clk2";
power-domains = <&cpg>;
resets = <&cpg R9A07G044_SSI0_RST_M2_REG>;
dmas = <&dmac 0x2655>,
<&dmac 0x2656>;
dma-names = "tx", "rx";
#sound-dai-cells = <0>;
};

View File

@ -20,7 +20,9 @@ properties:
- items:
- enum:
- rockchip,px30-i2s
- rockchip,rk1808-i2s
- rockchip,rk3036-i2s
- rockchip,rk3128-i2s
- rockchip,rk3188-i2s
- rockchip,rk3228-i2s
- rockchip,rk3288-i2s
@ -29,6 +31,7 @@ properties:
- rockchip,rk3366-i2s
- rockchip,rk3368-i2s
- rockchip,rk3399-i2s
- rockchip,rv1126-i2s
- const: rockchip,rk3066-i2s
reg:
@ -61,6 +64,14 @@ properties:
power-domains:
maxItems: 1
reset-names:
items:
- const: reset-m
- const: reset-h
resets:
maxItems: 2
rockchip,capture-channels:
$ref: /schemas/types.yaml#/definitions/uint32
default: 2

View File

@ -23,6 +23,7 @@ properties:
- const: rockchip,rk3366-spdif
- const: rockchip,rk3368-spdif
- const: rockchip,rk3399-spdif
- const: rockchip,rk3568-spdif
- items:
- enum:
- rockchip,rk3188-spdif

View File

@ -271,6 +271,8 @@ patternProperties:
description: Shenzen Chuangsiqi Technology Co.,Ltd.
"^cubietech,.*":
description: Cubietech, Ltd.
"^cui,.*":
description: CUI Devices
"^cypress,.*":
description: Cypress Semiconductor Corporation
"^cznic,.*":

View File

@ -1059,6 +1059,12 @@ The model name ``generic`` is treated as a special case. When this
model is given, the driver uses the generic codec parser without
"codec-patch". It's sometimes good for testing and debugging.
The model option can be used also for aliasing to another PCI or codec
SSID. When it's passed in the form of ``model=XXXX:YYYY`` where XXXX
and YYYY are the sub-vendor and sub-device IDs in hex numbers,
respectively, the driver will refer to that SSID as a reference to the
quirk table.
If the default configuration doesn't work and one of the above
matches with your device, report it together with alsa-info.sh
output (with ``--no-upload`` option) to kernel bugzilla or alsa-devel
@ -2252,6 +2258,27 @@ delayed_register
The driver prints a message like "Found post-registration device
assignment: 1234abcd:04" for such a device, so that user can
notice the need.
quirk_flags
Contains the bit flags for various device specific workarounds.
Applied to the corresponding card index.
* bit 0: Skip reading sample rate for devices
* bit 1: Create Media Controller API entries
* bit 2: Allow alignment on audio sub-slot at transfer
* bit 3: Add length specifier to transfers
* bit 4: Start playback stream at first in implement feedback mode
* bit 5: Skip clock selector setup
* bit 6: Ignore errors from clock source search
* bit 7: Indicates ITF-USB DSD based DACs
* bit 8: Add a delay of 20ms at each control message handling
* bit 9: Add a delay of 1-2ms at each control message handling
* bit 10: Add a delay of 5-6ms at each control message handling
* bit 11: Add a delay of 50ms at each interface setup
* bit 12: Perform sample rate validations at probe
* bit 13: Disable runtime PM autosuspend
* bit 14: Ignore errors for mixer access
* bit 15: Support generic DSD raw U32_BE format
* bit 16: Set up the interface at first like UAC1
This module supports multiple devices, autoprobe and hotplugging.
@ -2261,11 +2288,14 @@ check.
NB: ``ignore_ctl_error=1`` may help when you get an error at accessing
the mixer element such as URB error -22. This happens on some
buggy USB device or the controller.
buggy USB device or the controller. This workaround corresponds to
the ``quirk_flags`` bit 14, too.
NB: quirk_alias option is provided only for testing / development.
NB: ``quirk_alias`` option is provided only for testing / development.
If you want to have a proper support, contact to upstream for
adding the matching quirk in the driver code statically.
Ditto for ``quirk_flags``. If a device is known to require specific
workarounds, please report to the upstream.
Module snd-usb-caiaq
--------------------

View File

@ -215,6 +215,17 @@ There are a few special model option values:
* when ``generic`` is passed, the codec-specific parser is skipped and
only the generic parser is used.
A new style for the model option that was introduced since 5.15 kernel
is to pass the PCI or codec SSID in the form of ``model=XXXX:YYYY``
where XXXX and YYYY are the sub-vendor and sub-device IDs in hex
numbers, respectively. This is a kind of aliasing to another device;
when this form is given, the driver will refer to that SSID as a
reference to the quirk table. It'd be useful especially when the
target quirk isn't listed in the model table. For example, passing
model=103c:8862 will apply the quirk for HP ProBook 445 G8 (which
isn't found in the model table as of writing) as long as the device is
handled equivalently by the same driver.
Speaker and Headphone Output
----------------------------

View File

@ -4172,6 +4172,39 @@ module license as GPL, etc., otherwise the system is shown as “tainted”.
MODULE_LICENSE("GPL");
Device-Managed Resources
========================
In the examples above, all resources are allocated and released
manually. But human beings are lazy in nature, especially developers
are lazier. So there are some ways to automate the release part; it's
the (device-)managed resources aka devres or devm family. For
example, an object allocated via :c:func:`devm_kmalloc()` will be
freed automatically at unbinding the device.
ALSA core provides also the device-managed helper, namely,
:c:func:`snd_devm_card_new()` for creating a card object.
Call this functions instead of the normal :c:func:`snd_card_new()`,
and you can forget the explicit :c:func:`snd_card_free()` call, as
it's called automagically at error and removal paths.
One caveat is that the call of :c:func:`snd_card_free()` would be put
at the beginning of the call chain only after you call
:c:func:`snd_card_register()`.
Also, the ``private_free`` callback is always called at the card free,
so be careful to put the hardware clean-up procedure in
``private_free`` callback. It might be called even before you
actually set up at an earlier error path. For avoiding such an
invalid initialization, you can set ``private_free`` callback after
:c:func:`snd_card_register()` call succeeds.
Another thing to be remarked is that you should use device-managed
helpers for each component as much as possible once when you manage
the card in that way. Mixing up with the normal and the managed
resources may screw up the release order.
How To Put Your Driver Into ALSA Tree
=====================================

View File

@ -41,80 +41,6 @@ static int md_flags;
module_param_named(sdw_md_flags, md_flags, int, 0444);
MODULE_PARM_DESC(sdw_md_flags, "SoundWire Intel Master device flags (0x0 all off)");
/* Intel SHIM Registers Definition */
#define SDW_SHIM_LCAP 0x0
#define SDW_SHIM_LCTL 0x4
#define SDW_SHIM_IPPTR 0x8
#define SDW_SHIM_SYNC 0xC
#define SDW_SHIM_CTLSCAP(x) (0x010 + 0x60 * (x))
#define SDW_SHIM_CTLS0CM(x) (0x012 + 0x60 * (x))
#define SDW_SHIM_CTLS1CM(x) (0x014 + 0x60 * (x))
#define SDW_SHIM_CTLS2CM(x) (0x016 + 0x60 * (x))
#define SDW_SHIM_CTLS3CM(x) (0x018 + 0x60 * (x))
#define SDW_SHIM_PCMSCAP(x) (0x020 + 0x60 * (x))
#define SDW_SHIM_PCMSYCHM(x, y) (0x022 + (0x60 * (x)) + (0x2 * (y)))
#define SDW_SHIM_PCMSYCHC(x, y) (0x042 + (0x60 * (x)) + (0x2 * (y)))
#define SDW_SHIM_PDMSCAP(x) (0x062 + 0x60 * (x))
#define SDW_SHIM_IOCTL(x) (0x06C + 0x60 * (x))
#define SDW_SHIM_CTMCTL(x) (0x06E + 0x60 * (x))
#define SDW_SHIM_WAKEEN 0x190
#define SDW_SHIM_WAKESTS 0x192
#define SDW_SHIM_LCTL_SPA BIT(0)
#define SDW_SHIM_LCTL_SPA_MASK GENMASK(3, 0)
#define SDW_SHIM_LCTL_CPA BIT(8)
#define SDW_SHIM_LCTL_CPA_MASK GENMASK(11, 8)
#define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1)
#define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1)
#define SDW_SHIM_SYNC_SYNCPRD GENMASK(14, 0)
#define SDW_SHIM_SYNC_SYNCCPU BIT(15)
#define SDW_SHIM_SYNC_CMDSYNC_MASK GENMASK(19, 16)
#define SDW_SHIM_SYNC_CMDSYNC BIT(16)
#define SDW_SHIM_SYNC_SYNCGO BIT(24)
#define SDW_SHIM_PCMSCAP_ISS GENMASK(3, 0)
#define SDW_SHIM_PCMSCAP_OSS GENMASK(7, 4)
#define SDW_SHIM_PCMSCAP_BSS GENMASK(12, 8)
#define SDW_SHIM_PCMSYCM_LCHN GENMASK(3, 0)
#define SDW_SHIM_PCMSYCM_HCHN GENMASK(7, 4)
#define SDW_SHIM_PCMSYCM_STREAM GENMASK(13, 8)
#define SDW_SHIM_PCMSYCM_DIR BIT(15)
#define SDW_SHIM_PDMSCAP_ISS GENMASK(3, 0)
#define SDW_SHIM_PDMSCAP_OSS GENMASK(7, 4)
#define SDW_SHIM_PDMSCAP_BSS GENMASK(12, 8)
#define SDW_SHIM_PDMSCAP_CPSS GENMASK(15, 13)
#define SDW_SHIM_IOCTL_MIF BIT(0)
#define SDW_SHIM_IOCTL_CO BIT(1)
#define SDW_SHIM_IOCTL_COE BIT(2)
#define SDW_SHIM_IOCTL_DO BIT(3)
#define SDW_SHIM_IOCTL_DOE BIT(4)
#define SDW_SHIM_IOCTL_BKE BIT(5)
#define SDW_SHIM_IOCTL_WPDD BIT(6)
#define SDW_SHIM_IOCTL_CIBD BIT(8)
#define SDW_SHIM_IOCTL_DIBD BIT(9)
#define SDW_SHIM_CTMCTL_DACTQE BIT(0)
#define SDW_SHIM_CTMCTL_DODS BIT(1)
#define SDW_SHIM_CTMCTL_DOAIS GENMASK(4, 3)
#define SDW_SHIM_WAKEEN_ENABLE BIT(0)
#define SDW_SHIM_WAKESTS_STATUS BIT(0)
/* Intel ALH Register definitions */
#define SDW_ALH_STRMZCFG(x) (0x000 + (0x4 * (x)))
#define SDW_ALH_NUM_STREAMS 64
#define SDW_ALH_STRMZCFG_DMAT_VAL 0x3
#define SDW_ALH_STRMZCFG_DMAT GENMASK(7, 0)
#define SDW_ALH_STRMZCFG_CHN GENMASK(19, 16)
enum intel_pdi_type {
INTEL_PDI_IN = 0,
INTEL_PDI_OUT = 1,

View File

@ -18,12 +18,6 @@
#include "cadence_master.h"
#include "intel.h"
#define SDW_SHIM_LCAP 0x0
#define SDW_SHIM_BASE 0x2C000
#define SDW_ALH_BASE 0x2C800
#define SDW_LINK_BASE 0x30000
#define SDW_LINK_SIZE 0x10000
static void intel_link_dev_release(struct device *dev)
{
struct auxiliary_device *auxdev = to_auxiliary_dev(dev);
@ -69,8 +63,8 @@ static struct sdw_intel_link_dev *intel_link_dev_register(struct sdw_intel_res *
link->mmio_base = res->mmio_base;
link->registers = res->mmio_base + SDW_LINK_BASE
+ (SDW_LINK_SIZE * link_id);
link->shim = res->mmio_base + SDW_SHIM_BASE;
link->alh = res->mmio_base + SDW_ALH_BASE;
link->shim = res->mmio_base + res->shim_base;
link->alh = res->mmio_base + res->alh_base;
link->ops = res->ops;
link->dev = res->dev;
@ -220,6 +214,8 @@ static struct sdw_intel_ctx
}
ctx->mmio_base = res->mmio_base;
ctx->shim_base = res->shim_base;
ctx->alh_base = res->alh_base;
ctx->link_mask = res->link_mask;
ctx->handle = res->handle;
mutex_init(&ctx->shim_lock);
@ -308,7 +304,7 @@ sdw_intel_startup_controller(struct sdw_intel_ctx *ctx)
return -EINVAL;
/* Check SNDWLCAP.LCOUNT */
caps = ioread32(ctx->mmio_base + SDW_SHIM_BASE + SDW_SHIM_LCAP);
caps = ioread32(ctx->mmio_base + ctx->shim_base + SDW_SHIM_LCAP);
caps &= GENMASK(2, 0);
/* Check HW supported vs property value */

View File

@ -96,6 +96,7 @@ enum {
MCASP_VERSION_2, /* DA8xx/OMAPL1x */
MCASP_VERSION_3, /* TI81xx/AM33xx */
MCASP_VERSION_4, /* DRA7xxx */
MCASP_VERSION_OMAP, /* OMAP4/5 */
};
enum mcbsp_clk_input_pin {

View File

@ -7,6 +7,85 @@
#include <linux/irqreturn.h>
#include <linux/soundwire/sdw.h>
#define SDW_SHIM_BASE 0x2C000
#define SDW_ALH_BASE 0x2C800
#define SDW_LINK_BASE 0x30000
#define SDW_LINK_SIZE 0x10000
/* Intel SHIM Registers Definition */
#define SDW_SHIM_LCAP 0x0
#define SDW_SHIM_LCTL 0x4
#define SDW_SHIM_IPPTR 0x8
#define SDW_SHIM_SYNC 0xC
#define SDW_SHIM_CTLSCAP(x) (0x010 + 0x60 * (x))
#define SDW_SHIM_CTLS0CM(x) (0x012 + 0x60 * (x))
#define SDW_SHIM_CTLS1CM(x) (0x014 + 0x60 * (x))
#define SDW_SHIM_CTLS2CM(x) (0x016 + 0x60 * (x))
#define SDW_SHIM_CTLS3CM(x) (0x018 + 0x60 * (x))
#define SDW_SHIM_PCMSCAP(x) (0x020 + 0x60 * (x))
#define SDW_SHIM_PCMSYCHM(x, y) (0x022 + (0x60 * (x)) + (0x2 * (y)))
#define SDW_SHIM_PCMSYCHC(x, y) (0x042 + (0x60 * (x)) + (0x2 * (y)))
#define SDW_SHIM_PDMSCAP(x) (0x062 + 0x60 * (x))
#define SDW_SHIM_IOCTL(x) (0x06C + 0x60 * (x))
#define SDW_SHIM_CTMCTL(x) (0x06E + 0x60 * (x))
#define SDW_SHIM_WAKEEN 0x190
#define SDW_SHIM_WAKESTS 0x192
#define SDW_SHIM_LCTL_SPA BIT(0)
#define SDW_SHIM_LCTL_SPA_MASK GENMASK(3, 0)
#define SDW_SHIM_LCTL_CPA BIT(8)
#define SDW_SHIM_LCTL_CPA_MASK GENMASK(11, 8)
#define SDW_SHIM_SYNC_SYNCPRD_VAL_24 (24000 / SDW_CADENCE_GSYNC_KHZ - 1)
#define SDW_SHIM_SYNC_SYNCPRD_VAL_38_4 (38400 / SDW_CADENCE_GSYNC_KHZ - 1)
#define SDW_SHIM_SYNC_SYNCPRD GENMASK(14, 0)
#define SDW_SHIM_SYNC_SYNCCPU BIT(15)
#define SDW_SHIM_SYNC_CMDSYNC_MASK GENMASK(19, 16)
#define SDW_SHIM_SYNC_CMDSYNC BIT(16)
#define SDW_SHIM_SYNC_SYNCGO BIT(24)
#define SDW_SHIM_PCMSCAP_ISS GENMASK(3, 0)
#define SDW_SHIM_PCMSCAP_OSS GENMASK(7, 4)
#define SDW_SHIM_PCMSCAP_BSS GENMASK(12, 8)
#define SDW_SHIM_PCMSYCM_LCHN GENMASK(3, 0)
#define SDW_SHIM_PCMSYCM_HCHN GENMASK(7, 4)
#define SDW_SHIM_PCMSYCM_STREAM GENMASK(13, 8)
#define SDW_SHIM_PCMSYCM_DIR BIT(15)
#define SDW_SHIM_PDMSCAP_ISS GENMASK(3, 0)
#define SDW_SHIM_PDMSCAP_OSS GENMASK(7, 4)
#define SDW_SHIM_PDMSCAP_BSS GENMASK(12, 8)
#define SDW_SHIM_PDMSCAP_CPSS GENMASK(15, 13)
#define SDW_SHIM_IOCTL_MIF BIT(0)
#define SDW_SHIM_IOCTL_CO BIT(1)
#define SDW_SHIM_IOCTL_COE BIT(2)
#define SDW_SHIM_IOCTL_DO BIT(3)
#define SDW_SHIM_IOCTL_DOE BIT(4)
#define SDW_SHIM_IOCTL_BKE BIT(5)
#define SDW_SHIM_IOCTL_WPDD BIT(6)
#define SDW_SHIM_IOCTL_CIBD BIT(8)
#define SDW_SHIM_IOCTL_DIBD BIT(9)
#define SDW_SHIM_CTMCTL_DACTQE BIT(0)
#define SDW_SHIM_CTMCTL_DODS BIT(1)
#define SDW_SHIM_CTMCTL_DOAIS GENMASK(4, 3)
#define SDW_SHIM_WAKEEN_ENABLE BIT(0)
#define SDW_SHIM_WAKESTS_STATUS BIT(0)
/* Intel ALH Register definitions */
#define SDW_ALH_STRMZCFG(x) (0x000 + (0x4 * (x)))
#define SDW_ALH_NUM_STREAMS 64
#define SDW_ALH_STRMZCFG_DMAT_VAL 0x3
#define SDW_ALH_STRMZCFG_DMAT GENMASK(7, 0)
#define SDW_ALH_STRMZCFG_CHN GENMASK(19, 16)
/**
* struct sdw_intel_stream_params_data: configuration passed during
* the @params_stream callback, e.g. for interaction with DSP
@ -116,6 +195,8 @@ struct sdw_intel_slave_id {
* @link_list: list to handle interrupts across all links
* @shim_lock: mutex to handle concurrent rmw access to shared SHIM registers.
* @shim_mask: flags to track initialization of SHIM shared registers
* @shim_base: sdw shim base.
* @alh_base: sdw alh base.
*/
struct sdw_intel_ctx {
int count;
@ -128,6 +209,8 @@ struct sdw_intel_ctx {
struct list_head link_list;
struct mutex shim_lock; /* lock for access to shared SHIM registers */
u32 shim_mask;
u32 shim_base;
u32 alh_base;
};
/**
@ -146,6 +229,8 @@ struct sdw_intel_ctx {
* machine-specific quirks are handled in the DSP driver.
* @clock_stop_quirks: mask array of possible behaviors requested by the
* DSP driver. The quirks are common for all links for now.
* @shim_base: sdw shim base.
* @alh_base: sdw alh base.
*/
struct sdw_intel_res {
int count;
@ -157,6 +242,8 @@ struct sdw_intel_res {
struct device *dev;
u32 link_mask;
u32 clock_stop_quirks;
u32 shim_base;
u32 alh_base;
};
/*

View File

@ -165,8 +165,6 @@ struct snd_compr {
};
/* compress device register APIs */
int snd_compress_register(struct snd_compr *device);
int snd_compress_deregister(struct snd_compr *device);
int snd_compress_new(struct snd_card *card, int device,
int type, const char *id, struct snd_compr *compr);

View File

@ -117,6 +117,8 @@ struct snd_card {
struct device card_dev; /* cardX object for sysfs */
const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */
bool registered; /* card_dev is registered? */
bool managed; /* managed via devres */
bool releasing; /* during card free process */
int sync_irq; /* assigned irq, used for PCM sync */
wait_queue_head_t remove_sleep;
@ -274,6 +276,9 @@ extern int (*snd_mixer_oss_notify_callback)(struct snd_card *card, int cmd);
int snd_card_new(struct device *parent, int idx, const char *xid,
struct module *module, int extra_size,
struct snd_card **card_ret);
int snd_devm_card_new(struct device *parent, int idx, const char *xid,
struct module *module, size_t extra_size,
struct snd_card **card_ret);
int snd_card_disconnect(struct snd_card *card);
void snd_card_disconnect_sync(struct snd_card *card);
@ -324,6 +329,7 @@ int snd_device_get_state(struct snd_card *card, void *device_data);
void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode);
void snd_dma_disable(unsigned long dma);
unsigned int snd_dma_pointer(unsigned long dma, unsigned int size);
int snd_devm_request_dma(struct device *dev, int dma, const char *name);
#endif
/* misc.c */

View File

@ -1701,7 +1701,7 @@ struct snd_emu10k1 {
struct snd_dma_buffer silent_page; /* silent page */
struct snd_dma_buffer ptb_pages; /* page table pages */
struct snd_dma_device p16v_dma_dev;
struct snd_dma_buffer p16v_buffer;
struct snd_dma_buffer *p16v_buffer;
struct snd_util_memhdr *memhdr; /* page allocation list */
@ -1796,14 +1796,12 @@ int snd_emu10k1_create(struct snd_card *card,
unsigned short extout_mask,
long max_cache_bytes,
int enable_ir,
uint subsystem,
struct snd_emu10k1 ** remu);
uint subsystem);
int snd_emu10k1_pcm(struct snd_emu10k1 *emu, int device);
int snd_emu10k1_pcm_mic(struct snd_emu10k1 *emu, int device);
int snd_emu10k1_pcm_efx(struct snd_emu10k1 *emu, int device);
int snd_p16v_pcm(struct snd_emu10k1 *emu, int device);
int snd_p16v_free(struct snd_emu10k1 * emu);
int snd_p16v_mixer(struct snd_emu10k1 * emu);
int snd_emu10k1_pcm_multi(struct snd_emu10k1 *emu, int device);
int snd_emu10k1_fx8010_pcm(struct snd_emu10k1 *emu, int device);

View File

@ -56,9 +56,6 @@ struct snd_emu8000 {
unsigned long port1; /* Port usually base+0 */
unsigned long port2; /* Port usually at base+0x400 */
unsigned long port3; /* Port usually at base+0x800 */
struct resource *res_port1;
struct resource *res_port2;
struct resource *res_port3;
unsigned short last_reg;/* Last register command */
spinlock_t reg_lock;

View File

@ -114,7 +114,6 @@ struct hda_codec_ops {
int (*resume)(struct hda_codec *codec);
int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
#endif
void (*reboot_notify)(struct hda_codec *codec);
void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on);
};

View File

@ -51,7 +51,7 @@ enum hdac_ext_stream_type {
* @decoupled: stream host and link is decoupled
* @link_locked: link is locked
* @link_prepared: link is prepared
* link_substream: link substream
* @link_substream: link substream
*/
struct hdac_ext_stream {
struct hdac_stream hstream;

View File

@ -31,13 +31,13 @@ struct snd_dma_device {
#define SNDRV_DMA_TYPE_UNKNOWN 0 /* not defined */
#define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */
#define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */
#define SNDRV_DMA_TYPE_DEV_UC 5 /* continuous non-cahced */
#define SNDRV_DMA_TYPE_DEV_WC 5 /* continuous write-combined */
#ifdef CONFIG_SND_DMA_SGBUF
#define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */
#define SNDRV_DMA_TYPE_DEV_UC_SG 6 /* SG non-cached */
#define SNDRV_DMA_TYPE_DEV_WC_SG 6 /* SG write-combined */
#else
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */
#define SNDRV_DMA_TYPE_DEV_UC_SG SNDRV_DMA_TYPE_DEV_UC
#define SNDRV_DMA_TYPE_DEV_WC_SG SNDRV_DMA_TYPE_DEV_WC
#endif
#ifdef CONFIG_GENERIC_ALLOCATOR
#define SNDRV_DMA_TYPE_DEV_IRAM 4 /* generic device iram-buffer */
@ -79,5 +79,9 @@ struct page *snd_sgbuf_get_page(struct snd_dma_buffer *dmab, size_t offset);
unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
unsigned int ofs, unsigned int size);
/* device-managed memory allocator */
struct snd_dma_buffer *snd_devm_alloc_pages(struct device *dev, int type,
size_t size);
#endif /* __SOUND_MEMALLOC_H */

View File

@ -1204,11 +1204,48 @@ void snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
void snd_pcm_set_managed_buffer(struct snd_pcm_substream *substream, int type,
struct device *data, size_t size, size_t max);
void snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type,
struct device *data,
size_t size, size_t max);
int snd_pcm_set_managed_buffer(struct snd_pcm_substream *substream, int type,
struct device *data, size_t size, size_t max);
int snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type,
struct device *data,
size_t size, size_t max);
/**
* snd_pcm_set_fixed_buffer - Preallocate and set up the fixed size PCM buffer
* @substream: the pcm substream instance
* @type: DMA type (SNDRV_DMA_TYPE_*)
* @data: DMA type dependent data
* @size: the requested pre-allocation size in bytes
*
* This is a variant of snd_pcm_set_managed_buffer(), but this pre-allocates
* only the given sized buffer and doesn't allow re-allocation nor dynamic
* allocation of a larger buffer unlike the standard one.
* The function may return -ENOMEM error, hence the caller must check it.
*/
static inline int __must_check
snd_pcm_set_fixed_buffer(struct snd_pcm_substream *substream, int type,
struct device *data, size_t size)
{
return snd_pcm_set_managed_buffer(substream, type, data, size, 0);
}
/**
* snd_pcm_set_fixed_buffer_all - Preallocate and set up the fixed size PCM buffer
* @pcm: the pcm instance
* @type: DMA type (SNDRV_DMA_TYPE_*)
* @data: DMA type dependent data
* @size: the requested pre-allocation size in bytes
*
* Apply the set up of the fixed buffer via snd_pcm_set_fixed_buffer() for
* all substream. If any of allocation fails, it returns -ENOMEM, hence the
* caller must check the return value.
*/
static inline int __must_check
snd_pcm_set_fixed_buffer_all(struct snd_pcm *pcm, int type,
struct device *data, size_t size)
{
return snd_pcm_set_managed_buffer_all(pcm, type, data, size, 0);
}
int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
size_t size, gfp_t gfp_flags);

View File

@ -14,18 +14,12 @@ struct snd_soc_component;
extern int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
extern int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream);
extern int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
extern snd_pcm_uframes_t pxa2xx_pcm_pointer(struct snd_pcm_substream *substream);
extern int pxa2xx_pcm_prepare(struct snd_pcm_substream *substream);
extern int pxa2xx_pcm_open(struct snd_pcm_substream *substream);
extern int pxa2xx_pcm_close(struct snd_pcm_substream *substream);
extern int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma);
extern int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream);
extern void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm);
extern void pxa2xx_soc_pcm_free(struct snd_soc_component *component,
struct snd_pcm *pcm);
extern int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm);
extern int pxa2xx_soc_pcm_new(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *rtd);
extern int pxa2xx_soc_pcm_open(struct snd_soc_component *component,
@ -35,8 +29,6 @@ extern int pxa2xx_soc_pcm_close(struct snd_soc_component *component,
extern int pxa2xx_soc_pcm_hw_params(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
extern int pxa2xx_soc_pcm_hw_free(struct snd_soc_component *component,
struct snd_pcm_substream *substream);
extern int pxa2xx_soc_pcm_prepare(struct snd_soc_component *component,
struct snd_pcm_substream *substream);
extern int pxa2xx_soc_pcm_trigger(struct snd_soc_component *component,
@ -44,9 +36,6 @@ extern int pxa2xx_soc_pcm_trigger(struct snd_soc_component *component,
extern snd_pcm_uframes_t
pxa2xx_soc_pcm_pointer(struct snd_soc_component *component,
struct snd_pcm_substream *substream);
extern int pxa2xx_soc_pcm_mmap(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct vm_area_struct *vma);
/* AC97 */

View File

@ -101,5 +101,6 @@ struct sof_dev_desc {
};
int sof_dai_get_mclk(struct snd_soc_pcm_runtime *rtd);
int sof_dai_get_bclk(struct snd_soc_pcm_runtime *rtd);
#endif

View File

@ -299,6 +299,7 @@ typedef int __bitwise snd_pcm_subformat_t;
#define SNDRV_PCM_INFO_HAS_LINK_ABSOLUTE_ATIME 0x02000000 /* report absolute hardware link audio time, not reset on startup */
#define SNDRV_PCM_INFO_HAS_LINK_ESTIMATED_ATIME 0x04000000 /* report estimated link audio time */
#define SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME 0x08000000 /* report synchronized audio/system time */
#define SNDRV_PCM_INFO_EXPLICIT_SYNC 0x10000000 /* needs explicit sync of pointers and data */
#define SNDRV_PCM_INFO_DRAIN_TRIGGER 0x40000000 /* internal kernel flag - trigger in drain */
#define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */

View File

@ -233,6 +233,8 @@
*
* %SKL_TKN_U32_ASTATE_CLK_SRC: Clock source for A-State entry
*
* %SKL_TKN_U32_FMT_CFG_IDX: Format config index
*
* module_id and loadable flags dont have tokens as these values will be
* read from the DSP FW manifest
*
@ -324,7 +326,9 @@ enum SKL_TKNS {
SKL_TKN_U32_ASTATE_COUNT,
SKL_TKN_U32_ASTATE_KCPS,
SKL_TKN_U32_ASTATE_CLK_SRC,
SKL_TKN_MAX = SKL_TKN_U32_ASTATE_CLK_SRC,
SKL_TKN_U32_FMT_CFG_IDX = 96,
SKL_TKN_MAX = SKL_TKN_U32_FMT_CFG_IDX,
};
#endif

View File

@ -172,38 +172,28 @@ static const struct snd_pcm_ops pxa2xx_ac97_pcm_ops = {
.open = pxa2xx_ac97_pcm_open,
.close = pxa2xx_ac97_pcm_close,
.hw_params = pxa2xx_pcm_hw_params,
.hw_free = pxa2xx_pcm_hw_free,
.prepare = pxa2xx_ac97_pcm_prepare,
.trigger = pxa2xx_pcm_trigger,
.pointer = pxa2xx_pcm_pointer,
.mmap = pxa2xx_pcm_mmap,
};
static int pxa2xx_ac97_pcm_new(struct snd_card *card)
{
struct snd_pcm *pcm;
int stream, ret;
int ret;
ret = snd_pcm_new(card, "PXA2xx-PCM", 0, 1, 1, &pcm);
if (ret)
goto out;
pcm->private_free = pxa2xx_pcm_free_dma_buffers;
ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
if (ret)
goto out;
stream = SNDRV_PCM_STREAM_PLAYBACK;
snd_pcm_set_ops(pcm, stream, &pxa2xx_ac97_pcm_ops);
ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
if (ret)
goto out;
stream = SNDRV_PCM_STREAM_CAPTURE;
snd_pcm_set_ops(pcm, stream, &pxa2xx_ac97_pcm_ops);
ret = pxa2xx_pcm_preallocate_dma_buffer(pcm, stream);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &pxa2xx_ac97_pcm_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &pxa2xx_ac97_pcm_ops);
ret = pxa2xx_pcm_preallocate_dma_buffer(pcm);
if (ret)
goto out;

View File

@ -54,19 +54,10 @@ int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
if (ret)
return ret;
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
return 0;
}
EXPORT_SYMBOL(pxa2xx_pcm_hw_params);
int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
{
snd_pcm_set_runtime_buffer(substream, NULL);
return 0;
}
EXPORT_SYMBOL(pxa2xx_pcm_hw_free);
int pxa2xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
return snd_dmaengine_pcm_trigger(substream, cmd);
@ -131,57 +122,15 @@ int pxa2xx_pcm_close(struct snd_pcm_substream *substream)
}
EXPORT_SYMBOL(pxa2xx_pcm_close);
int pxa2xx_pcm_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm)
{
struct snd_pcm_runtime *runtime = substream->runtime;
return dma_mmap_wc(substream->pcm->card->dev, vma, runtime->dma_area,
runtime->dma_addr, runtime->dma_bytes);
}
EXPORT_SYMBOL(pxa2xx_pcm_mmap);
int pxa2xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
struct snd_dma_buffer *buf = &substream->dma_buffer;
size_t size = pxa2xx_pcm_hardware.buffer_bytes_max;
buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = pcm->card->dev;
buf->private_data = NULL;
buf->area = dma_alloc_wc(pcm->card->dev, size, &buf->addr, GFP_KERNEL);
if (!buf->area)
return -ENOMEM;
buf->bytes = size;
return 0;
return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_WC,
pcm->card->dev, size);
}
EXPORT_SYMBOL(pxa2xx_pcm_preallocate_dma_buffer);
void pxa2xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
{
struct snd_pcm_substream *substream;
struct snd_dma_buffer *buf;
int stream;
for (stream = 0; stream < 2; stream++) {
substream = pcm->streams[stream].substream;
if (!substream)
continue;
buf = &substream->dma_buffer;
if (!buf->area)
continue;
dma_free_wc(pcm->card->dev, buf->bytes, buf->area, buf->addr);
buf->area = NULL;
}
}
EXPORT_SYMBOL(pxa2xx_pcm_free_dma_buffers);
void pxa2xx_soc_pcm_free(struct snd_soc_component *component,
struct snd_pcm *pcm)
{
pxa2xx_pcm_free_dma_buffers(pcm);
}
EXPORT_SYMBOL(pxa2xx_soc_pcm_free);
int pxa2xx_soc_pcm_new(struct snd_soc_component *component,
struct snd_soc_pcm_runtime *rtd)
{
@ -193,21 +142,7 @@ int pxa2xx_soc_pcm_new(struct snd_soc_component *component,
if (ret)
return ret;
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = pxa2xx_pcm_preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
goto out;
}
out:
return ret;
return pxa2xx_pcm_preallocate_dma_buffer(pcm);
}
EXPORT_SYMBOL(pxa2xx_soc_pcm_new);
@ -233,13 +168,6 @@ int pxa2xx_soc_pcm_hw_params(struct snd_soc_component *component,
}
EXPORT_SYMBOL(pxa2xx_soc_pcm_hw_params);
int pxa2xx_soc_pcm_hw_free(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
return pxa2xx_pcm_hw_free(substream);
}
EXPORT_SYMBOL(pxa2xx_soc_pcm_hw_free);
int pxa2xx_soc_pcm_prepare(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
@ -262,14 +190,6 @@ pxa2xx_soc_pcm_pointer(struct snd_soc_component *component,
}
EXPORT_SYMBOL(pxa2xx_soc_pcm_pointer);
int pxa2xx_soc_pcm_mmap(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
return pxa2xx_pcm_mmap(substream, vma);
}
EXPORT_SYMBOL(pxa2xx_soc_pcm_mmap);
MODULE_AUTHOR("Nicolas Pitre");
MODULE_DESCRIPTION("Intel PXA2xx sound library");
MODULE_LICENSE("GPL");

View File

@ -47,8 +47,6 @@
* driver should be able to register multiple nodes
*/
static DEFINE_MUTEX(device_mutex);
struct snd_compr_file {
unsigned long caps;
struct snd_compr_stream stream;
@ -1179,6 +1177,7 @@ int snd_compress_new(struct snd_card *card, int device,
compr->card = card;
compr->device = device;
compr->direction = dirn;
mutex_init(&compr->lock);
snd_compress_set_id(compr, id);
@ -1193,72 +1192,6 @@ int snd_compress_new(struct snd_card *card, int device,
}
EXPORT_SYMBOL_GPL(snd_compress_new);
static int snd_compress_add_device(struct snd_compr *device)
{
int ret;
if (!device->card)
return -EINVAL;
/* register the card */
ret = snd_card_register(device->card);
if (ret)
goto out;
return 0;
out:
pr_err("failed with %d\n", ret);
return ret;
}
static int snd_compress_remove_device(struct snd_compr *device)
{
return snd_card_free(device->card);
}
/**
* snd_compress_register - register compressed device
*
* @device: compressed device to register
*/
int snd_compress_register(struct snd_compr *device)
{
int retval;
if (device->name == NULL || device->ops == NULL)
return -EINVAL;
pr_debug("Registering compressed device %s\n", device->name);
if (snd_BUG_ON(!device->ops->open))
return -EINVAL;
if (snd_BUG_ON(!device->ops->free))
return -EINVAL;
if (snd_BUG_ON(!device->ops->set_params))
return -EINVAL;
if (snd_BUG_ON(!device->ops->trigger))
return -EINVAL;
mutex_init(&device->lock);
/* register a compressed card */
mutex_lock(&device_mutex);
retval = snd_compress_add_device(device);
mutex_unlock(&device_mutex);
return retval;
}
EXPORT_SYMBOL_GPL(snd_compress_register);
int snd_compress_deregister(struct snd_compr *device)
{
pr_debug("Removing compressed device %s\n", device->name);
mutex_lock(&device_mutex);
snd_compress_remove_device(device);
mutex_unlock(&device_mutex);
return 0;
}
EXPORT_SYMBOL_GPL(snd_compress_deregister);
MODULE_DESCRIPTION("ALSA Compressed offload framework");
MODULE_AUTHOR("Vinod Koul <vinod.koul@linux.intel.com>");
MODULE_LICENSE("GPL v2");

View File

@ -564,7 +564,7 @@ static ssize_t set_led_id(struct snd_ctl_led_card *led_card, const char *buf, si
else {
for (; *s >= ' '; s++);
*s = '\0';
strlcpy(id.name, buf2, sizeof(id.name));
strscpy(id.name, buf2, sizeof(id.name));
}
break;
}

View File

@ -134,6 +134,9 @@ void snd_device_initialize(struct device *dev, struct snd_card *card)
}
EXPORT_SYMBOL_GPL(snd_device_initialize);
static int snd_card_init(struct snd_card *card, struct device *parent,
int idx, const char *xid, struct module *module,
size_t extra_size);
static int snd_card_do_free(struct snd_card *card);
static const struct attribute_group card_dev_attr_group;
@ -163,9 +166,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
{
struct snd_card *card;
int err;
#ifdef CONFIG_SND_DEBUG
char name[8];
#endif
if (snd_BUG_ON(!card_ret))
return -EINVAL;
@ -176,6 +176,74 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
card = kzalloc(sizeof(*card) + extra_size, GFP_KERNEL);
if (!card)
return -ENOMEM;
err = snd_card_init(card, parent, idx, xid, module, extra_size);
if (err < 0) {
kfree(card);
return err;
}
*card_ret = card;
return 0;
}
EXPORT_SYMBOL(snd_card_new);
static void __snd_card_release(struct device *dev, void *data)
{
snd_card_free(data);
}
/**
* snd_devm_card_new - managed snd_card object creation
* @parent: the parent device object
* @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
* @xid: card identification (ASCII string)
* @module: top level module for locking
* @extra_size: allocate this extra size after the main soundcard structure
* @card_ret: the pointer to store the created card instance
*
* This function works like snd_card_new() but manages the allocated resource
* via devres, i.e. you don't need to free explicitly.
*
* When a snd_card object is created with this function and registered via
* snd_card_register(), the very first devres action to call snd_card_free()
* is added automatically. In that way, the resource disconnection is assured
* at first, then released in the expected order.
*/
int snd_devm_card_new(struct device *parent, int idx, const char *xid,
struct module *module, size_t extra_size,
struct snd_card **card_ret)
{
struct snd_card *card;
int err;
*card_ret = NULL;
card = devres_alloc(__snd_card_release, sizeof(*card) + extra_size,
GFP_KERNEL);
if (!card)
return -ENOMEM;
card->managed = true;
err = snd_card_init(card, parent, idx, xid, module, extra_size);
if (err < 0) {
devres_free(card);
return err;
}
devres_add(parent, card);
*card_ret = card;
return 0;
}
EXPORT_SYMBOL_GPL(snd_devm_card_new);
static int snd_card_init(struct snd_card *card, struct device *parent,
int idx, const char *xid, struct module *module,
size_t extra_size)
{
int err;
#ifdef CONFIG_SND_DEBUG
char name[8];
#endif
if (extra_size > 0)
card->private_data = (char *)card + sizeof(struct snd_card);
if (xid)
@ -197,7 +265,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
mutex_unlock(&snd_card_mutex);
dev_err(parent, "cannot find the slot for index %d (range 0-%i), error: %d\n",
idx, snd_ecards_limit - 1, err);
kfree(card);
return err;
}
set_bit(idx, snd_cards_lock); /* lock it */
@ -256,8 +323,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
sprintf(name, "card%d", idx);
card->debugfs_root = debugfs_create_dir(name, sound_debugfs_root);
#endif
*card_ret = card;
return 0;
__error_ctl:
@ -266,7 +331,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid,
put_device(&card->card_dev);
return err;
}
EXPORT_SYMBOL(snd_card_new);
/**
* snd_card_ref - Get the card object from the index
@ -481,6 +545,7 @@ EXPORT_SYMBOL_GPL(snd_card_disconnect_sync);
static int snd_card_do_free(struct snd_card *card)
{
card->releasing = true;
#if IS_ENABLED(CONFIG_SND_MIXER_OSS)
if (snd_mixer_oss_notify_callback)
snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_FREE);
@ -498,7 +563,8 @@ static int snd_card_do_free(struct snd_card *card)
#endif
if (card->release_completion)
complete(card->release_completion);
kfree(card);
if (!card->managed)
kfree(card);
return 0;
}
@ -539,6 +605,15 @@ int snd_card_free(struct snd_card *card)
DECLARE_COMPLETION_ONSTACK(released);
int ret;
/* The call of snd_card_free() is allowed from various code paths;
* a manual call from the driver and the call via devres_free, and
* we need to avoid double-free. Moreover, the release via devres
* may call snd_card_free() twice due to its nature, we need to have
* the check here at the beginning.
*/
if (card->releasing)
return 0;
card->release_completion = &released;
ret = snd_card_free_when_closed(card);
if (ret)
@ -745,6 +820,11 @@ int snd_card_add_dev_attr(struct snd_card *card,
}
EXPORT_SYMBOL_GPL(snd_card_add_dev_attr);
static void trigger_card_free(void *data)
{
snd_card_free(data);
}
/**
* snd_card_register - register the soundcard
* @card: soundcard structure
@ -768,6 +848,15 @@ int snd_card_register(struct snd_card *card)
if (err < 0)
return err;
card->registered = true;
} else {
if (card->managed)
devm_remove_action(card->dev, trigger_card_free, card);
}
if (card->managed) {
err = devm_add_action(card->dev, trigger_card_free, card);
if (err < 0)
return err;
}
err = snd_device_register_all(card);

View File

@ -97,3 +97,41 @@ unsigned int snd_dma_pointer(unsigned long dma, unsigned int size)
return size - result;
}
EXPORT_SYMBOL(snd_dma_pointer);
struct snd_dma_data {
int dma;
};
static void __snd_release_dma(struct device *dev, void *data)
{
struct snd_dma_data *p = data;
snd_dma_disable(p->dma);
free_dma(p->dma);
}
/**
* snd_devm_request_dma - the managed version of request_dma()
* @dev: the device pointer
* @dma: the dma number
* @name: the name string of the requester
*
* Returns zero on success, or a negative error code.
* The requested DMA will be automatically released at unbinding via devres.
*/
int snd_devm_request_dma(struct device *dev, int dma, const char *name)
{
struct snd_dma_data *p;
if (request_dma(dma, name))
return -EBUSY;
p = devres_alloc(__snd_release_dma, sizeof(*p), GFP_KERNEL);
if (!p) {
free_dma(dma);
return -ENOMEM;
}
p->dma = dma;
devres_add(dev, p);
return 0;
}
EXPORT_SYMBOL_GPL(snd_devm_request_dma);

View File

@ -29,12 +29,12 @@ static inline gfp_t snd_mem_get_gfp_flags(const struct snd_dma_buffer *dmab,
return (__force gfp_t)(unsigned long)dmab->dev.dev;
}
static int __snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
static void *__snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
{
const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
if (WARN_ON_ONCE(!ops || !ops->alloc))
return -EINVAL;
return NULL;
return ops->alloc(dmab, size);
}
@ -54,8 +54,6 @@ static int __snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
int snd_dma_alloc_pages(int type, struct device *device, size_t size,
struct snd_dma_buffer *dmab)
{
int err;
if (WARN_ON(!size))
return -ENXIO;
if (WARN_ON(!dmab))
@ -65,12 +63,9 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
dmab->dev.type = type;
dmab->dev.dev = device;
dmab->bytes = 0;
dmab->area = NULL;
dmab->addr = 0;
dmab->private_data = NULL;
err = __snd_dma_alloc_pages(dmab, size);
if (err < 0)
return err;
dmab->area = __snd_dma_alloc_pages(dmab, size);
if (!dmab->area)
return -ENOMEM;
dmab->bytes = size;
@ -127,6 +122,52 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
}
EXPORT_SYMBOL(snd_dma_free_pages);
/* called by devres */
static void __snd_release_pages(struct device *dev, void *res)
{
snd_dma_free_pages(res);
}
/**
* snd_devm_alloc_pages - allocate the buffer and manage with devres
* @dev: the device pointer
* @type: the DMA buffer type
* @size: the buffer size to allocate
*
* Allocate buffer pages depending on the given type and manage using devres.
* The pages will be released automatically at the device removal.
*
* Unlike snd_dma_alloc_pages(), this function requires the real device pointer,
* hence it can't work with SNDRV_DMA_TYPE_CONTINUOUS or
* SNDRV_DMA_TYPE_VMALLOC type.
*
* The function returns the snd_dma_buffer object at success, or NULL if failed.
*/
struct snd_dma_buffer *
snd_devm_alloc_pages(struct device *dev, int type, size_t size)
{
struct snd_dma_buffer *dmab;
int err;
if (WARN_ON(type == SNDRV_DMA_TYPE_CONTINUOUS ||
type == SNDRV_DMA_TYPE_VMALLOC))
return NULL;
dmab = devres_alloc(__snd_release_pages, sizeof(*dmab), GFP_KERNEL);
if (!dmab)
return NULL;
err = snd_dma_alloc_pages(type, dev, size, dmab);
if (err < 0) {
devres_free(dmab);
return NULL;
}
devres_add(dev, dmab);
return dmab;
}
EXPORT_SYMBOL_GPL(snd_devm_alloc_pages);
/**
* snd_dma_buffer_mmap - perform mmap of the given DMA buffer
* @dmab: buffer allocation information
@ -198,12 +239,14 @@ EXPORT_SYMBOL(snd_sgbuf_get_chunk_size);
/*
* Continuous pages allocator
*/
static int snd_dma_continuous_alloc(struct snd_dma_buffer *dmab, size_t size)
static void *snd_dma_continuous_alloc(struct snd_dma_buffer *dmab, size_t size)
{
gfp_t gfp = snd_mem_get_gfp_flags(dmab, GFP_KERNEL);
void *p = alloc_pages_exact(size, gfp);
dmab->area = alloc_pages_exact(size, gfp);
return 0;
if (p)
dmab->addr = page_to_phys(virt_to_page(p));
return p;
}
static void snd_dma_continuous_free(struct snd_dma_buffer *dmab)
@ -215,7 +258,7 @@ static int snd_dma_continuous_mmap(struct snd_dma_buffer *dmab,
struct vm_area_struct *area)
{
return remap_pfn_range(area, area->vm_start,
page_to_pfn(virt_to_page(dmab->area)),
dmab->addr >> PAGE_SHIFT,
area->vm_end - area->vm_start,
area->vm_page_prot);
}
@ -229,12 +272,11 @@ static const struct snd_malloc_ops snd_dma_continuous_ops = {
/*
* VMALLOC allocator
*/
static int snd_dma_vmalloc_alloc(struct snd_dma_buffer *dmab, size_t size)
static void *snd_dma_vmalloc_alloc(struct snd_dma_buffer *dmab, size_t size)
{
gfp_t gfp = snd_mem_get_gfp_flags(dmab, GFP_KERNEL | __GFP_HIGHMEM);
dmab->area = __vmalloc(size, gfp);
return 0;
return __vmalloc(size, gfp);
}
static void snd_dma_vmalloc_free(struct snd_dma_buffer *dmab)
@ -248,11 +290,13 @@ static int snd_dma_vmalloc_mmap(struct snd_dma_buffer *dmab,
return remap_vmalloc_range(area, dmab->area, 0);
}
#define get_vmalloc_page_addr(dmab, offset) \
page_to_phys(vmalloc_to_page((dmab)->area + (offset)))
static dma_addr_t snd_dma_vmalloc_get_addr(struct snd_dma_buffer *dmab,
size_t offset)
{
return page_to_phys(vmalloc_to_page(dmab->area + offset)) +
offset % PAGE_SIZE;
return get_vmalloc_page_addr(dmab, offset) + offset % PAGE_SIZE;
}
static struct page *snd_dma_vmalloc_get_page(struct snd_dma_buffer *dmab,
@ -265,11 +309,23 @@ static unsigned int
snd_dma_vmalloc_get_chunk_size(struct snd_dma_buffer *dmab,
unsigned int ofs, unsigned int size)
{
ofs %= PAGE_SIZE;
size += ofs;
if (size > PAGE_SIZE)
size = PAGE_SIZE;
return size - ofs;
unsigned int start, end;
unsigned long addr;
start = ALIGN_DOWN(ofs, PAGE_SIZE);
end = ofs + size - 1; /* the last byte address */
/* check page continuity */
addr = get_vmalloc_page_addr(dmab, start);
for (;;) {
start += PAGE_SIZE;
if (start > end)
break;
addr += PAGE_SIZE;
if (get_vmalloc_page_addr(dmab, start) != addr)
return start - ofs;
}
/* ok, all on continuous pages */
return size;
}
static const struct snd_malloc_ops snd_dma_vmalloc_ops = {
@ -286,20 +342,20 @@ static const struct snd_malloc_ops snd_dma_vmalloc_ops = {
* IRAM allocator
*/
#ifdef CONFIG_GENERIC_ALLOCATOR
static int snd_dma_iram_alloc(struct snd_dma_buffer *dmab, size_t size)
static void *snd_dma_iram_alloc(struct snd_dma_buffer *dmab, size_t size)
{
struct device *dev = dmab->dev.dev;
struct gen_pool *pool;
void *p;
if (dev->of_node) {
pool = of_gen_pool_get(dev->of_node, "iram", 0);
/* Assign the pool into private_data field */
dmab->private_data = pool;
dmab->area = gen_pool_dma_alloc_align(pool, size, &dmab->addr,
PAGE_SIZE);
if (dmab->area)
return 0;
p = gen_pool_dma_alloc_align(pool, size, &dmab->addr, PAGE_SIZE);
if (p)
return p;
}
/* Internal memory might have limited size and no enough space,
@ -334,31 +390,31 @@ static const struct snd_malloc_ops snd_dma_iram_ops = {
};
#endif /* CONFIG_GENERIC_ALLOCATOR */
#define DEFAULT_GFP \
(GFP_KERNEL | \
__GFP_COMP | /* compound page lets parts be mapped */ \
__GFP_NORETRY | /* don't trigger OOM-killer */ \
__GFP_NOWARN) /* no stack trace print - this call is non-critical */
/*
* Coherent device pages allocator
*/
static int snd_dma_dev_alloc(struct snd_dma_buffer *dmab, size_t size)
static void *snd_dma_dev_alloc(struct snd_dma_buffer *dmab, size_t size)
{
gfp_t gfp_flags;
void *p;
gfp_flags = GFP_KERNEL
| __GFP_COMP /* compound page lets parts be mapped */
| __GFP_NORETRY /* don't trigger OOM-killer */
| __GFP_NOWARN; /* no stack trace print - this call is non-critical */
dmab->area = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr,
gfp_flags);
p = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr, DEFAULT_GFP);
#ifdef CONFIG_X86
if (dmab->area && dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
set_memory_wc((unsigned long)dmab->area,
PAGE_ALIGN(size) >> PAGE_SHIFT);
if (p && dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC)
set_memory_wc((unsigned long)p, PAGE_ALIGN(size) >> PAGE_SHIFT);
#endif
return 0;
return p;
}
static void snd_dma_dev_free(struct snd_dma_buffer *dmab)
{
#ifdef CONFIG_X86
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC)
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC)
set_memory_wb((unsigned long)dmab->area,
PAGE_ALIGN(dmab->bytes) >> PAGE_SHIFT);
#endif
@ -368,6 +424,10 @@ static void snd_dma_dev_free(struct snd_dma_buffer *dmab)
static int snd_dma_dev_mmap(struct snd_dma_buffer *dmab,
struct vm_area_struct *area)
{
#ifdef CONFIG_X86
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC)
area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
#endif
return dma_mmap_coherent(dmab->dev.dev, area,
dmab->area, dmab->addr, dmab->bytes);
}
@ -377,6 +437,37 @@ static const struct snd_malloc_ops snd_dma_dev_ops = {
.free = snd_dma_dev_free,
.mmap = snd_dma_dev_mmap,
};
/*
* Write-combined pages
*/
#ifdef CONFIG_X86
/* On x86, share the same ops as the standard dev ops */
#define snd_dma_wc_ops snd_dma_dev_ops
#else /* CONFIG_X86 */
static void *snd_dma_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
{
return dma_alloc_wc(dmab->dev.dev, size, &dmab->addr, DEFAULT_GFP);
}
static void snd_dma_wc_free(struct snd_dma_buffer *dmab)
{
dma_free_wc(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
}
static int snd_dma_wc_mmap(struct snd_dma_buffer *dmab,
struct vm_area_struct *area)
{
return dma_mmap_wc(dmab->dev.dev, area,
dmab->area, dmab->addr, dmab->bytes);
}
static const struct snd_malloc_ops snd_dma_wc_ops = {
.alloc = snd_dma_wc_alloc,
.free = snd_dma_wc_free,
.mmap = snd_dma_wc_mmap,
};
#endif /* CONFIG_X86 */
#endif /* CONFIG_HAS_DMA */
/*
@ -387,14 +478,14 @@ static const struct snd_malloc_ops *dma_ops[] = {
[SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops,
#ifdef CONFIG_HAS_DMA
[SNDRV_DMA_TYPE_DEV] = &snd_dma_dev_ops,
[SNDRV_DMA_TYPE_DEV_UC] = &snd_dma_dev_ops,
[SNDRV_DMA_TYPE_DEV_WC] = &snd_dma_wc_ops,
#ifdef CONFIG_GENERIC_ALLOCATOR
[SNDRV_DMA_TYPE_DEV_IRAM] = &snd_dma_iram_ops,
#endif /* CONFIG_GENERIC_ALLOCATOR */
#endif /* CONFIG_HAS_DMA */
#ifdef CONFIG_SND_DMA_SGBUF
[SNDRV_DMA_TYPE_DEV_SG] = &snd_dma_sg_ops,
[SNDRV_DMA_TYPE_DEV_UC_SG] = &snd_dma_sg_ops,
[SNDRV_DMA_TYPE_DEV_WC_SG] = &snd_dma_sg_ops,
#endif
};

View File

@ -3,7 +3,7 @@
#define __MEMALLOC_LOCAL_H
struct snd_malloc_ops {
int (*alloc)(struct snd_dma_buffer *dmab, size_t size);
void *(*alloc)(struct snd_dma_buffer *dmab, size_t size);
void (*free)(struct snd_dma_buffer *dmab);
dma_addr_t (*get_addr)(struct snd_dma_buffer *dmab, size_t offset);
struct page *(*get_page)(struct snd_dma_buffer *dmab, size_t offset);

View File

@ -1746,7 +1746,7 @@ static int snd_pcm_lib_ioctl_fifo_size(struct snd_pcm_substream *substream,
channels = params_channels(params);
frame_size = snd_pcm_format_size(format, channels);
if (frame_size > 0)
params->fifo_size /= (unsigned)frame_size;
params->fifo_size /= frame_size;
}
return 0;
}

View File

@ -67,7 +67,8 @@ static void do_free_pages(struct snd_card *card, struct snd_dma_buffer *dmab)
*
* the minimum size is snd_minimum_buffer. it should be power of 2.
*/
static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t size)
static int preallocate_pcm_pages(struct snd_pcm_substream *substream,
size_t size, bool no_fallback)
{
struct snd_dma_buffer *dmab = &substream->dma_buffer;
struct snd_card *card = substream->pcm->card;
@ -79,6 +80,8 @@ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t siz
size, dmab);
if (err != -ENOMEM)
return err;
if (no_fallback)
break;
size >>= 1;
} while (size >= snd_minimum_buffer);
dmab->bytes = 0; /* tell error */
@ -86,7 +89,7 @@ static int preallocate_pcm_pages(struct snd_pcm_substream *substream, size_t siz
substream->pcm->card->number, substream->pcm->device,
substream->stream ? 'c' : 'p', substream->number,
substream->pcm->name, orig_size);
return 0;
return -ENOMEM;
}
/**
@ -222,18 +225,31 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream)
/*
* pre-allocate the buffer and create a proc file for the substream
*/
static void preallocate_pages(struct snd_pcm_substream *substream,
static int preallocate_pages(struct snd_pcm_substream *substream,
int type, struct device *data,
size_t size, size_t max, bool managed)
{
int err;
if (snd_BUG_ON(substream->dma_buffer.dev.type))
return;
return -EINVAL;
substream->dma_buffer.dev.type = type;
substream->dma_buffer.dev.dev = data;
if (size > 0 && preallocate_dma && substream->number < maximum_substreams)
preallocate_pcm_pages(substream, size);
if (size > 0) {
if (!max) {
/* no fallback, only also inform -ENOMEM */
err = preallocate_pcm_pages(substream, size, true);
if (err < 0)
return err;
} else if (preallocate_dma &&
substream->number < maximum_substreams) {
err = preallocate_pcm_pages(substream, size, false);
if (err < 0 && err != -ENOMEM)
return err;
}
}
if (substream->dma_buffer.bytes > 0)
substream->buffer_bytes_max = substream->dma_buffer.bytes;
@ -242,17 +258,22 @@ static void preallocate_pages(struct snd_pcm_substream *substream,
preallocate_info_init(substream);
if (managed)
substream->managed_buffer_alloc = 1;
return 0;
}
static void preallocate_pages_for_all(struct snd_pcm *pcm, int type,
static int preallocate_pages_for_all(struct snd_pcm *pcm, int type,
void *data, size_t size, size_t max,
bool managed)
{
struct snd_pcm_substream *substream;
int stream;
int stream, err;
for_each_pcm_substream(pcm, stream, substream)
preallocate_pages(substream, type, data, size, max, managed);
for_each_pcm_substream(pcm, stream, substream) {
err = preallocate_pages(substream, type, data, size, max, managed);
if (err < 0)
return err;
}
return 0;
}
/**
@ -309,11 +330,22 @@ EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
* When a buffer is actually allocated before the PCM hw_params call, it
* turns on the runtime buffer_changed flag for drivers changing their h/w
* parameters accordingly.
*
* When @size is non-zero and @max is zero, this tries to allocate for only
* the exact buffer size without fallback, and may return -ENOMEM.
* Otherwise, the function tries to allocate smaller chunks if the allocation
* fails. This is the behavior of snd_pcm_set_fixed_buffer().
*
* When both @size and @max are zero, the function only sets up the buffer
* for later dynamic allocations. It's used typically for buffers with
* SNDRV_DMA_TYPE_VMALLOC type.
*
* Upon successful buffer allocation and setup, the function returns 0.
*/
void snd_pcm_set_managed_buffer(struct snd_pcm_substream *substream, int type,
int snd_pcm_set_managed_buffer(struct snd_pcm_substream *substream, int type,
struct device *data, size_t size, size_t max)
{
preallocate_pages(substream, type, data, size, max, true);
return preallocate_pages(substream, type, data, size, max, true);
}
EXPORT_SYMBOL(snd_pcm_set_managed_buffer);
@ -329,11 +361,11 @@ EXPORT_SYMBOL(snd_pcm_set_managed_buffer);
* Do pre-allocation to all substreams of the given pcm for the specified DMA
* type and size, and set the managed_buffer_alloc flag to each substream.
*/
void snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type,
struct device *data,
size_t size, size_t max)
int snd_pcm_set_managed_buffer_all(struct snd_pcm *pcm, int type,
struct device *data,
size_t size, size_t max)
{
preallocate_pages_for_all(pcm, type, data, size, max, true);
return preallocate_pages_for_all(pcm, type, data, size, max, true);
}
EXPORT_SYMBOL(snd_pcm_set_managed_buffer_all);
@ -376,6 +408,9 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size)
substream->dma_buffer.bytes >= size) {
dmab = &substream->dma_buffer; /* use the pre-allocated buffer */
} else {
/* dma_max=0 means the fixed size preallocation */
if (substream->dma_buffer.area && !substream->dma_max)
return -ENOMEM;
dmab = kzalloc(sizeof(*dmab), GFP_KERNEL);
if (! dmab)
return -ENOMEM;

View File

@ -243,13 +243,18 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream,
static bool hw_support_mmap(struct snd_pcm_substream *substream)
{
struct snd_dma_buffer *dmabuf;
if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_MMAP))
return false;
if (substream->ops->mmap || substream->ops->page)
return true;
switch (substream->dma_buffer.dev.type) {
dmabuf = snd_pcm_get_dma_buf(substream);
if (!dmabuf)
dmabuf = &substream->dma_buffer;
switch (dmabuf->dev.type) {
case SNDRV_DMA_TYPE_UNKNOWN:
/* we can't know the device, so just assume that the driver does
* everything right
@ -259,7 +264,7 @@ static bool hw_support_mmap(struct snd_pcm_substream *substream)
case SNDRV_DMA_TYPE_VMALLOC:
return true;
default:
return dma_can_mmap(substream->dma_buffer.dev.dev);
return dma_can_mmap(dmabuf->dev.dev);
}
}
@ -3616,6 +3621,12 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
static bool pcm_status_mmap_allowed(struct snd_pcm_file *pcm_file)
{
/* If drivers require the explicit sync (typically for non-coherent
* pages), we have to disable the mmap of status and control data
* to enforce the control via SYNC_PTR ioctl.
*/
if (pcm_file->substream->runtime->hw.info & SNDRV_PCM_INFO_EXPLICIT_SYNC)
return false;
/* See pcm_control_mmap_allowed() below.
* Since older alsa-lib requires both status and control mmaps to be
* coupled, we have to disable the status mmap for old alsa-lib, too.
@ -3630,6 +3641,9 @@ static bool pcm_control_mmap_allowed(struct snd_pcm_file *pcm_file)
{
if (pcm_file->no_compat_mmap)
return false;
/* see above */
if (pcm_file->substream->runtime->hw.info & SNDRV_PCM_INFO_EXPLICIT_SYNC)
return false;
/* Disallow the control mmap when SYNC_APPLPTR flag is set;
* it enforces the user-space to fall back to snd_pcm_sync_ptr(),
* thus it effectively assures the manual update of appl_ptr.

View File

@ -20,15 +20,15 @@
are redirected to output port immediately.
The routing can be done via aconnect program in alsa-utils.
Each client has a static client number 62 (= SNDRV_SEQ_CLIENT_DUMMY).
Each client has a static client number 14 (= SNDRV_SEQ_CLIENT_DUMMY).
If you want to auto-load this module, you may add the following alias
in your /etc/conf.modules file.
alias snd-seq-client-62 snd-seq-dummy
alias snd-seq-client-14 snd-seq-dummy
The module is loaded on demand for client 62, or /proc/asound/seq/
The module is loaded on demand for client 14, or /proc/asound/seq/
is accessed. If you don't need this module to be loaded, alias
snd-seq-client-62 as "off". This will help modprobe.
snd-seq-client-14 as "off". This will help modprobe.
The number of ports to be created can be specified via the module
parameter "ports". For example, to create four ports, add the

View File

@ -43,8 +43,8 @@ static void snd_dma_sg_free(struct snd_dma_buffer *dmab)
dmab->area = NULL;
tmpb.dev.type = SNDRV_DMA_TYPE_DEV;
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC_SG)
tmpb.dev.type = SNDRV_DMA_TYPE_DEV_UC;
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
tmpb.dev.type = SNDRV_DMA_TYPE_DEV_WC;
tmpb.dev.dev = sgbuf->dev;
for (i = 0; i < sgbuf->pages; i++) {
if (!(sgbuf->table[i].addr & ~PAGE_MASK))
@ -63,7 +63,7 @@ static void snd_dma_sg_free(struct snd_dma_buffer *dmab)
#define MAX_ALLOC_PAGES 32
static int snd_dma_sg_alloc(struct snd_dma_buffer *dmab, size_t size)
static void *snd_dma_sg_alloc(struct snd_dma_buffer *dmab, size_t size)
{
struct snd_sg_buf *sgbuf;
unsigned int i, pages, chunk, maxpages;
@ -72,12 +72,13 @@ static int snd_dma_sg_alloc(struct snd_dma_buffer *dmab, size_t size)
struct page **pgtable;
int type = SNDRV_DMA_TYPE_DEV;
pgprot_t prot = PAGE_KERNEL;
void *area;
dmab->private_data = sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL);
if (!sgbuf)
return -ENOMEM;
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_UC_SG) {
type = SNDRV_DMA_TYPE_DEV_UC;
return NULL;
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) {
type = SNDRV_DMA_TYPE_DEV_WC;
#ifdef pgprot_noncached
prot = pgprot_noncached(PAGE_KERNEL);
#endif
@ -127,14 +128,14 @@ static int snd_dma_sg_alloc(struct snd_dma_buffer *dmab, size_t size)
}
sgbuf->size = size;
dmab->area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, prot);
if (! dmab->area)
area = vmap(sgbuf->page_table, sgbuf->pages, VM_MAP, prot);
if (!area)
goto _failed;
return 0;
return area;
_failed:
snd_dma_sg_free(dmab); /* free the table */
return -ENOMEM;
return NULL;
}
static dma_addr_t snd_dma_sg_get_addr(struct snd_dma_buffer *dmab,
@ -182,10 +183,19 @@ static unsigned int snd_dma_sg_get_chunk_size(struct snd_dma_buffer *dmab,
return size;
}
static int snd_dma_sg_mmap(struct snd_dma_buffer *dmab,
struct vm_area_struct *area)
{
if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
return -ENOENT; /* continue with the default mmap handler */
}
const struct snd_malloc_ops snd_dma_sg_ops = {
.alloc = snd_dma_sg_alloc,
.free = snd_dma_sg_free,
.get_addr = snd_dma_sg_get_addr,
.get_page = snd_dma_sg_get_page,
.get_chunk_size = snd_dma_sg_get_chunk_size,
.mmap = snd_dma_sg_mmap,
};

View File

@ -102,7 +102,7 @@ config SND_ALOOP
configured number of substreams (see the pcm_substreams module
parameter).
The loopback device allows time sychronization with an external
The loopback device allows time synchronization with an external
timing source using the time shift universal control (+-20%
of system time).

View File

@ -1712,8 +1712,8 @@ static int loopback_probe(struct platform_device *devptr)
int dev = devptr->id;
int err;
err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct loopback), &card);
err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct loopback), &card);
if (err < 0)
return err;
loopback = card->private_data;
@ -1730,13 +1730,13 @@ static int loopback_probe(struct platform_device *devptr)
err = loopback_pcm_new(loopback, 0, pcm_substreams[dev]);
if (err < 0)
goto __nodev;
return err;
err = loopback_pcm_new(loopback, 1, pcm_substreams[dev]);
if (err < 0)
goto __nodev;
return err;
err = loopback_mixer_new(loopback, pcm_notify[dev] ? 1 : 0);
if (err < 0)
goto __nodev;
return err;
loopback_cable_proc_new(loopback, 0);
loopback_cable_proc_new(loopback, 1);
loopback_timer_source_proc_new(loopback);
@ -1744,18 +1744,9 @@ static int loopback_probe(struct platform_device *devptr)
strcpy(card->shortname, "Loopback");
sprintf(card->longname, "Loopback %i", dev + 1);
err = snd_card_register(card);
if (!err) {
platform_set_drvdata(devptr, card);
return 0;
}
__nodev:
snd_card_free(card);
return err;
}
static int loopback_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
if (err < 0)
return err;
platform_set_drvdata(devptr, card);
return 0;
}
@ -1786,7 +1777,6 @@ static SIMPLE_DEV_PM_OPS(loopback_pm, loopback_suspend, loopback_resume);
static struct platform_driver loopback_driver = {
.probe = loopback_probe,
.remove = loopback_remove,
.driver = {
.name = SND_LOOPBACK_DRIVER,
.pm = LOOPBACK_PM_OPS,

View File

@ -1025,8 +1025,8 @@ static int snd_dummy_probe(struct platform_device *devptr)
int idx, err;
int dev = devptr->id;
err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_dummy), &card);
err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_dummy), &card);
if (err < 0)
return err;
dummy = card->private_data;
@ -1047,7 +1047,7 @@ static int snd_dummy_probe(struct platform_device *devptr)
pcm_substreams[dev] = MAX_PCM_SUBSTREAMS;
err = snd_card_dummy_pcm(dummy, idx, pcm_substreams[dev]);
if (err < 0)
goto __nodev;
return err;
}
dummy->pcm_hw = dummy_pcm_hardware;
@ -1078,7 +1078,7 @@ static int snd_dummy_probe(struct platform_device *devptr)
err = snd_card_dummy_new_mixer(dummy);
if (err < 0)
goto __nodev;
return err;
strcpy(card->driver, "Dummy");
strcpy(card->shortname, "Dummy");
sprintf(card->longname, "Dummy %i", dev + 1);
@ -1086,18 +1086,9 @@ static int snd_dummy_probe(struct platform_device *devptr)
dummy_proc_init(dummy);
err = snd_card_register(card);
if (err == 0) {
platform_set_drvdata(devptr, card);
return 0;
}
__nodev:
snd_card_free(card);
return err;
}
static int snd_dummy_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
if (err < 0)
return err;
platform_set_drvdata(devptr, card);
return 0;
}
@ -1128,7 +1119,6 @@ static SIMPLE_DEV_PM_OPS(snd_dummy_pm, snd_dummy_suspend, snd_dummy_resume);
static struct platform_driver snd_dummy_driver = {
.probe = snd_dummy_probe,
.remove = snd_dummy_remove,
.driver = {
.name = SND_DUMMY_DRIVER,
.pm = SND_DUMMY_PM_OPS,

View File

@ -59,8 +59,8 @@ static int snd_mpu401_create(struct device *devptr, int dev,
snd_printk(KERN_ERR "the uart_enter option is obsolete; remove it\n");
*rcard = NULL;
err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE,
0, &card);
err = snd_devm_card_new(devptr, index[dev], id[dev], THIS_MODULE,
0, &card);
if (err < 0)
return err;
strcpy(card->driver, "MPU-401 UART");
@ -76,15 +76,11 @@ static int snd_mpu401_create(struct device *devptr, int dev,
irq[dev], NULL);
if (err < 0) {
printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]);
goto _err;
return err;
}
*rcard = card;
return 0;
_err:
snd_card_free(card);
return err;
}
static int snd_mpu401_probe(struct platform_device *devptr)
@ -105,25 +101,16 @@ static int snd_mpu401_probe(struct platform_device *devptr)
if (err < 0)
return err;
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
platform_set_drvdata(devptr, card);
return 0;
}
static int snd_mpu401_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
return 0;
}
#define SND_MPU401_DRIVER "snd_mpu401"
static struct platform_driver snd_mpu401_driver = {
.probe = snd_mpu401_probe,
.remove = snd_mpu401_remove,
.driver = {
.name = SND_MPU401_DRIVER,
},
@ -184,10 +171,8 @@ static int snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
if (err < 0)
return err;
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
pnp_set_drvdata(pnp_dev, card);
snd_mpu401_devices++;
++dev;
@ -196,19 +181,10 @@ static int snd_mpu401_pnp_probe(struct pnp_dev *pnp_dev,
return -ENODEV;
}
static void snd_mpu401_pnp_remove(struct pnp_dev *dev)
{
struct snd_card *card = (struct snd_card *) pnp_get_drvdata(dev);
snd_card_disconnect(card);
snd_card_free_when_closed(card);
}
static struct pnp_driver snd_mpu401_pnp_driver = {
.name = "mpu401",
.id_table = snd_mpu401_pnpids,
.probe = snd_mpu401_pnp_probe,
.remove = snd_mpu401_pnp_remove,
};
#else
static struct pnp_driver snd_mpu401_pnp_driver;

View File

@ -566,13 +566,15 @@ static irqreturn_t snd_mtpav_irqh(int irq, void *dev_id)
*/
static int snd_mtpav_get_ISA(struct mtpav *mcard)
{
mcard->res_port = request_region(port, 3, "MotuMTPAV MIDI");
mcard->res_port = devm_request_region(mcard->card->dev, port, 3,
"MotuMTPAV MIDI");
if (!mcard->res_port) {
snd_printk(KERN_ERR "MTVAP port 0x%lx is busy\n", port);
return -EBUSY;
}
mcard->port = port;
if (request_irq(irq, snd_mtpav_irqh, 0, "MOTU MTPAV", mcard)) {
if (devm_request_irq(mcard->card->dev, irq, snd_mtpav_irqh, 0,
"MOTU MTPAV", mcard)) {
snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq);
return -EBUSY;
}
@ -667,9 +669,6 @@ static void snd_mtpav_free(struct snd_card *card)
if (crd->istimer > 0)
snd_mtpav_remove_output_timer(crd);
spin_unlock_irqrestore(&crd->spinlock, flags);
if (crd->irq >= 0)
free_irq(crd->irq, (void *)crd);
release_and_free_resource(crd->res_port);
}
/*
@ -680,8 +679,8 @@ static int snd_mtpav_probe(struct platform_device *dev)
int err;
struct mtpav *mtp_card;
err = snd_card_new(&dev->dev, index, id, THIS_MODULE,
sizeof(*mtp_card), &card);
err = snd_devm_card_new(&dev->dev, index, id, THIS_MODULE,
sizeof(*mtp_card), &card);
if (err < 0)
return err;
@ -698,13 +697,13 @@ static int snd_mtpav_probe(struct platform_device *dev)
err = snd_mtpav_get_RAWMIDI(mtp_card);
if (err < 0)
goto __error;
return err;
mtp_card->inmidiport = mtp_card->num_ports + MTPAV_PIDX_BROADCAST;
err = snd_mtpav_get_ISA(mtp_card);
if (err < 0)
goto __error;
return err;
strcpy(card->driver, "MTPAV");
strcpy(card->shortname, "MTPAV on parallel port");
@ -715,28 +714,17 @@ static int snd_mtpav_probe(struct platform_device *dev)
err = snd_card_register(mtp_card->card);
if (err < 0)
goto __error;
return err;
platform_set_drvdata(dev, card);
printk(KERN_INFO "Motu MidiTimePiece on parallel port irq: %d ioport: 0x%lx\n", irq, port);
return 0;
__error:
snd_card_free(card);
return err;
}
static int snd_mtpav_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
return 0;
}
#define SND_MTPAV_DRIVER "snd_mtpav"
static struct platform_driver snd_mtpav_driver = {
.probe = snd_mtpav_probe,
.remove = snd_mtpav_remove,
.driver = {
.name = SND_MTPAV_DRIVER,
},

View File

@ -42,9 +42,8 @@ struct snd_pcsp pcsp_chip;
static int snd_pcsp_create(struct snd_card *card)
{
static const struct snd_device_ops ops = { };
unsigned int resolution = hrtimer_resolution;
int err, div, min_div, order;
int div, min_div, order;
if (!nopcm) {
if (resolution > PCSP_MAX_PERIOD_NS) {
@ -83,15 +82,18 @@ static int snd_pcsp_create(struct snd_card *card)
pcsp_chip.port = 0x61;
pcsp_chip.irq = -1;
pcsp_chip.dma = -1;
/* Register device */
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, &pcsp_chip, &ops);
if (err < 0)
return err;
card->private_data = &pcsp_chip;
return 0;
}
static void pcsp_stop_beep(struct snd_pcsp *chip);
static void alsa_card_pcsp_free(struct snd_card *card)
{
pcsp_stop_beep(card->private_data);
}
static int snd_card_pcsp_probe(int devnum, struct device *dev)
{
struct snd_card *card;
@ -103,22 +105,22 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev)
hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
pcsp_chip.timer.function = pcsp_do_timer;
err = snd_card_new(dev, index, id, THIS_MODULE, 0, &card);
err = snd_devm_card_new(dev, index, id, THIS_MODULE, 0, &card);
if (err < 0)
return err;
err = snd_pcsp_create(card);
if (err < 0)
goto free_card;
return err;
if (!nopcm) {
err = snd_pcsp_new_pcm(&pcsp_chip);
if (err < 0)
goto free_card;
return err;
}
err = snd_pcsp_new_mixer(&pcsp_chip, nopcm);
if (err < 0)
goto free_card;
return err;
strcpy(card->driver, "PC-Speaker");
strcpy(card->shortname, "pcsp");
@ -127,13 +129,10 @@ static int snd_card_pcsp_probe(int devnum, struct device *dev)
err = snd_card_register(card);
if (err < 0)
goto free_card;
return err;
card->private_free = alsa_card_pcsp_free;
return 0;
free_card:
snd_card_free(card);
return err;
}
static int alsa_card_pcsp_init(struct device *dev)
@ -155,11 +154,6 @@ static int alsa_card_pcsp_init(struct device *dev)
return 0;
}
static void alsa_card_pcsp_exit(struct snd_pcsp *chip)
{
snd_card_free(chip->card);
}
static int pcsp_probe(struct platform_device *dev)
{
int err;
@ -169,23 +163,13 @@ static int pcsp_probe(struct platform_device *dev)
return err;
err = alsa_card_pcsp_init(&dev->dev);
if (err < 0) {
pcspkr_input_remove(pcsp_chip.input_dev);
if (err < 0)
return err;
}
platform_set_drvdata(dev, &pcsp_chip);
return 0;
}
static int pcsp_remove(struct platform_device *dev)
{
struct snd_pcsp *chip = platform_get_drvdata(dev);
pcspkr_input_remove(chip->input_dev);
alsa_card_pcsp_exit(chip);
return 0;
}
static void pcsp_stop_beep(struct snd_pcsp *chip)
{
pcsp_sync_stop(chip);
@ -218,7 +202,6 @@ static struct platform_driver pcsp_platform_driver = {
.pm = PCSP_PM_OPS,
},
.probe = pcsp_probe,
.remove = pcsp_remove,
.shutdown = pcsp_shutdown,
};

View File

@ -78,7 +78,7 @@ int pcspkr_input_init(struct input_dev **rdev, struct device *dev)
{
int err;
struct input_dev *input_dev = input_allocate_device();
struct input_dev *input_dev = devm_input_allocate_device(dev);
if (!input_dev)
return -ENOMEM;
@ -95,19 +95,9 @@ int pcspkr_input_init(struct input_dev **rdev, struct device *dev)
input_dev->event = pcspkr_input_event;
err = input_register_device(input_dev);
if (err) {
input_free_device(input_dev);
if (err)
return err;
}
*rdev = input_dev;
return 0;
}
int pcspkr_input_remove(struct input_dev *dev)
{
pcspkr_stop_sound();
input_unregister_device(dev); /* this also does kfree() */
return 0;
}

View File

@ -9,7 +9,6 @@
#define __PCSP_INPUT_H__
int pcspkr_input_init(struct input_dev **rdev, struct device *dev);
int pcspkr_input_remove(struct input_dev *dev);
void pcspkr_stop_sound(void);
#endif

View File

@ -115,7 +115,6 @@ struct snd_uart16550 {
int irq;
unsigned long base;
struct resource *res_base;
unsigned int speed;
unsigned int speed_base;
@ -323,8 +322,7 @@ static int snd_uart16550_detect(struct snd_uart16550 *uart)
return -ENODEV; /* Not configured */
}
uart->res_base = request_region(io_base, 8, "Serial MIDI");
if (uart->res_base == NULL) {
if (!devm_request_region(uart->card->dev, io_base, 8, "Serial MIDI")) {
snd_printk(KERN_ERR "u16550: can't grab port 0x%lx\n", io_base);
return -EBUSY;
}
@ -752,21 +750,6 @@ static const struct snd_rawmidi_ops snd_uart16550_input =
.trigger = snd_uart16550_input_trigger,
};
static int snd_uart16550_free(struct snd_uart16550 *uart)
{
if (uart->irq >= 0)
free_irq(uart->irq, uart);
release_and_free_resource(uart->res_base);
kfree(uart);
return 0;
};
static int snd_uart16550_dev_free(struct snd_device *device)
{
struct snd_uart16550 *uart = device->device_data;
return snd_uart16550_free(uart);
}
static int snd_uart16550_create(struct snd_card *card,
unsigned long iobase,
int irq,
@ -776,14 +759,11 @@ static int snd_uart16550_create(struct snd_card *card,
int droponfull,
struct snd_uart16550 **ruart)
{
static const struct snd_device_ops ops = {
.dev_free = snd_uart16550_dev_free,
};
struct snd_uart16550 *uart;
int err;
uart = kzalloc(sizeof(*uart), GFP_KERNEL);
uart = devm_kzalloc(card->dev, sizeof(*uart), GFP_KERNEL);
if (!uart)
return -ENOMEM;
uart->adaptor = adaptor;
@ -796,13 +776,12 @@ static int snd_uart16550_create(struct snd_card *card,
err = snd_uart16550_detect(uart);
if (err <= 0) {
printk(KERN_ERR "no UART detected at 0x%lx\n", iobase);
snd_uart16550_free(uart);
return -ENODEV;
}
if (irq >= 0 && irq != SNDRV_AUTO_IRQ) {
if (request_irq(irq, snd_uart16550_interrupt,
0, "Serial MIDI", uart)) {
if (devm_request_irq(card->dev, irq, snd_uart16550_interrupt,
0, "Serial MIDI", uart)) {
snd_printk(KERN_WARNING
"irq %d busy. Using Polling.\n", irq);
} else {
@ -819,13 +798,6 @@ static int snd_uart16550_create(struct snd_card *card,
timer_setup(&uart->buffer_timer, snd_uart16550_buffer_timer, 0);
uart->timer_running = 0;
/* Register device */
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, uart, &ops);
if (err < 0) {
snd_uart16550_free(uart);
return err;
}
switch (uart->adaptor) {
case SNDRV_SERIAL_MS124W_SA:
case SNDRV_SERIAL_MS124W_MB:
@ -927,8 +899,8 @@ static int snd_serial_probe(struct platform_device *devptr)
return -ENODEV;
}
err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
if (err < 0)
return err;
@ -939,11 +911,11 @@ static int snd_serial_probe(struct platform_device *devptr)
base[dev], adaptor[dev], droponfull[dev],
&uart);
if (err < 0)
goto _err;
return err;
err = snd_uart16550_rmidi(uart, 0, outs[dev], ins[dev], &uart->rmidi);
if (err < 0)
goto _err;
return err;
sprintf(card->longname, "%s [%s] at %#lx, irq %d",
card->shortname,
@ -953,27 +925,16 @@ static int snd_serial_probe(struct platform_device *devptr)
err = snd_card_register(card);
if (err < 0)
goto _err;
return err;
platform_set_drvdata(devptr, card);
return 0;
_err:
snd_card_free(card);
return err;
}
static int snd_serial_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
return 0;
}
#define SND_SERIAL_DRIVER "snd_serial_u16550"
static struct platform_driver snd_serial_driver = {
.probe = snd_serial_probe,
.remove = snd_serial_remove,
.driver = {
.name = SND_SERIAL_DRIVER,
},

View File

@ -75,8 +75,8 @@ static int snd_virmidi_probe(struct platform_device *devptr)
int idx, err;
int dev = devptr->id;
err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_virmidi), &card);
err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_virmidi), &card);
if (err < 0)
return err;
vmidi = card->private_data;
@ -94,7 +94,7 @@ static int snd_virmidi_probe(struct platform_device *devptr)
err = snd_virmidi_new(card, idx, &rmidi);
if (err < 0)
goto __nodev;
return err;
rdev = rmidi->private_data;
vmidi->midi[idx] = rmidi;
strcpy(rmidi->name, "Virtual Raw MIDI");
@ -106,18 +106,10 @@ static int snd_virmidi_probe(struct platform_device *devptr)
sprintf(card->longname, "Virtual MIDI Card %i", dev + 1);
err = snd_card_register(card);
if (!err) {
platform_set_drvdata(devptr, card);
return 0;
}
__nodev:
snd_card_free(card);
return err;
}
if (err)
return err;
static int snd_virmidi_remove(struct platform_device *devptr)
{
snd_card_free(platform_get_drvdata(devptr));
platform_set_drvdata(devptr, card);
return 0;
}
@ -125,7 +117,6 @@ static int snd_virmidi_remove(struct platform_device *devptr)
static struct platform_driver snd_virmidi_driver = {
.probe = snd_virmidi_probe,
.remove = snd_virmidi_remove,
.driver = {
.name = SND_VIRMIDI_DRIVER,
},

View File

@ -774,6 +774,11 @@ int snd_vx_resume(struct vx_core *chip)
EXPORT_SYMBOL(snd_vx_resume);
#endif
static void snd_vx_release(struct device *dev, void *data)
{
snd_vx_free_firmware(data);
}
/**
* snd_vx_create - constructor for struct vx_core
* @card: card instance
@ -784,6 +789,8 @@ EXPORT_SYMBOL(snd_vx_resume);
* this function allocates the instance and prepare for the hardware
* initialization.
*
* The object is managed via devres, and will be automatically released.
*
* return the instance pointer if successful, NULL in error.
*/
struct vx_core *snd_vx_create(struct snd_card *card,
@ -796,8 +803,9 @@ struct vx_core *snd_vx_create(struct snd_card *card,
if (snd_BUG_ON(!card || !hw || !ops))
return NULL;
chip = kzalloc(sizeof(*chip) + extra_size, GFP_KERNEL);
if (! chip)
chip = devres_alloc(snd_vx_release, sizeof(*chip) + extra_size,
GFP_KERNEL);
if (!chip)
return NULL;
mutex_init(&chip->lock);
chip->irq = -1;

View File

@ -12,11 +12,11 @@
#define V2_CLOCK_RATE_SHIFT 3
#define V2_CLOCK_SRC_MASK 0x00000007
#define V2_CLOCK_SRC_SHIFT 0
#define V2_CLOCK_SRC_AESEBU_ON_XLR 0x07
#define V2_CLOCK_SRC_AESEBU_ON_XLR 0x07 // In Traveler.
#define V2_CLOCK_SRC_ADAT_ON_DSUB 0x05
#define V2_CLOCK_SRC_WORD_ON_BNC 0x04
#define V2_CLOCK_SRC_SPH 0x03
#define V2_CLOCK_SRC_SPDIF 0x02 // on either coaxial or optical
#define V2_CLOCK_SRC_SPDIF 0x02 // on either coaxial or optical. AES/EBU in 896HD.
#define V2_CLOCK_SRC_ADAT_ON_OPT 0x01
#define V2_CLOCK_SRC_INTERNAL 0x00
#define V2_CLOCK_FETCH_ENABLE 0x02000000
@ -100,7 +100,9 @@ static int get_clock_source(struct snd_motu *motu, u32 data,
bool support_iec60958_on_opt = (motu->spec == &snd_motu_spec_828mk2 ||
motu->spec == &snd_motu_spec_traveler);
if (!support_iec60958_on_opt) {
if (motu->spec == &snd_motu_spec_896hd) {
*src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR;
} else if (!support_iec60958_on_opt) {
*src = SND_MOTU_CLOCK_SOURCE_SPDIF_ON_COAX;
} else {
__be32 reg;
@ -129,6 +131,7 @@ static int get_clock_source(struct snd_motu *motu, u32 data,
*src = SND_MOTU_CLOCK_SOURCE_ADAT_ON_DSUB;
break;
case V2_CLOCK_SRC_AESEBU_ON_XLR:
// For Traveler.
*src = SND_MOTU_CLOCK_SOURCE_AESEBU_ON_XLR;
break;
default:
@ -153,7 +156,7 @@ int snd_motu_protocol_v2_get_clock_source(struct snd_motu *motu,
return get_clock_source(motu, be32_to_cpu(reg), src);
}
// Expected for Traveler and 896HD, which implements Altera Cyclone EP1C3.
// Expected for Traveler, which implements Altera Cyclone EP1C3.
static int switch_fetching_mode_cyclone(struct snd_motu *motu, u32 *data,
bool enable)
{
@ -190,6 +193,9 @@ int snd_motu_protocol_v2_switch_fetching_mode(struct snd_motu *motu,
if (motu->spec == &snd_motu_spec_828mk2) {
// 828mkII implements Altera ACEX 1K EP1K30. Nothing to do.
return 0;
} else if (motu->spec == &snd_motu_spec_896hd) {
// 896HD implements Altera Cyclone EP1C3 but nothing to do.
return 0;
} else {
__be32 reg;
u32 data;
@ -274,6 +280,14 @@ const struct snd_motu_spec snd_motu_spec_828mk2 = {
.rx_fixed_pcm_chunks = {14, 14, 0},
};
const struct snd_motu_spec snd_motu_spec_896hd = {
.name = "896HD",
.protocol_version = SND_MOTU_PROTOCOL_V2,
// No support for MIDI.
.tx_fixed_pcm_chunks = {14, 14, 8},
.rx_fixed_pcm_chunks = {14, 14, 8},
};
const struct snd_motu_spec snd_motu_spec_traveler = {
.name = "Traveler",
.protocol_version = SND_MOTU_PROTOCOL_V2,

View File

@ -153,6 +153,7 @@ static const struct ieee1394_device_id motu_id_table[] = {
SND_MOTU_DEV_ENTRY(0x000001, &snd_motu_spec_828),
SND_MOTU_DEV_ENTRY(0x000002, &snd_motu_spec_896),
SND_MOTU_DEV_ENTRY(0x000003, &snd_motu_spec_828mk2),
SND_MOTU_DEV_ENTRY(0x000005, &snd_motu_spec_896hd),
SND_MOTU_DEV_ENTRY(0x000009, &snd_motu_spec_traveler),
SND_MOTU_DEV_ENTRY(0x00000d, &snd_motu_spec_ultralite),
SND_MOTU_DEV_ENTRY(0x00000f, &snd_motu_spec_8pre),

View File

@ -126,6 +126,7 @@ extern const struct snd_motu_spec snd_motu_spec_828;
extern const struct snd_motu_spec snd_motu_spec_896;
extern const struct snd_motu_spec snd_motu_spec_828mk2;
extern const struct snd_motu_spec snd_motu_spec_896hd;
extern const struct snd_motu_spec snd_motu_spec_traveler;
extern const struct snd_motu_spec snd_motu_spec_ultralite;
extern const struct snd_motu_spec snd_motu_spec_8pre;

View File

@ -124,28 +124,24 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
struct snd_ad1816a *chip;
struct snd_opl3 *opl3;
error = snd_card_new(&pcard->card->dev,
index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_ad1816a), &card);
error = snd_devm_card_new(&pcard->card->dev,
index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_ad1816a), &card);
if (error < 0)
return error;
chip = card->private_data;
error = snd_card_ad1816a_pnp(dev, pcard, pid);
if (error) {
snd_card_free(card);
if (error)
return error;
}
error = snd_ad1816a_create(card, port[dev],
irq[dev],
dma1[dev],
dma2[dev],
chip);
if (error) {
snd_card_free(card);
if (error)
return error;
}
if (clockfreq[dev] >= 5000 && clockfreq[dev] <= 100000)
chip->clock_freq = clockfreq[dev];
@ -155,22 +151,16 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);
error = snd_ad1816a_pcm(chip, 0);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_ad1816a_mixer(chip);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_ad1816a_timer(chip, 0);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
if (mpu_port[dev] > 0) {
if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
@ -186,18 +176,14 @@ static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx.\n", fm_port[dev], fm_port[dev] + 2);
} else {
error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
}
}
error = snd_card_register(card);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
pnp_set_card_drvdata(pcard, card);
return 0;
}
@ -223,12 +209,6 @@ static int snd_ad1816a_pnp_detect(struct pnp_card_link *card,
return -ENODEV;
}
static void snd_ad1816a_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_ad1816a_pnp_suspend(struct pnp_card_link *pcard,
pm_message_t state)
@ -255,7 +235,6 @@ static struct pnp_card_driver ad1816a_pnpc_driver = {
.name = "ad1816a",
.id_table = snd_ad1816a_pnpids,
.probe = snd_ad1816a_pnp_detect,
.remove = snd_ad1816a_pnp_remove,
#ifdef CONFIG_PM
.suspend = snd_ad1816a_pnp_suspend,
.resume = snd_ad1816a_pnp_resume,

View File

@ -541,28 +541,6 @@ static int snd_ad1816a_probe(struct snd_ad1816a *chip)
return 0;
}
static int snd_ad1816a_free(struct snd_ad1816a *chip)
{
release_and_free_resource(chip->res_port);
if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip);
if (chip->dma1 >= 0) {
snd_dma_disable(chip->dma1);
free_dma(chip->dma1);
}
if (chip->dma2 >= 0) {
snd_dma_disable(chip->dma2);
free_dma(chip->dma2);
}
return 0;
}
static int snd_ad1816a_dev_free(struct snd_device *device)
{
struct snd_ad1816a *chip = device->device_data;
return snd_ad1816a_free(chip);
}
static const char *snd_ad1816a_chip_id(struct snd_ad1816a *chip)
{
switch (chip->hardware) {
@ -580,37 +558,31 @@ int snd_ad1816a_create(struct snd_card *card,
unsigned long port, int irq, int dma1, int dma2,
struct snd_ad1816a *chip)
{
static const struct snd_device_ops ops = {
.dev_free = snd_ad1816a_dev_free,
};
int error;
chip->irq = -1;
chip->dma1 = -1;
chip->dma2 = -1;
chip->res_port = request_region(port, 16, "AD1816A");
chip->res_port = devm_request_region(card->dev, port, 16, "AD1816A");
if (!chip->res_port) {
snd_printk(KERN_ERR "ad1816a: can't grab port 0x%lx\n", port);
snd_ad1816a_free(chip);
return -EBUSY;
}
if (request_irq(irq, snd_ad1816a_interrupt, 0, "AD1816A", (void *) chip)) {
if (devm_request_irq(card->dev, irq, snd_ad1816a_interrupt, 0,
"AD1816A", (void *) chip)) {
snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq);
snd_ad1816a_free(chip);
return -EBUSY;
}
chip->irq = irq;
card->sync_irq = chip->irq;
if (request_dma(dma1, "AD1816A - 1")) {
if (snd_devm_request_dma(card->dev, dma1, "AD1816A - 1")) {
snd_printk(KERN_ERR "ad1816a: can't grab DMA1 %d\n", dma1);
snd_ad1816a_free(chip);
return -EBUSY;
}
chip->dma1 = dma1;
if (request_dma(dma2, "AD1816A - 2")) {
if (snd_devm_request_dma(card->dev, dma2, "AD1816A - 2")) {
snd_printk(KERN_ERR "ad1816a: can't grab DMA2 %d\n", dma2);
snd_ad1816a_free(chip);
return -EBUSY;
}
chip->dma2 = dma2;
@ -620,20 +592,11 @@ int snd_ad1816a_create(struct snd_card *card,
spin_lock_init(&chip->lock);
error = snd_ad1816a_probe(chip);
if (error) {
snd_ad1816a_free(chip);
if (error)
return error;
}
snd_ad1816a_init(chip);
/* Register device */
error = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (error < 0) {
snd_ad1816a_free(chip);
return error;
}
return 0;
}

View File

@ -72,7 +72,7 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n)
struct snd_wss *chip;
int error;
error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
error = snd_devm_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
if (error < 0)
return error;
@ -80,17 +80,17 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n)
thinkpad[n] ? WSS_HW_THINKPAD : WSS_HW_DETECT,
0, &chip);
if (error < 0)
goto out;
return error;
card->private_data = chip;
error = snd_wss_pcm(chip, 0);
if (error < 0)
goto out;
return error;
error = snd_wss_mixer(chip);
if (error < 0)
goto out;
return error;
strscpy(card->driver, "AD1848", sizeof(card->driver));
strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname));
@ -106,18 +106,10 @@ static int snd_ad1848_probe(struct device *dev, unsigned int n)
error = snd_card_register(card);
if (error < 0)
goto out;
return error;
dev_set_drvdata(dev, card);
return 0;
out: snd_card_free(card);
return error;
}
static void snd_ad1848_remove(struct device *dev, unsigned int n)
{
snd_card_free(dev_get_drvdata(dev));
}
#ifdef CONFIG_PM
@ -145,7 +137,6 @@ static int snd_ad1848_resume(struct device *dev, unsigned int n)
static struct isa_driver snd_ad1848_driver = {
.match = snd_ad1848_match,
.probe = snd_ad1848_probe,
.remove = snd_ad1848_remove,
#ifdef CONFIG_PM
.suspend = snd_ad1848_suspend,
.resume = snd_ad1848_resume,

View File

@ -43,30 +43,23 @@ static int snd_adlib_match(struct device *dev, unsigned int n)
return 1;
}
static void snd_adlib_free(struct snd_card *card)
{
release_and_free_resource(card->private_data);
}
static int snd_adlib_probe(struct device *dev, unsigned int n)
{
struct snd_card *card;
struct snd_opl3 *opl3;
int error;
error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
error = snd_devm_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
if (error < 0) {
dev_err(dev, "could not create card\n");
return error;
}
card->private_data = request_region(port[n], 4, CRD_NAME);
card->private_data = devm_request_region(dev, port[n], 4, CRD_NAME);
if (!card->private_data) {
dev_err(dev, "could not grab ports\n");
error = -EBUSY;
goto out;
return -EBUSY;
}
card->private_free = snd_adlib_free;
strcpy(card->driver, DEV_NAME);
strcpy(card->shortname, CRD_NAME);
@ -75,37 +68,28 @@ static int snd_adlib_probe(struct device *dev, unsigned int n)
error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
if (error < 0) {
dev_err(dev, "could not create OPL\n");
goto out;
return error;
}
error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
if (error < 0) {
dev_err(dev, "could not create FM\n");
goto out;
return error;
}
error = snd_card_register(card);
if (error < 0) {
dev_err(dev, "could not register card\n");
goto out;
return error;
}
dev_set_drvdata(dev, card);
return 0;
out: snd_card_free(card);
return error;
}
static void snd_adlib_remove(struct device *dev, unsigned int n)
{
snd_card_free(dev_get_drvdata(dev));
}
static struct isa_driver snd_adlib_driver = {
.match = snd_adlib_match,
.probe = snd_adlib_probe,
.remove = snd_adlib_remove,
.driver = {
.name = DEV_NAME

View File

@ -170,18 +170,16 @@ static int snd_card_als100_probe(int dev,
struct snd_card_als100 *acard;
struct snd_opl3 *opl3;
error = snd_card_new(&pcard->card->dev,
index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_als100), &card);
error = snd_devm_card_new(&pcard->card->dev,
index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_als100), &card);
if (error < 0)
return error;
acard = card->private_data;
error = snd_card_als100_pnp(dev, acard, pcard, pid);
if (error) {
snd_card_free(card);
if (error)
return error;
}
if (pid->driver_data == SB_HW_DT019X)
dma16[dev] = -1;
@ -191,10 +189,8 @@ static int snd_card_als100_probe(int dev,
dma8[dev], dma16[dev],
pid->driver_data,
&chip);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
acard->chip = chip;
if (pid->driver_data == SB_HW_DT019X) {
@ -213,16 +209,12 @@ static int snd_card_als100_probe(int dev,
}
error = snd_sb16dsp_pcm(chip, 0);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_sbmixer_new(chip);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
int mpu_type = MPU401_HW_ALS100;
@ -249,23 +241,17 @@ static int snd_card_als100_probe(int dev,
fm_port[dev], fm_port[dev] + 2);
} else {
error = snd_opl3_timer_new(opl3, 0, 1);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
}
}
error = snd_card_register(card);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
pnp_set_card_drvdata(pcard, card);
return 0;
}
@ -291,12 +277,6 @@ static int snd_als100_pnp_detect(struct pnp_card_link *card,
return -ENODEV;
}
static void snd_als100_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_als100_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
{
@ -327,7 +307,6 @@ static struct pnp_card_driver als100_pnpc_driver = {
.name = "als100",
.id_table = snd_als100_pnpids,
.probe = snd_als100_pnp_detect,
.remove = snd_als100_pnp_remove,
#ifdef CONFIG_PM
.suspend = snd_als100_pnp_suspend,
.resume = snd_als100_pnp_resume,

View File

@ -169,33 +169,27 @@ static int snd_card_azt2320_probe(int dev,
struct snd_wss *chip;
struct snd_opl3 *opl3;
error = snd_card_new(&pcard->card->dev,
index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_azt2320), &card);
error = snd_devm_card_new(&pcard->card->dev,
index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_azt2320), &card);
if (error < 0)
return error;
acard = card->private_data;
error = snd_card_azt2320_pnp(dev, acard, pcard, pid);
if (error) {
snd_card_free(card);
if (error)
return error;
}
error = snd_card_azt2320_enable_wss(port[dev]);
if (error) {
snd_card_free(card);
if (error)
return error;
}
error = snd_wss_create(card, wss_port[dev], -1,
irq[dev],
dma1[dev], dma2[dev],
WSS_HW_DETECT, 0, &chip);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
strcpy(card->driver, "AZT2320");
strcpy(card->shortname, "Aztech AZT2320");
@ -203,20 +197,14 @@ static int snd_card_azt2320_probe(int dev,
card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);
error = snd_wss_pcm(chip, 0);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_wss_mixer(chip);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_wss_timer(chip, 0);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
if (snd_mpu401_uart_new(card, 0, MPU401_HW_AZT2320,
@ -233,23 +221,17 @@ static int snd_card_azt2320_probe(int dev,
fm_port[dev], fm_port[dev] + 2);
} else {
error = snd_opl3_timer_new(opl3, 1, 2);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
}
}
error = snd_card_register(card);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
pnp_set_card_drvdata(pcard, card);
return 0;
}
@ -275,12 +257,6 @@ static int snd_azt2320_pnp_detect(struct pnp_card_link *card,
return -ENODEV;
}
static void snd_azt2320_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_azt2320_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
{
@ -310,7 +286,6 @@ static struct pnp_card_driver azt2320_pnpc_driver = {
.name = "azt2320",
.id_table = snd_azt2320_pnpids,
.probe = snd_azt2320_pnp_detect,
.remove = snd_azt2320_pnp_remove,
#ifdef CONFIG_PM
.suspend = snd_azt2320_pnp_suspend,
.resume = snd_azt2320_pnp_resume,

View File

@ -294,8 +294,8 @@ static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
}
outb(val, port);
err = snd_card_new(pdev, index[ndev], id[ndev], THIS_MODULE,
sizeof(struct snd_cmi8328), &card);
err = snd_devm_card_new(pdev, index[ndev], id[ndev], THIS_MODULE,
sizeof(struct snd_cmi8328), &card);
if (err < 0)
return err;
cmi = card->private_data;
@ -306,18 +306,18 @@ static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
err = snd_wss_create(card, port + 4, -1, irq[ndev], dma1[ndev],
dma2[ndev], WSS_HW_DETECT, 0, &cmi->wss);
if (err < 0)
goto error;
return err;
err = snd_wss_pcm(cmi->wss, 0);
if (err < 0)
goto error;
return err;
err = snd_wss_mixer(cmi->wss);
if (err < 0)
goto error;
return err;
err = snd_cmi8328_mixer(cmi->wss);
if (err < 0)
goto error;
return err;
if (snd_wss_timer(cmi->wss, 0) < 0)
snd_printk(KERN_WARNING "error initializing WSS timer\n");
@ -371,24 +371,21 @@ static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
dev_set_drvdata(pdev, card);
err = snd_card_register(card);
if (err < 0)
goto error;
return err;
#ifdef SUPPORT_JOYSTICK
if (!gameport[ndev])
return 0;
/* gameport is hardwired to 0x200 */
res = request_region(0x200, 8, "CMI8328 gameport");
res = devm_request_region(pdev, 0x200, 8, "CMI8328 gameport");
if (!res)
snd_printk(KERN_WARNING "unable to allocate gameport I/O port\n");
else {
struct gameport *gp = cmi->gameport = gameport_allocate_port();
if (!cmi->gameport)
release_and_free_resource(res);
else {
if (cmi->gameport) {
gameport_set_name(gp, "CMI8328 Gameport");
gameport_set_phys(gp, "%s/gameport0", dev_name(pdev));
gameport_set_dev_parent(gp, pdev);
gp->io = 0x200;
gameport_set_port_data(gp, res);
/* Enable gameport */
snd_cmi8328_cfg_write(port, CFG1,
CFG1_SB_DISABLE | CFG1_GAMEPORT);
@ -397,10 +394,6 @@ static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
}
#endif
return 0;
error:
snd_card_free(card);
return err;
}
static void snd_cmi8328_remove(struct device *pdev, unsigned int dev)
@ -409,17 +402,13 @@ static void snd_cmi8328_remove(struct device *pdev, unsigned int dev)
struct snd_cmi8328 *cmi = card->private_data;
#ifdef SUPPORT_JOYSTICK
if (cmi->gameport) {
struct resource *res = gameport_get_port_data(cmi->gameport);
if (cmi->gameport)
gameport_unregister_port(cmi->gameport);
release_and_free_resource(res);
}
#endif
/* disable everything */
snd_cmi8328_cfg_write(cmi->port, CFG1, CFG1_SB_DISABLE);
snd_cmi8328_cfg_write(cmi->port, CFG2, 0);
snd_cmi8328_cfg_write(cmi->port, CFG3, 0);
snd_card_free(card);
}
#ifdef CONFIG_PM

View File

@ -507,8 +507,8 @@ static int snd_cmi8330_card_new(struct device *pdev, int dev,
struct snd_cmi8330 *acard;
int err;
err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_cmi8330), &card);
err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_cmi8330), &card);
if (err < 0) {
snd_printk(KERN_ERR PFX "could not get a new card\n");
return err;
@ -629,20 +629,12 @@ static int snd_cmi8330_isa_probe(struct device *pdev,
if (err < 0)
return err;
err = snd_cmi8330_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
dev_set_drvdata(pdev, card);
return 0;
}
static void snd_cmi8330_isa_remove(struct device *devptr,
unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
#ifdef CONFIG_PM
static int snd_cmi8330_isa_suspend(struct device *dev, unsigned int n,
pm_message_t state)
@ -661,7 +653,6 @@ static int snd_cmi8330_isa_resume(struct device *dev, unsigned int n)
static struct isa_driver snd_cmi8330_driver = {
.match = snd_cmi8330_isa_match,
.probe = snd_cmi8330_isa_probe,
.remove = snd_cmi8330_isa_remove,
#ifdef CONFIG_PM
.suspend = snd_cmi8330_isa_suspend,
.resume = snd_cmi8330_isa_resume,
@ -693,25 +684,16 @@ static int snd_cmi8330_pnp_detect(struct pnp_card_link *pcard,
res = snd_cmi8330_pnp(dev, card->private_data, pcard, pid);
if (res < 0) {
snd_printk(KERN_ERR PFX "PnP detection failed\n");
snd_card_free(card);
return res;
}
res = snd_cmi8330_probe(card, dev);
if (res < 0) {
snd_card_free(card);
if (res < 0)
return res;
}
pnp_set_card_drvdata(pcard, card);
dev++;
return 0;
}
static void snd_cmi8330_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_cmi8330_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
{
@ -729,7 +711,6 @@ static struct pnp_card_driver cmi8330_pnpc_driver = {
.name = "cmi8330",
.id_table = snd_cmi8330_pnpids,
.probe = snd_cmi8330_pnp_detect,
.remove = snd_cmi8330_pnp_remove,
#ifdef CONFIG_PM
.suspend = snd_cmi8330_pnp_suspend,
.resume = snd_cmi8330_pnp_resume,

View File

@ -79,20 +79,20 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n)
struct snd_wss *chip;
int error;
error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
error = snd_devm_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
if (error < 0)
return error;
error = snd_wss_create(card, port[n], -1, irq[n], dma1[n], dma2[n],
WSS_HW_DETECT, 0, &chip);
if (error < 0)
goto out;
return error;
card->private_data = chip;
error = snd_wss_pcm(chip, 0);
if (error < 0)
goto out;
return error;
strscpy(card->driver, "CS4231", sizeof(card->driver));
strscpy(card->shortname, chip->pcm->name, sizeof(card->shortname));
@ -108,11 +108,11 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n)
error = snd_wss_mixer(chip);
if (error < 0)
goto out;
return error;
error = snd_wss_timer(chip, 0);
if (error < 0)
goto out;
return error;
if (mpu_port[n] > 0 && mpu_port[n] != SNDRV_AUTO_PORT) {
if (mpu_irq[n] == SNDRV_AUTO_IRQ)
@ -125,18 +125,10 @@ static int snd_cs4231_probe(struct device *dev, unsigned int n)
error = snd_card_register(card);
if (error < 0)
goto out;
return error;
dev_set_drvdata(dev, card);
return 0;
out: snd_card_free(card);
return error;
}
static void snd_cs4231_remove(struct device *dev, unsigned int n)
{
snd_card_free(dev_get_drvdata(dev));
}
#ifdef CONFIG_PM
@ -164,7 +156,6 @@ static int snd_cs4231_resume(struct device *dev, unsigned int n)
static struct isa_driver snd_cs4231_driver = {
.match = snd_cs4231_match,
.probe = snd_cs4231_probe,
.remove = snd_cs4231_remove,
#ifdef CONFIG_PM
.suspend = snd_cs4231_suspend,
.resume = snd_cs4231_resume,

View File

@ -76,7 +76,6 @@ static int pnp_registered;
struct snd_card_cs4236 {
struct snd_wss *chip;
struct resource *res_sb_port;
#ifdef CONFIG_PNP
struct pnp_dev *wss;
struct pnp_dev *ctrl;
@ -309,24 +308,16 @@ static int snd_card_cs423x_pnpc(int dev, struct snd_card_cs4236 *acard,
#define is_isapnp_selected(dev) 0
#endif
static void snd_card_cs4236_free(struct snd_card *card)
{
struct snd_card_cs4236 *acard = card->private_data;
release_and_free_resource(acard->res_sb_port);
}
static int snd_cs423x_card_new(struct device *pdev, int dev,
struct snd_card **cardp)
{
struct snd_card *card;
int err;
err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_cs4236), &card);
err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_cs4236), &card);
if (err < 0)
return err;
card->private_free = snd_card_cs4236_free;
*cardp = card;
return 0;
}
@ -340,8 +331,8 @@ static int snd_cs423x_probe(struct snd_card *card, int dev)
acard = card->private_data;
if (sb_port[dev] > 0 && sb_port[dev] != SNDRV_AUTO_PORT) {
acard->res_sb_port = request_region(sb_port[dev], 16, IDENT " SB");
if (!acard->res_sb_port) {
if (!devm_request_region(card->dev, sb_port[dev], 16,
IDENT " SB")) {
printk(KERN_ERR IDENT ": unable to register SB port at 0x%lx\n", sb_port[dev]);
return -EBUSY;
}
@ -448,21 +439,12 @@ static int snd_cs423x_isa_probe(struct device *pdev,
if (err < 0)
return err;
err = snd_cs423x_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
dev_set_drvdata(pdev, card);
return 0;
}
static void snd_cs423x_isa_remove(struct device *pdev,
unsigned int dev)
{
snd_card_free(dev_get_drvdata(pdev));
}
#ifdef CONFIG_PM
static int snd_cs423x_suspend(struct snd_card *card)
{
@ -495,7 +477,6 @@ static int snd_cs423x_isa_resume(struct device *dev, unsigned int n)
static struct isa_driver cs423x_isa_driver = {
.match = snd_cs423x_isa_match,
.probe = snd_cs423x_isa_probe,
.remove = snd_cs423x_isa_remove,
#ifdef CONFIG_PM
.suspend = snd_cs423x_isa_suspend,
.resume = snd_cs423x_isa_resume,
@ -539,24 +520,16 @@ static int snd_cs423x_pnpbios_detect(struct pnp_dev *pdev,
err = snd_card_cs423x_pnp(dev, card->private_data, pdev, cdev);
if (err < 0) {
printk(KERN_ERR "PnP BIOS detection failed for " IDENT "\n");
snd_card_free(card);
return err;
}
err = snd_cs423x_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
pnp_set_drvdata(pdev, card);
dev++;
return 0;
}
static void snd_cs423x_pnp_remove(struct pnp_dev *pdev)
{
snd_card_free(pnp_get_drvdata(pdev));
}
#ifdef CONFIG_PM
static int snd_cs423x_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
{
@ -573,7 +546,6 @@ static struct pnp_driver cs423x_pnp_driver = {
.name = "cs423x-pnpbios",
.id_table = snd_cs423x_pnpbiosids,
.probe = snd_cs423x_pnpbios_detect,
.remove = snd_cs423x_pnp_remove,
#ifdef CONFIG_PM
.suspend = snd_cs423x_pnp_suspend,
.resume = snd_cs423x_pnp_resume,
@ -601,25 +573,16 @@ static int snd_cs423x_pnpc_detect(struct pnp_card_link *pcard,
if (res < 0) {
printk(KERN_ERR "isapnp detection failed and probing for " IDENT
" is not supported\n");
snd_card_free(card);
return res;
}
res = snd_cs423x_probe(card, dev);
if (res < 0) {
snd_card_free(card);
if (res < 0)
return res;
}
pnp_set_card_drvdata(pcard, card);
dev++;
return 0;
}
static void snd_cs423x_pnpc_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_cs423x_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
{
@ -637,7 +600,6 @@ static struct pnp_card_driver cs423x_pnpc_driver = {
.name = CS423X_ISAPNP_DRIVER,
.id_table = snd_cs423x_pnpids,
.probe = snd_cs423x_pnpc_detect,
.remove = snd_cs423x_pnpc_remove,
#ifdef CONFIG_PM
.suspend = snd_cs423x_pnpc_suspend,
.resume = snd_cs423x_pnpc_resume,

View File

@ -298,7 +298,6 @@ int snd_cs4236_create(struct snd_card *card,
if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR "please, specify control port "
"for CS4236+ chips\n");
snd_device_free(card, chip);
return -ENODEV;
}
ver1 = snd_cs4236_ctrl_in(chip, 1);
@ -308,7 +307,6 @@ int snd_cs4236_create(struct snd_card *card,
if (ver1 != ver2) {
snd_printk(KERN_ERR "CS4236+ chip detected, but "
"control port 0x%lx is not valid\n", cport);
snd_device_free(card, chip);
return -ENODEV;
}
snd_cs4236_ctrl_out(chip, 0, 0x00);

View File

@ -166,36 +166,27 @@ static int snd_es1688_isa_probe(struct device *dev, unsigned int n)
struct snd_card *card;
int error;
error = snd_card_new(dev, index[n], id[n], THIS_MODULE,
sizeof(struct snd_es1688), &card);
error = snd_devm_card_new(dev, index[n], id[n], THIS_MODULE,
sizeof(struct snd_es1688), &card);
if (error < 0)
return error;
error = snd_es1688_legacy_create(card, dev, n);
if (error < 0)
goto out;
return error;
error = snd_es1688_probe(card, n);
if (error < 0)
goto out;
return error;
dev_set_drvdata(dev, card);
return 0;
out:
snd_card_free(card);
return error;
}
static void snd_es1688_isa_remove(struct device *dev, unsigned int n)
{
snd_card_free(dev_get_drvdata(dev));
}
static struct isa_driver snd_es1688_driver = {
.match = snd_es1688_match,
.probe = snd_es1688_isa_probe,
.remove = snd_es1688_isa_remove,
#if 0 /* FIXME */
.suspend = snd_es1688_suspend,
.resume = snd_es1688_resume,
@ -249,22 +240,18 @@ static int snd_es968_pnp_detect(struct pnp_card_link *pcard,
if (dev == SNDRV_CARDS)
return -ENODEV;
error = snd_card_new(&pcard->card->dev,
index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_es1688), &card);
error = snd_devm_card_new(&pcard->card->dev,
index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_es1688), &card);
if (error < 0)
return error;
error = snd_card_es968_pnp(card, dev, pcard, pid);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_es1688_probe(card, dev);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
pnp_set_card_drvdata(pcard, card);
snd_es968_pnp_is_probed = 1;
return 0;
@ -272,8 +259,6 @@ static int snd_es968_pnp_detect(struct pnp_card_link *pcard,
static void snd_es968_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
snd_es968_pnp_is_probed = 0;
}

View File

@ -87,9 +87,6 @@
struct snd_es18xx {
unsigned long port; /* port of ESS chip */
unsigned long ctrl_port; /* Control port of ESS chip */
struct resource *res_port;
struct resource *res_mpu_port;
struct resource *res_ctrl_port;
int irq; /* IRQ number of ESS chip */
int dma1; /* DMA1 */
int dma2; /* DMA2 */
@ -1531,7 +1528,7 @@ static int snd_es18xx_initialize(struct snd_es18xx *chip,
return 0;
}
static int snd_es18xx_identify(struct snd_es18xx *chip)
static int snd_es18xx_identify(struct snd_card *card, struct snd_es18xx *chip)
{
int hi,lo;
@ -1573,8 +1570,8 @@ static int snd_es18xx_identify(struct snd_es18xx *chip)
udelay(10);
chip->ctrl_port += inb(chip->port + 0x05);
chip->res_ctrl_port = request_region(chip->ctrl_port, 8, "ES18xx - CTRL");
if (!chip->res_ctrl_port) {
if (!devm_request_region(card->dev, chip->ctrl_port, 8,
"ES18xx - CTRL")) {
snd_printk(KERN_ERR PFX "unable go grab port 0x%lx\n", chip->ctrl_port);
return -EBUSY;
}
@ -1601,11 +1598,12 @@ static int snd_es18xx_identify(struct snd_es18xx *chip)
return 0;
}
static int snd_es18xx_probe(struct snd_es18xx *chip,
static int snd_es18xx_probe(struct snd_card *card,
struct snd_es18xx *chip,
unsigned long mpu_port,
unsigned long fm_port)
{
if (snd_es18xx_identify(chip) < 0) {
if (snd_es18xx_identify(card, chip) < 0) {
snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
return -ENODEV;
}
@ -1722,31 +1720,6 @@ static int snd_es18xx_resume(struct snd_card *card)
}
#endif /* CONFIG_PM */
static int snd_es18xx_free(struct snd_card *card)
{
struct snd_es18xx *chip = card->private_data;
release_and_free_resource(chip->res_port);
release_and_free_resource(chip->res_ctrl_port);
release_and_free_resource(chip->res_mpu_port);
if (chip->irq >= 0)
free_irq(chip->irq, (void *) card);
if (chip->dma1 >= 0) {
disable_dma(chip->dma1);
free_dma(chip->dma1);
}
if (chip->dma2 >= 0 && chip->dma1 != chip->dma2) {
disable_dma(chip->dma2);
free_dma(chip->dma2);
}
return 0;
}
static int snd_es18xx_dev_free(struct snd_device *device)
{
return snd_es18xx_free(device->card);
}
static int snd_es18xx_new_device(struct snd_card *card,
unsigned long port,
unsigned long mpu_port,
@ -1754,10 +1727,6 @@ static int snd_es18xx_new_device(struct snd_card *card,
int irq, int dma1, int dma2)
{
struct snd_es18xx *chip = card->private_data;
static const struct snd_device_ops ops = {
.dev_free = snd_es18xx_dev_free,
};
int err;
spin_lock_init(&chip->reg_lock);
spin_lock_init(&chip->mixer_lock);
@ -1768,45 +1737,34 @@ static int snd_es18xx_new_device(struct snd_card *card,
chip->audio2_vol = 0x00;
chip->active = 0;
chip->res_port = request_region(port, 16, "ES18xx");
if (chip->res_port == NULL) {
snd_es18xx_free(card);
if (!devm_request_region(card->dev, port, 16, "ES18xx")) {
snd_printk(KERN_ERR PFX "unable to grap ports 0x%lx-0x%lx\n", port, port + 16 - 1);
return -EBUSY;
}
if (request_irq(irq, snd_es18xx_interrupt, 0, "ES18xx",
(void *) card)) {
snd_es18xx_free(card);
if (devm_request_irq(card->dev, irq, snd_es18xx_interrupt, 0, "ES18xx",
(void *) card)) {
snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq);
return -EBUSY;
}
chip->irq = irq;
card->sync_irq = chip->irq;
if (request_dma(dma1, "ES18xx DMA 1")) {
snd_es18xx_free(card);
if (snd_devm_request_dma(card->dev, dma1, "ES18xx DMA 1")) {
snd_printk(KERN_ERR PFX "unable to grap DMA1 %d\n", dma1);
return -EBUSY;
}
chip->dma1 = dma1;
if (dma2 != dma1 && request_dma(dma2, "ES18xx DMA 2")) {
snd_es18xx_free(card);
if (dma2 != dma1 &&
snd_devm_request_dma(card->dev, dma2, "ES18xx DMA 2")) {
snd_printk(KERN_ERR PFX "unable to grap DMA2 %d\n", dma2);
return -EBUSY;
}
chip->dma2 = dma2;
if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) {
snd_es18xx_free(card);
if (snd_es18xx_probe(card, chip, mpu_port, fm_port) < 0)
return -ENODEV;
}
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_es18xx_free(card);
return err;
}
return 0;
}
@ -2088,8 +2046,8 @@ static int snd_audiodrive_pnpc(int dev, struct snd_es18xx *chip,
static int snd_es18xx_card_new(struct device *pdev, int dev,
struct snd_card **cardp)
{
return snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_es18xx), cardp);
return snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_es18xx), cardp);
}
static int snd_audiodrive_probe(struct snd_card *card, int dev)
@ -2164,10 +2122,8 @@ static int snd_es18xx_isa_probe1(int dev, struct device *devptr)
if (err < 0)
return err;
err = snd_audiodrive_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
dev_set_drvdata(devptr, card);
return 0;
}
@ -2215,12 +2171,6 @@ static int snd_es18xx_isa_probe(struct device *pdev, unsigned int dev)
}
}
static void snd_es18xx_isa_remove(struct device *devptr,
unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
#ifdef CONFIG_PM
static int snd_es18xx_isa_suspend(struct device *dev, unsigned int n,
pm_message_t state)
@ -2239,7 +2189,6 @@ static int snd_es18xx_isa_resume(struct device *dev, unsigned int n)
static struct isa_driver snd_es18xx_isa_driver = {
.match = snd_es18xx_isa_match,
.probe = snd_es18xx_isa_probe,
.remove = snd_es18xx_isa_remove,
#ifdef CONFIG_PM
.suspend = snd_es18xx_isa_suspend,
.resume = snd_es18xx_isa_resume,
@ -2271,25 +2220,16 @@ static int snd_audiodrive_pnp_detect(struct pnp_dev *pdev,
if (err < 0)
return err;
err = snd_audiodrive_pnp(dev, card->private_data, pdev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_audiodrive_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
pnp_set_drvdata(pdev, card);
dev++;
return 0;
}
static void snd_audiodrive_pnp_remove(struct pnp_dev *pdev)
{
snd_card_free(pnp_get_drvdata(pdev));
}
#ifdef CONFIG_PM
static int snd_audiodrive_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
{
@ -2305,7 +2245,6 @@ static struct pnp_driver es18xx_pnp_driver = {
.name = "es18xx-pnpbios",
.id_table = snd_audiodrive_pnpbiosids,
.probe = snd_audiodrive_pnp_detect,
.remove = snd_audiodrive_pnp_remove,
#ifdef CONFIG_PM
.suspend = snd_audiodrive_pnp_suspend,
.resume = snd_audiodrive_pnp_resume,
@ -2331,27 +2270,17 @@ static int snd_audiodrive_pnpc_detect(struct pnp_card_link *pcard,
return res;
res = snd_audiodrive_pnpc(dev, card->private_data, pcard, pid);
if (res < 0) {
snd_card_free(card);
if (res < 0)
return res;
}
res = snd_audiodrive_probe(card, dev);
if (res < 0) {
snd_card_free(card);
if (res < 0)
return res;
}
pnp_set_card_drvdata(pcard, card);
dev++;
return 0;
}
static void snd_audiodrive_pnpc_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_audiodrive_pnpc_suspend(struct pnp_card_link *pcard, pm_message_t state)
{
@ -2370,7 +2299,6 @@ static struct pnp_card_driver es18xx_pnpc_driver = {
.name = "es18xx",
.id_table = snd_audiodrive_pnpids,
.probe = snd_audiodrive_pnpc_detect,
.remove = snd_audiodrive_pnpc_remove,
#ifdef CONFIG_PM
.suspend = snd_audiodrive_pnpc_suspend,
.resume = snd_audiodrive_pnpc_resume,

View File

@ -472,20 +472,10 @@ static void snd_galaxy_free(struct snd_card *card)
{
struct snd_galaxy *galaxy = card->private_data;
if (galaxy->wss_port) {
if (galaxy->wss_port)
wss_set_config(galaxy->wss_port, 0);
ioport_unmap(galaxy->wss_port);
release_and_free_resource(galaxy->res_wss_port);
}
if (galaxy->config_port) {
if (galaxy->config_port)
galaxy_set_config(galaxy, galaxy->config);
ioport_unmap(galaxy->config_port);
release_and_free_resource(galaxy->res_config_port);
}
if (galaxy->port) {
ioport_unmap(galaxy->port);
release_and_free_resource(galaxy->res_port);
}
}
static int snd_galaxy_probe(struct device *dev, unsigned int n)
@ -496,56 +486,60 @@ static int snd_galaxy_probe(struct device *dev, unsigned int n)
u8 type;
int err;
err = snd_card_new(dev, index[n], id[n], THIS_MODULE,
sizeof(*galaxy), &card);
err = snd_devm_card_new(dev, index[n], id[n], THIS_MODULE,
sizeof(*galaxy), &card);
if (err < 0)
return err;
card->private_free = snd_galaxy_free;
galaxy = card->private_data;
galaxy->res_port = request_region(port[n], 16, DRV_NAME);
galaxy->res_port = devm_request_region(dev, port[n], 16, DRV_NAME);
if (!galaxy->res_port) {
dev_err(dev, "could not grab ports %#lx-%#lx\n", port[n],
port[n] + 15);
err = -EBUSY;
goto error;
return -EBUSY;
}
galaxy->port = ioport_map(port[n], 16);
galaxy->port = devm_ioport_map(dev, port[n], 16);
if (!galaxy->port)
return -ENOMEM;
err = galaxy_init(galaxy, &type);
if (err < 0) {
dev_err(dev, "did not find a Sound Galaxy at %#lx\n", port[n]);
goto error;
return err;
}
dev_info(dev, "Sound Galaxy (type %d) found at %#lx\n", type, port[n]);
galaxy->res_config_port = request_region(port[n] + GALAXY_PORT_CONFIG,
16, DRV_NAME);
galaxy->res_config_port =
devm_request_region(dev, port[n] + GALAXY_PORT_CONFIG, 16,
DRV_NAME);
if (!galaxy->res_config_port) {
dev_err(dev, "could not grab ports %#lx-%#lx\n",
port[n] + GALAXY_PORT_CONFIG,
port[n] + GALAXY_PORT_CONFIG + 15);
err = -EBUSY;
goto error;
return -EBUSY;
}
galaxy->config_port = ioport_map(port[n] + GALAXY_PORT_CONFIG, 16);
galaxy->config_port =
devm_ioport_map(dev, port[n] + GALAXY_PORT_CONFIG, 16);
if (!galaxy->config_port)
return -ENOMEM;
galaxy_config(galaxy, config[n]);
galaxy->res_wss_port = request_region(wss_port[n], 4, DRV_NAME);
galaxy->res_wss_port = devm_request_region(dev, wss_port[n], 4, DRV_NAME);
if (!galaxy->res_wss_port) {
dev_err(dev, "could not grab ports %#lx-%#lx\n", wss_port[n],
wss_port[n] + 3);
err = -EBUSY;
goto error;
return -EBUSY;
}
galaxy->wss_port = ioport_map(wss_port[n], 4);
galaxy->wss_port = devm_ioport_map(dev, wss_port[n], 4);
if (!galaxy->wss_port)
return -ENOMEM;
err = galaxy_wss_config(galaxy, wss_config[n]);
if (err < 0) {
dev_err(dev, "could not configure WSS\n");
goto error;
return err;
}
strcpy(card->driver, DRV_NAME);
@ -557,25 +551,25 @@ static int snd_galaxy_probe(struct device *dev, unsigned int n)
err = snd_wss_create(card, wss_port[n] + 4, -1, irq[n], dma1[n],
dma2[n], WSS_HW_DETECT, 0, &chip);
if (err < 0)
goto error;
return err;
err = snd_wss_pcm(chip, 0);
if (err < 0)
goto error;
return err;
err = snd_wss_mixer(chip);
if (err < 0)
goto error;
return err;
err = snd_wss_timer(chip, 0);
if (err < 0)
goto error;
return err;
if (mpu_port[n] >= 0) {
err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
mpu_port[n], 0, mpu_irq[n], NULL);
if (err < 0)
goto error;
return err;
}
if (fm_port[n] >= 0) {
@ -585,38 +579,28 @@ static int snd_galaxy_probe(struct device *dev, unsigned int n)
OPL3_HW_AUTO, 0, &opl3);
if (err < 0) {
dev_err(dev, "no OPL device at %#lx\n", fm_port[n]);
goto error;
return err;
}
err = snd_opl3_timer_new(opl3, 1, 2);
if (err < 0)
goto error;
return err;
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0)
goto error;
return err;
}
err = snd_card_register(card);
if (err < 0)
goto error;
return err;
dev_set_drvdata(dev, card);
return 0;
error:
snd_card_free(card);
return err;
}
static void snd_galaxy_remove(struct device *dev, unsigned int n)
{
snd_card_free(dev_get_drvdata(dev));
}
static struct isa_driver snd_galaxy_driver = {
.match = snd_galaxy_match,
.probe = snd_galaxy_probe,
.remove = snd_galaxy_remove,
.driver = {
.name = DEV_NAME

View File

@ -87,24 +87,10 @@ static void snd_gus_init_control(struct snd_gus_card *gus)
static int snd_gus_free(struct snd_gus_card *gus)
{
if (gus->gf1.res_port2 == NULL)
goto __hw_end;
snd_gf1_stop(gus);
snd_gus_init_dma_irq(gus, 0);
__hw_end:
release_and_free_resource(gus->gf1.res_port1);
release_and_free_resource(gus->gf1.res_port2);
if (gus->gf1.irq >= 0)
free_irq(gus->gf1.irq, (void *) gus);
if (gus->gf1.dma1 >= 0) {
disable_dma(gus->gf1.dma1);
free_dma(gus->gf1.dma1);
if (gus->gf1.res_port2) {
snd_gf1_stop(gus);
snd_gus_init_dma_irq(gus, 0);
}
if (!gus->equal_dma && gus->gf1.dma2 >= 0) {
disable_dma(gus->gf1.dma2);
free_dma(gus->gf1.dma2);
}
kfree(gus);
return 0;
}
@ -130,7 +116,7 @@ int snd_gus_create(struct snd_card *card,
};
*rgus = NULL;
gus = kzalloc(sizeof(*gus), GFP_KERNEL);
gus = devm_kzalloc(card->dev, sizeof(*gus), GFP_KERNEL);
if (gus == NULL)
return -ENOMEM;
spin_lock_init(&gus->reg_lock);
@ -156,35 +142,33 @@ int snd_gus_create(struct snd_card *card,
gus->gf1.reg_timerctrl = GUSP(gus, TIMERCNTRL);
gus->gf1.reg_timerdata = GUSP(gus, TIMERDATA);
/* allocate resources */
gus->gf1.res_port1 = request_region(port, 16, "GUS GF1 (Adlib/SB)");
gus->gf1.res_port1 = devm_request_region(card->dev, port, 16,
"GUS GF1 (Adlib/SB)");
if (!gus->gf1.res_port1) {
snd_printk(KERN_ERR "gus: can't grab SB port 0x%lx\n", port);
snd_gus_free(gus);
return -EBUSY;
}
gus->gf1.res_port2 = request_region(port + 0x100, 12, "GUS GF1 (Synth)");
gus->gf1.res_port2 = devm_request_region(card->dev, port + 0x100, 12,
"GUS GF1 (Synth)");
if (!gus->gf1.res_port2) {
snd_printk(KERN_ERR "gus: can't grab synth port 0x%lx\n", port + 0x100);
snd_gus_free(gus);
return -EBUSY;
}
if (irq >= 0 && request_irq(irq, snd_gus_interrupt, 0, "GUS GF1", (void *) gus)) {
if (irq >= 0 && devm_request_irq(card->dev, irq, snd_gus_interrupt, 0,
"GUS GF1", (void *) gus)) {
snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq);
snd_gus_free(gus);
return -EBUSY;
}
gus->gf1.irq = irq;
card->sync_irq = irq;
if (request_dma(dma1, "GUS - 1")) {
if (snd_devm_request_dma(card->dev, dma1, "GUS - 1")) {
snd_printk(KERN_ERR "gus: can't grab DMA1 %d\n", dma1);
snd_gus_free(gus);
return -EBUSY;
}
gus->gf1.dma1 = dma1;
if (dma2 >= 0 && dma1 != dma2) {
if (request_dma(dma2, "GUS - 2")) {
if (snd_devm_request_dma(card->dev, dma2, "GUS - 2")) {
snd_printk(KERN_ERR "gus: can't grab DMA2 %d\n", dma2);
snd_gus_free(gus);
return -EBUSY;
}
gus->gf1.dma2 = dma2;
@ -209,10 +193,8 @@ int snd_gus_create(struct snd_card *card,
gus->gf1.volume_ramp = 25;
gus->gf1.smooth_pan = 1;
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, gus, &ops);
if (err < 0) {
snd_gus_free(gus);
if (err < 0)
return err;
}
*rgus = gus;
return 0;
}

View File

@ -135,7 +135,7 @@ static int snd_gusclassic_probe(struct device *dev, unsigned int n)
struct snd_gus_card *gus;
int error;
error = snd_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
error = snd_devm_card_new(dev, index[n], id[n], THIS_MODULE, 0, &card);
if (error < 0)
return error;
@ -144,37 +144,37 @@ static int snd_gusclassic_probe(struct device *dev, unsigned int n)
error = snd_gusclassic_create(card, dev, n, &gus);
if (error < 0)
goto out;
return error;
error = snd_gusclassic_detect(gus);
if (error < 0)
goto out;
return error;
gus->joystick_dac = joystick_dac[n];
error = snd_gus_initialize(gus);
if (error < 0)
goto out;
return error;
error = -ENODEV;
if (gus->max_flag || gus->ess_flag) {
dev_err(dev, "GUS Classic or ACE soundcard was "
"not detected at 0x%lx\n", gus->gf1.port);
goto out;
return error;
}
error = snd_gf1_new_mixer(gus);
if (error < 0)
goto out;
return error;
error = snd_gf1_pcm_new(gus, 0, 0);
if (error < 0)
goto out;
return error;
if (!gus->ace_flag) {
error = snd_gf1_rawmidi_new(gus, 0);
if (error < 0)
goto out;
return error;
}
sprintf(card->longname + strlen(card->longname),
@ -187,27 +187,17 @@ static int snd_gusclassic_probe(struct device *dev, unsigned int n)
error = snd_card_register(card);
if (error < 0)
goto out;
return error;
dev_set_drvdata(dev, card);
return 0;
out: snd_card_free(card);
return error;
}
static void snd_gusclassic_remove(struct device *dev, unsigned int n)
{
snd_card_free(dev_get_drvdata(dev));
}
static struct isa_driver snd_gusclassic_driver = {
.match = snd_gusclassic_match,
.probe = snd_gusclassic_probe,
.remove = snd_gusclassic_remove,
#if 0 /* FIXME */
.suspend = snd_gusclassic_suspend,
.remove = snd_gusclassic_remove,
#endif
.driver = {
.name = DEV_NAME

View File

@ -228,8 +228,8 @@ static int snd_gusextreme_probe(struct device *dev, unsigned int n)
struct snd_opl3 *opl3;
int error;
error = snd_card_new(dev, index[n], id[n], THIS_MODULE,
sizeof(struct snd_es1688), &card);
error = snd_devm_card_new(dev, index[n], id[n], THIS_MODULE,
sizeof(struct snd_es1688), &card);
if (error < 0)
return error;
@ -243,56 +243,56 @@ static int snd_gusextreme_probe(struct device *dev, unsigned int n)
error = snd_gusextreme_es1688_create(card, es1688, dev, n);
if (error < 0)
goto out;
return error;
if (gf1_port[n] < 0)
gf1_port[n] = es1688->port + 0x20;
error = snd_gusextreme_gus_card_create(card, dev, n, &gus);
if (error < 0)
goto out;
return error;
error = snd_gusextreme_detect(gus, es1688);
if (error < 0)
goto out;
return error;
gus->joystick_dac = joystick_dac[n];
error = snd_gus_initialize(gus);
if (error < 0)
goto out;
return error;
error = -ENODEV;
if (!gus->ess_flag) {
dev_err(dev, "GUS Extreme soundcard was not "
"detected at 0x%lx\n", gus->gf1.port);
goto out;
return error;
}
gus->codec_flag = 1;
error = snd_es1688_pcm(card, es1688, 0);
if (error < 0)
goto out;
return error;
error = snd_es1688_mixer(card, es1688);
if (error < 0)
goto out;
return error;
snd_component_add(card, "ES1688");
if (pcm_channels[n] > 0) {
error = snd_gf1_pcm_new(gus, 1, 1);
if (error < 0)
goto out;
return error;
}
error = snd_gf1_new_mixer(gus);
if (error < 0)
goto out;
return error;
error = snd_gusextreme_mixer(card);
if (error < 0)
goto out;
return error;
if (snd_opl3_create(card, es1688->port, es1688->port + 2,
OPL3_HW_OPL3, 0, &opl3) < 0)
@ -300,14 +300,14 @@ static int snd_gusextreme_probe(struct device *dev, unsigned int n)
else {
error = snd_opl3_hwdep_new(opl3, 0, 2, NULL);
if (error < 0)
goto out;
return error;
}
if (es1688->mpu_port >= 0x300) {
error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
es1688->mpu_port, 0, mpu_irq[n], NULL);
if (error < 0)
goto out;
return error;
}
sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, "
@ -316,24 +316,15 @@ static int snd_gusextreme_probe(struct device *dev, unsigned int n)
error = snd_card_register(card);
if (error < 0)
goto out;
return error;
dev_set_drvdata(dev, card);
return 0;
out: snd_card_free(card);
return error;
}
static void snd_gusextreme_remove(struct device *dev, unsigned int n)
{
snd_card_free(dev_get_drvdata(dev));
}
static struct isa_driver snd_gusextreme_driver = {
.match = snd_gusextreme_match,
.probe = snd_gusextreme_probe,
.remove = snd_gusextreme_remove,
#if 0 /* FIXME */
.suspend = snd_gusextreme_suspend,
.resume = snd_gusextreme_resume,

View File

@ -179,16 +179,6 @@ static int snd_gusmax_mixer(struct snd_wss *chip)
return 0;
}
static void snd_gusmax_free(struct snd_card *card)
{
struct snd_gusmax *maxcard = card->private_data;
if (maxcard == NULL)
return;
if (maxcard->irq >= 0)
free_irq(maxcard->irq, (void *)maxcard);
}
static int snd_gusmax_match(struct device *pdev, unsigned int dev)
{
return enable[dev];
@ -204,11 +194,10 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
struct snd_wss *wss;
struct snd_gusmax *maxcard;
err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_gusmax), &card);
err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_gusmax), &card);
if (err < 0)
return err;
card->private_free = snd_gusmax_free;
maxcard = card->private_data;
maxcard->card = card;
maxcard->irq = -1;
@ -218,8 +207,7 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
xirq = snd_legacy_find_free_irq(possible_irqs);
if (xirq < 0) {
snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
err = -EBUSY;
goto _err;
return -EBUSY;
}
}
xdma1 = dma1[dev];
@ -227,8 +215,7 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
xdma1 = snd_legacy_find_free_dma(possible_dmas);
if (xdma1 < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");
err = -EBUSY;
goto _err;
return -EBUSY;
}
}
xdma2 = dma2[dev];
@ -236,8 +223,7 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
xdma2 = snd_legacy_find_free_dma(possible_dmas);
if (xdma2 < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");
err = -EBUSY;
goto _err;
return -EBUSY;
}
}
@ -267,29 +253,28 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
}
}
if (err < 0)
goto _err;
return err;
err = snd_gusmax_detect(gus);
if (err < 0)
goto _err;
return err;
maxcard->gus_status_reg = gus->gf1.reg_irqstat;
maxcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;
snd_gusmax_init(dev, card, gus);
err = snd_gus_initialize(gus);
if (err < 0)
goto _err;
return err;
if (!gus->max_flag) {
snd_printk(KERN_ERR PFX "GUS MAX soundcard was not detected at 0x%lx\n", gus->gf1.port);
err = -ENODEV;
goto _err;
return -ENODEV;
}
if (request_irq(xirq, snd_gusmax_interrupt, 0, "GUS MAX", (void *)maxcard)) {
if (devm_request_irq(card->dev, xirq, snd_gusmax_interrupt, 0,
"GUS MAX", (void *)maxcard)) {
snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
err = -EBUSY;
goto _err;
return -EBUSY;
}
maxcard->irq = xirq;
card->sync_irq = maxcard->irq;
@ -303,32 +288,32 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
WSS_HWSHARE_DMA2,
&wss);
if (err < 0)
goto _err;
return err;
err = snd_wss_pcm(wss, 0);
if (err < 0)
goto _err;
return err;
err = snd_wss_mixer(wss);
if (err < 0)
goto _err;
return err;
err = snd_wss_timer(wss, 2);
if (err < 0)
goto _err;
return err;
if (pcm_channels[dev] > 0) {
err = snd_gf1_pcm_new(gus, 1, 1);
if (err < 0)
goto _err;
return err;
}
err = snd_gusmax_mixer(wss);
if (err < 0)
goto _err;
return err;
err = snd_gf1_rawmidi_new(gus, 0);
if (err < 0)
goto _err;
return err;
sprintf(card->longname + strlen(card->longname), " at 0x%lx, irq %i, dma %i", gus->gf1.port, xirq, xdma1);
if (xdma2 >= 0)
@ -336,22 +321,13 @@ static int snd_gusmax_probe(struct device *pdev, unsigned int dev)
err = snd_card_register(card);
if (err < 0)
goto _err;
return err;
maxcard->gus = gus;
maxcard->wss = wss;
dev_set_drvdata(pdev, card);
return 0;
_err:
snd_card_free(card);
return err;
}
static void snd_gusmax_remove(struct device *devptr, unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
#define DEV_NAME "gusmax"
@ -359,7 +335,6 @@ static void snd_gusmax_remove(struct device *devptr, unsigned int dev)
static struct isa_driver snd_gusmax_driver = {
.match = snd_gusmax_match,
.probe = snd_gusmax_probe,
.remove = snd_gusmax_remove,
/* FIXME: suspend/resume */
.driver = {
.name = DEV_NAME

View File

@ -204,13 +204,15 @@ static int snd_interwave_detect_stb(struct snd_interwave *iwcard,
port = 0x360;
}
while (port <= 0x380) {
iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)");
iwcard->i2c_res = devm_request_region(card->dev, port, 1,
"InterWave (I2C bus)");
if (iwcard->i2c_res)
break;
port += 0x10;
}
} else {
iwcard->i2c_res = request_region(port, 1, "InterWave (I2C bus)");
iwcard->i2c_res = devm_request_region(card->dev, port, 1,
"InterWave (I2C bus)");
}
if (iwcard->i2c_res == NULL) {
snd_printk(KERN_ERR "interwave: can't grab i2c bus port\n");
@ -598,19 +600,6 @@ static int snd_interwave_pnp(int dev, struct snd_interwave *iwcard,
}
#endif /* CONFIG_PNP */
static void snd_interwave_free(struct snd_card *card)
{
struct snd_interwave *iwcard = card->private_data;
if (iwcard == NULL)
return;
#ifdef SNDRV_STB
release_and_free_resource(iwcard->i2c_res);
#endif
if (iwcard->irq >= 0)
free_irq(iwcard->irq, (void *)iwcard);
}
static int snd_interwave_card_new(struct device *pdev, int dev,
struct snd_card **cardp)
{
@ -618,14 +607,13 @@ static int snd_interwave_card_new(struct device *pdev, int dev,
struct snd_interwave *iwcard;
int err;
err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_interwave), &card);
err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_interwave), &card);
if (err < 0)
return err;
iwcard = card->private_data;
iwcard->card = card;
iwcard->irq = -1;
card->private_free = snd_interwave_free;
*cardp = card;
return 0;
}
@ -671,8 +659,8 @@ static int snd_interwave_probe(struct snd_card *card, int dev)
if (err < 0)
return err;
if (request_irq(xirq, snd_interwave_interrupt, 0,
"InterWave", iwcard)) {
if (devm_request_irq(card->dev, xirq, snd_interwave_interrupt, 0,
"InterWave", iwcard)) {
snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);
return -EBUSY;
}
@ -779,10 +767,8 @@ static int snd_interwave_isa_probe1(int dev, struct device *devptr)
return err;
err = snd_interwave_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
dev_set_drvdata(devptr, card);
return 0;
}
@ -843,15 +829,9 @@ static int snd_interwave_isa_probe(struct device *pdev,
}
}
static void snd_interwave_isa_remove(struct device *devptr, unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
static struct isa_driver snd_interwave_driver = {
.match = snd_interwave_isa_match,
.probe = snd_interwave_isa_probe,
.remove = snd_interwave_isa_remove,
/* FIXME: suspend,resume */
.driver = {
.name = INTERWAVE_DRIVER
@ -878,32 +858,21 @@ static int snd_interwave_pnp_detect(struct pnp_card_link *pcard,
return res;
res = snd_interwave_pnp(dev, card->private_data, pcard, pid);
if (res < 0) {
snd_card_free(card);
if (res < 0)
return res;
}
res = snd_interwave_probe(card, dev);
if (res < 0) {
snd_card_free(card);
if (res < 0)
return res;
}
pnp_set_card_drvdata(pcard, card);
dev++;
return 0;
}
static void snd_interwave_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
static struct pnp_card_driver interwave_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = INTERWAVE_PNP_DRIVER,
.id_table = snd_interwave_pnpids,
.probe = snd_interwave_pnp_detect,
.remove = snd_interwave_pnp_remove,
/* FIXME: suspend,resume */
};

View File

@ -425,7 +425,7 @@ static void snd_msnd_capture_reset_queue(struct snd_msnd *chip,
}
static const struct snd_pcm_hardware snd_msnd_playback = {
.info = SNDRV_PCM_INFO_MMAP |
.info = SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_BATCH,
@ -444,7 +444,7 @@ static const struct snd_pcm_hardware snd_msnd_playback = {
};
static const struct snd_pcm_hardware snd_msnd_capture = {
.info = SNDRV_PCM_INFO_MMAP |
.info = SNDRV_PCM_INFO_MMAP_IOMEM |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_BATCH,
@ -473,6 +473,7 @@ static int snd_msnd_playback_open(struct snd_pcm_substream *substream)
snd_msnd_enable_irq(chip);
runtime->dma_area = (__force void *)chip->mappedbase;
runtime->dma_addr = chip->base;
runtime->dma_bytes = 0x3000;
chip->playback_substream = substream;
@ -566,6 +567,7 @@ static const struct snd_pcm_ops snd_msnd_playback_ops = {
.prepare = snd_msnd_playback_prepare,
.trigger = snd_msnd_playback_trigger,
.pointer = snd_msnd_playback_pointer,
.mmap = snd_pcm_lib_mmap_iomem,
};
static int snd_msnd_capture_open(struct snd_pcm_substream *substream)
@ -576,6 +578,7 @@ static int snd_msnd_capture_open(struct snd_pcm_substream *substream)
set_bit(F_AUDIO_READ_INUSE, &chip->flags);
snd_msnd_enable_irq(chip);
runtime->dma_area = (__force void *)chip->mappedbase + 0x3000;
runtime->dma_addr = chip->base + 0x3000;
runtime->dma_bytes = 0x3000;
memset(runtime->dma_area, 0, runtime->dma_bytes);
chip->capture_substream = substream;
@ -662,6 +665,7 @@ static const struct snd_pcm_ops snd_msnd_capture_ops = {
.prepare = snd_msnd_capture_prepare,
.trigger = snd_msnd_capture_trigger,
.pointer = snd_msnd_capture_pointer,
.mmap = snd_pcm_lib_mmap_iomem,
};

View File

@ -472,11 +472,6 @@ static int snd_msnd_dsp_full_reset(struct snd_card *card)
return rv;
}
static int snd_msnd_dev_free(struct snd_device *device)
{
snd_printdd("snd_msnd_chip_free()\n");
return 0;
}
static int snd_msnd_send_dsp_cmd_chk(struct snd_msnd *chip, u8 cmd)
{
@ -528,58 +523,47 @@ static int snd_msnd_attach(struct snd_card *card)
{
struct snd_msnd *chip = card->private_data;
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_msnd_dev_free,
};
err = request_irq(chip->irq, snd_msnd_interrupt, 0, card->shortname,
chip);
err = devm_request_irq(card->dev, chip->irq, snd_msnd_interrupt, 0,
card->shortname, chip);
if (err < 0) {
printk(KERN_ERR LOGNAME ": Couldn't grab IRQ %d\n", chip->irq);
return err;
}
card->sync_irq = chip->irq;
if (request_region(chip->io, DSP_NUMIO, card->shortname) == NULL) {
free_irq(chip->irq, chip);
if (!devm_request_region(card->dev, chip->io, DSP_NUMIO,
card->shortname))
return -EBUSY;
}
if (!request_mem_region(chip->base, BUFFSIZE, card->shortname)) {
if (!devm_request_mem_region(card->dev, chip->base, BUFFSIZE,
card->shortname)) {
printk(KERN_ERR LOGNAME
": unable to grab memory region 0x%lx-0x%lx\n",
chip->base, chip->base + BUFFSIZE - 1);
release_region(chip->io, DSP_NUMIO);
free_irq(chip->irq, chip);
return -EBUSY;
}
chip->mappedbase = ioremap(chip->base, 0x8000);
chip->mappedbase = devm_ioremap(card->dev, chip->base, 0x8000);
if (!chip->mappedbase) {
printk(KERN_ERR LOGNAME
": unable to map memory region 0x%lx-0x%lx\n",
chip->base, chip->base + BUFFSIZE - 1);
err = -EIO;
goto err_release_region;
return -EIO;
}
err = snd_msnd_dsp_full_reset(card);
if (err < 0)
goto err_release_region;
/* Register device */
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0)
goto err_release_region;
return err;
err = snd_msnd_pcm(card, 0);
if (err < 0) {
printk(KERN_ERR LOGNAME ": error creating new PCM device\n");
goto err_release_region;
return err;
}
err = snd_msndmix_new(card);
if (err < 0) {
printk(KERN_ERR LOGNAME ": error creating new Mixer device\n");
goto err_release_region;
return err;
}
@ -595,7 +579,7 @@ static int snd_msnd_attach(struct snd_card *card)
if (err < 0) {
printk(KERN_ERR LOGNAME
": error creating new Midi device\n");
goto err_release_region;
return err;
}
mpu = chip->rmidi->private_data;
@ -610,30 +594,12 @@ static int snd_msnd_attach(struct snd_card *card)
err = snd_card_register(card);
if (err < 0)
goto err_release_region;
return err;
return 0;
err_release_region:
iounmap(chip->mappedbase);
release_mem_region(chip->base, BUFFSIZE);
release_region(chip->io, DSP_NUMIO);
free_irq(chip->irq, chip);
return err;
}
static void snd_msnd_unload(struct snd_card *card)
{
struct snd_msnd *chip = card->private_data;
iounmap(chip->mappedbase);
release_mem_region(chip->base, BUFFSIZE);
release_region(chip->io, DSP_NUMIO);
free_irq(chip->irq, chip);
snd_card_free(card);
}
#ifndef MSND_CLASSIC
/* Pinnacle/Fiji Logical Device Configuration */
@ -892,8 +858,8 @@ static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
return -ENODEV;
}
err = snd_card_new(pdev, index[idx], id[idx], THIS_MODULE,
sizeof(struct snd_msnd), &card);
err = snd_devm_card_new(pdev, index[idx], id[idx], THIS_MODULE,
sizeof(struct snd_msnd), &card);
if (err < 0)
return err;
@ -934,17 +900,15 @@ static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
printk(KERN_INFO LOGNAME ": Non-PnP mode: configuring at port 0x%lx\n",
cfg[idx]);
if (!request_region(cfg[idx], 2, "Pinnacle/Fiji Config")) {
if (!devm_request_region(card->dev, cfg[idx], 2,
"Pinnacle/Fiji Config")) {
printk(KERN_ERR LOGNAME ": Config port 0x%lx conflict\n",
cfg[idx]);
snd_card_free(card);
return -EIO;
}
if (reset[idx])
if (snd_msnd_pinnacle_cfg_reset(cfg[idx])) {
err = -EIO;
goto cfg_error;
}
if (snd_msnd_pinnacle_cfg_reset(cfg[idx]))
return -EIO;
/* DSP */
err = snd_msnd_write_cfg_logical(cfg[idx], 0,
@ -952,7 +916,7 @@ static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
irq[idx], mem[idx]);
if (err)
goto cfg_error;
return err;
/* The following are Pinnacle specific */
@ -967,7 +931,7 @@ static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
mpu_irq[idx], 0);
if (err)
goto cfg_error;
return err;
}
/* IDE */
@ -982,7 +946,7 @@ static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
ide_irq[idx], 0);
if (err)
goto cfg_error;
return err;
}
/* Joystick */
@ -995,9 +959,8 @@ static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
0, 0);
if (err)
goto cfg_error;
return err;
}
release_region(cfg[idx], 2);
#endif /* MSND_CLASSIC */
@ -1027,37 +990,22 @@ static int snd_msnd_isa_probe(struct device *pdev, unsigned int idx)
err = snd_msnd_probe(card);
if (err < 0) {
printk(KERN_ERR LOGNAME ": Probe failed\n");
snd_card_free(card);
return err;
}
err = snd_msnd_attach(card);
if (err < 0) {
printk(KERN_ERR LOGNAME ": Attach failed\n");
snd_card_free(card);
return err;
}
dev_set_drvdata(pdev, card);
return 0;
#ifndef MSND_CLASSIC
cfg_error:
release_region(cfg[idx], 2);
snd_card_free(card);
return err;
#endif
}
static void snd_msnd_isa_remove(struct device *pdev, unsigned int dev)
{
snd_msnd_unload(dev_get_drvdata(pdev));
}
static struct isa_driver snd_msnd_driver = {
.match = snd_msnd_isa_match,
.probe = snd_msnd_isa_probe,
.remove = snd_msnd_isa_remove,
/* FIXME: suspend, resume */
.driver = {
.name = DEV_NAME
@ -1107,9 +1055,9 @@ static int snd_msnd_pnp_detect(struct pnp_card_link *pcard,
* Create a new ALSA sound card entry, in anticipation
* of detecting our hardware ...
*/
ret = snd_card_new(&pcard->card->dev,
index[idx], id[idx], THIS_MODULE,
sizeof(struct snd_msnd), &card);
ret = snd_devm_card_new(&pcard->card->dev,
index[idx], id[idx], THIS_MODULE,
sizeof(struct snd_msnd), &card);
if (ret < 0)
return ret;
@ -1151,28 +1099,18 @@ static int snd_msnd_pnp_detect(struct pnp_card_link *pcard,
ret = snd_msnd_probe(card);
if (ret < 0) {
printk(KERN_ERR LOGNAME ": Probe failed\n");
goto _release_card;
return ret;
}
ret = snd_msnd_attach(card);
if (ret < 0) {
printk(KERN_ERR LOGNAME ": Attach failed\n");
goto _release_card;
return ret;
}
pnp_set_card_drvdata(pcard, card);
++idx;
return 0;
_release_card:
snd_card_free(card);
return ret;
}
static void snd_msnd_pnp_remove(struct pnp_card_link *pcard)
{
snd_msnd_unload(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
static int isa_registered;
@ -1191,7 +1129,6 @@ static struct pnp_card_driver msnd_pnpc_driver = {
.name = "msnd_pinnacle",
.id_table = msnd_pnpids,
.probe = snd_msnd_pnp_detect,
.remove = snd_msnd_pnp_remove,
};
#endif /* CONFIG_PNP */

View File

@ -208,7 +208,8 @@ static int snd_opl3sa2_detect(struct snd_card *card)
char str[2];
port = chip->port;
chip->res_port = request_region(port, 2, "OPL3-SA control");
chip->res_port = devm_request_region(card->dev, port, 2,
"OPL3-SA control");
if (!chip->res_port) {
snd_printk(KERN_ERR PFX "can't grab port 0x%lx\n", port);
return -EBUSY;
@ -609,14 +610,6 @@ static int snd_opl3sa2_pnp(int dev, struct snd_opl3sa2 *chip,
}
#endif /* CONFIG_PNP */
static void snd_opl3sa2_free(struct snd_card *card)
{
struct snd_opl3sa2 *chip = card->private_data;
if (chip->irq >= 0)
free_irq(chip->irq, card);
release_and_free_resource(chip->res_port);
}
static int snd_opl3sa2_card_new(struct device *pdev, int dev,
struct snd_card **cardp)
{
@ -624,8 +617,8 @@ static int snd_opl3sa2_card_new(struct device *pdev, int dev,
struct snd_opl3sa2 *chip;
int err;
err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_opl3sa2), &card);
err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_opl3sa2), &card);
if (err < 0)
return err;
strcpy(card->driver, "OPL3SA2");
@ -633,7 +626,6 @@ static int snd_opl3sa2_card_new(struct device *pdev, int dev,
chip = card->private_data;
spin_lock_init(&chip->reg_lock);
chip->irq = -1;
card->private_free = snd_opl3sa2_free;
*cardp = card;
return 0;
}
@ -658,8 +650,8 @@ static int snd_opl3sa2_probe(struct snd_card *card, int dev)
err = snd_opl3sa2_detect(card);
if (err < 0)
return err;
err = request_irq(xirq, snd_opl3sa2_interrupt, 0,
"OPL3-SA2", card);
err = devm_request_irq(card->dev, xirq, snd_opl3sa2_interrupt, 0,
"OPL3-SA2", card);
if (err) {
snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq);
return -ENODEV;
@ -737,25 +729,16 @@ static int snd_opl3sa2_pnp_detect(struct pnp_dev *pdev,
if (err < 0)
return err;
err = snd_opl3sa2_pnp(dev, card->private_data, pdev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_opl3sa2_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
pnp_set_drvdata(pdev, card);
dev++;
return 0;
}
static void snd_opl3sa2_pnp_remove(struct pnp_dev *pdev)
{
snd_card_free(pnp_get_drvdata(pdev));
}
#ifdef CONFIG_PM
static int snd_opl3sa2_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
{
@ -771,7 +754,6 @@ static struct pnp_driver opl3sa2_pnp_driver = {
.name = "snd-opl3sa2-pnpbios",
.id_table = snd_opl3sa2_pnpbiosids,
.probe = snd_opl3sa2_pnp_detect,
.remove = snd_opl3sa2_pnp_remove,
#ifdef CONFIG_PM
.suspend = snd_opl3sa2_pnp_suspend,
.resume = snd_opl3sa2_pnp_resume,
@ -803,26 +785,16 @@ static int snd_opl3sa2_pnp_cdetect(struct pnp_card_link *pcard,
if (err < 0)
return err;
err = snd_opl3sa2_pnp(dev, card->private_data, pdev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = snd_opl3sa2_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
pnp_set_card_drvdata(pcard, card);
dev++;
return 0;
}
static void snd_opl3sa2_pnp_cremove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_opl3sa2_pnp_csuspend(struct pnp_card_link *pcard, pm_message_t state)
{
@ -839,7 +811,6 @@ static struct pnp_card_driver opl3sa2_pnpc_driver = {
.name = "snd-opl3sa2-cpnp",
.id_table = snd_opl3sa2_pnpids,
.probe = snd_opl3sa2_pnp_cdetect,
.remove = snd_opl3sa2_pnp_cremove,
#ifdef CONFIG_PM
.suspend = snd_opl3sa2_pnp_csuspend,
.resume = snd_opl3sa2_pnp_cresume,
@ -885,20 +856,12 @@ static int snd_opl3sa2_isa_probe(struct device *pdev,
if (err < 0)
return err;
err = snd_opl3sa2_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
dev_set_drvdata(pdev, card);
return 0;
}
static void snd_opl3sa2_isa_remove(struct device *devptr,
unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
#ifdef CONFIG_PM
static int snd_opl3sa2_isa_suspend(struct device *dev, unsigned int n,
pm_message_t state)
@ -917,7 +880,6 @@ static int snd_opl3sa2_isa_resume(struct device *dev, unsigned int n)
static struct isa_driver snd_opl3sa2_isa_driver = {
.match = snd_opl3sa2_isa_match,
.probe = snd_opl3sa2_isa_probe,
.remove = snd_opl3sa2_isa_remove,
#ifdef CONFIG_PM
.suspend = snd_opl3sa2_isa_suspend,
.resume = snd_opl3sa2_isa_resume,

View File

@ -1159,12 +1159,13 @@ __skip_mpu:
return 0;
}
static int snd_miro_opti_check(struct snd_miro *chip)
static int snd_miro_opti_check(struct snd_card *card, struct snd_miro *chip)
{
unsigned char value;
chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
"OPTi9xx MC");
chip->res_mc_base =
devm_request_region(card->dev, chip->mc_base,
chip->mc_base_size, "OPTi9xx MC");
if (chip->res_mc_base == NULL)
return -ENOMEM;
@ -1173,7 +1174,7 @@ static int snd_miro_opti_check(struct snd_miro *chip)
if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
return 0;
release_and_free_resource(chip->res_mc_base);
devm_release_resource(card->dev, chip->res_mc_base);
chip->res_mc_base = NULL;
return -ENODEV;
@ -1190,7 +1191,7 @@ static int snd_card_miro_detect(struct snd_card *card,
if (err < 0)
return err;
err = snd_miro_opti_check(chip);
err = snd_miro_opti_check(card, chip);
if (err == 0)
return 1;
}
@ -1214,7 +1215,8 @@ static int snd_card_miro_aci_detect(struct snd_card *card,
regval=inb(miro->mc_base + 4);
aci->aci_port = (regval & 0x10) ? 0x344 : 0x354;
miro->res_aci_port = request_region(aci->aci_port, 3, "miro aci");
miro->res_aci_port =
devm_request_region(card->dev, aci->aci_port, 3, "miro aci");
if (miro->res_aci_port == NULL) {
snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n",
aci->aci_port, aci->aci_port+2);
@ -1253,16 +1255,6 @@ static int snd_card_miro_aci_detect(struct snd_card *card,
return 0;
}
static void snd_card_miro_free(struct snd_card *card)
{
struct snd_miro *miro = card->private_data;
release_and_free_resource(miro->res_aci_port);
if (miro->aci)
miro->aci->aci_port = 0;
release_and_free_resource(miro->res_mc_base);
}
static int snd_miro_probe(struct snd_card *card)
{
int error;
@ -1271,9 +1263,10 @@ static int snd_miro_probe(struct snd_card *card)
struct snd_rawmidi *rmidi;
if (!miro->res_mc_base) {
miro->res_mc_base = request_region(miro->mc_base,
miro->mc_base_size,
"miro (OPTi9xx MC)");
miro->res_mc_base = devm_request_region(card->dev,
miro->mc_base,
miro->mc_base_size,
"miro (OPTi9xx MC)");
if (miro->res_mc_base == NULL) {
snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
return -ENOMEM;
@ -1408,17 +1401,15 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
struct snd_miro *miro;
struct snd_card *card;
error = snd_card_new(devptr, index, id, THIS_MODULE,
sizeof(struct snd_miro), &card);
error = snd_devm_card_new(devptr, index, id, THIS_MODULE,
sizeof(struct snd_miro), &card);
if (error < 0)
return error;
card->private_free = snd_card_miro_free;
miro = card->private_data;
error = snd_card_miro_detect(card, miro);
if (error < 0) {
snd_card_free(card);
snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n");
return -ENODEV;
}
@ -1426,7 +1417,6 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
if (port == SNDRV_AUTO_PORT) {
port = snd_legacy_find_free_ioport(possible_ports, 4);
if (port < 0) {
snd_card_free(card);
snd_printk(KERN_ERR "unable to find a free WSS port\n");
return -EBUSY;
}
@ -1435,7 +1425,6 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
if (mpu_port == SNDRV_AUTO_PORT) {
mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
if (mpu_port < 0) {
snd_card_free(card);
snd_printk(KERN_ERR
"unable to find a free MPU401 port\n");
return -EBUSY;
@ -1445,7 +1434,6 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
if (irq == SNDRV_AUTO_IRQ) {
irq = snd_legacy_find_free_irq(possible_irqs);
if (irq < 0) {
snd_card_free(card);
snd_printk(KERN_ERR "unable to find a free IRQ\n");
return -EBUSY;
}
@ -1453,7 +1441,6 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
if (mpu_irq == SNDRV_AUTO_IRQ) {
mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
if (mpu_irq < 0) {
snd_card_free(card);
snd_printk(KERN_ERR
"unable to find a free MPU401 IRQ\n");
return -EBUSY;
@ -1462,7 +1449,6 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
if (dma1 == SNDRV_AUTO_DMA) {
dma1 = snd_legacy_find_free_dma(possible_dma1s);
if (dma1 < 0) {
snd_card_free(card);
snd_printk(KERN_ERR "unable to find a free DMA1\n");
return -EBUSY;
}
@ -1470,34 +1456,24 @@ static int snd_miro_isa_probe(struct device *devptr, unsigned int n)
if (dma2 == SNDRV_AUTO_DMA) {
dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
if (dma2 < 0) {
snd_card_free(card);
snd_printk(KERN_ERR "unable to find a free DMA2\n");
return -EBUSY;
}
}
error = snd_miro_probe(card);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
dev_set_drvdata(devptr, card);
return 0;
}
static void snd_miro_isa_remove(struct device *devptr,
unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
#define DEV_NAME "miro"
static struct isa_driver snd_miro_driver = {
.match = snd_miro_isa_match,
.probe = snd_miro_isa_probe,
.remove = snd_miro_isa_remove,
/* FIXME: suspend/resume */
.driver = {
.name = DEV_NAME
@ -1578,39 +1554,31 @@ static int snd_miro_pnp_probe(struct pnp_card_link *pcard,
return -EBUSY;
if (!isapnp)
return -ENODEV;
err = snd_card_new(&pcard->card->dev, index, id, THIS_MODULE,
sizeof(struct snd_miro), &card);
err = snd_devm_card_new(&pcard->card->dev, index, id, THIS_MODULE,
sizeof(struct snd_miro), &card);
if (err < 0)
return err;
card->private_free = snd_card_miro_free;
miro = card->private_data;
err = snd_card_miro_pnp(miro, pcard, pid);
if (err) {
snd_card_free(card);
if (err)
return err;
}
/* only miroSOUND PCM20 and PCM12 == OPTi924 */
err = snd_miro_init(miro, OPTi9XX_HW_82C924);
if (err) {
snd_card_free(card);
if (err)
return err;
}
err = snd_miro_opti_check(miro);
err = snd_miro_opti_check(card, miro);
if (err) {
snd_printk(KERN_ERR "OPTI chip not found\n");
snd_card_free(card);
return err;
}
err = snd_miro_probe(card);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
pnp_set_card_drvdata(pcard, card);
snd_miro_pnp_is_probed = 1;
return 0;
@ -1618,8 +1586,6 @@ static int snd_miro_pnp_probe(struct pnp_card_link *pcard,
static void snd_miro_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
snd_miro_pnp_is_probed = 0;
}

View File

@ -654,16 +654,18 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
#endif /* OPTi93X */
static int snd_opti9xx_read_check(struct snd_opti9xx *chip)
static int snd_opti9xx_read_check(struct snd_card *card,
struct snd_opti9xx *chip)
{
unsigned char value;
#ifdef OPTi93X
unsigned long flags;
#endif
chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
"OPTi9xx MC");
if (chip->res_mc_base == NULL)
chip->res_mc_base =
devm_request_region(card->dev, chip->mc_base,
chip->mc_base_size, "OPTi9xx MC");
if (!chip->res_mc_base)
return -EBUSY;
#ifndef OPTi93X
value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
@ -671,9 +673,10 @@ static int snd_opti9xx_read_check(struct snd_opti9xx *chip)
if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
return 0;
#else /* OPTi93X */
chip->res_mc_indir = request_region(chip->mc_indir_index, 2,
"OPTi93x MC");
if (chip->res_mc_indir == NULL)
chip->res_mc_indir =
devm_request_region(card->dev, chip->mc_indir_index, 2,
"OPTi93x MC");
if (!chip->res_mc_indir)
return -EBUSY;
spin_lock_irqsave(&chip->lock, flags);
@ -686,10 +689,10 @@ static int snd_opti9xx_read_check(struct snd_opti9xx *chip)
if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
return 0;
release_and_free_resource(chip->res_mc_indir);
devm_release_resource(card->dev, chip->res_mc_indir);
chip->res_mc_indir = NULL;
#endif /* OPTi93X */
release_and_free_resource(chip->res_mc_base);
devm_release_resource(card->dev, chip->res_mc_base);
chip->res_mc_base = NULL;
return -ENODEV;
@ -709,7 +712,7 @@ static int snd_card_opti9xx_detect(struct snd_card *card,
if (err < 0)
return err;
err = snd_opti9xx_read_check(chip);
err = snd_opti9xx_read_check(card, chip);
if (err == 0)
return 1;
#ifdef OPTi93X
@ -789,22 +792,6 @@ static int snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
}
#endif /* CONFIG_PNP */
static void snd_card_opti9xx_free(struct snd_card *card)
{
struct snd_opti9xx *chip = card->private_data;
if (chip) {
#ifdef OPTi93X
if (chip->irq > 0) {
disable_irq(chip->irq);
free_irq(chip->irq, chip);
}
release_and_free_resource(chip->res_mc_indir);
#endif
release_and_free_resource(chip->res_mc_base);
}
}
static int snd_opti9xx_probe(struct snd_card *card)
{
static const long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
@ -860,8 +847,8 @@ static int snd_opti9xx_probe(struct snd_card *card)
return error;
#endif
#ifdef OPTi93X
error = request_irq(irq, snd_opti93x_interrupt,
0, DEV_NAME" - WSS", chip);
error = devm_request_irq(card->dev, irq, snd_opti93x_interrupt,
0, DEV_NAME" - WSS", chip);
if (error < 0) {
snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq);
return error;
@ -931,11 +918,10 @@ static int snd_opti9xx_card_new(struct device *pdev, struct snd_card **cardp)
struct snd_card *card;
int err;
err = snd_card_new(pdev, index, id, THIS_MODULE,
sizeof(struct snd_opti9xx), &card);
err = snd_devm_card_new(pdev, index, id, THIS_MODULE,
sizeof(struct snd_opti9xx), &card);
if (err < 0)
return err;
card->private_free = snd_card_opti9xx_free;
*cardp = card;
return 0;
}
@ -1012,25 +998,15 @@ static int snd_opti9xx_isa_probe(struct device *devptr,
return error;
error = snd_card_opti9xx_detect(card, card->private_data);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
error = snd_opti9xx_probe(card);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
dev_set_drvdata(devptr, card);
return 0;
}
static void snd_opti9xx_isa_remove(struct device *devptr,
unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
#ifdef CONFIG_PM
static int snd_opti9xx_suspend(struct snd_card *card)
{
@ -1075,7 +1051,6 @@ static int snd_opti9xx_isa_resume(struct device *dev, unsigned int n)
static struct isa_driver snd_opti9xx_driver = {
.match = snd_opti9xx_isa_match,
.probe = snd_opti9xx_isa_probe,
.remove = snd_opti9xx_isa_remove,
#ifdef CONFIG_PM
.suspend = snd_opti9xx_isa_suspend,
.resume = snd_opti9xx_isa_resume,
@ -1114,26 +1089,20 @@ static int snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
hw = OPTi9XX_HW_82C931;
break;
default:
snd_card_free(card);
return -ENODEV;
}
error = snd_opti9xx_init(chip, hw);
if (error) {
snd_card_free(card);
if (error)
return error;
}
error = snd_opti9xx_read_check(chip);
error = snd_opti9xx_read_check(card, chip);
if (error) {
snd_printk(KERN_ERR "OPTI chip not found\n");
snd_card_free(card);
return error;
}
error = snd_opti9xx_probe(card);
if (error < 0) {
snd_card_free(card);
if (error < 0)
return error;
}
pnp_set_card_drvdata(pcard, card);
snd_opti9xx_pnp_is_probed = 1;
return 0;
@ -1141,8 +1110,6 @@ static int snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
static void snd_opti9xx_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
snd_opti9xx_pnp_is_probed = 0;
}

View File

@ -1048,27 +1048,6 @@ __error:
return err;
}
/*
* free resources
*/
static int snd_emu8000_free(struct snd_emu8000 *hw)
{
release_and_free_resource(hw->res_port1);
release_and_free_resource(hw->res_port2);
release_and_free_resource(hw->res_port3);
kfree(hw);
return 0;
}
/*
*/
static int snd_emu8000_dev_free(struct snd_device *device)
{
struct snd_emu8000 *hw = device->device_data;
return snd_emu8000_free(hw);
}
/*
* initialize and register emu8000 synth device.
*/
@ -1079,9 +1058,6 @@ snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
struct snd_seq_device *awe;
struct snd_emu8000 *hw;
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_emu8000_dev_free,
};
if (awe_ret)
*awe_ret = NULL;
@ -1089,7 +1065,7 @@ snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
if (seq_ports <= 0)
return 0;
hw = kzalloc(sizeof(*hw), GFP_KERNEL);
hw = devm_kzalloc(card->dev, sizeof(*hw), GFP_KERNEL);
if (hw == NULL)
return -ENOMEM;
spin_lock_init(&hw->reg_lock);
@ -1097,12 +1073,10 @@ snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
hw->port1 = port;
hw->port2 = port + 0x400;
hw->port3 = port + 0x800;
hw->res_port1 = request_region(hw->port1, 4, "Emu8000-1");
hw->res_port2 = request_region(hw->port2, 4, "Emu8000-2");
hw->res_port3 = request_region(hw->port3, 4, "Emu8000-3");
if (!hw->res_port1 || !hw->res_port2 || !hw->res_port3) {
if (!devm_request_region(card->dev, hw->port1, 4, "Emu8000-1") ||
!devm_request_region(card->dev, hw->port2, 4, "Emu8000-2") ||
!devm_request_region(card->dev, hw->port3, 4, "Emu8000-3")) {
snd_printk(KERN_ERR "sbawe: can't grab ports 0x%lx, 0x%lx, 0x%lx\n", hw->port1, hw->port2, hw->port3);
snd_emu8000_free(hw);
return -EBUSY;
}
hw->mem_size = 0;
@ -1115,23 +1089,13 @@ snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
hw->fm_chorus_depth = 0;
hw->fm_reverb_depth = 0;
if (snd_emu8000_detect(hw) < 0) {
snd_emu8000_free(hw);
if (snd_emu8000_detect(hw) < 0)
return -ENODEV;
}
snd_emu8000_init_hw(hw);
err = snd_emu8000_create_mixer(card, hw);
if (err < 0) {
snd_emu8000_free(hw);
if (err < 0)
return err;
}
err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops);
if (err < 0) {
snd_emu8000_free(hw);
return err;
}
#if IS_ENABLED(CONFIG_SND_SEQUENCER)
if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
sizeof(struct snd_emu8000*), &awe) >= 0) {

View File

@ -226,8 +226,8 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
static const int possible_dmas16[] = {5, 7, -1};
int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq;
err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_jazz16), &card);
err = snd_devm_card_new(devptr, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_jazz16), &card);
if (err < 0)
return err;
@ -238,8 +238,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
xirq = snd_legacy_find_free_irq(possible_irqs);
if (xirq < 0) {
snd_printk(KERN_ERR "unable to find a free IRQ\n");
err = -EBUSY;
goto err_free;
return -EBUSY;
}
}
xdma8 = dma8[dev];
@ -247,8 +246,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
xdma8 = snd_legacy_find_free_dma(possible_dmas8);
if (xdma8 < 0) {
snd_printk(KERN_ERR "unable to find a free DMA8\n");
err = -EBUSY;
goto err_free;
return -EBUSY;
}
}
xdma16 = dma16[dev];
@ -256,8 +254,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
xdma16 = snd_legacy_find_free_dma(possible_dmas16);
if (xdma16 < 0) {
snd_printk(KERN_ERR "unable to find a free DMA16\n");
err = -EBUSY;
goto err_free;
return -EBUSY;
}
}
@ -267,7 +264,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
err = jazz16_detect_board(port[dev], xmpu_port);
if (err < 0) {
printk(KERN_ERR "Media Vision Jazz16 board not detected\n");
goto err_free;
return err;
}
err = snd_sbdsp_create(card, port[dev], irq[dev],
jazz16_interrupt,
@ -275,7 +272,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
SB_HW_JAZZ16,
&chip);
if (err < 0)
goto err_free;
return err;
xmpu_irq = mpu_irq[dev];
if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT)
@ -283,7 +280,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
err = jazz16_configure_board(chip, xmpu_irq);
if (err < 0) {
printk(KERN_ERR "Media Vision Jazz16 configuration failed\n");
goto err_free;
return err;
}
jazz16->chip = chip;
@ -296,10 +293,10 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
err = snd_sb8dsp_pcm(chip, 0);
if (err < 0)
goto err_free;
return err;
err = snd_sbmixer_new(chip);
if (err < 0)
goto err_free;
return err;
err = snd_opl3_create(card, chip->port, chip->port + 2,
OPL3_HW_AUTO, 1, &opl3);
@ -309,7 +306,7 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
else {
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0)
goto err_free;
return err;
}
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
@ -326,21 +323,10 @@ static int snd_jazz16_probe(struct device *devptr, unsigned int dev)
err = snd_card_register(card);
if (err < 0)
goto err_free;
return err;
dev_set_drvdata(devptr, card);
return 0;
err_free:
snd_card_free(card);
return err;
}
static void snd_jazz16_remove(struct device *devptr, unsigned int dev)
{
struct snd_card *card = dev_get_drvdata(devptr);
snd_card_free(card);
}
#ifdef CONFIG_PM
@ -372,7 +358,6 @@ static int snd_jazz16_resume(struct device *pdev, unsigned int n)
static struct isa_driver snd_jazz16_driver = {
.match = snd_jazz16_match,
.probe = snd_jazz16_probe,
.remove = snd_jazz16_remove,
#ifdef CONFIG_PM
.suspend = snd_jazz16_suspend,
.resume = snd_jazz16_resume,

View File

@ -285,15 +285,6 @@ __wt_error:
#endif /* CONFIG_PNP */
static void snd_sb16_free(struct snd_card *card)
{
struct snd_card_sb16 *acard = card->private_data;
if (acard == NULL)
return;
release_and_free_resource(acard->fm_res);
}
#ifdef CONFIG_PNP
#define is_isapnp_selected(dev) isapnp[dev]
#else
@ -306,11 +297,10 @@ static int snd_sb16_card_new(struct device *devptr, int dev,
struct snd_card *card;
int err;
err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_sb16), &card);
err = snd_devm_card_new(devptr, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_sb16), &card);
if (err < 0)
return err;
card->private_free = snd_sb16_free;
*cardp = card;
return 0;
}
@ -482,17 +472,16 @@ static int snd_sb16_isa_probe1(int dev, struct device *pdev)
/* non-PnP FM port address is hardwired with base port address */
fm_port[dev] = port[dev];
/* block the 0x388 port to avoid PnP conflicts */
acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
acard->fm_res = devm_request_region(card->dev, 0x388, 4,
"SoundBlaster FM");
#ifdef SNDRV_SBAWE_EMU8000
/* non-PnP AWE port address is hardwired with base port address */
awe_port[dev] = port[dev] + 0x400;
#endif
err = snd_sb16_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
dev_set_drvdata(pdev, card);
return 0;
}
@ -547,11 +536,6 @@ static int snd_sb16_isa_probe(struct device *pdev, unsigned int dev)
}
}
static void snd_sb16_isa_remove(struct device *pdev, unsigned int dev)
{
snd_card_free(dev_get_drvdata(pdev));
}
#ifdef CONFIG_PM
static int snd_sb16_isa_suspend(struct device *dev, unsigned int n,
pm_message_t state)
@ -574,7 +558,6 @@ static int snd_sb16_isa_resume(struct device *dev, unsigned int n)
static struct isa_driver snd_sb16_isa_driver = {
.match = snd_sb16_isa_match,
.probe = snd_sb16_isa_probe,
.remove = snd_sb16_isa_remove,
#ifdef CONFIG_PM
.suspend = snd_sb16_isa_suspend,
.resume = snd_sb16_isa_resume,
@ -600,15 +583,11 @@ static int snd_sb16_pnp_detect(struct pnp_card_link *pcard,
if (res < 0)
return res;
res = snd_card_sb16_pnp(dev, card->private_data, pcard, pid);
if (res < 0) {
snd_card_free(card);
if (res < 0)
return res;
}
res = snd_sb16_probe(card, dev);
if (res < 0) {
snd_card_free(card);
if (res < 0)
return res;
}
pnp_set_card_drvdata(pcard, card);
dev++;
return 0;
@ -617,12 +596,6 @@ static int snd_sb16_pnp_detect(struct pnp_card_link *pcard,
return -ENODEV;
}
static void snd_sb16_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_sb16_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
{
@ -643,7 +616,6 @@ static struct pnp_card_driver sb16_pnpc_driver = {
#endif
.id_table = snd_sb16_pnpids,
.probe = snd_sb16_pnp_detect,
.remove = snd_sb16_pnp_remove,
#ifdef CONFIG_PM
.suspend = snd_sb16_pnp_suspend,
.resume = snd_sb16_pnp_resume,

View File

@ -54,15 +54,6 @@ static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id)
}
}
static void snd_sb8_free(struct snd_card *card)
{
struct snd_sb8 *acard = card->private_data;
if (acard == NULL)
return;
release_and_free_resource(acard->fm_res);
}
static int snd_sb8_match(struct device *pdev, unsigned int dev)
{
if (!enable[dev])
@ -86,26 +77,26 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
struct snd_opl3 *opl3;
int err;
err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_sb8), &card);
err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_sb8), &card);
if (err < 0)
return err;
acard = card->private_data;
card->private_free = snd_sb8_free;
/*
* Block the 0x388 port to avoid PnP conflicts.
* No need to check this value after request_region,
* as we never do anything with it.
*/
acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");
acard->fm_res = devm_request_region(card->dev, 0x388, 4,
"SoundBlaster FM");
if (port[dev] != SNDRV_AUTO_PORT) {
err = snd_sbdsp_create(card, port[dev], irq[dev],
snd_sb8_interrupt, dma8[dev],
-1, SB_HW_AUTO, &chip);
if (err < 0)
goto _err;
return err;
} else {
/* auto-probe legacy ports */
static const unsigned long possible_ports[] = {
@ -125,10 +116,8 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
break;
}
}
if (i >= ARRAY_SIZE(possible_ports)) {
err = -EINVAL;
goto _err;
}
if (i >= ARRAY_SIZE(possible_ports))
return -EINVAL;
}
acard->chip = chip;
@ -139,17 +128,16 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
else
snd_printk(KERN_WARNING "SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
port[dev]);
err = -ENODEV;
goto _err;
return -ENODEV;
}
err = snd_sb8dsp_pcm(chip, 0);
if (err < 0)
goto _err;
return err;
err = snd_sbmixer_new(chip);
if (err < 0)
goto _err;
return err;
if (chip->hardware == SB_HW_10 || chip->hardware == SB_HW_20) {
err = snd_opl3_create(card, chip->port + 8, 0,
@ -167,12 +155,12 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
if (err >= 0) {
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0)
goto _err;
return err;
}
err = snd_sb8dsp_midi(chip, 0);
if (err < 0)
goto _err;
return err;
strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8");
strcpy(card->shortname, chip->name);
@ -183,19 +171,10 @@ static int snd_sb8_probe(struct device *pdev, unsigned int dev)
err = snd_card_register(card);
if (err < 0)
goto _err;
return err;
dev_set_drvdata(pdev, card);
return 0;
_err:
snd_card_free(card);
return err;
}
static void snd_sb8_remove(struct device *pdev, unsigned int dev)
{
snd_card_free(dev_get_drvdata(pdev));
}
#ifdef CONFIG_PM
@ -229,7 +208,6 @@ static int snd_sb8_resume(struct device *dev, unsigned int n)
static struct isa_driver snd_sb8_driver = {
.match = snd_sb8_match,
.probe = snd_sb8_probe,
.remove = snd_sb8_remove,
#ifdef CONFIG_PM
.suspend = snd_sb8_suspend,
.resume = snd_sb8_resume,

View File

@ -168,31 +168,6 @@ static int snd_sbdsp_probe(struct snd_sb * chip)
return 0;
}
static int snd_sbdsp_free(struct snd_sb *chip)
{
release_and_free_resource(chip->res_port);
if (chip->irq >= 0)
free_irq(chip->irq, (void *) chip);
#ifdef CONFIG_ISA
if (chip->dma8 >= 0) {
disable_dma(chip->dma8);
free_dma(chip->dma8);
}
if (chip->dma16 >= 0 && chip->dma16 != chip->dma8) {
disable_dma(chip->dma16);
free_dma(chip->dma16);
}
#endif
kfree(chip);
return 0;
}
static int snd_sbdsp_dev_free(struct snd_device *device)
{
struct snd_sb *chip = device->device_data;
return snd_sbdsp_free(chip);
}
int snd_sbdsp_create(struct snd_card *card,
unsigned long port,
int irq,
@ -204,15 +179,12 @@ int snd_sbdsp_create(struct snd_card *card,
{
struct snd_sb *chip;
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_sbdsp_dev_free,
};
if (snd_BUG_ON(!r_chip))
return -EINVAL;
*r_chip = NULL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
chip = devm_kzalloc(card->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
spin_lock_init(&chip->reg_lock);
spin_lock_init(&chip->open_lock);
@ -223,13 +195,12 @@ int snd_sbdsp_create(struct snd_card *card,
chip->dma16 = -1;
chip->port = port;
if (request_irq(irq, irq_handler,
(hardware == SB_HW_ALS4000 ||
hardware == SB_HW_CS5530) ?
IRQF_SHARED : 0,
"SoundBlaster", (void *) chip)) {
if (devm_request_irq(card->dev, irq, irq_handler,
(hardware == SB_HW_ALS4000 ||
hardware == SB_HW_CS5530) ?
IRQF_SHARED : 0,
"SoundBlaster", (void *) chip)) {
snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq);
snd_sbdsp_free(chip);
return -EBUSY;
}
chip->irq = irq;
@ -238,17 +209,17 @@ int snd_sbdsp_create(struct snd_card *card,
if (hardware == SB_HW_ALS4000)
goto __skip_allocation;
chip->res_port = request_region(port, 16, "SoundBlaster");
chip->res_port = devm_request_region(card->dev, port, 16,
"SoundBlaster");
if (!chip->res_port) {
snd_printk(KERN_ERR "sb: can't grab port 0x%lx\n", port);
snd_sbdsp_free(chip);
return -EBUSY;
}
#ifdef CONFIG_ISA
if (dma8 >= 0 && request_dma(dma8, "SoundBlaster - 8bit")) {
if (dma8 >= 0 && snd_devm_request_dma(card->dev, dma8,
"SoundBlaster - 8bit")) {
snd_printk(KERN_ERR "sb: can't grab DMA8 %d\n", dma8);
snd_sbdsp_free(chip);
return -EBUSY;
}
chip->dma8 = dma8;
@ -256,9 +227,9 @@ int snd_sbdsp_create(struct snd_card *card,
if (hardware != SB_HW_ALS100 && (dma16 < 5 || dma16 > 7)) {
/* no duplex */
dma16 = -1;
} else if (request_dma(dma16, "SoundBlaster - 16bit")) {
} else if (snd_devm_request_dma(card->dev, dma16,
"SoundBlaster - 16bit")) {
snd_printk(KERN_ERR "sb: can't grab DMA16 %d\n", dma16);
snd_sbdsp_free(chip);
return -EBUSY;
}
}
@ -269,15 +240,8 @@ int snd_sbdsp_create(struct snd_card *card,
chip->card = card;
chip->hardware = hardware;
err = snd_sbdsp_probe(chip);
if (err < 0) {
snd_sbdsp_free(chip);
if (err < 0)
return err;
}
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_sbdsp_free(chip);
return err;
}
*r_chip = chip;
return 0;
}

View File

@ -529,6 +529,14 @@ static int snd_sc6000_match(struct device *devptr, unsigned int dev)
return 1;
}
static void snd_sc6000_free(struct snd_card *card)
{
char __iomem *vport = (char __force __iomem *)card->private_data;
if (vport)
sc6000_setup_board(vport, 0);
}
static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
{
static const int possible_irqs[] = { 5, 7, 9, 10, 11, -1 };
@ -539,22 +547,19 @@ static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
struct snd_card *card;
struct snd_wss *chip;
struct snd_opl3 *opl3;
char __iomem **vport;
char __iomem *vport;
char __iomem *vmss_port;
err = snd_card_new(devptr, index[dev], id[dev], THIS_MODULE,
sizeof(vport), &card);
err = snd_devm_card_new(devptr, index[dev], id[dev], THIS_MODULE,
0, &card);
if (err < 0)
return err;
vport = card->private_data;
if (xirq == SNDRV_AUTO_IRQ) {
xirq = snd_legacy_find_free_irq(possible_irqs);
if (xirq < 0) {
snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
err = -EBUSY;
goto err_exit;
return -EBUSY;
}
}
@ -562,68 +567,65 @@ static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
xdma = snd_legacy_find_free_dma(possible_dmas);
if (xdma < 0) {
snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
err = -EBUSY;
goto err_exit;
return -EBUSY;
}
}
if (!request_region(port[dev], 0x10, DRV_NAME)) {
if (!devm_request_region(devptr, port[dev], 0x10, DRV_NAME)) {
snd_printk(KERN_ERR PFX
"I/O port region is already in use.\n");
err = -EBUSY;
goto err_exit;
return -EBUSY;
}
*vport = devm_ioport_map(devptr, port[dev], 0x10);
if (*vport == NULL) {
vport = devm_ioport_map(devptr, port[dev], 0x10);
if (!vport) {
snd_printk(KERN_ERR PFX
"I/O port cannot be iomapped.\n");
err = -EBUSY;
goto err_unmap1;
return -EBUSY;
}
card->private_data = (void __force *)vport;
/* to make it marked as used */
if (!request_region(mss_port[dev], 4, DRV_NAME)) {
if (!devm_request_region(devptr, mss_port[dev], 4, DRV_NAME)) {
snd_printk(KERN_ERR PFX
"SC-6000 port I/O port region is already in use.\n");
err = -EBUSY;
goto err_unmap1;
return -EBUSY;
}
vmss_port = devm_ioport_map(devptr, mss_port[dev], 4);
if (!vmss_port) {
snd_printk(KERN_ERR PFX
"MSS port I/O cannot be iomapped.\n");
err = -EBUSY;
goto err_unmap2;
return -EBUSY;
}
snd_printd("Initializing BASE[0x%lx] IRQ[%d] DMA[%d] MIRQ[%d]\n",
port[dev], xirq, xdma,
mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]);
err = sc6000_init_board(*vport, vmss_port, dev);
err = sc6000_init_board(vport, vmss_port, dev);
if (err < 0)
goto err_unmap2;
return err;
card->private_free = snd_sc6000_free;
err = snd_wss_create(card, mss_port[dev] + 4, -1, xirq, xdma, -1,
WSS_HW_DETECT, 0, &chip);
if (err < 0)
goto err_unmap2;
return err;
err = snd_wss_pcm(chip, 0);
if (err < 0) {
snd_printk(KERN_ERR PFX
"error creating new WSS PCM device\n");
goto err_unmap2;
return err;
}
err = snd_wss_mixer(chip);
if (err < 0) {
snd_printk(KERN_ERR PFX "error creating new WSS mixer\n");
goto err_unmap2;
return err;
}
err = snd_sc6000_mixer(chip);
if (err < 0) {
snd_printk(KERN_ERR PFX "the mixer rewrite failed\n");
goto err_unmap2;
return err;
}
if (snd_opl3_create(card,
0x388, 0x388 + 2,
@ -633,7 +635,7 @@ static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
} else {
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0)
goto err_unmap2;
return err;
}
if (mpu_port[dev] != SNDRV_AUTO_PORT) {
@ -654,39 +656,15 @@ static int snd_sc6000_probe(struct device *devptr, unsigned int dev)
err = snd_card_register(card);
if (err < 0)
goto err_unmap2;
return err;
dev_set_drvdata(devptr, card);
return 0;
err_unmap2:
sc6000_setup_board(*vport, 0);
release_region(mss_port[dev], 4);
err_unmap1:
release_region(port[dev], 0x10);
err_exit:
snd_card_free(card);
return err;
}
static void snd_sc6000_remove(struct device *devptr, unsigned int dev)
{
struct snd_card *card = dev_get_drvdata(devptr);
char __iomem **vport = card->private_data;
if (sc6000_setup_board(*vport, 0) < 0)
snd_printk(KERN_WARNING "sc6000_setup_board failed on exit!\n");
release_region(port[dev], 0x10);
release_region(mss_port[dev], 4);
snd_card_free(card);
}
static struct isa_driver snd_sc6000_driver = {
.match = snd_sc6000_match,
.probe = snd_sc6000_probe,
.remove = snd_sc6000_remove,
/* FIXME: suspend/resume */
.driver = {
.name = DRV_NAME,

View File

@ -327,17 +327,6 @@ static void activate_ad1845_unsafe(unsigned io_base)
sscape_write_unsafe(io_base, GA_CDCFG_REG, 0x80);
}
/*
* Do the necessary ALSA-level cleanup to deallocate our driver ...
*/
static void soundscape_free(struct snd_card *c)
{
struct soundscape *sscape = get_card_soundscape(c);
release_and_free_resource(sscape->io_res);
release_and_free_resource(sscape->wss_res);
free_dma(sscape->chip->dma1);
}
/*
* Tell the SoundScape to begin a DMA transfer using the given channel.
* All locking issues are left to the caller.
@ -941,7 +930,7 @@ static int create_sscape(int dev, struct snd_card *card)
* Grab IO ports that we will need to probe so that we
* can detect and control this hardware ...
*/
io_res = request_region(port[dev], 8, "SoundScape");
io_res = devm_request_region(card->dev, port[dev], 8, "SoundScape");
if (!io_res) {
snd_printk(KERN_ERR
"sscape: can't grab port 0x%lx\n", port[dev]);
@ -949,22 +938,22 @@ static int create_sscape(int dev, struct snd_card *card)
}
wss_res = NULL;
if (sscape->type == SSCAPE_VIVO) {
wss_res = request_region(wss_port[dev], 4, "SoundScape");
wss_res = devm_request_region(card->dev, wss_port[dev], 4,
"SoundScape");
if (!wss_res) {
snd_printk(KERN_ERR "sscape: can't grab port 0x%lx\n",
wss_port[dev]);
err = -EBUSY;
goto _release_region;
return -EBUSY;
}
}
/*
* Grab one DMA channel ...
*/
err = request_dma(dma[dev], "SoundScape");
err = snd_devm_request_dma(card->dev, dma[dev], "SoundScape");
if (err < 0) {
snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", dma[dev]);
goto _release_region;
return err;
}
spin_lock_init(&sscape->lock);
@ -975,8 +964,7 @@ static int create_sscape(int dev, struct snd_card *card)
if (!detect_sscape(sscape, wss_port[dev])) {
printk(KERN_ERR "sscape: hardware not detected at 0x%x\n",
sscape->io_base);
err = -ENODEV;
goto _release_dma;
return -ENODEV;
}
switch (sscape->type) {
@ -1006,15 +994,13 @@ static int create_sscape(int dev, struct snd_card *card)
irq_cfg = get_irq_config(sscape->type, irq[dev]);
if (irq_cfg == INVALID_IRQ) {
snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]);
err = -ENXIO;
goto _release_dma;
return -ENXIO;
}
mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]);
if (mpu_irq_cfg == INVALID_IRQ) {
snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]);
err = -ENXIO;
goto _release_dma;
return -ENXIO;
}
/*
@ -1060,7 +1046,7 @@ static int create_sscape(int dev, struct snd_card *card)
snd_printk(KERN_ERR
"sscape: No AD1845 device at 0x%lx, IRQ %d\n",
wss_port[dev], irq[dev]);
goto _release_dma;
return err;
}
strcpy(card->driver, "SoundScape");
strcpy(card->shortname, name);
@ -1082,7 +1068,7 @@ static int create_sscape(int dev, struct snd_card *card)
snd_printk(KERN_ERR "sscape: Failed to create "
"MPU-401 device at 0x%lx\n",
port[dev]);
goto _release_dma;
return err;
}
/*
@ -1109,24 +1095,7 @@ static int create_sscape(int dev, struct snd_card *card)
}
}
/*
* Now that we have successfully created this sound card,
* it is safe to store the pointer.
* NOTE: we only register the sound card's "destructor"
* function now that our "constructor" has completed.
*/
card->private_free = soundscape_free;
return 0;
_release_dma:
free_dma(dma[dev]);
_release_region:
release_and_free_resource(wss_res);
release_and_free_resource(io_res);
return err;
}
@ -1156,8 +1125,8 @@ static int snd_sscape_probe(struct device *pdev, unsigned int dev)
struct soundscape *sscape;
int ret;
ret = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct soundscape), &card);
ret = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(struct soundscape), &card);
if (ret < 0)
return ret;
@ -1168,24 +1137,15 @@ static int snd_sscape_probe(struct device *pdev, unsigned int dev)
ret = create_sscape(dev, card);
if (ret < 0)
goto _release_card;
return ret;
ret = snd_card_register(card);
if (ret < 0) {
snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
goto _release_card;
return ret;
}
dev_set_drvdata(pdev, card);
return 0;
_release_card:
snd_card_free(card);
return ret;
}
static void snd_sscape_remove(struct device *devptr, unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
#define DEV_NAME "sscape"
@ -1193,7 +1153,6 @@ static void snd_sscape_remove(struct device *devptr, unsigned int dev)
static struct isa_driver snd_sscape_driver = {
.match = snd_sscape_match,
.probe = snd_sscape_probe,
.remove = snd_sscape_remove,
/* FIXME: suspend/resume */
.driver = {
.name = DEV_NAME
@ -1244,9 +1203,9 @@ static int sscape_pnp_detect(struct pnp_card_link *pcard,
* Create a new ALSA sound card entry, in anticipation
* of detecting our hardware ...
*/
ret = snd_card_new(&pcard->card->dev,
index[idx], id[idx], THIS_MODULE,
sizeof(struct soundscape), &card);
ret = snd_devm_card_new(&pcard->card->dev,
index[idx], id[idx], THIS_MODULE,
sizeof(struct soundscape), &card);
if (ret < 0)
return ret;
@ -1277,27 +1236,17 @@ static int sscape_pnp_detect(struct pnp_card_link *pcard,
ret = create_sscape(idx, card);
if (ret < 0)
goto _release_card;
return ret;
ret = snd_card_register(card);
if (ret < 0) {
snd_printk(KERN_ERR "sscape: Failed to register sound card\n");
goto _release_card;
return ret;
}
pnp_set_card_drvdata(pcard, card);
++idx;
return 0;
_release_card:
snd_card_free(card);
return ret;
}
static void sscape_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
static struct pnp_card_driver sscape_pnpc_driver = {
@ -1305,7 +1254,6 @@ static struct pnp_card_driver sscape_pnpc_driver = {
.name = "sscape",
.id_table = sscape_pnpids,
.probe = sscape_pnp_detect,
.remove = sscape_pnp_remove,
};
#endif /* CONFIG_PNP */

View File

@ -308,18 +308,6 @@ static struct snd_rawmidi *snd_wavefront_new_midi(struct snd_card *card,
return rmidi;
}
static void
snd_wavefront_free(struct snd_card *card)
{
snd_wavefront_card_t *acard = (snd_wavefront_card_t *)card->private_data;
if (acard) {
release_and_free_resource(acard->wavefront.res_base);
if (acard->wavefront.irq > 0)
free_irq(acard->wavefront.irq, (void *)acard);
}
}
static int snd_wavefront_card_new(struct device *pdev, int dev,
struct snd_card **cardp)
{
@ -327,8 +315,8 @@ static int snd_wavefront_card_new(struct device *pdev, int dev,
snd_wavefront_card_t *acard;
int err;
err = snd_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(snd_wavefront_card_t), &card);
err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
sizeof(snd_wavefront_card_t), &card);
if (err < 0)
return err;
@ -339,7 +327,6 @@ static int snd_wavefront_card_new(struct device *pdev, int dev,
spin_lock_init(&acard->wavefront.midi.open);
spin_lock_init(&acard->wavefront.midi.virtual);
acard->wavefront.card = card;
card->private_free = snd_wavefront_free;
*cardp = card;
return 0;
@ -394,15 +381,17 @@ snd_wavefront_probe (struct snd_card *card, int dev)
/* ------- ICS2115 Wavetable synth ------- */
acard->wavefront.res_base = request_region(ics2115_port[dev], 16,
"ICS2115");
acard->wavefront.res_base =
devm_request_region(card->dev, ics2115_port[dev], 16,
"ICS2115");
if (acard->wavefront.res_base == NULL) {
snd_printk(KERN_ERR "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n",
ics2115_port[dev], ics2115_port[dev] + 16 - 1);
return -EBUSY;
}
if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt,
0, "ICS2115", acard)) {
if (devm_request_irq(card->dev, ics2115_irq[dev],
snd_wavefront_ics2115_interrupt,
0, "ICS2115", acard)) {
snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]);
return -EBUSY;
}
@ -556,27 +545,18 @@ static int snd_wavefront_isa_probe(struct device *pdev,
if (err < 0)
return err;
err = snd_wavefront_probe(card, dev);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
dev_set_drvdata(pdev, card);
return 0;
}
static void snd_wavefront_isa_remove(struct device *devptr,
unsigned int dev)
{
snd_card_free(dev_get_drvdata(devptr));
}
#define DEV_NAME "wavefront"
static struct isa_driver snd_wavefront_driver = {
.match = snd_wavefront_isa_match,
.probe = snd_wavefront_isa_probe,
.remove = snd_wavefront_isa_remove,
/* FIXME: suspend, resume */
.driver = {
.name = DEV_NAME
@ -606,7 +586,6 @@ static int snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
if (snd_wavefront_pnp (dev, card->private_data, pcard, pid) < 0) {
if (cs4232_pcm_port[dev] == SNDRV_AUTO_PORT) {
snd_printk (KERN_ERR "isapnp detection failed\n");
snd_card_free (card);
return -ENODEV;
}
}
@ -620,18 +599,11 @@ static int snd_wavefront_pnp_detect(struct pnp_card_link *pcard,
return 0;
}
static void snd_wavefront_pnp_remove(struct pnp_card_link *pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
static struct pnp_card_driver wavefront_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = "wavefront",
.id_table = snd_wavefront_pnpids,
.probe = snd_wavefront_pnp_detect,
.remove = snd_wavefront_pnp_remove,
/* FIXME: suspend,resume */
};

View File

@ -1655,36 +1655,6 @@ static void snd_wss_resume(struct snd_wss *chip)
}
#endif /* CONFIG_PM */
static int snd_wss_free(struct snd_wss *chip)
{
release_and_free_resource(chip->res_port);
release_and_free_resource(chip->res_cport);
if (chip->irq >= 0) {
disable_irq(chip->irq);
if (!(chip->hwshare & WSS_HWSHARE_IRQ))
free_irq(chip->irq, (void *) chip);
}
if (!(chip->hwshare & WSS_HWSHARE_DMA1) && chip->dma1 >= 0) {
snd_dma_disable(chip->dma1);
free_dma(chip->dma1);
}
if (!(chip->hwshare & WSS_HWSHARE_DMA2) &&
chip->dma2 >= 0 && chip->dma2 != chip->dma1) {
snd_dma_disable(chip->dma2);
free_dma(chip->dma2);
}
if (chip->timer)
snd_device_free(chip->card, chip->timer);
kfree(chip);
return 0;
}
static int snd_wss_dev_free(struct snd_device *device)
{
struct snd_wss *chip = device->device_data;
return snd_wss_free(chip);
}
const char *snd_wss_chip_id(struct snd_wss *chip)
{
switch (chip->hardware) {
@ -1738,7 +1708,7 @@ static int snd_wss_new(struct snd_card *card,
struct snd_wss *chip;
*rchip = NULL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
chip = devm_kzalloc(card->dev, sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
chip->hardware = hardware;
@ -1774,9 +1744,6 @@ int snd_wss_create(struct snd_card *card,
unsigned short hwshare,
struct snd_wss **rchip)
{
static const struct snd_device_ops ops = {
.dev_free = snd_wss_dev_free,
};
struct snd_wss *chip;
int err;
@ -1788,42 +1755,39 @@ int snd_wss_create(struct snd_card *card,
chip->dma1 = -1;
chip->dma2 = -1;
chip->res_port = request_region(port, 4, "WSS");
chip->res_port = devm_request_region(card->dev, port, 4, "WSS");
if (!chip->res_port) {
snd_printk(KERN_ERR "wss: can't grab port 0x%lx\n", port);
snd_wss_free(chip);
return -EBUSY;
}
chip->port = port;
if ((long)cport >= 0) {
chip->res_cport = request_region(cport, 8, "CS4232 Control");
chip->res_cport = devm_request_region(card->dev, cport, 8,
"CS4232 Control");
if (!chip->res_cport) {
snd_printk(KERN_ERR
"wss: can't grab control port 0x%lx\n", cport);
snd_wss_free(chip);
return -ENODEV;
}
}
chip->cport = cport;
if (!(hwshare & WSS_HWSHARE_IRQ))
if (request_irq(irq, snd_wss_interrupt, 0,
"WSS", (void *) chip)) {
if (devm_request_irq(card->dev, irq, snd_wss_interrupt, 0,
"WSS", (void *) chip)) {
snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq);
snd_wss_free(chip);
return -EBUSY;
}
chip->irq = irq;
card->sync_irq = chip->irq;
if (!(hwshare & WSS_HWSHARE_DMA1) && request_dma(dma1, "WSS - 1")) {
if (!(hwshare & WSS_HWSHARE_DMA1) &&
snd_devm_request_dma(card->dev, dma1, "WSS - 1")) {
snd_printk(KERN_ERR "wss: can't grab DMA1 %d\n", dma1);
snd_wss_free(chip);
return -EBUSY;
}
chip->dma1 = dma1;
if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 &&
dma2 >= 0 && request_dma(dma2, "WSS - 2")) {
if (!(hwshare & WSS_HWSHARE_DMA2) && dma1 != dma2 && dma2 >= 0 &&
snd_devm_request_dma(card->dev, dma2, "WSS - 2")) {
snd_printk(KERN_ERR "wss: can't grab DMA2 %d\n", dma2);
snd_wss_free(chip);
return -EBUSY;
}
if (dma1 == dma2 || dma2 < 0) {
@ -1839,10 +1803,8 @@ int snd_wss_create(struct snd_card *card,
}
/* global setup */
if (snd_wss_probe(chip) < 0) {
snd_wss_free(chip);
if (snd_wss_probe(chip) < 0)
return -ENODEV;
}
snd_wss_init(chip);
#if 0
@ -1853,13 +1815,6 @@ int snd_wss_create(struct snd_card *card,
}
#endif
/* Register device */
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_wss_free(chip);
return err;
}
#ifdef CONFIG_PM
/* Power Management */
chip->suspend = snd_wss_suspend;

View File

@ -563,22 +563,9 @@ snd_harmony_capture_close(struct snd_pcm_substream *ss)
return 0;
}
static int
snd_harmony_hw_params(struct snd_pcm_substream *ss,
struct snd_pcm_hw_params *hw)
{
struct snd_harmony *h = snd_pcm_substream_chip(ss);
if (h->dma.type == SNDRV_DMA_TYPE_CONTINUOUS)
ss->runtime->dma_addr = __pa(ss->runtime->dma_area);
return 0;
}
static const struct snd_pcm_ops snd_harmony_playback_ops = {
.open = snd_harmony_playback_open,
.close = snd_harmony_playback_close,
.hw_params = snd_harmony_hw_params,
.prepare = snd_harmony_playback_prepare,
.trigger = snd_harmony_playback_trigger,
.pointer = snd_harmony_playback_pointer,
@ -587,7 +574,6 @@ static const struct snd_pcm_ops snd_harmony_playback_ops = {
static const struct snd_pcm_ops snd_harmony_capture_ops = {
.open = snd_harmony_capture_open,
.close = snd_harmony_capture_close,
.hw_params = snd_harmony_hw_params,
.prepare = snd_harmony_capture_prepare,
.trigger = snd_harmony_capture_trigger,
.pointer = snd_harmony_capture_pointer,

View File

@ -740,20 +740,6 @@ snd_ad1889_ac97_xinit(struct snd_ad1889 *chip)
}
static void
snd_ad1889_ac97_bus_free(struct snd_ac97_bus *bus)
{
struct snd_ad1889 *chip = bus->private_data;
chip->ac97_bus = NULL;
}
static void
snd_ad1889_ac97_free(struct snd_ac97 *ac97)
{
struct snd_ad1889 *chip = ac97->private_data;
chip->ac97 = NULL;
}
static int
snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
{
@ -771,11 +757,8 @@ snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
if (err < 0)
return err;
chip->ac97_bus->private_free = snd_ad1889_ac97_bus_free;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
ac97.private_free = snd_ad1889_ac97_free;
ac97.pci = chip->pci;
err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97);
@ -787,11 +770,10 @@ snd_ad1889_ac97_init(struct snd_ad1889 *chip, const char *quirk_override)
return 0;
}
static int
snd_ad1889_free(struct snd_ad1889 *chip)
static void
snd_ad1889_free(struct snd_card *card)
{
if (chip->irq < 0)
goto skip_hw;
struct snd_ad1889 *chip = card->private_data;
spin_lock_irq(&chip->lock);
@ -805,28 +787,51 @@ snd_ad1889_free(struct snd_ad1889 *chip)
ad1889_readl(chip, AD_DMA_DISR); /* flush, dammit! */
spin_unlock_irq(&chip->lock);
if (chip->irq >= 0)
free_irq(chip->irq, chip);
skip_hw:
iounmap(chip->iobase);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
return 0;
}
static int
snd_ad1889_dev_free(struct snd_device *device)
snd_ad1889_create(struct snd_card *card, struct pci_dev *pci)
{
struct snd_ad1889 *chip = device->device_data;
return snd_ad1889_free(chip);
}
struct snd_ad1889 *chip = card->private_data;
int err;
static int
snd_ad1889_init(struct snd_ad1889 *chip)
{
err = pcim_enable_device(pci);
if (err < 0)
return err;
/* check PCI availability (32bit DMA) */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
dev_err(card->dev, "error setting 32-bit DMA mask.\n");
return -ENXIO;
}
chip->card = card;
chip->pci = pci;
chip->irq = -1;
/* (1) PCI resource allocation */
err = pcim_iomap_regions(pci, 1 << 0, card->driver);
if (err < 0)
return err;
chip->bar = pci_resource_start(pci, 0);
chip->iobase = pcim_iomap_table(pci)[0];
pci_set_master(pci);
spin_lock_init(&chip->lock); /* only now can we call ad1889_free */
if (devm_request_irq(&pci->dev, pci->irq, snd_ad1889_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(card->dev, "cannot obtain IRQ %d\n", pci->irq);
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_ad1889_free;
/* (2) initialization of the chip hardware */
ad1889_writew(chip, AD_DS_CCS, AD_DS_CCS_CLKEN); /* turn on clock */
ad1889_readw(chip, AD_DS_CCS); /* flush posted write */
@ -838,94 +843,6 @@ snd_ad1889_init(struct snd_ad1889 *chip)
return 0;
}
static int
snd_ad1889_create(struct snd_card *card,
struct pci_dev *pci,
struct snd_ad1889 **rchip)
{
int err;
struct snd_ad1889 *chip;
static const struct snd_device_ops ops = {
.dev_free = snd_ad1889_dev_free,
};
*rchip = NULL;
err = pci_enable_device(pci);
if (err < 0)
return err;
/* check PCI availability (32bit DMA) */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
dev_err(card->dev, "error setting 32-bit DMA mask.\n");
pci_disable_device(pci);
return -ENXIO;
}
/* allocate chip specific data with zero-filled memory */
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
}
chip->card = card;
card->private_data = chip;
chip->pci = pci;
chip->irq = -1;
/* (1) PCI resource allocation */
err = pci_request_regions(pci, card->driver);
if (err < 0)
goto free_and_ret;
chip->bar = pci_resource_start(pci, 0);
chip->iobase = pci_ioremap_bar(pci, 0);
if (chip->iobase == NULL) {
dev_err(card->dev, "unable to reserve region.\n");
err = -EBUSY;
goto free_and_ret;
}
pci_set_master(pci);
spin_lock_init(&chip->lock); /* only now can we call ad1889_free */
if (request_irq(pci->irq, snd_ad1889_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(card->dev, "cannot obtain IRQ %d\n", pci->irq);
snd_ad1889_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
/* (2) initialization of the chip hardware */
err = snd_ad1889_init(chip);
if (err < 0) {
snd_ad1889_free(chip);
return err;
}
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_ad1889_free(chip);
return err;
}
*rchip = chip;
return 0;
free_and_ret:
kfree(chip);
pci_disable_device(pci);
return err;
}
static int
snd_ad1889_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
@ -944,19 +861,19 @@ snd_ad1889_probe(struct pci_dev *pci,
}
/* (2) */
err = snd_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE,
0, &card);
/* XXX REVISIT: we can probably allocate chip in this call */
err = snd_devm_card_new(&pci->dev, index[devno], id[devno], THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
return err;
chip = card->private_data;
strcpy(card->driver, "AD1889");
strcpy(card->shortname, "Analog Devices AD1889");
/* (3) */
err = snd_ad1889_create(card, pci, &chip);
err = snd_ad1889_create(card, pci);
if (err < 0)
goto free_and_ret;
return err;
/* (4) */
sprintf(card->longname, "%s at 0x%lx irq %i",
@ -966,11 +883,11 @@ snd_ad1889_probe(struct pci_dev *pci,
/* register AC97 mixer */
err = snd_ad1889_ac97_init(chip, ac97_quirk[devno]);
if (err < 0)
goto free_and_ret;
return err;
err = snd_ad1889_pcm_init(chip, 0);
if (err < 0)
goto free_and_ret;
return err;
/* register proc interface */
snd_ad1889_proc_init(chip);
@ -978,23 +895,13 @@ snd_ad1889_probe(struct pci_dev *pci,
/* (6) */
err = snd_card_register(card);
if (err < 0)
goto free_and_ret;
return err;
/* (7) */
pci_set_drvdata(pci, card);
devno++;
return 0;
free_and_ret:
snd_card_free(card);
return err;
}
static void
snd_ad1889_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
static const struct pci_device_id snd_ad1889_ids[] = {
@ -1007,7 +914,6 @@ static struct pci_driver ad1889_pci_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_ad1889_ids,
.probe = snd_ad1889_probe,
.remove = snd_ad1889_remove,
};
module_pci_driver(ad1889_pci_driver);

View File

@ -1914,22 +1914,14 @@ static SIMPLE_DEV_PM_OPS(ali_pm, ali_suspend, ali_resume);
#define ALI_PM_OPS NULL
#endif /* CONFIG_PM_SLEEP */
static int snd_ali_free(struct snd_ali * codec)
static void snd_ali_free(struct snd_card *card)
{
struct snd_ali *codec = card->private_data;
if (codec->hw_initialized)
snd_ali_disable_address_interrupt(codec);
if (codec->irq >= 0)
free_irq(codec->irq, codec);
if (codec->port)
pci_release_regions(codec->pci);
pci_disable_device(codec->pci);
#ifdef CONFIG_PM_SLEEP
kfree(codec->image);
#endif
pci_dev_put(codec->pci_m1533);
pci_dev_put(codec->pci_m7101);
kfree(codec);
return 0;
}
static int snd_ali_chip_init(struct snd_ali *codec)
@ -2017,8 +2009,9 @@ static int snd_ali_resources(struct snd_ali *codec)
return err;
codec->port = pci_resource_start(codec->pci, 0);
if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
IRQF_SHARED, KBUILD_MODNAME, codec)) {
if (devm_request_irq(&codec->pci->dev, codec->pci->irq,
snd_ali_card_interrupt,
IRQF_SHARED, KBUILD_MODNAME, codec)) {
dev_err(codec->card->dev, "Unable to request irq.\n");
return -EBUSY;
}
@ -2027,48 +2020,29 @@ static int snd_ali_resources(struct snd_ali *codec)
dev_dbg(codec->card->dev, "resources allocated.\n");
return 0;
}
static int snd_ali_dev_free(struct snd_device *device)
{
struct snd_ali *codec = device->device_data;
snd_ali_free(codec);
return 0;
}
static int snd_ali_create(struct snd_card *card,
struct pci_dev *pci,
int pcm_streams,
int spdif_support,
struct snd_ali **r_ali)
int spdif_support)
{
struct snd_ali *codec;
struct snd_ali *codec = card->private_data;
int i, err;
unsigned short cmdw;
static const struct snd_device_ops ops = {
.dev_free = snd_ali_dev_free,
};
*r_ali = NULL;
dev_dbg(card->dev, "creating ...\n");
/* enable PCI device */
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 31 bits */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31))) {
dev_err(card->dev,
"architecture does not support 31bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
codec = kzalloc(sizeof(*codec), GFP_KERNEL);
if (!codec) {
pci_disable_device(pci);
return -ENOMEM;
}
spin_lock_init(&codec->reg_lock);
spin_lock_init(&codec->voice_alloc);
@ -2089,12 +2063,10 @@ static int snd_ali_create(struct snd_card *card,
cmdw |= PCI_COMMAND_IO;
pci_write_config_word(pci, PCI_COMMAND, cmdw);
}
pci_set_master(pci);
if (snd_ali_resources(codec)) {
snd_ali_free(codec);
if (snd_ali_resources(codec))
return -EBUSY;
}
card->private_free = snd_ali_free;
codec->synth.chmap = 0;
codec->synth.chcnt = 0;
@ -2121,24 +2093,15 @@ static int snd_ali_create(struct snd_card *card,
codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL);
if (!codec->pci_m1533) {
dev_err(card->dev, "cannot find ALi 1533 chip.\n");
snd_ali_free(codec);
return -ENODEV;
}
/* M7101: power management */
codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL);
if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) {
dev_err(card->dev, "cannot find ALi 7101 chip.\n");
snd_ali_free(codec);
return -ENODEV;
}
dev_dbg(card->dev, "snd_device_new is called.\n");
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops);
if (err < 0) {
snd_ali_free(codec);
return err;
}
/* initialise synth voices*/
for (i = 0; i < ALI_CHANNELS; i++)
codec->synth.voices[i].number = i;
@ -2150,16 +2113,14 @@ static int snd_ali_create(struct snd_card *card,
}
#ifdef CONFIG_PM_SLEEP
codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL);
codec->image = devm_kmalloc(&pci->dev, sizeof(*codec->image),
GFP_KERNEL);
if (!codec->image)
dev_warn(card->dev, "can't allocate apm buffer\n");
#endif
snd_ali_enable_address_interrupt(codec);
codec->hw_initialized = 1;
*r_ali = codec;
dev_dbg(card->dev, "created.\n");
return 0;
}
@ -2172,24 +2133,25 @@ static int snd_ali_probe(struct pci_dev *pci,
dev_dbg(&pci->dev, "probe ...\n");
err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
err = snd_devm_card_new(&pci->dev, index, id, THIS_MODULE,
sizeof(*codec), &card);
if (err < 0)
return err;
codec = card->private_data;
err = snd_ali_create(card, pci, pcm_channels, spdif, &codec);
err = snd_ali_create(card, pci, pcm_channels, spdif);
if (err < 0)
goto error;
card->private_data = codec;
return err;
dev_dbg(&pci->dev, "mixer building ...\n");
err = snd_ali_mixer(codec);
if (err < 0)
goto error;
return err;
dev_dbg(&pci->dev, "pcm building ...\n");
err = snd_ali_build_pcms(codec);
if (err < 0)
goto error;
return err;
snd_ali_proc_init(codec);
@ -2202,26 +2164,16 @@ static int snd_ali_probe(struct pci_dev *pci,
dev_dbg(&pci->dev, "register card.\n");
err = snd_card_register(card);
if (err < 0)
goto error;
return err;
pci_set_drvdata(pci, card);
return 0;
error:
snd_card_free(card);
return err;
}
static void snd_ali_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
static struct pci_driver ali5451_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_ali_ids,
.probe = snd_ali_probe,
.remove = snd_ali_remove,
.driver = {
.pm = ALI_PM_OPS,
},

View File

@ -163,21 +163,11 @@ static void snd_als300_set_irq_flag(struct snd_als300 *chip, int cmd)
snd_als300_gcr_write(chip->port, MISC_CONTROL, tmp);
}
static int snd_als300_free(struct snd_als300 *chip)
static void snd_als300_free(struct snd_card *card)
{
snd_als300_set_irq_flag(chip, IRQ_DISABLE);
if (chip->irq >= 0)
free_irq(chip->irq, chip);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
return 0;
}
struct snd_als300 *chip = card->private_data;
static int snd_als300_dev_free(struct snd_device *device)
{
struct snd_als300 *chip = device->device_data;
return snd_als300_free(chip);
snd_als300_set_irq_flag(chip, IRQ_DISABLE);
}
static irqreturn_t snd_als300_interrupt(int irq, void *dev_id)
@ -248,11 +238,6 @@ static irqreturn_t snd_als300plus_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
static void snd_als300_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
static unsigned short snd_als300_ac97_read(struct snd_ac97 *ac97,
unsigned short reg)
{
@ -610,35 +595,22 @@ static void snd_als300_init(struct snd_als300 *chip)
}
static int snd_als300_create(struct snd_card *card,
struct pci_dev *pci, int chip_type,
struct snd_als300 **rchip)
struct pci_dev *pci, int chip_type)
{
struct snd_als300 *chip;
struct snd_als300 *chip = card->private_data;
void *irq_handler;
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_als300_dev_free,
};
*rchip = NULL;
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) {
dev_err(card->dev, "error setting 28bit DMA mask\n");
pci_disable_device(pci);
return -ENXIO;
}
pci_set_master(pci);
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
chip->card = card;
chip->pci = pci;
chip->irq = -1;
@ -646,11 +618,9 @@ static int snd_als300_create(struct snd_card *card,
spin_lock_init(&chip->reg_lock);
err = pci_request_regions(pci, "ALS300");
if (err < 0) {
kfree(chip);
pci_disable_device(pci);
if (err < 0)
return err;
}
chip->port = pci_resource_start(pci, 0);
if (chip->chip_type == DEVICE_ALS300_PLUS)
@ -658,38 +628,29 @@ static int snd_als300_create(struct snd_card *card,
else
irq_handler = snd_als300_interrupt;
if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
KBUILD_MODNAME, chip)) {
if (devm_request_irq(&pci->dev, pci->irq, irq_handler, IRQF_SHARED,
KBUILD_MODNAME, chip)) {
dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
snd_als300_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_als300_free;
snd_als300_init(chip);
err = snd_als300_ac97(chip);
if (err < 0) {
dev_err(card->dev, "Could not create ac97\n");
snd_als300_free(chip);
return err;
}
err = snd_als300_new_pcm(chip);
if (err < 0) {
dev_err(card->dev, "Could not create PCM\n");
snd_als300_free(chip);
return err;
}
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_als300_free(chip);
return err;
}
*rchip = chip;
return 0;
}
@ -737,20 +698,17 @@ static int snd_als300_probe(struct pci_dev *pci,
return -ENOENT;
}
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
return err;
chip = card->private_data;
chip_type = pci_id->driver_data;
err = snd_als300_create(card, pci, chip_type, &chip);
if (err < 0) {
snd_card_free(card);
err = snd_als300_create(card, pci, chip_type);
if (err < 0)
return err;
}
card->private_data = chip;
strcpy(card->driver, "ALS300");
if (chip->chip_type == DEVICE_ALS300_PLUS)
@ -764,10 +722,9 @@ static int snd_als300_probe(struct pci_dev *pci,
card->shortname, chip->port, chip->irq);
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
pci_set_drvdata(pci, card);
dev++;
return 0;
@ -777,7 +734,6 @@ static struct pci_driver als300_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_als300_ids,
.probe = snd_als300_probe,
.remove = snd_als300_remove,
.driver = {
.pm = SND_ALS300_PM_OPS,
},

View File

@ -746,13 +746,15 @@ static int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
if (joystick_port[dev] == 1) { /* auto-detect */
for (io_port = 0x200; io_port <= 0x218; io_port += 8) {
r = request_region(io_port, 8, "ALS4000 gameport");
r = devm_request_region(&acard->pci->dev, io_port, 8,
"ALS4000 gameport");
if (r)
break;
}
} else {
io_port = joystick_port[dev];
r = request_region(io_port, 8, "ALS4000 gameport");
r = devm_request_region(&acard->pci->dev, io_port, 8,
"ALS4000 gameport");
}
if (!r) {
@ -763,7 +765,6 @@ static int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
acard->gameport = gp = gameport_allocate_port();
if (!gp) {
dev_err(&acard->pci->dev, "cannot allocate memory for gameport\n");
release_and_free_resource(r);
return -ENOMEM;
}
@ -771,7 +772,6 @@ static int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
gameport_set_phys(gp, "pci%s/gameport0", pci_name(acard->pci));
gameport_set_dev_parent(gp, &acard->pci->dev);
gp->io = io_port;
gameport_set_port_data(gp, r);
/* Enable legacy joystick port */
snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1);
@ -784,15 +784,11 @@ static int snd_als4000_create_gameport(struct snd_card_als4000 *acard, int dev)
static void snd_als4000_free_gameport(struct snd_card_als4000 *acard)
{
if (acard->gameport) {
struct resource *r = gameport_get_port_data(acard->gameport);
gameport_unregister_port(acard->gameport);
acard->gameport = NULL;
/* disable joystick */
snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0);
release_and_free_resource(r);
}
}
#else
@ -808,8 +804,6 @@ static void snd_card_als4000_free( struct snd_card *card )
snd_als4k_gcr_write_addr(acard->iobase, ALS4K_GCR8C_MISC_CTRL, 0);
/* free resources */
snd_als4000_free_gameport(acard);
pci_release_regions(acard->pci);
pci_disable_device(acard->pci);
}
static int snd_card_als4000_probe(struct pci_dev *pci,
@ -832,36 +826,30 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
}
/* enable PCI device */
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
/* check, if we can restrict PCI DMA transfers to 24 bits */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(24))) {
dev_err(&pci->dev, "architecture does not support 24bit PCI busmaster DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
err = pci_request_regions(pci, "ALS4000");
if (err < 0) {
pci_disable_device(pci);
if (err < 0)
return err;
}
iobase = pci_resource_start(pci, 0);
pci_read_config_word(pci, PCI_COMMAND, &word);
pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO);
pci_set_master(pci);
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(*acard) /* private_data: acard */,
&card);
if (err < 0) {
pci_release_regions(pci);
pci_disable_device(pci);
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(*acard) /* private_data: acard */,
&card);
if (err < 0)
return err;
}
acard = card->private_data;
acard->pci = pci;
@ -881,7 +869,7 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
SB_HW_ALS4000,
&chip);
if (err < 0)
goto out_err;
return err;
acard->chip = chip;
chip->pci = pci;
@ -902,7 +890,7 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
if (err < 0) {
dev_err(&pci->dev, "no MPU-401 device at 0x%lx?\n",
iobase + ALS4K_IOB_30_MIDI_DATA);
goto out_err;
return err;
}
/* FIXME: ALS4000 has interesting MPU401 configuration features
* at ALS4K_CR1A_MPU401_UART_MODE_CONTROL
@ -912,11 +900,11 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
err = snd_als4000_pcm(chip, 0);
if (err < 0)
goto out_err;
return err;
err = snd_sbmixer_new(chip);
if (err < 0)
goto out_err;
return err;
if (snd_opl3_create(card,
iobase + ALS4K_IOB_10_ADLIB_ADDR0,
@ -928,30 +916,18 @@ static int snd_card_als4000_probe(struct pci_dev *pci,
} else {
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0)
goto out_err;
return err;
}
snd_als4000_create_gameport(acard, dev);
err = snd_card_register(card);
if (err < 0)
goto out_err;
return err;
pci_set_drvdata(pci, card);
dev++;
err = 0;
goto out;
out_err:
snd_card_free(card);
out:
return err;
}
static void snd_card_als4000_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
return 0;
}
#ifdef CONFIG_PM_SLEEP
@ -996,7 +972,6 @@ static struct pci_driver als4000_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_als4000_ids,
.probe = snd_card_als4000_probe,
.remove = snd_card_als4000_remove,
.driver = {
.pm = SND_ALS4000_PM_OPS,
},

View File

@ -1530,87 +1530,44 @@ static void snd_atiixp_proc_init(struct atiixp *chip)
* destructor
*/
static int snd_atiixp_free(struct atiixp *chip)
static void snd_atiixp_free(struct snd_card *card)
{
if (chip->irq < 0)
goto __hw_end;
snd_atiixp_chip_stop(chip);
__hw_end:
if (chip->irq >= 0)
free_irq(chip->irq, chip);
iounmap(chip->remap_addr);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
return 0;
}
static int snd_atiixp_dev_free(struct snd_device *device)
{
struct atiixp *chip = device->device_data;
return snd_atiixp_free(chip);
snd_atiixp_chip_stop(card->private_data);
}
/*
* constructor for chip instance
*/
static int snd_atiixp_create(struct snd_card *card,
struct pci_dev *pci,
struct atiixp **r_chip)
static int snd_atiixp_init(struct snd_card *card, struct pci_dev *pci)
{
static const struct snd_device_ops ops = {
.dev_free = snd_atiixp_dev_free,
};
struct atiixp *chip;
struct atiixp *chip = card->private_data;
int err;
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
spin_lock_init(&chip->reg_lock);
mutex_init(&chip->open_mutex);
chip->card = card;
chip->pci = pci;
chip->irq = -1;
err = pci_request_regions(pci, "ATI IXP AC97");
if (err < 0) {
pci_disable_device(pci);
kfree(chip);
err = pcim_iomap_regions(pci, 1 << 0, "ATI IXP AC97");
if (err < 0)
return err;
}
chip->addr = pci_resource_start(pci, 0);
chip->remap_addr = pci_ioremap_bar(pci, 0);
if (chip->remap_addr == NULL) {
dev_err(card->dev, "AC'97 space ioremap problem\n");
snd_atiixp_free(chip);
return -EIO;
}
chip->remap_addr = pcim_iomap_table(pci)[0];
if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
KBUILD_MODNAME, chip)) {
if (devm_request_irq(&pci->dev, pci->irq, snd_atiixp_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
snd_atiixp_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_atiixp_free;
pci_set_master(pci);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_atiixp_free(chip);
return err;
}
*r_chip = chip;
return 0;
}
@ -1622,30 +1579,31 @@ static int snd_atiixp_probe(struct pci_dev *pci,
struct atiixp *chip;
int err;
err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
err = snd_devm_card_new(&pci->dev, index, id, THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
return err;
chip = card->private_data;
strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA");
strcpy(card->shortname, "ATI IXP");
err = snd_atiixp_create(card, pci, &chip);
err = snd_atiixp_init(card, pci);
if (err < 0)
goto __error;
card->private_data = chip;
return err;
err = snd_atiixp_aclink_reset(chip);
if (err < 0)
goto __error;
return err;
chip->spdif_over_aclink = spdif_aclink;
err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk);
if (err < 0)
goto __error;
return err;
err = snd_atiixp_pcm_new(chip);
if (err < 0)
goto __error;
return err;
snd_atiixp_proc_init(chip);
@ -1659,26 +1617,16 @@ static int snd_atiixp_probe(struct pci_dev *pci,
err = snd_card_register(card);
if (err < 0)
goto __error;
return err;
pci_set_drvdata(pci, card);
return 0;
__error:
snd_card_free(card);
return err;
}
static void snd_atiixp_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
static struct pci_driver atiixp_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_atiixp_ids,
.probe = snd_atiixp_probe,
.remove = snd_atiixp_remove,
.driver = {
.pm = SND_ATIIXP_PM_OPS,
},

View File

@ -1159,87 +1159,44 @@ static void snd_atiixp_proc_init(struct atiixp_modem *chip)
* destructor
*/
static int snd_atiixp_free(struct atiixp_modem *chip)
static void snd_atiixp_free(struct snd_card *card)
{
if (chip->irq < 0)
goto __hw_end;
snd_atiixp_chip_stop(chip);
__hw_end:
if (chip->irq >= 0)
free_irq(chip->irq, chip);
iounmap(chip->remap_addr);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
return 0;
}
static int snd_atiixp_dev_free(struct snd_device *device)
{
struct atiixp_modem *chip = device->device_data;
return snd_atiixp_free(chip);
snd_atiixp_chip_stop(card->private_data);
}
/*
* constructor for chip instance
*/
static int snd_atiixp_create(struct snd_card *card,
struct pci_dev *pci,
struct atiixp_modem **r_chip)
static int snd_atiixp_init(struct snd_card *card, struct pci_dev *pci)
{
static const struct snd_device_ops ops = {
.dev_free = snd_atiixp_dev_free,
};
struct atiixp_modem *chip;
struct atiixp_modem *chip = card->private_data;
int err;
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
spin_lock_init(&chip->reg_lock);
mutex_init(&chip->open_mutex);
chip->card = card;
chip->pci = pci;
chip->irq = -1;
err = pci_request_regions(pci, "ATI IXP MC97");
if (err < 0) {
kfree(chip);
pci_disable_device(pci);
err = pcim_iomap_regions(pci, 1 << 0, "ATI IXP MC97");
if (err < 0)
return err;
}
chip->addr = pci_resource_start(pci, 0);
chip->remap_addr = pci_ioremap_bar(pci, 0);
if (chip->remap_addr == NULL) {
dev_err(card->dev, "AC'97 space ioremap problem\n");
snd_atiixp_free(chip);
return -EIO;
}
chip->remap_addr = pcim_iomap_table(pci)[0];
if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
KBUILD_MODNAME, chip)) {
if (devm_request_irq(&pci->dev, pci->irq, snd_atiixp_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
snd_atiixp_free(chip);
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_atiixp_free;
pci_set_master(pci);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
snd_atiixp_free(chip);
return err;
}
*r_chip = chip;
return 0;
}
@ -1251,28 +1208,29 @@ static int snd_atiixp_probe(struct pci_dev *pci,
struct atiixp_modem *chip;
int err;
err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card);
err = snd_devm_card_new(&pci->dev, index, id, THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
return err;
chip = card->private_data;
strcpy(card->driver, "ATIIXP-MODEM");
strcpy(card->shortname, "ATI IXP Modem");
err = snd_atiixp_create(card, pci, &chip);
err = snd_atiixp_init(card, pci);
if (err < 0)
goto __error;
card->private_data = chip;
return err;
err = snd_atiixp_aclink_reset(chip);
if (err < 0)
goto __error;
return err;
err = snd_atiixp_mixer_new(chip, ac97_clock);
if (err < 0)
goto __error;
return err;
err = snd_atiixp_pcm_new(chip);
if (err < 0)
goto __error;
return err;
snd_atiixp_proc_init(chip);
@ -1283,26 +1241,16 @@ static int snd_atiixp_probe(struct pci_dev *pci,
err = snd_card_register(card);
if (err < 0)
goto __error;
return err;
pci_set_drvdata(pci, card);
return 0;
__error:
snd_card_free(card);
return err;
}
static void snd_atiixp_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
static struct pci_driver atiixp_modem_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_atiixp_ids,
.probe = snd_atiixp_probe,
.remove = snd_atiixp_remove,
.driver = {
.pm = SND_ATIIXP_PM_OPS,
},

View File

@ -123,56 +123,35 @@ static void snd_vortex_workaround(struct pci_dev *vortex, int fix)
// component-destructor
// (see "Management of Cards and Components")
static int snd_vortex_dev_free(struct snd_device *device)
static void snd_vortex_free(struct snd_card *card)
{
vortex_t *vortex = device->device_data;
vortex_t *vortex = card->private_data;
vortex_gameport_unregister(vortex);
vortex_core_shutdown(vortex);
// Take down PCI interface.
free_irq(vortex->irq, vortex);
iounmap(vortex->mmio);
pci_release_regions(vortex->pci_dev);
pci_disable_device(vortex->pci_dev);
kfree(vortex);
return 0;
}
// chip-specific constructor
// (see "Management of Cards and Components")
static int
snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
snd_vortex_create(struct snd_card *card, struct pci_dev *pci)
{
vortex_t *chip;
vortex_t *chip = card->private_data;
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_vortex_dev_free,
};
*rchip = NULL;
// check PCI availability (DMA).
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
dev_err(card->dev, "error to set DMA mask\n");
pci_disable_device(pci);
return -ENXIO;
}
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
chip->card = card;
// initialize the stuff
chip->pci_dev = pci;
chip->io = pci_resource_start(pci, 0);
chip->vendor = pci->vendor;
chip->device = pci->device;
chip->card = card;
@ -181,16 +160,12 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
// (1) PCI resource allocation
// Get MMIO area
//
err = pci_request_regions(pci, CARD_NAME_SHORT);
err = pcim_iomap_regions(pci, 1 << 0, CARD_NAME_SHORT);
if (err)
goto regions_out;
return err;
chip->mmio = pci_ioremap_bar(pci, 0);
if (!chip->mmio) {
dev_err(card->dev, "MMIO area remap failed.\n");
err = -ENOMEM;
goto ioremap_out;
}
chip->io = pci_resource_start(pci, 0);
chip->mmio = pcim_iomap_table(pci)[0];
/* Init audio core.
* This must be done before we do request_irq otherwise we can get spurious
@ -198,44 +173,22 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
err = vortex_core_init(chip);
if (err) {
dev_err(card->dev, "hw core init failed\n");
goto core_out;
return err;
}
err = request_irq(pci->irq, vortex_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip);
err = devm_request_irq(&pci->dev, pci->irq, vortex_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip);
if (err) {
dev_err(card->dev, "cannot grab irq\n");
goto irq_out;
return err;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_vortex_free;
pci_set_master(pci);
// End of PCI setup.
// Register alsa root device.
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0)
goto alloc_out;
*rchip = chip;
return 0;
alloc_out:
free_irq(chip->irq, chip);
irq_out:
vortex_core_shutdown(chip);
core_out:
iounmap(chip->mmio);
ioremap_out:
pci_release_regions(chip->pci_dev);
regions_out:
pci_disable_device(chip->pci_dev);
//FIXME: this not the right place to unregister the gameport
vortex_gameport_unregister(chip);
kfree(chip);
return err;
}
// constructor -- see "Constructor" sub-section
@ -255,17 +208,16 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
return -ENOENT;
}
// (2)
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
return err;
chip = card->private_data;
// (3)
err = snd_vortex_create(card, pci, &chip);
if (err < 0) {
snd_card_free(card);
err = snd_vortex_create(card, pci);
if (err < 0)
return err;
}
snd_vortex_workaround(pci, pcifix[dev]);
// Card details needed in snd_vortex_midi
@ -276,50 +228,37 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
// (4) Alloc components.
err = snd_vortex_mixer(chip);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
// ADB pcm.
err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_PCM);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
#ifndef CHIP_AU8820
// ADB SPDIF
err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
// A3D
err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
#endif
/*
// ADB I2S
if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_I2S, 1)) < 0) {
snd_card_free(card);
return err;
}
*/
#ifndef CHIP_AU8810
// WT pcm.
err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
#endif
err = snd_vortex_midi(chip);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
vortex_gameport_register(chip);
@ -342,15 +281,11 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
// (5)
err = pci_read_config_word(pci, PCI_DEVICE_ID, &chip->device);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
err = pci_read_config_word(pci, PCI_VENDOR_ID, &chip->vendor);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
chip->rev = pci->revision;
#ifdef CHIP_AU8830
if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) {
@ -359,18 +294,14 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
chip->rev);
dev_alert(card->dev,
"Please email the results of 'lspci -vv' to openvortex-dev@nongnu.org.\n");
snd_card_free(card);
err = -ENODEV;
return err;
return -ENODEV;
}
#endif
// (6)
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
// (7)
pci_set_drvdata(pci, card);
dev++;
@ -379,18 +310,11 @@ snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
return 0;
}
// destructor -- see "Destructor" sub-section
static void snd_vortex_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
// pci_driver definition
static struct pci_driver vortex_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_vortex_ids,
.probe = snd_vortex_probe,
.remove = snd_vortex_remove,
};
module_pci_driver(vortex_driver);

View File

@ -99,12 +99,9 @@ struct aw2 {
/*********************************
* FUNCTION DECLARATIONS
********************************/
static int snd_aw2_dev_free(struct snd_device *device);
static int snd_aw2_create(struct snd_card *card,
struct pci_dev *pci, struct aw2 **rchip);
static int snd_aw2_create(struct snd_card *card, struct pci_dev *pci);
static int snd_aw2_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id);
static void snd_aw2_remove(struct pci_dev *pci);
static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream);
static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream);
@ -157,7 +154,6 @@ static struct pci_driver aw2_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_aw2_ids,
.probe = snd_aw2_probe,
.remove = snd_aw2_remove,
};
module_pci_driver(aw2_driver);
@ -196,41 +192,23 @@ static const struct snd_kcontrol_new aw2_control = {
********************************/
/* component-destructor */
static int snd_aw2_dev_free(struct snd_device *device)
static void snd_aw2_free(struct snd_card *card)
{
struct aw2 *chip = device->device_data;
struct aw2 *chip = card->private_data;
/* Free hardware */
snd_aw2_saa7146_free(&chip->saa7146);
/* release the irq */
if (chip->irq >= 0)
free_irq(chip->irq, (void *)chip);
/* release the i/o ports & memory */
iounmap(chip->iobase_virt);
pci_release_regions(chip->pci);
/* disable the PCI entry */
pci_disable_device(chip->pci);
/* release the data */
kfree(chip);
return 0;
}
/* chip-specific constructor */
static int snd_aw2_create(struct snd_card *card,
struct pci_dev *pci, struct aw2 **rchip)
struct pci_dev *pci)
{
struct aw2 *chip;
struct aw2 *chip = card->private_data;
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_aw2_dev_free,
};
*rchip = NULL;
/* initialize the PCI entry */
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
pci_set_master(pci);
@ -238,14 +216,8 @@ static int snd_aw2_create(struct snd_card *card,
/* check PCI availability (32bit DMA) */
if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) {
dev_err(card->dev, "Impossible to set 32bit mask DMA\n");
pci_disable_device(pci);
return -ENXIO;
}
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
pci_disable_device(pci);
return -ENOMEM;
}
/* initialize the stuff */
chip->card = card;
@ -253,52 +225,23 @@ static int snd_aw2_create(struct snd_card *card,
chip->irq = -1;
/* (1) PCI resource allocation */
err = pci_request_regions(pci, "Audiowerk2");
if (err < 0) {
pci_disable_device(pci);
kfree(chip);
err = pcim_iomap_regions(pci, 1 << 0, "Audiowerk2");
if (err < 0)
return err;
}
chip->iobase_phys = pci_resource_start(pci, 0);
chip->iobase_virt =
ioremap(chip->iobase_phys,
pci_resource_len(pci, 0));
if (chip->iobase_virt == NULL) {
dev_err(card->dev, "unable to remap memory region");
pci_release_regions(pci);
pci_disable_device(pci);
kfree(chip);
return -ENOMEM;
}
chip->iobase_virt = pcim_iomap_table(pci)[0];
/* (2) initialization of the chip hardware */
snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
if (devm_request_irq(&pci->dev, pci->irq, snd_aw2_saa7146_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(card->dev, "Cannot grab irq %d\n", pci->irq);
iounmap(chip->iobase_virt);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0) {
free_irq(chip->irq, (void *)chip);
iounmap(chip->iobase_virt);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
return err;
}
*rchip = chip;
card->private_free = snd_aw2_free;
dev_info(card->dev,
"Audiowerk 2 sound card (saa7146 chipset) detected and managed\n");
@ -323,17 +266,16 @@ static int snd_aw2_probe(struct pci_dev *pci,
}
/* (2) Create card instance */
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
return err;
chip = card->private_data;
/* (3) Create main component */
err = snd_aw2_create(card, pci, &chip);
if (err < 0) {
snd_card_free(card);
err = snd_aw2_create(card, pci);
if (err < 0)
return err;
}
/* initialize mutex */
mutex_init(&chip->mtx);
@ -351,10 +293,8 @@ static int snd_aw2_probe(struct pci_dev *pci,
/* (6) Register card instance */
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
if (err < 0)
return err;
}
/* (7) Set PCI driver data */
pci_set_drvdata(pci, card);
@ -363,12 +303,6 @@ static int snd_aw2_probe(struct pci_dev *pci,
return 0;
}
/* destructor */
static void snd_aw2_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
/* open callback */
static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream)
{

View File

@ -2244,32 +2244,15 @@ out:
/******************************************************************/
static int
snd_azf3328_free(struct snd_azf3328 *chip)
static void
snd_azf3328_free(struct snd_card *card)
{
if (chip->irq < 0)
goto __end_hw;
struct snd_azf3328 *chip = card->private_data;
snd_azf3328_mixer_reset(chip);
snd_azf3328_timer_stop(chip->timer);
snd_azf3328_gameport_free(chip);
__end_hw:
if (chip->irq >= 0)
free_irq(chip->irq, chip);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
return 0;
}
static int
snd_azf3328_dev_free(struct snd_device *device)
{
struct snd_azf3328 *chip = device->device_data;
return snd_azf3328_free(chip);
}
#if 0
@ -2350,29 +2333,18 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
static int
snd_azf3328_create(struct snd_card *card,
struct pci_dev *pci,
unsigned long device_type,
struct snd_azf3328 **rchip)
unsigned long device_type)
{
struct snd_azf3328 *chip;
struct snd_azf3328 *chip = card->private_data;
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_azf3328_dev_free,
};
u8 dma_init;
enum snd_azf3328_codec_type codec_type;
struct snd_azf3328_codec_data *codec_setup;
*rchip = NULL;
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL) {
err = -ENOMEM;
goto out_err;
}
spin_lock_init(&chip->reg_lock);
chip->card = card;
chip->pci = pci;
@ -2383,13 +2355,12 @@ snd_azf3328_create(struct snd_card *card,
dev_err(card->dev,
"architecture does not support 24bit PCI busmaster DMA\n"
);
err = -ENXIO;
goto out_err;
return -ENXIO;
}
err = pci_request_regions(pci, "Aztech AZF3328");
if (err < 0)
goto out_err;
return err;
chip->ctrl_io = pci_resource_start(pci, 0);
chip->game_io = pci_resource_start(pci, 1);
@ -2415,26 +2386,22 @@ snd_azf3328_create(struct snd_card *card,
codec_setup->type = AZF_CODEC_I2S_OUT;
codec_setup->name = "I2S_OUT";
if (request_irq(pci->irq, snd_azf3328_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
if (devm_request_irq(&pci->dev, pci->irq, snd_azf3328_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip)) {
dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
err = -EBUSY;
goto out_err;
return -EBUSY;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_azf3328_free;
pci_set_master(pci);
snd_azf3328_debug_show_ports(chip);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0)
goto out_err;
/* create mixer interface & switches */
err = snd_azf3328_mixer_new(chip);
if (err < 0)
goto out_err;
return err;
/* standard codec init stuff */
/* default DMA init value */
@ -2456,18 +2423,7 @@ snd_azf3328_create(struct snd_card *card,
spin_unlock_irq(codec->lock);
}
*rchip = chip;
err = 0;
goto out;
out_err:
if (chip)
snd_azf3328_free(chip);
pci_disable_device(pci);
out:
return err;
return 0;
}
static int
@ -2479,29 +2435,25 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
struct snd_opl3 *opl3;
int err;
if (dev >= SNDRV_CARDS) {
err = -ENODEV;
goto out;
}
if (dev >= SNDRV_CARDS)
return -ENODEV;
if (!enable[dev]) {
dev++;
err = -ENOENT;
goto out;
return -ENOENT;
}
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
goto out;
return err;
chip = card->private_data;
strcpy(card->driver, "AZF3328");
strcpy(card->shortname, "Aztech AZF3328 (PCI168)");
err = snd_azf3328_create(card, pci, pci_id->driver_data, &chip);
err = snd_azf3328_create(card, pci, pci_id->driver_data);
if (err < 0)
goto out_err;
card->private_data = chip;
return err;
/* chose to use MPU401_HW_AZT2320 ID instead of MPU401_HW_MPU401,
since our hardware ought to be similar, thus use same ID. */
@ -2515,16 +2467,16 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
dev_err(card->dev, "no MPU-401 device at 0x%lx?\n",
chip->mpu_io
);
goto out_err;
return err;
}
err = snd_azf3328_timer(chip, 0);
if (err < 0)
goto out_err;
return err;
err = snd_azf3328_pcm(chip);
if (err < 0)
goto out_err;
return err;
if (snd_opl3_create(card, chip->opl3_io, chip->opl3_io+2,
OPL3_HW_AUTO, 1, &opl3) < 0) {
@ -2535,10 +2487,10 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
/* need to use IDs 1, 2 since ID 0 is snd_azf3328_timer above */
err = snd_opl3_timer_new(opl3, 1, 2);
if (err < 0)
goto out_err;
return err;
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0)
goto out_err;
return err;
opl3->private_data = chip;
}
@ -2547,7 +2499,7 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
err = snd_card_register(card);
if (err < 0)
goto out_err;
return err;
#ifdef MODULE
dev_info(card->dev,
@ -2565,22 +2517,7 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
pci_set_drvdata(pci, card);
dev++;
err = 0;
goto out;
out_err:
dev_err(card->dev, "something failed, exiting\n");
snd_card_free(card);
out:
return err;
}
static void
snd_azf3328_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
return 0;
}
#ifdef CONFIG_PM_SLEEP
@ -2709,7 +2646,6 @@ static struct pci_driver azf3328_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_azf3328_ids,
.probe = snd_azf3328_probe,
.remove = snd_azf3328_remove,
.driver = {
.pm = SND_AZF3328_PM_OPS,
},

View File

@ -656,23 +656,11 @@ static const struct snd_kcontrol_new snd_bt87x_capture_source = {
.put = snd_bt87x_capture_source_put,
};
static int snd_bt87x_free(struct snd_bt87x *chip)
static void snd_bt87x_free(struct snd_card *card)
{
if (chip->mmio)
snd_bt87x_stop(chip);
if (chip->irq >= 0)
free_irq(chip->irq, chip);
iounmap(chip->mmio);
pci_release_regions(chip->pci);
pci_disable_device(chip->pci);
kfree(chip);
return 0;
}
struct snd_bt87x *chip = card->private_data;
static int snd_bt87x_dev_free(struct snd_device *device)
{
struct snd_bt87x *chip = device->device_data;
return snd_bt87x_free(chip);
snd_bt87x_stop(chip);
}
static int snd_bt87x_pcm(struct snd_bt87x *chip, int device, char *name)
@ -694,43 +682,24 @@ static int snd_bt87x_pcm(struct snd_bt87x *chip, int device, char *name)
}
static int snd_bt87x_create(struct snd_card *card,
struct pci_dev *pci,
struct snd_bt87x **rchip)
struct pci_dev *pci)
{
struct snd_bt87x *chip;
struct snd_bt87x *chip = card->private_data;
int err;
static const struct snd_device_ops ops = {
.dev_free = snd_bt87x_dev_free
};
*rchip = NULL;
err = pci_enable_device(pci);
err = pcim_enable_device(pci);
if (err < 0)
return err;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
}
chip->card = card;
chip->pci = pci;
chip->irq = -1;
spin_lock_init(&chip->reg_lock);
err = pci_request_regions(pci, "Bt87x audio");
if (err < 0) {
kfree(chip);
pci_disable_device(pci);
err = pcim_iomap_regions(pci, 1 << 0, "Bt87x audio");
if (err < 0)
return err;
}
chip->mmio = pci_ioremap_bar(pci, 0);
if (!chip->mmio) {
dev_err(card->dev, "cannot remap io memory\n");
err = -ENOMEM;
goto fail;
}
chip->mmio = pcim_iomap_table(pci)[0];
chip->reg_control = CTL_A_PWRDN | CTL_DA_ES2 |
CTL_PKTP_16 | (15 << CTL_DA_SDR_SHIFT);
@ -739,26 +708,18 @@ static int snd_bt87x_create(struct snd_card *card,
snd_bt87x_writel(chip, REG_INT_MASK, 0);
snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
KBUILD_MODNAME, chip);
err = devm_request_irq(&pci->dev, pci->irq, snd_bt87x_interrupt,
IRQF_SHARED, KBUILD_MODNAME, chip);
if (err < 0) {
dev_err(card->dev, "cannot grab irq %d\n", pci->irq);
goto fail;
return err;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
card->private_free = snd_bt87x_free;
pci_set_master(pci);
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
if (err < 0)
goto fail;
*rchip = chip;
return 0;
fail:
snd_bt87x_free(chip);
return err;
}
#define BT_DEVICE(chip, subvend, subdev, id) \
@ -868,14 +829,15 @@ static int snd_bt87x_probe(struct pci_dev *pci,
return -ENOENT;
}
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(*chip), &card);
if (err < 0)
return err;
chip = card->private_data;
err = snd_bt87x_create(card, pci, &chip);
err = snd_bt87x_create(card, pci);
if (err < 0)
goto _error;
return err;
memcpy(&chip->board, &snd_bt87x_boards[boardid], sizeof(chip->board));
@ -887,24 +849,24 @@ static int snd_bt87x_probe(struct pci_dev *pci,
err = snd_bt87x_pcm(chip, DEVICE_DIGITAL, "Bt87x Digital");
if (err < 0)
goto _error;
return err;
}
if (!chip->board.no_analog) {
err = snd_bt87x_pcm(chip, DEVICE_ANALOG, "Bt87x Analog");
if (err < 0)
goto _error;
return err;
err = snd_ctl_add(card, snd_ctl_new1(
&snd_bt87x_capture_volume, chip));
if (err < 0)
goto _error;
return err;
err = snd_ctl_add(card, snd_ctl_new1(
&snd_bt87x_capture_boost, chip));
if (err < 0)
goto _error;
return err;
err = snd_ctl_add(card, snd_ctl_new1(
&snd_bt87x_capture_source, chip));
if (err < 0)
goto _error;
return err;
}
dev_info(card->dev, "bt87x%d: Using board %d, %sanalog, %sdigital "
"(rate %d Hz)\n", dev, boardid,
@ -920,20 +882,11 @@ static int snd_bt87x_probe(struct pci_dev *pci,
err = snd_card_register(card);
if (err < 0)
goto _error;
return err;
pci_set_drvdata(pci, card);
++dev;
return 0;
_error:
snd_card_free(card);
return err;
}
static void snd_bt87x_remove(struct pci_dev *pci)
{
snd_card_free(pci_get_drvdata(pci));
}
/* default entries for all Bt87x cards - it's not exported */
@ -948,7 +901,6 @@ static struct pci_driver driver = {
.name = KBUILD_MODNAME,
.id_table = snd_bt87x_ids,
.probe = snd_bt87x_probe,
.remove = snd_bt87x_remove,
};
static int __init alsa_card_bt87x_init(void)

View File

@ -667,7 +667,6 @@ struct snd_ca0106 {
struct pci_dev *pci;
unsigned long port;
struct resource *res_port;
int irq;
unsigned int serial; /* serial number */
@ -688,7 +687,7 @@ struct snd_ca0106 {
u8 i2c_capture_volume[4][2];
int capture_mic_line_in;
struct snd_dma_buffer buffer;
struct snd_dma_buffer *buffer;
struct snd_ca_midi midi;
struct snd_ca_midi midi2;

Some files were not shown because too many files have changed in this diff Show More