cregit-Linux how code gets into the kernel

Release 4.14 drivers/misc/spear13xx_pcie_gadget.c

Directory: drivers/misc
/*
 * drivers/misc/spear13xx_pcie_gadget.c
 *
 * Copyright (C) 2010 ST Microelectronics
 * Pratyush Anand<pratyush.anand@gmail.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/device.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pci_regs.h>
#include <linux/configfs.h>
#include <mach/pcie.h>
#include <mach/misc_regs.h>


#define IN0_MEM_SIZE	(200 * 1024 * 1024 - 1)
/* In current implementation address translation is done using IN0 only.
 * So IN1 start address and IN0 end address has been kept same
*/

#define IN1_MEM_SIZE	(0 * 1024 * 1024 - 1)

#define IN_IO_SIZE	(20 * 1024 * 1024 - 1)

#define IN_CFG0_SIZE	(12 * 1024 * 1024 - 1)

#define IN_CFG1_SIZE	(12 * 1024 * 1024 - 1)

#define IN_MSG_SIZE	(12 * 1024 * 1024 - 1)
/* Keep default BAR size as 4K*/
/* AORAM would be mapped by default*/

#define INBOUND_ADDR_MASK	(SPEAR13XX_SYSRAM1_SIZE - 1)


#define INT_TYPE_NO_INT	0

#define INT_TYPE_INTX	1

#define INT_TYPE_MSI	2

struct spear_pcie_gadget_config {
	
void __iomem *base;
	
void __iomem *va_app_base;
	
void __iomem *va_dbi_base;
	
char int_type[10];
	
ulong requested_msi;
	
ulong configured_msi;
	
ulong bar0_size;
	
ulong bar0_rw_offset;
	
void __iomem *va_bar0_address;
};


struct pcie_gadget_target {
	
struct configfs_subsystem subsys;
	
struct spear_pcie_gadget_config config;
};


struct pcie_gadget_target_attr {
	
struct configfs_attribute	attr;
	
ssize_t		(*show)(struct spear_pcie_gadget_config *config,
						char *buf);
	
ssize_t		(*store)(struct spear_pcie_gadget_config *config,
						 const char *buf,
						 size_t count);
};


static void enable_dbi_access(struct pcie_app_reg __iomem *app_reg) { /* Enable DBI access */ writel(readl(&app_reg->slv_armisc) | (1 << AXI_OP_DBI_ACCESS_ID), &app_reg->slv_armisc); writel(readl(&app_reg->slv_awmisc) | (1 << AXI_OP_DBI_ACCESS_ID), &app_reg->slv_awmisc); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand57100.00%1100.00%
Total57100.00%1100.00%


static void disable_dbi_access(struct pcie_app_reg __iomem *app_reg) { /* disable DBI access */ writel(readl(&app_reg->slv_armisc) & ~(1 << AXI_OP_DBI_ACCESS_ID), &app_reg->slv_armisc); writel(readl(&app_reg->slv_awmisc) & ~(1 << AXI_OP_DBI_ACCESS_ID), &app_reg->slv_awmisc); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand59100.00%1100.00%
Total59100.00%1100.00%


static void spear_dbi_read_reg(struct spear_pcie_gadget_config *config, int where, int size, u32 *val) { struct pcie_app_reg __iomem *app_reg = config->va_app_base; ulong va_address; /* Enable DBI access */ enable_dbi_access(app_reg); va_address = (ulong)config->va_dbi_base + (where & ~0x3); *val = readl(va_address); if (size == 1) *val = (*val >> (8 * (where & 3))) & 0xff; else if (size == 2) *val = (*val >> (8 * (where & 3))) & 0xffff; /* Disable DBI access */ disable_dbi_access(app_reg); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand123100.00%1100.00%
Total123100.00%1100.00%


static void spear_dbi_write_reg(struct spear_pcie_gadget_config *config, int where, int size, u32 val) { struct pcie_app_reg __iomem *app_reg = config->va_app_base; ulong va_address; /* Enable DBI access */ enable_dbi_access(app_reg); va_address = (ulong)config->va_dbi_base + (where & ~0x3); if (size == 4) writel(val, va_address); else if (size == 2) writew(val, va_address + (where & 2)); else if (size == 1) writeb(val, va_address + (where & 3)); /* Disable DBI access */ disable_dbi_access(app_reg); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand114100.00%1100.00%
Total114100.00%1100.00%

#define PCI_FIND_CAP_TTL 48
static int pci_find_own_next_cap_ttl(struct spear_pcie_gadget_config *config, u32 pos, int cap, int *ttl) { u32 id; while ((*ttl)--) { spear_dbi_read_reg(config, pos, 1, &pos); if (pos < 0x40) break; pos &= ~3; spear_dbi_read_reg(config, pos + PCI_CAP_LIST_ID, 1, &id); if (id == 0xff) break; if (id == cap) return pos; pos += PCI_CAP_LIST_NEXT; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand95100.00%1100.00%
Total95100.00%1100.00%


static int pci_find_own_next_cap(struct spear_pcie_gadget_config *config, u32 pos, int cap) { int ttl = PCI_FIND_CAP_TTL; return pci_find_own_next_cap_ttl(config, pos, cap, &ttl); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand35100.00%1100.00%
Total35100.00%1100.00%


static int pci_find_own_cap_start(struct spear_pcie_gadget_config *config, u8 hdr_type) { u32 status; spear_dbi_read_reg(config, PCI_STATUS, 2, &status); if (!(status & PCI_STATUS_CAP_LIST)) return 0; switch (hdr_type) { case PCI_HEADER_TYPE_NORMAL: case PCI_HEADER_TYPE_BRIDGE: return PCI_CAPABILITY_LIST; case PCI_HEADER_TYPE_CARDBUS: return PCI_CB_CAPABILITY_LIST; default: return 0; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand69100.00%1100.00%
Total69100.00%1100.00%

/* * Tell if a device supports a given PCI capability. * Returns the address of the requested capability structure within the * device's PCI configuration space or 0 in case the device does not * support it. Possible values for @cap: * * %PCI_CAP_ID_PM Power Management * %PCI_CAP_ID_AGP Accelerated Graphics Port * %PCI_CAP_ID_VPD Vital Product Data * %PCI_CAP_ID_SLOTID Slot Identification * %PCI_CAP_ID_MSI Message Signalled Interrupts * %PCI_CAP_ID_CHSWP CompactPCI HotSwap * %PCI_CAP_ID_PCIX PCI-X * %PCI_CAP_ID_EXP PCI Express */
static int pci_find_own_capability(struct spear_pcie_gadget_config *config, int cap) { u32 pos; u32 hdr_type; spear_dbi_read_reg(config, PCI_HEADER_TYPE, 1, &hdr_type); pos = pci_find_own_cap_start(config, hdr_type); if (pos) pos = pci_find_own_next_cap(config, pos, cap); return pos; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand59100.00%1100.00%
Total59100.00%1100.00%


static irqreturn_t spear_pcie_gadget_irq(int irq, void *dev_id) { return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand16100.00%1100.00%
Total16100.00%1100.00%

/* * configfs interfaces show/store functions */
static struct pcie_gadget_target *to_target(struct config_item *item) { return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct pcie_gadget_target, subsys) : NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Christoph Hellwig34100.00%1100.00%
Total34100.00%1100.00%


static ssize_t pcie_gadget_link_show(struct config_item *item, char *buf) { struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base; if (readl(&app_reg->app_status_1) & ((u32)1 << XMLH_LINK_UP_ID)) return sprintf(buf, "UP"); else return sprintf(buf, "DOWN"); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand5789.06%150.00%
Christoph Hellwig710.94%150.00%
Total64100.00%2100.00%


static ssize_t pcie_gadget_link_store(struct config_item *item, const char *buf, size_t count) { struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base; if (sysfs_streq(buf, "UP")) writel(readl(&app_reg->app_ctrl_0) | (1 << APP_LTSSM_ENABLE_ID), &app_reg->app_ctrl_0); else if (sysfs_streq(buf, "DOWN")) writel(readl(&app_reg->app_ctrl_0) & ~(1 << APP_LTSSM_ENABLE_ID), &app_reg->app_ctrl_0); else return -EINVAL; return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand9793.27%150.00%
Christoph Hellwig76.73%150.00%
Total104100.00%2100.00%


static ssize_t pcie_gadget_int_type_show(struct config_item *item, char *buf) { return sprintf(buf, "%s", to_target(item)->int_type); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand2376.67%150.00%
Christoph Hellwig723.33%150.00%
Total30100.00%2100.00%


static ssize_t pcie_gadget_int_type_store(struct config_item *item, const char *buf, size_t count) { struct spear_pcie_gadget_config *config = to_target(item) u32 cap, vec, flags; ulong vector; if (sysfs_streq(buf, "INTA")) spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1); else if (sysfs_streq(buf, "MSI")) { vector = config->requested_msi; vec = 0; while (vector > 1) { vector /= 2; vec++; } spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 0); cap = pci_find_own_capability(config, PCI_CAP_ID_MSI); spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags); flags &= ~PCI_MSI_FLAGS_QMASK; flags |= vec << 1; spear_dbi_write_reg(config, cap + PCI_MSI_FLAGS, 1, flags); } else return -EINVAL; strcpy(config->int_type, buf); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand15892.94%150.00%
Christoph Hellwig127.06%150.00%
Total170100.00%2100.00%


static ssize_t pcie_gadget_no_of_msi_show(struct config_item *item, char *buf) { struct spear_pcie_gadget_config *config = to_target(item) struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base; u32 cap, vec, flags; ulong vector; if ((readl(&app_reg->msg_status) & (1 << CFG_MSI_EN_ID)) != (1 << CFG_MSI_EN_ID)) vector = 0; else { cap = pci_find_own_capability(config, PCI_CAP_ID_MSI); spear_dbi_read_reg(config, cap + PCI_MSI_FLAGS, 1, &flags); flags &= ~PCI_MSI_FLAGS_QSIZE; vec = flags >> 4; vector = 1; while (vec--) vector *= 2; } config->configured_msi = vector; return sprintf(buf, "%lu", vector); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand12387.23%150.00%
Christoph Hellwig1812.77%150.00%
Total141100.00%2100.00%


static ssize_t pcie_gadget_no_of_msi_store(struct config_item *item, const char *buf, size_t count) { int ret; ret = kstrtoul(buf, 0, &to_target(item)->requested_msi); if (ret) return ret; if (config->requested_msi > 32) config->requested_msi = 32; return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand4571.43%133.33%
Jingoo Han1117.46%133.33%
Christoph Hellwig711.11%133.33%
Total63100.00%3100.00%


static ssize_t pcie_gadget_inta_store(struct config_item *item, const char *buf, size_t count) { struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base; ulong en; int ret; ret = kstrtoul(buf, 0, &en); if (ret) return ret; if (en) writel(readl(&app_reg->app_ctrl_0) | (1 << SYS_INT_ID), &app_reg->app_ctrl_0); else writel(readl(&app_reg->app_ctrl_0) & ~(1 << SYS_INT_ID), &app_reg->app_ctrl_0); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand9283.64%133.33%
Jingoo Han1110.00%133.33%
Christoph Hellwig76.36%133.33%
Total110100.00%3100.00%


static ssize_t pcie_gadget_send_msi_store(struct config_item *item, const char *buf, size_t count) { struct spear_pcie_gadget_config *config = to_target(item) struct pcie_app_reg __iomem *app_reg = config->va_app_base; ulong vector; u32 ven_msi; int ret; ret = kstrtoul(buf, 0, &vector); if (ret) return ret; if (!config->configured_msi) return -EINVAL; if (vector >= config->configured_msi) return -EINVAL; ven_msi = readl(&app_reg->ven_msi_1); ven_msi &= ~VEN_MSI_FUN_NUM_MASK; ven_msi |= 0 << VEN_MSI_FUN_NUM_ID; ven_msi &= ~VEN_MSI_TC_MASK; ven_msi |= 0 << VEN_MSI_TC_ID; ven_msi &= ~VEN_MSI_VECTOR_MASK; ven_msi |= vector << VEN_MSI_VECTOR_ID; /* generating interrupt for msi vector */ ven_msi |= VEN_MSI_REQ_EN; writel(ven_msi, &app_reg->ven_msi_1); udelay(1); ven_msi &= ~VEN_MSI_REQ_EN; writel(ven_msi, &app_reg->ven_msi_1); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand14585.29%133.33%
Christoph Hellwig148.24%133.33%
Jingoo Han116.47%133.33%
Total170100.00%3100.00%


static ssize_t pcie_gadget_vendor_id_show(struct config_item *item, char *buf) { u32 id; spear_dbi_read_reg(to_target(item), PCI_VENDOR_ID, 2, &id); return sprintf(buf, "%x", id); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand3683.72%150.00%
Christoph Hellwig716.28%150.00%
Total43100.00%2100.00%


static ssize_t pcie_gadget_vendor_id_store(struct config_item *item, const char *buf, size_t count) { ulong id; int ret; ret = kstrtoul(buf, 0, &id); if (ret) return ret; spear_dbi_write_reg(to_target(item), PCI_VENDOR_ID, 2, id); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand4370.49%133.33%
Jingoo Han1118.03%133.33%
Christoph Hellwig711.48%133.33%
Total61100.00%3100.00%


static ssize_t pcie_gadget_device_id_show(struct config_item *item, char *buf) { u32 id; spear_dbi_read_reg(to_target(item), PCI_DEVICE_ID, 2, &id); return sprintf(buf, "%x", id); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand3683.72%150.00%
Christoph Hellwig716.28%150.00%
Total43100.00%2100.00%


static ssize_t pcie_gadget_device_id_store(struct config_item *item, const char *buf, size_t count) { ulong id; int ret; ret = kstrtoul(buf, 0, &id); if (ret) return ret; spear_dbi_write_reg(to_target(item), PCI_DEVICE_ID, 2, id); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand4370.49%133.33%
Jingoo Han1118.03%133.33%
Christoph Hellwig711.48%133.33%
Total61100.00%3100.00%


static ssize_t pcie_gadget_bar0_size_show(struct config_item *item, char *buf) { return sprintf(buf, "%lx", to_target(item)->bar0_size); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand2376.67%150.00%
Christoph Hellwig723.33%150.00%
Total30100.00%2100.00%


static ssize_t pcie_gadget_bar0_size_store(struct config_item *item, const char *buf, size_t count) { struct spear_pcie_gadget_config *config = to_target(item) ulong size; u32 pos, pos1; u32 no_of_bit = 0; int ret; ret = kstrtoul(buf, 0, &size); if (ret) return ret; /* min bar size is 256 */ if (size <= 0x100) size = 0x100; /* max bar size is 1MB*/ else if (size >= 0x100000) size = 0x100000; else { pos = 0; pos1 = 0; while (pos < 21) { pos = find_next_bit((ulong *)&size, 21, pos); if (pos != 21) pos1 = pos + 1; pos++; no_of_bit++; } if (no_of_bit == 2) pos1--; size = 1 << pos1; } config->bar0_size = size; spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, size - 1); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand15386.93%133.33%
Christoph Hellwig126.82%133.33%
Jingoo Han116.25%133.33%
Total176100.00%3100.00%


static ssize_t pcie_gadget_bar0_address_show(struct config_item *item, char *buf) { struct pcie_app_reg __iomem *app_reg = to_target(item)->va_app_base; u32 address = readl(&app_reg->pim0_mem_addr_start); return sprintf(buf, "%x", address); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand4285.71%150.00%
Christoph Hellwig714.29%150.00%
Total49100.00%2100.00%


static ssize_t pcie_gadget_bar0_address_store(struct config_item *item, const char *buf, size_t count) { struct spear_pcie_gadget_config *config = to_target(item) struct pcie_app_reg __iomem *app_reg = config->va_app_base; ulong address; int ret; ret = kstrtoul(buf, 0, &address); if (ret) return ret; address &= ~(config->bar0_size - 1); if (config->va_bar0_address) iounmap(config->va_bar0_address); config->va_bar0_address = ioremap(address, config->bar0_size); if (!config->va_bar0_address) return -ENOMEM; writel(address, &app_reg->pim0_mem_addr_start); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand9979.84%133.33%
Christoph Hellwig1411.29%133.33%
Jingoo Han118.87%133.33%
Total124100.00%3100.00%


static ssize_t pcie_gadget_bar0_rw_offset_show(struct config_item *item, char *buf) { return sprintf(buf, "%lx", to_target(item)->bar0_rw_offset); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand2376.67%150.00%
Christoph Hellwig723.33%150.00%
Total30100.00%2100.00%


static ssize_t pcie_gadget_bar0_rw_offset_store(struct config_item *item, const char *buf, size_t count) { ulong offset; int ret; ret = kstrtoul(buf, 0, &offset); if (ret) return ret; if (offset % 4) return -EINVAL; to_target(item)->bar0_rw_offset = offset; return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand4872.73%133.33%
Jingoo Han1116.67%133.33%
Christoph Hellwig710.61%133.33%
Total66100.00%3100.00%


static ssize_t pcie_gadget_bar0_data_show(struct config_item *item, char *buf) { struct spear_pcie_gadget_config *config = to_target(item) ulong data; if (!config->va_bar0_address) return -ENOMEM; data = readl((ulong)config->va_bar0_address + config->bar0_rw_offset); return sprintf(buf, "%lx", data); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand5281.25%150.00%
Christoph Hellwig1218.75%150.00%
Total64100.00%2100.00%


static ssize_t pcie_gadget_bar0_data_store(struct config_item *item, const char *buf, size_t count) { struct spear_pcie_gadget_config *config = to_target(item) ulong data; int ret; ret = kstrtoul(buf, 0, &data); if (ret) return ret; if (!config->va_bar0_address) return -ENOMEM; writel(data, (ulong)config->va_bar0_address + config->bar0_rw_offset); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand6072.29%133.33%
Christoph Hellwig1214.46%133.33%
Jingoo Han1113.25%133.33%
Total83100.00%3100.00%

CONFIGFS_ATTR(pcie_gadget_, link); CONFIGFS_ATTR(pcie_gadget_, int_type); CONFIGFS_ATTR(pcie_gadget_, no_of_msi); CONFIGFS_ATTR_WO(pcie_gadget_, inta); CONFIGFS_ATTR_WO(pcie_gadget_, send_msi); CONFIGFS_ATTR(pcie_gadget_, vendor_id); CONFIGFS_ATTR(pcie_gadget_, device_id); CONFIGFS_ATTR(pcie_gadget_, bar0_size); CONFIGFS_ATTR(pcie_gadget_, bar0_address); CONFIGFS_ATTR(pcie_gadget_, bar0_rw_offset); CONFIGFS_ATTR(pcie_gadget_, bar0_data); static struct configfs_attribute *pcie_gadget_target_attrs[] = { &pcie_gadget_attr_link, &pcie_gadget_attr_int_type, &pcie_gadget_attr_no_of_msi, &pcie_gadget_attr_inta, &pcie_gadget_attr_send_msi, &pcie_gadget_attr_vendor_id, &pcie_gadget_attr_device_id, &pcie_gadget_attr_bar0_size, &pcie_gadget_attr_bar0_address, &pcie_gadget_attr_bar0_rw_offset, &pcie_gadget_attr_bar0_data, NULL, }; static struct config_item_type pcie_gadget_target_type = { .ct_attrs = pcie_gadget_target_attrs, .ct_owner = THIS_MODULE, };
static void spear13xx_pcie_device_init(struct spear_pcie_gadget_config *config) { struct pcie_app_reg __iomem *app_reg = config->va_app_base; /*setup registers for outbound translation */ writel(config->base, &app_reg->in0_mem_addr_start); writel(app_reg->in0_mem_addr_start + IN0_MEM_SIZE, &app_reg->in0_mem_addr_limit); writel(app_reg->in0_mem_addr_limit + 1, &app_reg->in1_mem_addr_start); writel(app_reg->in1_mem_addr_start + IN1_MEM_SIZE, &app_reg->in1_mem_addr_limit); writel(app_reg->in1_mem_addr_limit + 1, &app_reg->in_io_addr_start); writel(app_reg->in_io_addr_start + IN_IO_SIZE, &app_reg->in_io_addr_limit); writel(app_reg->in_io_addr_limit + 1, &app_reg->in_cfg0_addr_start); writel(app_reg->in_cfg0_addr_start + IN_CFG0_SIZE, &app_reg->in_cfg0_addr_limit); writel(app_reg->in_cfg0_addr_limit + 1, &app_reg->in_cfg1_addr_start); writel(app_reg->in_cfg1_addr_start + IN_CFG1_SIZE, &app_reg->in_cfg1_addr_limit); writel(app_reg->in_cfg1_addr_limit + 1, &app_reg->in_msg_addr_start); writel(app_reg->in_msg_addr_start + IN_MSG_SIZE, &app_reg->in_msg_addr_limit); writel(app_reg->in0_mem_addr_start, &app_reg->pom0_mem_addr_start); writel(app_reg->in1_mem_addr_start, &app_reg->pom1_mem_addr_start); writel(app_reg->in_io_addr_start, &app_reg->pom_io_addr_start); /*setup registers for inbound translation */ /* Keep AORAM mapped at BAR0 as default */ config->bar0_size = INBOUND_ADDR_MASK + 1; spear_dbi_write_reg(config, PCIE_BAR0_MASK_REG, 4, INBOUND_ADDR_MASK); spear_dbi_write_reg(config, PCI_BASE_ADDRESS_0, 4, 0xC); config->va_bar0_address = ioremap(SPEAR13XX_SYSRAM1_BASE, config->bar0_size); writel(SPEAR13XX_SYSRAM1_BASE, &app_reg->pim0_mem_addr_start); writel(0, &app_reg->pim1_mem_addr_start); writel(INBOUND_ADDR_MASK + 1, &app_reg->mem0_addr_offset_limit); writel(0x0, &app_reg->pim_io_addr_start); writel(0x0, &app_reg->pim_io_addr_start); writel(0x0, &app_reg->pim_rom_addr_start); writel(DEVICE_TYPE_EP | (1 << MISCTRL_EN_ID) | ((u32)1 << REG_TRANSLATION_ENABLE), &app_reg->app_ctrl_0); /* disable all rx interrupts */ writel(0, &app_reg->int_mask); /* Select INTA as default*/ spear_dbi_write_reg(config, PCI_INTERRUPT_LINE, 1, 1); }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand379100.00%1100.00%
Total379100.00%1100.00%


static int spear_pcie_gadget_probe(struct platform_device *pdev) { struct resource *res0, *res1; unsigned int status = 0; int irq; struct clk *clk; static struct pcie_gadget_target *target; struct spear_pcie_gadget_config *config; struct config_item *cg_item; struct configfs_subsystem *subsys; target = devm_kzalloc(&pdev->dev, sizeof(*target), GFP_KERNEL); if (!target) { dev_err(&pdev->dev, "out of memory\n"); return -ENOMEM; } cg_item = &target->subsys.su_group.cg_item; sprintf(cg_item->ci_namebuf, "pcie_gadget.%d", pdev->id); cg_item->ci_type = &pcie_gadget_target_type; config = &target->config; /* get resource for application registers*/ res0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); config->va_app_base = devm_ioremap_resource(&pdev->dev, res0); if (IS_ERR(config->va_app_base)) { dev_err(&pdev->dev, "ioremap fail\n"); return PTR_ERR(config->va_app_base); } /* get resource for dbi registers*/ res1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); config->base = (void __iomem *)res1->start; config->va_dbi_base = devm_ioremap_resource(&pdev->dev, res1); if (IS_ERR(config->va_dbi_base)) { dev_err(&pdev->dev, "ioremap fail\n"); return PTR_ERR(config->va_dbi_base); } platform_set_drvdata(pdev, target); irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no update irq?\n"); return irq; } status = devm_request_irq(&pdev->dev, irq, spear_pcie_gadget_irq, 0, pdev->name, NULL); if (status) { dev_err(&pdev->dev, "pcie gadget interrupt IRQ%d already claimed\n", irq); return status; } /* Register configfs hooks */ subsys = &target->subsys; config_group_init(&subsys->su_group); mutex_init(&subsys->su_mutex); status = configfs_register_subsystem(subsys); if (status) return status; /* * init basic pcie application registers * do not enable clock if it is PCIE0.Ideally , all controller should * have been independent from others with respect to clock. But PCIE1 * and 2 depends on PCIE0.So PCIE0 clk is provided during board init. */ if (pdev->id == 1) { /* * Ideally CFG Clock should have been also enabled here. But * it is done currently during board init routne */ clk = clk_get_sys("pcie1", NULL); if (IS_ERR(clk)) { pr_err("%s:couldn't get clk for pcie1\n", __func__); return PTR_ERR(clk); } status = clk_enable(clk); if (status) { pr_err("%s:couldn't enable clk for pcie1\n", __func__); return status; } } else if (pdev->id == 2) { /* * Ideally CFG Clock should have been also enabled here. But * it is done currently during board init routne */ clk = clk_get_sys("pcie2", NULL); if (IS_ERR(clk)) { pr_err("%s:couldn't get clk for pcie2\n", __func__); return PTR_ERR(clk); } status = clk_enable(clk); if (status) { pr_err("%s:couldn't enable clk for pcie2\n", __func__); return status; } } spear13xx_pcie_device_init(config); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand40979.88%120.00%
Himangi Saraogi8115.82%120.00%
Wei Yongjun203.91%120.00%
Joe Perches10.20%120.00%
Jingoo Han10.20%120.00%
Total512100.00%5100.00%


static int spear_pcie_gadget_remove(struct platform_device *pdev) { static struct pcie_gadget_target *target; target = platform_get_drvdata(pdev); configfs_unregister_subsystem(&target->subsys); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand3497.14%150.00%
Jingoo Han12.86%150.00%
Total35100.00%2100.00%


static void spear_pcie_gadget_shutdown(struct platform_device *pdev) { }

Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand10100.00%1100.00%
Total10100.00%1100.00%

static struct platform_driver spear_pcie_gadget_driver = { .probe = spear_pcie_gadget_probe, .remove = spear_pcie_gadget_remove, .shutdown = spear_pcie_gadget_shutdown, .driver = { .name = "pcie-gadget-spear", .bus = &platform_bus_type }, }; module_platform_driver(spear_pcie_gadget_driver); MODULE_ALIAS("platform:pcie-gadget-spear"); MODULE_AUTHOR("Pratyush Anand"); MODULE_LICENSE("GPL");

Overall Contributors

PersonTokensPropCommitsCommitProp
Pratyush Anand319787.16%220.00%
Christoph Hellwig2637.17%110.00%
Jingoo Han1012.75%220.00%
Himangi Saraogi842.29%110.00%
Wei Yongjun200.55%110.00%
Axel Lin20.05%220.00%
Joe Perches10.03%110.00%
Total3668100.00%10100.00%
Directory: drivers/misc
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.