Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: at91: atmel-ssc: add device tree support

Add atmel-ssc for device tree support

Match "atmel,at91rm9200-ssc" for using pdc for data transfer
Match "atmel,at91sam9g45-ssc" for using dma for data transfer

Signed-off-by: Bo Shen <voice.shen@atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Bo Shen and committed by
Mark Brown
099343c6 636036d2

+123 -3
+15
Documentation/devicetree/bindings/misc/atmel-ssc.txt
··· 1 + * Atmel SSC driver. 2 + 3 + Required properties: 4 + - compatible: "atmel,at91rm9200-ssc" or "atmel,at91sam9g45-ssc" 5 + - atmel,at91rm9200-ssc: support pdc transfer 6 + - atmel,at91sam9g45-ssc: support dma transfer 7 + - reg: Should contain SSC registers location and length 8 + - interrupts: Should contain SSC interrupt 9 + 10 + Example: 11 + ssc0: ssc@fffbc000 { 12 + compatible = "atmel,at91rm9200-ssc"; 13 + reg = <0xfffbc000 0x4000>; 14 + interrupts = <14 4 5>; 15 + };
+8
arch/arm/boot/dts/at91sam9260.dtsi
··· 29 29 tcb0 = &tcb0; 30 30 tcb1 = &tcb1; 31 31 i2c0 = &i2c0; 32 + ssc0 = &ssc0; 32 33 }; 33 34 cpus { 34 35 cpu@0 { ··· 211 210 #address-cells = <1>; 212 211 #size-cells = <0>; 213 212 status = "disabled"; 213 + }; 214 + 215 + ssc0: ssc@fffbc000 { 216 + compatible = "atmel,at91rm9200-ssc"; 217 + reg = <0xfffbc000 0x4000>; 218 + interrupts = <14 4 5>; 219 + status = "disable"; 214 220 }; 215 221 216 222 adc0: adc@fffe0000 {
+16
arch/arm/boot/dts/at91sam9263.dtsi
··· 25 25 gpio4 = &pioE; 26 26 tcb0 = &tcb0; 27 27 i2c0 = &i2c0; 28 + ssc0 = &ssc0; 29 + ssc1 = &ssc1; 28 30 }; 29 31 cpus { 30 32 cpu@0 { ··· 173 171 atmel,use-dma-rx; 174 172 atmel,use-dma-tx; 175 173 status = "disabled"; 174 + }; 175 + 176 + ssc0: ssc@fff98000 { 177 + compatible = "atmel,at91rm9200-ssc"; 178 + reg = <0xfff98000 0x4000>; 179 + interrupts = <16 4 5>; 180 + status = "disable"; 181 + }; 182 + 183 + ssc1: ssc@fff9c000 { 184 + compatible = "atmel,at91rm9200-ssc"; 185 + reg = <0xfff9c000 0x4000>; 186 + interrupts = <17 4 5>; 187 + status = "disable"; 176 188 }; 177 189 178 190 macb0: ethernet@fffbc000 {
+16
arch/arm/boot/dts/at91sam9g45.dtsi
··· 31 31 tcb1 = &tcb1; 32 32 i2c0 = &i2c0; 33 33 i2c1 = &i2c1; 34 + ssc0 = &ssc0; 35 + ssc1 = &ssc1; 34 36 }; 35 37 cpus { 36 38 cpu@0 { ··· 226 224 #address-cells = <1>; 227 225 #size-cells = <0>; 228 226 status = "disabled"; 227 + }; 228 + 229 + ssc0: ssc@fff9c000 { 230 + compatible = "atmel,at91sam9g45-ssc"; 231 + reg = <0xfff9c000 0x4000>; 232 + interrupts = <16 4 5>; 233 + status = "disable"; 234 + }; 235 + 236 + ssc1: ssc@fffa0000 { 237 + compatible = "atmel,at91sam9g45-ssc"; 238 + reg = <0xfffa0000 0x4000>; 239 + interrupts = <17 4 5>; 240 + status = "disable"; 229 241 }; 230 242 231 243 adc0: adc@fffb0000 {
+8
arch/arm/boot/dts/at91sam9x5.dtsi
··· 30 30 i2c0 = &i2c0; 31 31 i2c1 = &i2c1; 32 32 i2c2 = &i2c2; 33 + ssc0 = &ssc0; 33 34 }; 34 35 cpus { 35 36 cpu@0 { ··· 86 85 compatible = "atmel,at91sam9260-pit"; 87 86 reg = <0xfffffe30 0xf>; 88 87 interrupts = <1 4 7>; 88 + }; 89 + 90 + ssc0: ssc@f0010000 { 91 + compatible = "atmel,at91sam9g45-ssc"; 92 + reg = <0xf0010000 0x4000>; 93 + interrupts = <28 4 5>; 94 + status = "disable"; 89 95 }; 90 96 91 97 tcb0: timer@f8008000 {
+3
arch/arm/mach-at91/at91rm9200.c
··· 187 187 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), 188 188 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), 189 189 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk), 190 + CLKDEV_CON_DEV_ID("pclk", "fffd0000.ssc", &ssc0_clk), 191 + CLKDEV_CON_DEV_ID("pclk", "fffd4000.ssc", &ssc1_clk), 192 + CLKDEV_CON_DEV_ID("pclk", "fffd8000.ssc", &ssc2_clk), 190 193 CLKDEV_CON_DEV_ID(NULL, "i2c-at91rm9200.0", &twi_clk), 191 194 /* fake hclk clock */ 192 195 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
+1
arch/arm/mach-at91/at91sam9260.c
··· 211 211 CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk), 212 212 CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk), 213 213 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc_clk), 214 + CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc_clk), 214 215 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9260.0", &twi_clk), 215 216 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi_clk), 216 217 /* more usart lookup table for DT entries */
+3
arch/arm/mach-at91/at91sam9261.c
··· 177 177 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), 178 178 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), 179 179 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.2", &ssc2_clk), 180 + CLKDEV_CON_DEV_ID("pclk", "fffbc000.ssc", &ssc0_clk), 181 + CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc1_clk), 182 + CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc2_clk), 180 183 CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &hck0), 181 184 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9261.0", &twi_clk), 182 185 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.0", &twi_clk),
+2
arch/arm/mach-at91/at91sam9263.c
··· 188 188 CLKDEV_CON_ID("hclk", &macb_clk), 189 189 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), 190 190 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), 191 + CLKDEV_CON_DEV_ID("pclk", "fff98000.ssc", &ssc0_clk), 192 + CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc1_clk), 191 193 CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk), 192 194 CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk), 193 195 CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+2
arch/arm/mach-at91/at91sam9g45.c
··· 241 241 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g10.1", &twi1_clk), 242 242 CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.0", &ssc0_clk), 243 243 CLKDEV_CON_DEV_ID("pclk", "at91sam9g45_ssc.1", &ssc1_clk), 244 + CLKDEV_CON_DEV_ID("pclk", "fff9c000.ssc", &ssc0_clk), 245 + CLKDEV_CON_DEV_ID("pclk", "fffa0000.ssc", &ssc1_clk), 244 246 CLKDEV_CON_DEV_ID(NULL, "atmel-trng", &trng_clk), 245 247 CLKDEV_CON_DEV_ID(NULL, "atmel_sha", &aestdessha_clk), 246 248 CLKDEV_CON_DEV_ID(NULL, "atmel_tdes", &aestdessha_clk),
+2
arch/arm/mach-at91/at91sam9rl.c
··· 186 186 CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk), 187 187 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.0", &ssc0_clk), 188 188 CLKDEV_CON_DEV_ID("pclk", "at91rm9200_ssc.1", &ssc1_clk), 189 + CLKDEV_CON_DEV_ID("pclk", "fffc0000.ssc", &ssc0_clk), 190 + CLKDEV_CON_DEV_ID("pclk", "fffc4000.ssc", &ssc1_clk), 189 191 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.0", &twi0_clk), 190 192 CLKDEV_CON_DEV_ID(NULL, "i2c-at91sam9g20.1", &twi1_clk), 191 193 CLKDEV_CON_ID("pioA", &pioA_clk),
+1
arch/arm/mach-at91/at91sam9x5.c
··· 231 231 CLKDEV_CON_DEV_ID("t0_clk", "f800c000.timer", &tcb0_clk), 232 232 CLKDEV_CON_DEV_ID("dma_clk", "ffffec00.dma-controller", &dma0_clk), 233 233 CLKDEV_CON_DEV_ID("dma_clk", "ffffee00.dma-controller", &dma1_clk), 234 + CLKDEV_CON_DEV_ID("pclk", "f0010000.ssc", &ssc_clk), 234 235 CLKDEV_CON_DEV_ID(NULL, "f8010000.i2c", &twi0_clk), 235 236 CLKDEV_CON_DEV_ID(NULL, "f8014000.i2c", &twi1_clk), 236 237 CLKDEV_CON_DEV_ID(NULL, "f8018000.i2c", &twi2_clk),
+46 -3
drivers/misc/atmel-ssc.c
··· 18 18 #include <linux/slab.h> 19 19 #include <linux/module.h> 20 20 21 + #include <linux/of.h> 22 + 21 23 /* Serialize access to ssc_list and user count */ 22 24 static DEFINE_SPINLOCK(user_lock); 23 25 static LIST_HEAD(ssc_list); ··· 31 29 32 30 spin_lock(&user_lock); 33 31 list_for_each_entry(ssc, &ssc_list, list) { 34 - if (ssc->pdev->id == ssc_num) { 32 + if (ssc->pdev->dev.of_node) { 33 + if (of_alias_get_id(ssc->pdev->dev.of_node, "ssc") 34 + == ssc_num) { 35 + ssc_valid = 1; 36 + break; 37 + } 38 + } else if (ssc->pdev->id == ssc_num) { 35 39 ssc_valid = 1; 36 40 break; 37 41 } ··· 96 88 } 97 89 }; 98 90 91 + #ifdef CONFIG_OF 92 + static const struct of_device_id atmel_ssc_dt_ids[] = { 93 + { 94 + .compatible = "atmel,at91rm9200-ssc", 95 + .data = &at91rm9200_config, 96 + }, { 97 + .compatible = "atmel,at91sam9g45-ssc", 98 + .data = &at91sam9g45_config, 99 + }, { 100 + /* sentinel */ 101 + } 102 + }; 103 + MODULE_DEVICE_TABLE(of, atmel_ssc_dt_ids); 104 + #endif 105 + 106 + static inline const struct atmel_ssc_platform_data * __init 107 + atmel_ssc_get_driver_data(struct platform_device *pdev) 108 + { 109 + if (pdev->dev.of_node) { 110 + const struct of_device_id *match; 111 + match = of_match_node(atmel_ssc_dt_ids, pdev->dev.of_node); 112 + if (match == NULL) 113 + return NULL; 114 + return match->data; 115 + } 116 + 117 + return (struct atmel_ssc_platform_data *) 118 + platform_get_device_id(pdev)->driver_data; 119 + } 120 + 99 121 static int ssc_probe(struct platform_device *pdev) 100 122 { 101 123 struct resource *regs; 102 124 struct ssc_device *ssc; 125 + const struct atmel_ssc_platform_data *plat_dat; 103 126 104 127 ssc = devm_kzalloc(&pdev->dev, sizeof(struct ssc_device), GFP_KERNEL); 105 128 if (!ssc) { ··· 139 100 } 140 101 141 102 ssc->pdev = pdev; 142 - ssc->pdata = (struct atmel_ssc_platform_data *) 143 - platform_get_device_id(pdev)->driver_data; 103 + 104 + plat_dat = atmel_ssc_get_driver_data(pdev); 105 + if (!plat_dat) 106 + return -ENODEV; 107 + ssc->pdata = (struct atmel_ssc_platform_data *)plat_dat; 144 108 145 109 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 146 110 if (!regs) { ··· 202 160 .driver = { 203 161 .name = "ssc", 204 162 .owner = THIS_MODULE, 163 + .of_match_table = of_match_ptr(atmel_ssc_dt_ids), 205 164 }, 206 165 .id_table = atmel_ssc_devtypes, 207 166 .probe = ssc_probe,