2 * drivers/misc/spear13xx_pcie_gadget.c
4 * Copyright (C) 2010 ST Microelectronics
5 * Pratyush Anand<pratyush.anand@gmail.com>
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.
12 #include <linux/device.h>
13 #include <linux/clk.h>
14 #include <linux/slab.h>
15 #include <linux/delay.h>
17 #include <linux/interrupt.h>
18 #include <linux/irq.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/pci_regs.h>
23 #include <linux/configfs.h>
24 #include <mach/pcie.h>
25 #include <mach/misc_regs.h>
27 #define IN0_MEM_SIZE (200 * 1024 * 1024 - 1)
28 /* In current implementation address translation is done using IN0 only.
29 * So IN1 start address and IN0 end address has been kept same
31 #define IN1_MEM_SIZE (0 * 1024 * 1024 - 1)
32 #define IN_IO_SIZE (20 * 1024 * 1024 - 1)
33 #define IN_CFG0_SIZE (12 * 1024 * 1024 - 1)
34 #define IN_CFG1_SIZE (12 * 1024 * 1024 - 1)
35 #define IN_MSG_SIZE (12 * 1024 * 1024 - 1)
36 /* Keep default BAR size as 4K*/
37 /* AORAM would be mapped by default*/
38 #define INBOUND_ADDR_MASK (SPEAR13XX_SYSRAM1_SIZE - 1)
40 #define INT_TYPE_NO_INT 0
41 #define INT_TYPE_INTX 1
42 #define INT_TYPE_MSI 2
43 struct spear_pcie_gadget_config
{
45 void __iomem
*va_app_base
;
46 void __iomem
*va_dbi_base
;
52 void __iomem
*va_bar0_address
;
55 struct pcie_gadget_target
{
56 struct configfs_subsystem subsys
;
57 struct spear_pcie_gadget_config config
;
60 struct pcie_gadget_target_attr
{
61 struct configfs_attribute attr
;
62 ssize_t (*show
)(struct spear_pcie_gadget_config
*config
,
64 ssize_t (*store
)(struct spear_pcie_gadget_config
*config
,
69 static void enable_dbi_access(struct pcie_app_reg __iomem
*app_reg
)
71 /* Enable DBI access */
72 writel(readl(&app_reg
->slv_armisc
) | (1 << AXI_OP_DBI_ACCESS_ID
),
73 &app_reg
->slv_armisc
);
74 writel(readl(&app_reg
->slv_awmisc
) | (1 << AXI_OP_DBI_ACCESS_ID
),
75 &app_reg
->slv_awmisc
);
79 static void disable_dbi_access(struct pcie_app_reg __iomem
*app_reg
)
81 /* disable DBI access */
82 writel(readl(&app_reg
->slv_armisc
) & ~(1 << AXI_OP_DBI_ACCESS_ID
),
83 &app_reg
->slv_armisc
);
84 writel(readl(&app_reg
->slv_awmisc
) & ~(1 << AXI_OP_DBI_ACCESS_ID
),
85 &app_reg
->slv_awmisc
);
89 static void spear_dbi_read_reg(struct spear_pcie_gadget_config
*config
,
90 int where
, int size
, u32
*val
)
92 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
95 /* Enable DBI access */
96 enable_dbi_access(app_reg
);
98 va_address
= (ulong
)config
->va_dbi_base
+ (where
& ~0x3);
100 *val
= readl(va_address
);
103 *val
= (*val
>> (8 * (where
& 3))) & 0xff;
105 *val
= (*val
>> (8 * (where
& 3))) & 0xffff;
107 /* Disable DBI access */
108 disable_dbi_access(app_reg
);
111 static void spear_dbi_write_reg(struct spear_pcie_gadget_config
*config
,
112 int where
, int size
, u32 val
)
114 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
117 /* Enable DBI access */
118 enable_dbi_access(app_reg
);
120 va_address
= (ulong
)config
->va_dbi_base
+ (where
& ~0x3);
123 writel(val
, va_address
);
125 writew(val
, va_address
+ (where
& 2));
127 writeb(val
, va_address
+ (where
& 3));
129 /* Disable DBI access */
130 disable_dbi_access(app_reg
);
133 #define PCI_FIND_CAP_TTL 48
135 static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config
*config
,
136 u32 pos
, int cap
, int *ttl
)
141 spear_dbi_read_reg(config
, pos
, 1, &pos
);
145 spear_dbi_read_reg(config
, pos
+ PCI_CAP_LIST_ID
, 1, &id
);
150 pos
+= PCI_CAP_LIST_NEXT
;
155 static int pci_find_own_next_cap(struct spear_pcie_gadget_config
*config
,
158 int ttl
= PCI_FIND_CAP_TTL
;
160 return pci_find_own_next_cap_ttl(config
, pos
, cap
, &ttl
);
163 static int pci_find_own_cap_start(struct spear_pcie_gadget_config
*config
,
168 spear_dbi_read_reg(config
, PCI_STATUS
, 2, &status
);
169 if (!(status
& PCI_STATUS_CAP_LIST
))
173 case PCI_HEADER_TYPE_NORMAL
:
174 case PCI_HEADER_TYPE_BRIDGE
:
175 return PCI_CAPABILITY_LIST
;
176 case PCI_HEADER_TYPE_CARDBUS
:
177 return PCI_CB_CAPABILITY_LIST
;
186 * Tell if a device supports a given PCI capability.
187 * Returns the address of the requested capability structure within the
188 * device's PCI configuration space or 0 in case the device does not
189 * support it. Possible values for @cap:
191 * %PCI_CAP_ID_PM Power Management
192 * %PCI_CAP_ID_AGP Accelerated Graphics Port
193 * %PCI_CAP_ID_VPD Vital Product Data
194 * %PCI_CAP_ID_SLOTID Slot Identification
195 * %PCI_CAP_ID_MSI Message Signalled Interrupts
196 * %PCI_CAP_ID_CHSWP CompactPCI HotSwap
197 * %PCI_CAP_ID_PCIX PCI-X
198 * %PCI_CAP_ID_EXP PCI Express
200 static int pci_find_own_capability(struct spear_pcie_gadget_config
*config
,
206 spear_dbi_read_reg(config
, PCI_HEADER_TYPE
, 1, &hdr_type
);
208 pos
= pci_find_own_cap_start(config
, hdr_type
);
210 pos
= pci_find_own_next_cap(config
, pos
, cap
);
215 static irqreturn_t
spear_pcie_gadget_irq(int irq
, void *dev_id
)
221 * configfs interfaces show/store functions
223 static ssize_t
pcie_gadget_show_link(
224 struct spear_pcie_gadget_config
*config
,
227 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
229 if (readl(&app_reg
->app_status_1
) & ((u32
)1 << XMLH_LINK_UP_ID
))
230 return sprintf(buf
, "UP");
232 return sprintf(buf
, "DOWN");
235 static ssize_t
pcie_gadget_store_link(
236 struct spear_pcie_gadget_config
*config
,
237 const char *buf
, size_t count
)
239 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
241 if (sysfs_streq(buf
, "UP"))
242 writel(readl(&app_reg
->app_ctrl_0
) | (1 << APP_LTSSM_ENABLE_ID
),
243 &app_reg
->app_ctrl_0
);
244 else if (sysfs_streq(buf
, "DOWN"))
245 writel(readl(&app_reg
->app_ctrl_0
)
246 & ~(1 << APP_LTSSM_ENABLE_ID
),
247 &app_reg
->app_ctrl_0
);
253 static ssize_t
pcie_gadget_show_int_type(
254 struct spear_pcie_gadget_config
*config
,
257 return sprintf(buf
, "%s", config
->int_type
);
260 static ssize_t
pcie_gadget_store_int_type(
261 struct spear_pcie_gadget_config
*config
,
262 const char *buf
, size_t count
)
267 if (sysfs_streq(buf
, "INTA"))
268 spear_dbi_write_reg(config
, PCI_INTERRUPT_LINE
, 1, 1);
270 else if (sysfs_streq(buf
, "MSI")) {
271 vector
= config
->requested_msi
;
277 spear_dbi_write_reg(config
, PCI_INTERRUPT_LINE
, 1, 0);
278 cap
= pci_find_own_capability(config
, PCI_CAP_ID_MSI
);
279 spear_dbi_read_reg(config
, cap
+ PCI_MSI_FLAGS
, 1, &flags
);
280 flags
&= ~PCI_MSI_FLAGS_QMASK
;
282 spear_dbi_write_reg(config
, cap
+ PCI_MSI_FLAGS
, 1, flags
);
286 strcpy(config
->int_type
, buf
);
291 static ssize_t
pcie_gadget_show_no_of_msi(
292 struct spear_pcie_gadget_config
*config
,
295 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
299 if ((readl(&app_reg
->msg_status
) & (1 << CFG_MSI_EN_ID
))
300 != (1 << CFG_MSI_EN_ID
))
303 cap
= pci_find_own_capability(config
, PCI_CAP_ID_MSI
);
304 spear_dbi_read_reg(config
, cap
+ PCI_MSI_FLAGS
, 1, &flags
);
305 flags
&= ~PCI_MSI_FLAGS_QSIZE
;
311 config
->configured_msi
= vector
;
313 return sprintf(buf
, "%lu", vector
);
316 static ssize_t
pcie_gadget_store_no_of_msi(
317 struct spear_pcie_gadget_config
*config
,
318 const char *buf
, size_t count
)
322 ret
= kstrtoul(buf
, 0, &config
->requested_msi
);
326 if (config
->requested_msi
> 32)
327 config
->requested_msi
= 32;
332 static ssize_t
pcie_gadget_store_inta(
333 struct spear_pcie_gadget_config
*config
,
334 const char *buf
, size_t count
)
336 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
340 ret
= kstrtoul(buf
, 0, &en
);
345 writel(readl(&app_reg
->app_ctrl_0
) | (1 << SYS_INT_ID
),
346 &app_reg
->app_ctrl_0
);
348 writel(readl(&app_reg
->app_ctrl_0
) & ~(1 << SYS_INT_ID
),
349 &app_reg
->app_ctrl_0
);
354 static ssize_t
pcie_gadget_store_send_msi(
355 struct spear_pcie_gadget_config
*config
,
356 const char *buf
, size_t count
)
358 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
363 ret
= kstrtoul(buf
, 0, &vector
);
367 if (!config
->configured_msi
)
370 if (vector
>= config
->configured_msi
)
373 ven_msi
= readl(&app_reg
->ven_msi_1
);
374 ven_msi
&= ~VEN_MSI_FUN_NUM_MASK
;
375 ven_msi
|= 0 << VEN_MSI_FUN_NUM_ID
;
376 ven_msi
&= ~VEN_MSI_TC_MASK
;
377 ven_msi
|= 0 << VEN_MSI_TC_ID
;
378 ven_msi
&= ~VEN_MSI_VECTOR_MASK
;
379 ven_msi
|= vector
<< VEN_MSI_VECTOR_ID
;
381 /* generating interrupt for msi vector */
382 ven_msi
|= VEN_MSI_REQ_EN
;
383 writel(ven_msi
, &app_reg
->ven_msi_1
);
385 ven_msi
&= ~VEN_MSI_REQ_EN
;
386 writel(ven_msi
, &app_reg
->ven_msi_1
);
391 static ssize_t
pcie_gadget_show_vendor_id(
392 struct spear_pcie_gadget_config
*config
,
397 spear_dbi_read_reg(config
, PCI_VENDOR_ID
, 2, &id
);
399 return sprintf(buf
, "%x", id
);
402 static ssize_t
pcie_gadget_store_vendor_id(
403 struct spear_pcie_gadget_config
*config
,
404 const char *buf
, size_t count
)
409 ret
= kstrtoul(buf
, 0, &id
);
413 spear_dbi_write_reg(config
, PCI_VENDOR_ID
, 2, id
);
418 static ssize_t
pcie_gadget_show_device_id(
419 struct spear_pcie_gadget_config
*config
,
424 spear_dbi_read_reg(config
, PCI_DEVICE_ID
, 2, &id
);
426 return sprintf(buf
, "%x", id
);
429 static ssize_t
pcie_gadget_store_device_id(
430 struct spear_pcie_gadget_config
*config
,
431 const char *buf
, size_t count
)
436 ret
= kstrtoul(buf
, 0, &id
);
440 spear_dbi_write_reg(config
, PCI_DEVICE_ID
, 2, id
);
445 static ssize_t
pcie_gadget_show_bar0_size(
446 struct spear_pcie_gadget_config
*config
,
449 return sprintf(buf
, "%lx", config
->bar0_size
);
452 static ssize_t
pcie_gadget_store_bar0_size(
453 struct spear_pcie_gadget_config
*config
,
454 const char *buf
, size_t count
)
461 ret
= kstrtoul(buf
, 0, &size
);
465 /* min bar size is 256 */
468 /* max bar size is 1MB*/
469 else if (size
>= 0x100000)
475 pos
= find_next_bit((ulong
*)&size
, 21, pos
);
486 config
->bar0_size
= size
;
487 spear_dbi_write_reg(config
, PCIE_BAR0_MASK_REG
, 4, size
- 1);
492 static ssize_t
pcie_gadget_show_bar0_address(
493 struct spear_pcie_gadget_config
*config
,
496 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
498 u32 address
= readl(&app_reg
->pim0_mem_addr_start
);
500 return sprintf(buf
, "%x", address
);
503 static ssize_t
pcie_gadget_store_bar0_address(
504 struct spear_pcie_gadget_config
*config
,
505 const char *buf
, size_t count
)
507 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
511 ret
= kstrtoul(buf
, 0, &address
);
515 address
&= ~(config
->bar0_size
- 1);
516 if (config
->va_bar0_address
)
517 iounmap(config
->va_bar0_address
);
518 config
->va_bar0_address
= ioremap(address
, config
->bar0_size
);
519 if (!config
->va_bar0_address
)
522 writel(address
, &app_reg
->pim0_mem_addr_start
);
527 static ssize_t
pcie_gadget_show_bar0_rw_offset(
528 struct spear_pcie_gadget_config
*config
,
531 return sprintf(buf
, "%lx", config
->bar0_rw_offset
);
534 static ssize_t
pcie_gadget_store_bar0_rw_offset(
535 struct spear_pcie_gadget_config
*config
,
536 const char *buf
, size_t count
)
541 ret
= kstrtoul(buf
, 0, &offset
);
548 config
->bar0_rw_offset
= offset
;
553 static ssize_t
pcie_gadget_show_bar0_data(
554 struct spear_pcie_gadget_config
*config
,
559 if (!config
->va_bar0_address
)
562 data
= readl((ulong
)config
->va_bar0_address
+ config
->bar0_rw_offset
);
564 return sprintf(buf
, "%lx", data
);
567 static ssize_t
pcie_gadget_store_bar0_data(
568 struct spear_pcie_gadget_config
*config
,
569 const char *buf
, size_t count
)
574 ret
= kstrtoul(buf
, 0, &data
);
578 if (!config
->va_bar0_address
)
581 writel(data
, (ulong
)config
->va_bar0_address
+ config
->bar0_rw_offset
);
587 * Attribute definitions.
590 #define PCIE_GADGET_TARGET_ATTR_RO(_name) \
591 static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
592 __CONFIGFS_ATTR(_name, S_IRUGO, pcie_gadget_show_##_name, NULL)
594 #define PCIE_GADGET_TARGET_ATTR_WO(_name) \
595 static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
596 __CONFIGFS_ATTR(_name, S_IWUSR, NULL, pcie_gadget_store_##_name)
598 #define PCIE_GADGET_TARGET_ATTR_RW(_name) \
599 static struct pcie_gadget_target_attr pcie_gadget_target_##_name = \
600 __CONFIGFS_ATTR(_name, S_IRUGO | S_IWUSR, pcie_gadget_show_##_name, \
601 pcie_gadget_store_##_name)
602 PCIE_GADGET_TARGET_ATTR_RW(link
);
603 PCIE_GADGET_TARGET_ATTR_RW(int_type
);
604 PCIE_GADGET_TARGET_ATTR_RW(no_of_msi
);
605 PCIE_GADGET_TARGET_ATTR_WO(inta
);
606 PCIE_GADGET_TARGET_ATTR_WO(send_msi
);
607 PCIE_GADGET_TARGET_ATTR_RW(vendor_id
);
608 PCIE_GADGET_TARGET_ATTR_RW(device_id
);
609 PCIE_GADGET_TARGET_ATTR_RW(bar0_size
);
610 PCIE_GADGET_TARGET_ATTR_RW(bar0_address
);
611 PCIE_GADGET_TARGET_ATTR_RW(bar0_rw_offset
);
612 PCIE_GADGET_TARGET_ATTR_RW(bar0_data
);
614 static struct configfs_attribute
*pcie_gadget_target_attrs
[] = {
615 &pcie_gadget_target_link
.attr
,
616 &pcie_gadget_target_int_type
.attr
,
617 &pcie_gadget_target_no_of_msi
.attr
,
618 &pcie_gadget_target_inta
.attr
,
619 &pcie_gadget_target_send_msi
.attr
,
620 &pcie_gadget_target_vendor_id
.attr
,
621 &pcie_gadget_target_device_id
.attr
,
622 &pcie_gadget_target_bar0_size
.attr
,
623 &pcie_gadget_target_bar0_address
.attr
,
624 &pcie_gadget_target_bar0_rw_offset
.attr
,
625 &pcie_gadget_target_bar0_data
.attr
,
629 static struct pcie_gadget_target
*to_target(struct config_item
*item
)
632 container_of(to_configfs_subsystem(to_config_group(item
)),
633 struct pcie_gadget_target
, subsys
) : NULL
;
637 * Item operations and type for pcie_gadget_target.
640 static ssize_t
pcie_gadget_target_attr_show(struct config_item
*item
,
641 struct configfs_attribute
*attr
,
644 ssize_t ret
= -EINVAL
;
645 struct pcie_gadget_target
*target
= to_target(item
);
646 struct pcie_gadget_target_attr
*t_attr
=
647 container_of(attr
, struct pcie_gadget_target_attr
, attr
);
650 ret
= t_attr
->show(&target
->config
, buf
);
654 static ssize_t
pcie_gadget_target_attr_store(struct config_item
*item
,
655 struct configfs_attribute
*attr
,
659 ssize_t ret
= -EINVAL
;
660 struct pcie_gadget_target
*target
= to_target(item
);
661 struct pcie_gadget_target_attr
*t_attr
=
662 container_of(attr
, struct pcie_gadget_target_attr
, attr
);
665 ret
= t_attr
->store(&target
->config
, buf
, count
);
669 static struct configfs_item_operations pcie_gadget_target_item_ops
= {
670 .show_attribute
= pcie_gadget_target_attr_show
,
671 .store_attribute
= pcie_gadget_target_attr_store
,
674 static struct config_item_type pcie_gadget_target_type
= {
675 .ct_attrs
= pcie_gadget_target_attrs
,
676 .ct_item_ops
= &pcie_gadget_target_item_ops
,
677 .ct_owner
= THIS_MODULE
,
680 static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config
*config
)
682 struct pcie_app_reg __iomem
*app_reg
= config
->va_app_base
;
684 /*setup registers for outbound translation */
686 writel(config
->base
, &app_reg
->in0_mem_addr_start
);
687 writel(app_reg
->in0_mem_addr_start
+ IN0_MEM_SIZE
,
688 &app_reg
->in0_mem_addr_limit
);
689 writel(app_reg
->in0_mem_addr_limit
+ 1, &app_reg
->in1_mem_addr_start
);
690 writel(app_reg
->in1_mem_addr_start
+ IN1_MEM_SIZE
,
691 &app_reg
->in1_mem_addr_limit
);
692 writel(app_reg
->in1_mem_addr_limit
+ 1, &app_reg
->in_io_addr_start
);
693 writel(app_reg
->in_io_addr_start
+ IN_IO_SIZE
,
694 &app_reg
->in_io_addr_limit
);
695 writel(app_reg
->in_io_addr_limit
+ 1, &app_reg
->in_cfg0_addr_start
);
696 writel(app_reg
->in_cfg0_addr_start
+ IN_CFG0_SIZE
,
697 &app_reg
->in_cfg0_addr_limit
);
698 writel(app_reg
->in_cfg0_addr_limit
+ 1, &app_reg
->in_cfg1_addr_start
);
699 writel(app_reg
->in_cfg1_addr_start
+ IN_CFG1_SIZE
,
700 &app_reg
->in_cfg1_addr_limit
);
701 writel(app_reg
->in_cfg1_addr_limit
+ 1, &app_reg
->in_msg_addr_start
);
702 writel(app_reg
->in_msg_addr_start
+ IN_MSG_SIZE
,
703 &app_reg
->in_msg_addr_limit
);
705 writel(app_reg
->in0_mem_addr_start
, &app_reg
->pom0_mem_addr_start
);
706 writel(app_reg
->in1_mem_addr_start
, &app_reg
->pom1_mem_addr_start
);
707 writel(app_reg
->in_io_addr_start
, &app_reg
->pom_io_addr_start
);
709 /*setup registers for inbound translation */
711 /* Keep AORAM mapped at BAR0 as default */
712 config
->bar0_size
= INBOUND_ADDR_MASK
+ 1;
713 spear_dbi_write_reg(config
, PCIE_BAR0_MASK_REG
, 4, INBOUND_ADDR_MASK
);
714 spear_dbi_write_reg(config
, PCI_BASE_ADDRESS_0
, 4, 0xC);
715 config
->va_bar0_address
= ioremap(SPEAR13XX_SYSRAM1_BASE
,
718 writel(SPEAR13XX_SYSRAM1_BASE
, &app_reg
->pim0_mem_addr_start
);
719 writel(0, &app_reg
->pim1_mem_addr_start
);
720 writel(INBOUND_ADDR_MASK
+ 1, &app_reg
->mem0_addr_offset_limit
);
722 writel(0x0, &app_reg
->pim_io_addr_start
);
723 writel(0x0, &app_reg
->pim_io_addr_start
);
724 writel(0x0, &app_reg
->pim_rom_addr_start
);
726 writel(DEVICE_TYPE_EP
| (1 << MISCTRL_EN_ID
)
727 | ((u32
)1 << REG_TRANSLATION_ENABLE
),
728 &app_reg
->app_ctrl_0
);
729 /* disable all rx interrupts */
730 writel(0, &app_reg
->int_mask
);
732 /* Select INTA as default*/
733 spear_dbi_write_reg(config
, PCI_INTERRUPT_LINE
, 1, 1);
736 static int spear_pcie_gadget_probe(struct platform_device
*pdev
)
738 struct resource
*res0
, *res1
;
739 unsigned int status
= 0;
742 static struct pcie_gadget_target
*target
;
743 struct spear_pcie_gadget_config
*config
;
744 struct config_item
*cg_item
;
745 struct configfs_subsystem
*subsys
;
747 target
= devm_kzalloc(&pdev
->dev
, sizeof(*target
), GFP_KERNEL
);
749 dev_err(&pdev
->dev
, "out of memory\n");
753 cg_item
= &target
->subsys
.su_group
.cg_item
;
754 sprintf(cg_item
->ci_namebuf
, "pcie_gadget.%d", pdev
->id
);
755 cg_item
->ci_type
= &pcie_gadget_target_type
;
756 config
= &target
->config
;
758 /* get resource for application registers*/
759 res0
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
760 config
->va_app_base
= devm_ioremap_resource(&pdev
->dev
, res0
);
761 if (IS_ERR(config
->va_app_base
)) {
762 dev_err(&pdev
->dev
, "ioremap fail\n");
763 return PTR_ERR(config
->va_app_base
);
766 /* get resource for dbi registers*/
767 res1
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
768 config
->base
= (void __iomem
*)res1
->start
;
770 config
->va_dbi_base
= devm_ioremap_resource(&pdev
->dev
, res1
);
771 if (IS_ERR(config
->va_dbi_base
)) {
772 dev_err(&pdev
->dev
, "ioremap fail\n");
773 return PTR_ERR(config
->va_dbi_base
);
776 platform_set_drvdata(pdev
, target
);
778 irq
= platform_get_irq(pdev
, 0);
780 dev_err(&pdev
->dev
, "no update irq?\n");
784 status
= devm_request_irq(&pdev
->dev
, irq
, spear_pcie_gadget_irq
,
785 0, pdev
->name
, NULL
);
788 "pcie gadget interrupt IRQ%d already claimed\n", irq
);
792 /* Register configfs hooks */
793 subsys
= &target
->subsys
;
794 config_group_init(&subsys
->su_group
);
795 mutex_init(&subsys
->su_mutex
);
796 status
= configfs_register_subsystem(subsys
);
801 * init basic pcie application registers
802 * do not enable clock if it is PCIE0.Ideally , all controller should
803 * have been independent from others with respect to clock. But PCIE1
804 * and 2 depends on PCIE0.So PCIE0 clk is provided during board init.
808 * Ideally CFG Clock should have been also enabled here. But
809 * it is done currently during board init routne
811 clk
= clk_get_sys("pcie1", NULL
);
813 pr_err("%s:couldn't get clk for pcie1\n", __func__
);
816 status
= clk_enable(clk
);
818 pr_err("%s:couldn't enable clk for pcie1\n", __func__
);
821 } else if (pdev
->id
== 2) {
823 * Ideally CFG Clock should have been also enabled here. But
824 * it is done currently during board init routne
826 clk
= clk_get_sys("pcie2", NULL
);
828 pr_err("%s:couldn't get clk for pcie2\n", __func__
);
831 status
= clk_enable(clk
);
833 pr_err("%s:couldn't enable clk for pcie2\n", __func__
);
837 spear13xx_pcie_device_init(config
);
842 static int spear_pcie_gadget_remove(struct platform_device
*pdev
)
844 static struct pcie_gadget_target
*target
;
846 target
= platform_get_drvdata(pdev
);
848 configfs_unregister_subsystem(&target
->subsys
);
853 static void spear_pcie_gadget_shutdown(struct platform_device
*pdev
)
857 static struct platform_driver spear_pcie_gadget_driver
= {
858 .probe
= spear_pcie_gadget_probe
,
859 .remove
= spear_pcie_gadget_remove
,
860 .shutdown
= spear_pcie_gadget_shutdown
,
862 .name
= "pcie-gadget-spear",
863 .bus
= &platform_bus_type
867 module_platform_driver(spear_pcie_gadget_driver
);
869 MODULE_ALIAS("platform:pcie-gadget-spear");
870 MODULE_AUTHOR("Pratyush Anand");
871 MODULE_LICENSE("GPL");