eCryptfs: Extend array bounds for all filename chars
[pandora-kernel.git] / drivers / misc / spear13xx_pcie_gadget.c
1 /*
2  * drivers/misc/spear13xx_pcie_gadget.c
3  *
4  * Copyright (C) 2010 ST Microelectronics
5  * Pratyush Anand<pratyush.anand@st.com>
6  *
7  * This file is licensed under the terms of the GNU General Public
8  * License version 2. This program is licensed "as is" without any
9  * warranty of any kind, whether express or implied.
10  */
11
12 #include <linux/clk.h>
13 #include <linux/slab.h>
14 #include <linux/delay.h>
15 #include <linux/io.h>
16 #include <linux/interrupt.h>
17 #include <linux/irq.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
21 #include <linux/pci_regs.h>
22 #include <linux/configfs.h>
23 #include <mach/pcie.h>
24 #include <mach/misc_regs.h>
25
26 #define IN0_MEM_SIZE    (200 * 1024 * 1024 - 1)
27 /* In current implementation address translation is done using IN0 only.
28  * So IN1 start address and IN0 end address has been kept same
29 */
30 #define IN1_MEM_SIZE    (0 * 1024 * 1024 - 1)
31 #define IN_IO_SIZE      (20 * 1024 * 1024 - 1)
32 #define IN_CFG0_SIZE    (12 * 1024 * 1024 - 1)
33 #define IN_CFG1_SIZE    (12 * 1024 * 1024 - 1)
34 #define IN_MSG_SIZE     (12 * 1024 * 1024 - 1)
35 /* Keep default BAR size as 4K*/
36 /* AORAM would be mapped by default*/
37 #define INBOUND_ADDR_MASK       (SPEAR13XX_SYSRAM1_SIZE - 1)
38
39 #define INT_TYPE_NO_INT 0
40 #define INT_TYPE_INTX   1
41 #define INT_TYPE_MSI    2
42 struct spear_pcie_gadget_config {
43         void __iomem *base;
44         void __iomem *va_app_base;
45         void __iomem *va_dbi_base;
46         char int_type[10];
47         ulong requested_msi;
48         ulong configured_msi;
49         ulong bar0_size;
50         ulong bar0_rw_offset;
51         void __iomem *va_bar0_address;
52 };
53
54 struct pcie_gadget_target {
55         struct configfs_subsystem subsys;
56         struct spear_pcie_gadget_config config;
57 };
58
59 struct pcie_gadget_target_attr {
60         struct configfs_attribute       attr;
61         ssize_t         (*show)(struct spear_pcie_gadget_config *config,
62                                                 char *buf);
63         ssize_t         (*store)(struct spear_pcie_gadget_config *config,
64                                                  const char *buf,
65                                                  size_t count);
66 };
67
68 static void enable_dbi_access(struct pcie_app_reg __iomem *app_reg)
69 {
70         /* Enable DBI access */
71         writel(readl(&app_reg->slv_armisc) | (1 << AXI_OP_DBI_ACCESS_ID),
72                         &app_reg->slv_armisc);
73         writel(readl(&app_reg->slv_awmisc) | (1 << AXI_OP_DBI_ACCESS_ID),
74                         &app_reg->slv_awmisc);
75
76 }
77
78 static void disable_dbi_access(struct pcie_app_reg __iomem *app_reg)
79 {
80         /* disable DBI access */
81         writel(readl(&app_reg->slv_armisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
82                         &app_reg->slv_armisc);
83         writel(readl(&app_reg->slv_awmisc) & ~(1 << AXI_OP_DBI_ACCESS_ID),
84                         &app_reg->slv_awmisc);
85
86 }
87
88 static void spear_dbi_read_reg(struct spear_pcie_gadget_config *config,
89                 int where, int size, u32 *val)
90 {
91         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
92         ulong va_address;
93
94         /* Enable DBI access */
95         enable_dbi_access(app_reg);
96
97         va_address = (ulong)config->va_dbi_base + (where & ~0x3);
98
99         *val = readl(va_address);
100
101         if (size == 1)
102                 *val = (*val >> (8 * (where & 3))) & 0xff;
103         else if (size == 2)
104                 *val = (*val >> (8 * (where & 3))) & 0xffff;
105
106         /* Disable DBI access */
107         disable_dbi_access(app_reg);
108 }
109
110 static void spear_dbi_write_reg(struct spear_pcie_gadget_config *config,
111                 int where, int size, u32 val)
112 {
113         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
114         ulong va_address;
115
116         /* Enable DBI access */
117         enable_dbi_access(app_reg);
118
119         va_address = (ulong)config->va_dbi_base + (where & ~0x3);
120
121         if (size == 4)
122                 writel(val, va_address);
123         else if (size == 2)
124                 writew(val, va_address + (where & 2));
125         else if (size == 1)
126                 writeb(val, va_address + (where & 3));
127
128         /* Disable DBI access */
129         disable_dbi_access(app_reg);
130 }
131
132 #define PCI_FIND_CAP_TTL        48
133
134 static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config,
135                 u32 pos, int cap, int *ttl)
136 {
137         u32 id;
138
139         while ((*ttl)--) {
140                 spear_dbi_read_reg(config, pos, 1, &pos);
141                 if (pos < 0x40)
142                         break;
143                 pos &= ~3;
144                 spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id);
145                 if (id == 0xff)
146                         break;
147                 if (id == cap)
148                         return pos;
149                 pos += PCI_CAP_LIST_NEXT;
150         }
151         return 0;
152 }
153
154 static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config,
155                         u32 pos, int cap)
156 {
157         int ttl = PCI_FIND_CAP_TTL;
158
159         return pci_find_own_next_cap_ttl(config, pos, cap, &ttl);
160 }
161
162 static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config,
163                                 u8 hdr_type)
164 {
165         u32 status;
166
167         spear_dbi_read_reg(config, PCI_STATUS, 2, &status);
168         if (!(status & PCI_STATUS_CAP_LIST))
169                 return 0;
170
171         switch (hdr_type) {
172         case PCI_HEADER_TYPE_NORMAL:
173         case PCI_HEADER_TYPE_BRIDGE:
174                 return PCI_CAPABILITY_LIST;
175         case PCI_HEADER_TYPE_CARDBUS:
176                 return PCI_CB_CAPABILITY_LIST;
177         default:
178                 return 0;
179         }
180
181         return 0;
182 }
183
184 /*
185  * Tell if a device supports a given PCI capability.
186  * Returns the address of the requested capability structure within the
187  * device's PCI configuration space or 0 in case the device does not
188  * support it. Possible values for @cap:
189  *
190  * %PCI_CAP_ID_PM       Power Management
191  * %PCI_CAP_ID_AGP      Accelerated Graphics Port
192  * %PCI_CAP_ID_VPD      Vital Product Data
193  * %PCI_CAP_ID_SLOTID   Slot Identification
194  * %PCI_CAP_ID_MSI      Message Signalled Interrupts
195  * %PCI_CAP_ID_CHSWP    CompactPCI HotSwap
196  * %PCI_CAP_ID_PCIX     PCI-X
197  * %PCI_CAP_ID_EXP      PCI Express
198  */
199 static int pci_find_own_capability(struct spear_pcie_gadget_config *config,
200                 int cap)
201 {
202         u32 pos;
203         u32 hdr_type;
204
205         spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type);
206
207         pos = pci_find_own_cap_start(config, hdr_type);
208         if (pos)
209                 pos = pci_find_own_next_cap(config, pos, cap);
210
211         return pos;
212 }
213
214 static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id)
215 {
216         return 0;
217 }
218
219 /*
220  * configfs interfaces show/store functions
221  */
222 static ssize_t pcie_gadget_show_link(
223                 struct spear_pcie_gadget_config *config,
224                 char *buf)
225 {
226         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
227
228         if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID))
229                 return sprintf(buf, "UP");
230         else
231                 return sprintf(buf, "DOWN");
232 }
233
234 static ssize_t pcie_gadget_store_link(
235                 struct spear_pcie_gadget_config *config,
236                 const char *buf, size_t count)
237 {
238         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
239
240         if (sysfs_streq(buf, "UP"))
241                 writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID),
242                         &app_reg->app_ctrl_0);
243         else if (sysfs_streq(buf, "DOWN"))
244                 writel(readl(&app_reg->app_ctrl_0)
245                                 & ~(1 << APP_LTSSM_ENABLE_ID),
246                                 &app_reg->app_ctrl_0);
247         else
248                 return -EINVAL;
249         return count;
250 }
251
252 static ssize_t pcie_gadget_show_int_type(
253                 struct spear_pcie_gadget_config *config,
254                 char *buf)
255 {
256         return sprintf(buf, "%s", config->int_type);
257 }
258
259 static ssize_t pcie_gadget_store_int_type(
260                 struct spear_pcie_gadget_config *config,
261                 const char *buf, size_t count)
262 {
263         u32 cap, vec, flags;
264         ulong vector;
265
266         if (sysfs_streq(buf, "INTA"))
267                 spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
268
269         else if (sysfs_streq(buf, "MSI")) {
270                 vector = config->requested_msi;
271                 vec = 0;
272                 while (vector > 1) {
273                         vector /= 2;
274                         vec++;
275                 }
276                 spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0);
277                 cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
278                 spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
279                 flags &= ~PCI_MSI_FLAGS_QMASK;
280                 flags |= vec << 1;
281                 spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags);
282         } else
283                 return -EINVAL;
284
285         strcpy(config->int_type, buf);
286
287         return count;
288 }
289
290 static ssize_t pcie_gadget_show_no_of_msi(
291                 struct spear_pcie_gadget_config *config,
292                 char *buf)
293 {
294         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
295         u32 cap, vec, flags;
296         ulong vector;
297
298         if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID))
299                         != (1 << CFG_MSI_EN_ID))
300                 vector = 0;
301         else {
302                 cap = pci_find_own_capability(config, PCI_CAP_ID_MSI);
303                 spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags);
304                 flags &= ~PCI_MSI_FLAGS_QSIZE;
305                 vec = flags >> 4;
306                 vector = 1;
307                 while (vec--)
308                         vector *= 2;
309         }
310         config->configured_msi = vector;
311
312         return sprintf(buf, "%lu", vector);
313 }
314
315 static ssize_t pcie_gadget_store_no_of_msi(
316                 struct spear_pcie_gadget_config *config,
317                 const char *buf, size_t count)
318 {
319         if (strict_strtoul(buf, 0, &config->requested_msi))
320                 return -EINVAL;
321         if (config->requested_msi > 32)
322                 config->requested_msi = 32;
323
324         return count;
325 }
326
327 static ssize_t pcie_gadget_store_inta(
328                 struct spear_pcie_gadget_config *config,
329                 const char *buf, size_t count)
330 {
331         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
332         ulong en;
333
334         if (strict_strtoul(buf, 0, &en))
335                 return -EINVAL;
336
337         if (en)
338                 writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID),
339                                 &app_reg->app_ctrl_0);
340         else
341                 writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID),
342                                 &app_reg->app_ctrl_0);
343
344         return count;
345 }
346
347 static ssize_t pcie_gadget_store_send_msi(
348                 struct spear_pcie_gadget_config *config,
349                 const char *buf, size_t count)
350 {
351         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
352         ulong vector;
353         u32 ven_msi;
354
355         if (strict_strtoul(buf, 0, &vector))
356                 return -EINVAL;
357
358         if (!config->configured_msi)
359                 return -EINVAL;
360
361         if (vector >= config->configured_msi)
362                 return -EINVAL;
363
364         ven_msi = readl(&app_reg->ven_msi_1);
365         ven_msi &= ~VEN_MSI_FUN_NUM_MASK;
366         ven_msi |= 0 << VEN_MSI_FUN_NUM_ID;
367         ven_msi &= ~VEN_MSI_TC_MASK;
368         ven_msi |= 0 << VEN_MSI_TC_ID;
369         ven_msi &= ~VEN_MSI_VECTOR_MASK;
370         ven_msi |= vector << VEN_MSI_VECTOR_ID;
371
372         /* generating interrupt for msi vector */
373         ven_msi |= VEN_MSI_REQ_EN;
374         writel(ven_msi, &app_reg->ven_msi_1);
375         udelay(1);
376         ven_msi &= ~VEN_MSI_REQ_EN;
377         writel(ven_msi, &app_reg->ven_msi_1);
378
379         return count;
380 }
381
382 static ssize_t pcie_gadget_show_vendor_id(
383                 struct spear_pcie_gadget_config *config,
384                 char *buf)
385 {
386         u32 id;
387
388         spear_dbi_read_reg(config, PCI_VENDOR_ID, 2, &id);
389
390         return sprintf(buf, "%x", id);
391 }
392
393 static ssize_t pcie_gadget_store_vendor_id(
394                 struct spear_pcie_gadget_config *config,
395                 const char *buf, size_t count)
396 {
397         ulong id;
398
399         if (strict_strtoul(buf, 0, &id))
400                 return -EINVAL;
401
402         spear_dbi_write_reg(config, PCI_VENDOR_ID, 2, id);
403
404         return count;
405 }
406
407 static ssize_t pcie_gadget_show_device_id(
408                 struct spear_pcie_gadget_config *config,
409                 char *buf)
410 {
411         u32 id;
412
413         spear_dbi_read_reg(config, PCI_DEVICE_ID, 2, &id);
414
415         return sprintf(buf, "%x", id);
416 }
417
418 static ssize_t pcie_gadget_store_device_id(
419                 struct spear_pcie_gadget_config *config,
420                 const char *buf, size_t count)
421 {
422         ulong id;
423
424         if (strict_strtoul(buf, 0, &id))
425                 return -EINVAL;
426
427         spear_dbi_write_reg(config, PCI_DEVICE_ID, 2, id);
428
429         return count;
430 }
431
432 static ssize_t pcie_gadget_show_bar0_size(
433                 struct spear_pcie_gadget_config *config,
434                 char *buf)
435 {
436         return sprintf(buf, "%lx", config->bar0_size);
437 }
438
439 static ssize_t pcie_gadget_store_bar0_size(
440                 struct spear_pcie_gadget_config *config,
441                 const char *buf, size_t count)
442 {
443         ulong size;
444         u32 pos, pos1;
445         u32 no_of_bit = 0;
446
447         if (strict_strtoul(buf, 0, &size))
448                 return -EINVAL;
449         /* min bar size is 256 */
450         if (size <= 0x100)
451                 size = 0x100;
452         /* max bar size is 1MB*/
453         else if (size >= 0x100000)
454                 size = 0x100000;
455         else {
456                 pos = 0;
457                 pos1 = 0;
458                 while (pos < 21) {
459                         pos = find_next_bit((ulong *)&size, 21, pos);
460                         if (pos != 21)
461                                 pos1 = pos + 1;
462                         pos++;
463                         no_of_bit++;
464                 }
465                 if (no_of_bit == 2)
466                         pos1--;
467
468                 size = 1 << pos1;
469         }
470         config->bar0_size = size;
471         spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1);
472
473         return count;
474 }
475
476 static ssize_t pcie_gadget_show_bar0_address(
477                 struct spear_pcie_gadget_config *config,
478                 char *buf)
479 {
480         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
481
482         u32 address = readl(&app_reg->pim0_mem_addr_start);
483
484         return sprintf(buf, "%x", address);
485 }
486
487 static ssize_t pcie_gadget_store_bar0_address(
488                 struct spear_pcie_gadget_config *config,
489                 const char *buf, size_t count)
490 {
491         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
492         ulong address;
493
494         if (strict_strtoul(buf, 0, &address))
495                 return -EINVAL;
496
497         address &= ~(config->bar0_size - 1);
498         if (config->va_bar0_address)
499                 iounmap(config->va_bar0_address);
500         config->va_bar0_address = ioremap(address, config->bar0_size);
501         if (!config->va_bar0_address)
502                 return -ENOMEM;
503
504         writel(address, &app_reg->pim0_mem_addr_start);
505
506         return count;
507 }
508
509 static ssize_t pcie_gadget_show_bar0_rw_offset(
510                 struct spear_pcie_gadget_config *config,
511                 char *buf)
512 {
513         return sprintf(buf, "%lx", config->bar0_rw_offset);
514 }
515
516 static ssize_t pcie_gadget_store_bar0_rw_offset(
517                 struct spear_pcie_gadget_config *config,
518                 const char *buf, size_t count)
519 {
520         ulong offset;
521
522         if (strict_strtoul(buf, 0, &offset))
523                 return -EINVAL;
524
525         if (offset % 4)
526                 return -EINVAL;
527
528         config->bar0_rw_offset = offset;
529
530         return count;
531 }
532
533 static ssize_t pcie_gadget_show_bar0_data(
534                 struct spear_pcie_gadget_config *config,
535                 char *buf)
536 {
537         ulong data;
538
539         if (!config->va_bar0_address)
540                 return -ENOMEM;
541
542         data = readl((ulong)config->va_bar0_address + config->bar0_rw_offset);
543
544         return sprintf(buf, "%lx", data);
545 }
546
547 static ssize_t pcie_gadget_store_bar0_data(
548                 struct spear_pcie_gadget_config *config,
549                 const char *buf, size_t count)
550 {
551         ulong data;
552
553         if (strict_strtoul(buf, 0, &data))
554                 return -EINVAL;
555
556         if (!config->va_bar0_address)
557                 return -ENOMEM;
558
559         writel(data, (ulong)config->va_bar0_address + config->bar0_rw_offset);
560
561         return count;
562 }
563
564 /*
565  * Attribute definitions.
566  */
567
568 #define PCIE_GADGET_TARGET_ATTR_RO(_name)                               \
569 static struct pcie_gadget_target_attr pcie_gadget_target_##_name =      \
570         __CONFIGFS_ATTR(_name, S_IRUGO, pcie_gadget_show_##_name, NULL)
571
572 #define PCIE_GADGET_TARGET_ATTR_WO(_name)                               \
573 static struct pcie_gadget_target_attr pcie_gadget_target_##_name =      \
574         __CONFIGFS_ATTR(_name, S_IWUSR, NULL, pcie_gadget_store_##_name)
575
576 #define PCIE_GADGET_TARGET_ATTR_RW(_name)                               \
577 static struct pcie_gadget_target_attr pcie_gadget_target_##_name =      \
578         __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, pcie_gadget_show_##_name, \
579                         pcie_gadget_store_##_name)
580 PCIE_GADGET_TARGET_ATTR_RW(link);
581 PCIE_GADGET_TARGET_ATTR_RW(int_type);
582 PCIE_GADGET_TARGET_ATTR_RW(no_of_msi);
583 PCIE_GADGET_TARGET_ATTR_WO(inta);
584 PCIE_GADGET_TARGET_ATTR_WO(send_msi);
585 PCIE_GADGET_TARGET_ATTR_RW(vendor_id);
586 PCIE_GADGET_TARGET_ATTR_RW(device_id);
587 PCIE_GADGET_TARGET_ATTR_RW(bar0_size);
588 PCIE_GADGET_TARGET_ATTR_RW(bar0_address);
589 PCIE_GADGET_TARGET_ATTR_RW(bar0_rw_offset);
590 PCIE_GADGET_TARGET_ATTR_RW(bar0_data);
591
592 static struct configfs_attribute *pcie_gadget_target_attrs[] = {
593         &pcie_gadget_target_link.attr,
594         &pcie_gadget_target_int_type.attr,
595         &pcie_gadget_target_no_of_msi.attr,
596         &pcie_gadget_target_inta.attr,
597         &pcie_gadget_target_send_msi.attr,
598         &pcie_gadget_target_vendor_id.attr,
599         &pcie_gadget_target_device_id.attr,
600         &pcie_gadget_target_bar0_size.attr,
601         &pcie_gadget_target_bar0_address.attr,
602         &pcie_gadget_target_bar0_rw_offset.attr,
603         &pcie_gadget_target_bar0_data.attr,
604         NULL,
605 };
606
607 static struct pcie_gadget_target *to_target(struct config_item *item)
608 {
609         return item ?
610                 container_of(to_configfs_subsystem(to_config_group(item)),
611                                 struct pcie_gadget_target, subsys) : NULL;
612 }
613
614 /*
615  * Item operations and type for pcie_gadget_target.
616  */
617
618 static ssize_t pcie_gadget_target_attr_show(struct config_item *item,
619                                            struct configfs_attribute *attr,
620                                            char *buf)
621 {
622         ssize_t ret = -EINVAL;
623         struct pcie_gadget_target *target = to_target(item);
624         struct pcie_gadget_target_attr *t_attr =
625                 container_of(attr, struct pcie_gadget_target_attr, attr);
626
627         if (t_attr->show)
628                 ret = t_attr->show(&target->config, buf);
629         return ret;
630 }
631
632 static ssize_t pcie_gadget_target_attr_store(struct config_item *item,
633                                         struct configfs_attribute *attr,
634                                         const char *buf,
635                                         size_t count)
636 {
637         ssize_t ret = -EINVAL;
638         struct pcie_gadget_target *target = to_target(item);
639         struct pcie_gadget_target_attr *t_attr =
640                 container_of(attr, struct pcie_gadget_target_attr, attr);
641
642         if (t_attr->store)
643                 ret = t_attr->store(&target->config, buf, count);
644         return ret;
645 }
646
647 static struct configfs_item_operations pcie_gadget_target_item_ops = {
648         .show_attribute         = pcie_gadget_target_attr_show,
649         .store_attribute        = pcie_gadget_target_attr_store,
650 };
651
652 static struct config_item_type pcie_gadget_target_type = {
653         .ct_attrs               = pcie_gadget_target_attrs,
654         .ct_item_ops            = &pcie_gadget_target_item_ops,
655         .ct_owner               = THIS_MODULE,
656 };
657
658 static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config)
659 {
660         struct pcie_app_reg __iomem *app_reg = config->va_app_base;
661
662         /*setup registers for outbound translation */
663
664         writel(config->base, &app_reg->in0_mem_addr_start);
665         writel(app_reg->in0_mem_addr_start + IN0_MEM_SIZE,
666                         &app_reg->in0_mem_addr_limit);
667         writel(app_reg->in0_mem_addr_limit + 1, &app_reg->in1_mem_addr_start);
668         writel(app_reg->in1_mem_addr_start + IN1_MEM_SIZE,
669                         &app_reg->in1_mem_addr_limit);
670         writel(app_reg->in1_mem_addr_limit + 1, &app_reg->in_io_addr_start);
671         writel(app_reg->in_io_addr_start + IN_IO_SIZE,
672                         &app_reg->in_io_addr_limit);
673         writel(app_reg->in_io_addr_limit + 1, &app_reg->in_cfg0_addr_start);
674         writel(app_reg->in_cfg0_addr_start + IN_CFG0_SIZE,
675                         &app_reg->in_cfg0_addr_limit);
676         writel(app_reg->in_cfg0_addr_limit + 1, &app_reg->in_cfg1_addr_start);
677         writel(app_reg->in_cfg1_addr_start + IN_CFG1_SIZE,
678                         &app_reg->in_cfg1_addr_limit);
679         writel(app_reg->in_cfg1_addr_limit + 1, &app_reg->in_msg_addr_start);
680         writel(app_reg->in_msg_addr_start + IN_MSG_SIZE,
681                         &app_reg->in_msg_addr_limit);
682
683         writel(app_reg->in0_mem_addr_start, &app_reg->pom0_mem_addr_start);
684         writel(app_reg->in1_mem_addr_start, &app_reg->pom1_mem_addr_start);
685         writel(app_reg->in_io_addr_start, &app_reg->pom_io_addr_start);
686
687         /*setup registers for inbound translation */
688
689         /* Keep AORAM mapped at BAR0 as default */
690         config->bar0_size = INBOUND_ADDR_MASK + 1;
691         spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK);
692         spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC);
693         config->va_bar0_address = ioremap(SPEAR13XX_SYSRAM1_BASE,
694                         config->bar0_size);
695
696         writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start);
697         writel(0, &app_reg->pim1_mem_addr_start);
698         writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit);
699
700         writel(0x0, &app_reg->pim_io_addr_start);
701         writel(0x0, &app_reg->pim_io_addr_start);
702         writel(0x0, &app_reg->pim_rom_addr_start);
703
704         writel(DEVICE_TYPE_EP | (1 << MISCTRL_EN_ID)
705                         | ((u32)1 << REG_TRANSLATION_ENABLE),
706                         &app_reg->app_ctrl_0);
707         /* disable all rx interrupts */
708         writel(0, &app_reg->int_mask);
709
710         /* Select INTA as default*/
711         spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1);
712 }
713
714 static int __devinit spear_pcie_gadget_probe(struct platform_device *pdev)
715 {
716         struct resource *res0, *res1;
717         unsigned int status = 0;
718         int irq;
719         struct clk *clk;
720         static struct pcie_gadget_target *target;
721         struct spear_pcie_gadget_config *config;
722         struct config_item              *cg_item;
723         struct configfs_subsystem *subsys;
724
725         /* get resource for application registers*/
726
727         res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
728         if (!res0) {
729                 dev_err(&pdev->dev, "no resource defined\n");
730                 return -EBUSY;
731         }
732         if (!request_mem_region(res0->start, resource_size(res0),
733                                 pdev->name)) {
734                 dev_err(&pdev->dev, "pcie gadget region already claimed\n");
735                 return -EBUSY;
736         }
737         /* get resource for dbi registers*/
738
739         res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
740         if (!res1) {
741                 dev_err(&pdev->dev, "no resource defined\n");
742                 goto err_rel_res0;
743         }
744         if (!request_mem_region(res1->start, resource_size(res1),
745                                 pdev->name)) {
746                 dev_err(&pdev->dev, "pcie gadget region already claimed\n");
747                 goto err_rel_res0;
748         }
749
750         target = kzalloc(sizeof(*target), GFP_KERNEL);
751         if (!target) {
752                 dev_err(&pdev->dev, "out of memory\n");
753                 status = -ENOMEM;
754                 goto err_rel_res;
755         }
756
757         cg_item = &target->subsys.su_group.cg_item;
758         sprintf(cg_item->ci_namebuf, "pcie_gadget.%d", pdev->id);
759         cg_item->ci_type        = &pcie_gadget_target_type;
760         config = &target->config;
761         config->va_app_base = (void __iomem *)ioremap(res0->start,
762                         resource_size(res0));
763         if (!config->va_app_base) {
764                 dev_err(&pdev->dev, "ioremap fail\n");
765                 status = -ENOMEM;
766                 goto err_kzalloc;
767         }
768
769         config->base = (void __iomem *)res1->start;
770
771         config->va_dbi_base = (void __iomem *)ioremap(res1->start,
772                         resource_size(res1));
773         if (!config->va_dbi_base) {
774                 dev_err(&pdev->dev, "ioremap fail\n");
775                 status = -ENOMEM;
776                 goto err_iounmap_app;
777         }
778
779         dev_set_drvdata(&pdev->dev, target);
780
781         irq = platform_get_irq(pdev, 0);
782         if (irq < 0) {
783                 dev_err(&pdev->dev, "no update irq?\n");
784                 status = irq;
785                 goto err_iounmap;
786         }
787
788         status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL);
789         if (status) {
790                 dev_err(&pdev->dev,
791                         "pcie gadget interrupt IRQ%d already claimed\n", irq);
792                 goto err_iounmap;
793         }
794
795         /* Register configfs hooks */
796         subsys = &target->subsys;
797         config_group_init(&subsys->su_group);
798         mutex_init(&subsys->su_mutex);
799         status = configfs_register_subsystem(subsys);
800         if (status)
801                 goto err_irq;
802
803         /*
804          * init basic pcie application registers
805          * do not enable clock if it is PCIE0.Ideally , all controller should
806          * have been independent from others with respect to clock. But PCIE1
807          * and 2 depends on PCIE0.So PCIE0 clk is provided during board init.
808          */
809         if (pdev->id == 1) {
810                 /*
811                  * Ideally CFG Clock should have been also enabled here. But
812                  * it is done currently during board init routne
813                  */
814                 clk = clk_get_sys("pcie1", NULL);
815                 if (IS_ERR(clk)) {
816                         pr_err("%s:couldn't get clk for pcie1\n", __func__);
817                         goto err_irq;
818                 }
819                 if (clk_enable(clk)) {
820                         pr_err("%s:couldn't enable clk for pcie1\n", __func__);
821                         goto err_irq;
822                 }
823         } else if (pdev->id == 2) {
824                 /*
825                  * Ideally CFG Clock should have been also enabled here. But
826                  * it is done currently during board init routne
827                  */
828                 clk = clk_get_sys("pcie2", NULL);
829                 if (IS_ERR(clk)) {
830                         pr_err("%s:couldn't get clk for pcie2\n", __func__);
831                         goto err_irq;
832                 }
833                 if (clk_enable(clk)) {
834                         pr_err("%s:couldn't enable clk for pcie2\n", __func__);
835                         goto err_irq;
836                 }
837         }
838         spear13xx_pcie_device_init(config);
839
840         return 0;
841 err_irq:
842         free_irq(irq, NULL);
843 err_iounmap:
844         iounmap(config->va_dbi_base);
845 err_iounmap_app:
846         iounmap(config->va_app_base);
847 err_kzalloc:
848         kfree(target);
849 err_rel_res:
850         release_mem_region(res1->start, resource_size(res1));
851 err_rel_res0:
852         release_mem_region(res0->start, resource_size(res0));
853         return status;
854 }
855
856 static int __devexit spear_pcie_gadget_remove(struct platform_device *pdev)
857 {
858         struct resource *res0, *res1;
859         static struct pcie_gadget_target *target;
860         struct spear_pcie_gadget_config *config;
861         int irq;
862
863         res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
864         res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
865         irq = platform_get_irq(pdev, 0);
866         target = dev_get_drvdata(&pdev->dev);
867         config = &target->config;
868
869         free_irq(irq, NULL);
870         iounmap(config->va_dbi_base);
871         iounmap(config->va_app_base);
872         release_mem_region(res1->start, resource_size(res1));
873         release_mem_region(res0->start, resource_size(res0));
874         configfs_unregister_subsystem(&target->subsys);
875         kfree(target);
876
877         return 0;
878 }
879
880 static void spear_pcie_gadget_shutdown(struct platform_device *pdev)
881 {
882 }
883
884 static struct platform_driver spear_pcie_gadget_driver = {
885         .probe = spear_pcie_gadget_probe,
886         .remove = spear_pcie_gadget_remove,
887         .shutdown = spear_pcie_gadget_shutdown,
888         .driver = {
889                 .name = "pcie-gadget-spear",
890                 .bus = &platform_bus_type
891         },
892 };
893
894 static int __init spear_pcie_gadget_init(void)
895 {
896         return platform_driver_register(&spear_pcie_gadget_driver);
897 }
898 module_init(spear_pcie_gadget_init);
899
900 static void __exit spear_pcie_gadget_exit(void)
901 {
902         platform_driver_unregister(&spear_pcie_gadget_driver);
903 }
904 module_exit(spear_pcie_gadget_exit);
905
906 MODULE_ALIAS("pcie-gadget-spear");
907 MODULE_AUTHOR("Pratyush Anand");
908 MODULE_LICENSE("GPL");