1 // SPDX-License-Identifier: GPL-2.0-or-later
3 #include <linux/acpi.h>
5 #include <linux/device.h>
7 #include <linux/init.h>
8 #include <linux/mod_devicetable.h>
9 #include <linux/platform_device.h>
10 #include <linux/pm_runtime.h>
11 #include <linux/property.h>
12 #include <linux/types.h>
14 #include "spi-pxa2xx.h"
16 static bool pxa2xx_spi_idma_filter(struct dma_chan
*chan
, void *param
)
18 return param
== chan
->device
->dev
;
22 pxa2xx_spi_init_ssp(struct platform_device
*pdev
, struct ssp_device
*ssp
, enum pxa_ssp_type type
)
24 struct device
*dev
= &pdev
->dev
;
29 ssp
->mmio_base
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res
);
30 if (IS_ERR(ssp
->mmio_base
))
31 return PTR_ERR(ssp
->mmio_base
);
33 ssp
->phys_base
= res
->start
;
35 ssp
->clk
= devm_clk_get(dev
, NULL
);
37 return PTR_ERR(ssp
->clk
);
39 ssp
->irq
= platform_get_irq(pdev
, 0);
46 status
= acpi_dev_uid_to_integer(ACPI_COMPANION(dev
), &uid
);
55 static void pxa2xx_spi_ssp_release(void *ssp
)
60 static struct ssp_device
*pxa2xx_spi_ssp_request(struct platform_device
*pdev
)
62 struct ssp_device
*ssp
;
65 ssp
= pxa_ssp_request(pdev
->id
, pdev
->name
);
69 status
= devm_add_action_or_reset(&pdev
->dev
, pxa2xx_spi_ssp_release
, ssp
);
71 return ERR_PTR(status
);
76 static struct pxa2xx_spi_controller
*
77 pxa2xx_spi_init_pdata(struct platform_device
*pdev
)
79 struct pxa2xx_spi_controller
*pdata
;
80 struct device
*dev
= &pdev
->dev
;
81 struct device
*parent
= dev
->parent
;
82 const void *match
= device_get_match_data(dev
);
83 enum pxa_ssp_type type
= SSP_UNDEFINED
;
84 struct ssp_device
*ssp
;
89 ssp
= pxa2xx_spi_ssp_request(pdev
);
95 type
= (enum pxa_ssp_type
)(uintptr_t)match
;
99 status
= device_property_read_u32(dev
, "intel,spi-pxa2xx-type", &value
);
101 return ERR_PTR(status
);
103 type
= (enum pxa_ssp_type
)value
;
106 /* Validate the SSP type correctness */
107 if (!(type
> SSP_UNDEFINED
&& type
< SSP_MAX
))
108 return ERR_PTR(-EINVAL
);
110 pdata
= devm_kzalloc(dev
, sizeof(*pdata
), GFP_KERNEL
);
112 return ERR_PTR(-ENOMEM
);
114 /* Platforms with iDMA 64-bit */
115 is_lpss_priv
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "lpss_priv");
117 pdata
->tx_param
= parent
;
118 pdata
->rx_param
= parent
;
119 pdata
->dma_filter
= pxa2xx_spi_idma_filter
;
122 /* Read number of chip select pins, if provided */
123 device_property_read_u32(dev
, "num-cs", &num_cs
);
125 pdata
->num_chipselect
= num_cs
;
126 pdata
->is_target
= device_property_read_bool(dev
, "spi-slave");
127 pdata
->enable_dma
= true;
128 pdata
->dma_burst_size
= 1;
130 /* If SSP has been already enumerated, use it */
134 status
= pxa2xx_spi_init_ssp(pdev
, &pdata
->ssp
, type
);
136 return ERR_PTR(status
);
141 static int pxa2xx_spi_platform_probe(struct platform_device
*pdev
)
143 struct pxa2xx_spi_controller
*platform_info
;
144 struct device
*dev
= &pdev
->dev
;
145 struct ssp_device
*ssp
;
148 platform_info
= dev_get_platdata(dev
);
149 if (!platform_info
) {
150 platform_info
= pxa2xx_spi_init_pdata(pdev
);
151 if (IS_ERR(platform_info
))
152 return dev_err_probe(dev
, PTR_ERR(platform_info
), "missing platform data\n");
155 ssp
= pxa2xx_spi_ssp_request(pdev
);
159 ssp
= &platform_info
->ssp
;
161 pm_runtime_set_autosuspend_delay(dev
, 50);
162 pm_runtime_use_autosuspend(dev
);
163 pm_runtime_set_active(dev
);
164 pm_runtime_enable(dev
);
166 ret
= pxa2xx_spi_probe(dev
, ssp
, platform_info
);
168 pm_runtime_disable(dev
);
173 static void pxa2xx_spi_platform_remove(struct platform_device
*pdev
)
175 struct device
*dev
= &pdev
->dev
;
177 pm_runtime_get_sync(dev
);
179 pxa2xx_spi_remove(dev
);
181 pm_runtime_put_noidle(dev
);
182 pm_runtime_disable(dev
);
185 static const struct acpi_device_id pxa2xx_spi_acpi_match
[] = {
194 MODULE_DEVICE_TABLE(acpi
, pxa2xx_spi_acpi_match
);
196 static const struct of_device_id pxa2xx_spi_of_match
[] = {
197 { .compatible
= "marvell,mmp2-ssp", .data
= (void *)MMP2_SSP
},
200 MODULE_DEVICE_TABLE(of
, pxa2xx_spi_of_match
);
202 static struct platform_driver driver
= {
204 .name
= "pxa2xx-spi",
205 .pm
= pm_ptr(&pxa2xx_spi_pm_ops
),
206 .acpi_match_table
= pxa2xx_spi_acpi_match
,
207 .of_match_table
= pxa2xx_spi_of_match
,
209 .probe
= pxa2xx_spi_platform_probe
,
210 .remove
= pxa2xx_spi_platform_remove
,
213 static int __init
pxa2xx_spi_init(void)
215 return platform_driver_register(&driver
);
217 subsys_initcall(pxa2xx_spi_init
);
219 static void __exit
pxa2xx_spi_exit(void)
221 platform_driver_unregister(&driver
);
223 module_exit(pxa2xx_spi_exit
);
225 MODULE_AUTHOR("Stephen Street");
226 MODULE_DESCRIPTION("PXA2xx SSP SPI Controller platform driver");
227 MODULE_LICENSE("GPL");
228 MODULE_IMPORT_NS("SPI_PXA2xx");
229 MODULE_ALIAS("platform:pxa2xx-spi");
230 MODULE_SOFTDEP("pre: dw_dmac");