diff options
Diffstat (limited to 'drivers')
217 files changed, 17254 insertions, 4140 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index acad70a0bb0d..aebd944bdaa1 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -454,32 +454,7 @@ config ACPI_REDUCED_HARDWARE_ONLY If you are unsure what to do, do not enable this option. -config ACPI_NFIT - tristate "ACPI NVDIMM Firmware Interface Table (NFIT)" - depends on PHYS_ADDR_T_64BIT - depends on BLK_DEV - depends on ARCH_HAS_MMIO_FLUSH - select LIBNVDIMM - help - Infrastructure to probe ACPI 6 compliant platforms for - NVDIMMs (NFIT) and register a libnvdimm device tree. In - addition to storage devices this also enables libnvdimm to pass - ACPI._DSM messages for platform/dimm configuration. - - To compile this driver as a module, choose M here: - the module will be called nfit. - -config ACPI_NFIT_DEBUG - bool "NFIT DSM debug" - depends on ACPI_NFIT - depends on DYNAMIC_DEBUG - default n - help - Enabling this option causes the nfit driver to dump the - input and output buffers of _DSM operations on the ACPI0012 - device and its children. This can be very verbose, so leave - it disabled unless you are debugging a hardware / firmware - issue. +source "drivers/acpi/nfit/Kconfig" source "drivers/acpi/apei/Kconfig" source "drivers/acpi/dptf/Kconfig" diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 88f54f03e3d2..35a6ccbe3025 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -69,7 +69,7 @@ obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o obj-$(CONFIG_ACPI_PROCESSOR) += processor.o obj-$(CONFIG_ACPI) += container.o obj-$(CONFIG_ACPI_THERMAL) += thermal.o -obj-$(CONFIG_ACPI_NFIT) += nfit.o +obj-$(CONFIG_ACPI_NFIT) += nfit/ obj-$(CONFIG_ACPI) += acpi_memhotplug.o obj-$(CONFIG_ACPI_HOTPLUG_IOAPIC) += ioapic.o obj-$(CONFIG_ACPI_BATTERY) += battery.o diff --git a/drivers/acpi/nfit/Kconfig b/drivers/acpi/nfit/Kconfig new file mode 100644 index 000000000000..dd0d53c52552 --- /dev/null +++ b/drivers/acpi/nfit/Kconfig @@ -0,0 +1,26 @@ +config ACPI_NFIT + tristate "ACPI NVDIMM Firmware Interface Table (NFIT)" + depends on PHYS_ADDR_T_64BIT + depends on BLK_DEV + depends on ARCH_HAS_MMIO_FLUSH + select LIBNVDIMM + help + Infrastructure to probe ACPI 6 compliant platforms for + NVDIMMs (NFIT) and register a libnvdimm device tree. In + addition to storage devices this also enables libnvdimm to pass + ACPI._DSM messages for platform/dimm configuration. + + To compile this driver as a module, choose M here: + the module will be called nfit. + +config ACPI_NFIT_DEBUG + bool "NFIT DSM debug" + depends on ACPI_NFIT + depends on DYNAMIC_DEBUG + default n + help + Enabling this option causes the nfit driver to dump the + input and output buffers of _DSM operations on the ACPI0012 + device and its children. This can be very verbose, so leave + it disabled unless you are debugging a hardware / firmware + issue. diff --git a/drivers/acpi/nfit/Makefile b/drivers/acpi/nfit/Makefile new file mode 100644 index 000000000000..a407e769f103 --- /dev/null +++ b/drivers/acpi/nfit/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ACPI_NFIT) := nfit.o +nfit-y := core.o +nfit-$(CONFIG_X86_MCE) += mce.o diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit/core.c index 1f0e06065ae6..8c234dd9b8bc 100644 --- a/drivers/acpi/nfit.c +++ b/drivers/acpi/nfit/core.c @@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/mutex.h> #include <linux/ndctl.h> +#include <linux/sysfs.h> #include <linux/delay.h> #include <linux/list.h> #include <linux/acpi.h> @@ -50,6 +51,9 @@ module_param(disable_vendor_specific, bool, S_IRUGO); MODULE_PARM_DESC(disable_vendor_specific, "Limit commands to the publicly specified set\n"); +LIST_HEAD(acpi_descs); +DEFINE_MUTEX(acpi_desc_lock); + static struct workqueue_struct *nfit_wq; struct nfit_table_prev { @@ -360,7 +364,7 @@ static const char *spa_type_name(u16 type) return to_name[type]; } -static int nfit_spa_type(struct acpi_nfit_system_address *spa) +int nfit_spa_type(struct acpi_nfit_system_address *spa) { int i; @@ -374,22 +378,25 @@ static bool add_spa(struct acpi_nfit_desc *acpi_desc, struct nfit_table_prev *prev, struct acpi_nfit_system_address *spa) { - size_t length = min_t(size_t, sizeof(*spa), spa->header.length); struct device *dev = acpi_desc->dev; struct nfit_spa *nfit_spa; + if (spa->header.length != sizeof(*spa)) + return false; + list_for_each_entry(nfit_spa, &prev->spas, list) { - if (memcmp(nfit_spa->spa, spa, length) == 0) { + if (memcmp(nfit_spa->spa, spa, sizeof(*spa)) == 0) { list_move_tail(&nfit_spa->list, &acpi_desc->spas); return true; } } - nfit_spa = devm_kzalloc(dev, sizeof(*nfit_spa), GFP_KERNEL); + nfit_spa = devm_kzalloc(dev, sizeof(*nfit_spa) + sizeof(*spa), + GFP_KERNEL); if (!nfit_spa) return false; INIT_LIST_HEAD(&nfit_spa->list); - nfit_spa->spa = spa; + memcpy(nfit_spa->spa, spa, sizeof(*spa)); list_add_tail(&nfit_spa->list, &acpi_desc->spas); dev_dbg(dev, "%s: spa index: %d type: %s\n", __func__, spa->range_index, @@ -401,21 +408,24 @@ static bool add_memdev(struct acpi_nfit_desc *acpi_desc, struct nfit_table_prev *prev, struct acpi_nfit_memory_map *memdev) { - size_t length = min_t(size_t, sizeof(*memdev), memdev->header.length); struct device *dev = acpi_desc->dev; struct nfit_memdev *nfit_memdev; + if (memdev->header.length != sizeof(*memdev)) + return false; + list_for_each_entry(nfit_memdev, &prev->memdevs, list) - if (memcmp(nfit_memdev->memdev, memdev, length) == 0) { + if (memcmp(nfit_memdev->memdev, memdev, sizeof(*memdev)) == 0) { list_move_tail(&nfit_memdev->list, &acpi_desc->memdevs); return true; } - nfit_memdev = devm_kzalloc(dev, sizeof(*nfit_memdev), GFP_KERNEL); + nfit_memdev = devm_kzalloc(dev, sizeof(*nfit_memdev) + sizeof(*memdev), + GFP_KERNEL); if (!nfit_memdev) return false; INIT_LIST_HEAD(&nfit_memdev->list); - nfit_memdev->memdev = memdev; + memcpy(nfit_memdev->memdev, memdev, sizeof(*memdev)); list_add_tail(&nfit_memdev->list, &acpi_desc->memdevs); dev_dbg(dev, "%s: memdev handle: %#x spa: %d dcr: %d\n", __func__, memdev->device_handle, memdev->range_index, @@ -423,25 +433,42 @@ static bool add_memdev(struct acpi_nfit_desc *acpi_desc, return true; } +/* + * An implementation may provide a truncated control region if no block windows + * are defined. + */ +static size_t sizeof_dcr(struct acpi_nfit_control_region *dcr) +{ + if (dcr->header.length < offsetof(struct acpi_nfit_control_region, + window_size)) + return 0; + if (dcr->windows) + return sizeof(*dcr); + return offsetof(struct acpi_nfit_control_region, window_size); +} + static bool add_dcr(struct acpi_nfit_desc *acpi_desc, struct nfit_table_prev *prev, struct acpi_nfit_control_region *dcr) { - size_t length = min_t(size_t, sizeof(*dcr), dcr->header.length); struct device *dev = acpi_desc->dev; struct nfit_dcr *nfit_dcr; + if (!sizeof_dcr(dcr)) + return false; + list_for_each_entry(nfit_dcr, &prev->dcrs, list) - if (memcmp(nfit_dcr->dcr, dcr, length) == 0) { + if (memcmp(nfit_dcr->dcr, dcr, sizeof_dcr(dcr)) == 0) { list_move_tail(&nfit_dcr->list, &acpi_desc->dcrs); return true; } - nfit_dcr = devm_kzalloc(dev, sizeof(*nfit_dcr), GFP_KERNEL); + nfit_dcr = devm_kzalloc(dev, sizeof(*nfit_dcr) + sizeof(*dcr), + GFP_KERNEL); if (!nfit_dcr) return false; INIT_LIST_HEAD(&nfit_dcr->list); - nfit_dcr->dcr = dcr; + memcpy(nfit_dcr->dcr, dcr, sizeof_dcr(dcr)); list_add_tail(&nfit_dcr->list, &acpi_desc->dcrs); dev_dbg(dev, "%s: dcr index: %d windows: %d\n", __func__, dcr->region_index, dcr->windows); @@ -452,71 +479,102 @@ static bool add_bdw(struct acpi_nfit_desc *acpi_desc, struct nfit_table_prev *prev, struct acpi_nfit_data_region *bdw) { - size_t length = min_t(size_t, sizeof(*bdw), bdw->header.length); struct device *dev = acpi_desc->dev; struct nfit_bdw *nfit_bdw; + if (bdw->header.length != sizeof(*bdw)) + return false; list_for_each_entry(nfit_bdw, &prev->bdws, list) - if (memcmp(nfit_bdw->bdw, bdw, length) == 0) { + if (memcmp(nfit_bdw->bdw, bdw, sizeof(*bdw)) == 0) { list_move_tail(&nfit_bdw->list, &acpi_desc->bdws); return true; } - nfit_bdw = devm_kzalloc(dev, sizeof(*nfit_bdw), GFP_KERNEL); + nfit_bdw = devm_kzalloc(dev, sizeof(*nfit_bdw) + sizeof(*bdw), + GFP_KERNEL); if (!nfit_bdw) return false; INIT_LIST_HEAD(&nfit_bdw->list); - nfit_bdw->bdw = bdw; + memcpy(nfit_bdw->bdw, bdw, sizeof(*bdw)); list_add_tail(&nfit_bdw->list, &acpi_desc->bdws); dev_dbg(dev, "%s: bdw dcr: %d windows: %d\n", __func__, bdw->region_index, bdw->windows); return true; } +static size_t sizeof_idt(struct acpi_nfit_interleave *idt) +{ + if (idt->header.length < sizeof(*idt)) + return 0; + return sizeof(*idt) + sizeof(u32) * (idt->line_count - 1); +} + static bool add_idt(struct acpi_nfit_desc *acpi_desc, struct nfit_table_prev *prev, struct acpi_nfit_interleave *idt) { - size_t length = min_t(size_t, sizeof(*idt), idt->header.length); struct device *dev = acpi_desc->dev; struct nfit_idt *nfit_idt; - list_for_each_entry(nfit_idt, &prev->idts, list) - if (memcmp(nfit_idt->idt, idt, length) == 0) { + if (!sizeof_idt(idt)) + return false; + + list_for_each_entry(nfit_idt, &prev->idts, list) { + if (sizeof_idt(nfit_idt->idt) != sizeof_idt(idt)) + continue; + + if (memcmp(nfit_idt->idt, idt, sizeof_idt(idt)) == 0) { list_move_tail(&nfit_idt->list, &acpi_desc->idts); return true; } + } - nfit_idt = devm_kzalloc(dev, sizeof(*nfit_idt), GFP_KERNEL); + nfit_idt = devm_kzalloc(dev, sizeof(*nfit_idt) + sizeof_idt(idt), + GFP_KERNEL); if (!nfit_idt) return false; INIT_LIST_HEAD(&nfit_idt->list); - nfit_idt->idt = idt; + memcpy(nfit_idt->idt, idt, sizeof_idt(idt)); list_add_tail(&nfit_idt->list, &acpi_desc->idts); dev_dbg(dev, "%s: idt index: %d num_lines: %d\n", __func__, idt->interleave_index, idt->line_count); return true; } +static size_t sizeof_flush(struct acpi_nfit_flush_address *flush) +{ + if (flush->header.length < sizeof(*flush)) + return 0; + return sizeof(*flush) + sizeof(u64) * (flush->hint_count - 1); +} + static bool add_flush(struct acpi_nfit_desc *acpi_desc, struct nfit_table_prev *prev, struct acpi_nfit_flush_address *flush) { - size_t length = min_t(size_t, sizeof(*flush), flush->header.length); struct device *dev = acpi_desc->dev; struct nfit_flush *nfit_flush; - list_for_each_entry(nfit_flush, &prev->flushes, list) - if (memcmp(nfit_flush->flush, flush, length) == 0) { + if (!sizeof_flush(flush)) + return false; + + list_for_each_entry(nfit_flush, &prev->flushes, list) { + if (sizeof_flush(nfit_flush->flush) != sizeof_flush(flush)) + continue; + + if (memcmp(nfit_flush->flush, flush, + sizeof_flush(flush)) == 0) { list_move_tail(&nfit_flush->list, &acpi_desc->flushes); return true; } + } - nfit_flush = devm_kzalloc(dev, sizeof(*nfit_flush), GFP_KERNEL); + nfit_flush = devm_kzalloc(dev, sizeof(*nfit_flush) + + sizeof_flush(flush), GFP_KERNEL); if (!nfit_flush) return false; INIT_LIST_HEAD(&nfit_flush->list); - nfit_flush->flush = flush; + memcpy(nfit_flush->flush, flush, sizeof_flush(flush)); list_add_tail(&nfit_flush->list, &acpi_desc->flushes); dev_dbg(dev, "%s: nfit_flush handle: %d hint_count: %d\n", __func__, flush->device_handle, flush->hint_count); @@ -614,7 +672,6 @@ static void nfit_mem_init_bdw(struct acpi_nfit_desc *acpi_desc, { u16 dcr = __to_nfit_memdev(nfit_mem)->region_index; struct nfit_memdev *nfit_memdev; - struct nfit_flush *nfit_flush; struct nfit_bdw *nfit_bdw; struct nfit_idt *nfit_idt; u16 idt_idx, range_index; @@ -647,14 +704,6 @@ static void nfit_mem_init_bdw(struct acpi_nfit_desc *acpi_desc, nfit_mem->idt_bdw = nfit_idt->idt; break; } - - list_for_each_entry(nfit_flush, &acpi_desc->flushes, list) { - if (nfit_flush->flush->device_handle != - nfit_memdev->memdev->device_handle) - continue; - nfit_mem->nfit_flush = nfit_flush; - break; - } break; } } @@ -675,6 +724,7 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc, } list_for_each_entry(nfit_memdev, &acpi_desc->memdevs, list) { + struct nfit_flush *nfit_flush; struct nfit_dcr *nfit_dcr; u32 device_handle; u16 dcr; @@ -721,6 +771,28 @@ static int nfit_mem_dcr_init(struct acpi_nfit_desc *acpi_desc, break; } + list_for_each_entry(nfit_flush, &acpi_desc->flushes, list) { + struct acpi_nfit_flush_address *flush; + u16 i; + + if (nfit_flush->flush->device_handle != device_handle) + continue; + nfit_mem->nfit_flush = nfit_flush; + flush = nfit_flush->flush; + nfit_mem->flush_wpq = devm_kzalloc(acpi_desc->dev, + flush->hint_count + * sizeof(struct resource), GFP_KERNEL); + if (!nfit_mem->flush_wpq) + return -ENOMEM; + for (i = 0; i < flush->hint_count; i++) { + struct resource *res = &nfit_mem->flush_wpq[i]; + + res->start = flush->hint_address[i]; + res->end = res->start + 8 - 1; + } + break; + } + if (dcr && !nfit_mem->dcr) { dev_err(acpi_desc->dev, "SPA %d missing DCR %d\n", spa->range_index, dcr); @@ -806,14 +878,85 @@ static ssize_t revision_show(struct device *dev, } static DEVICE_ATTR_RO(revision); +/* + * This shows the number of full Address Range Scrubs that have been + * completed since driver load time. Userspace can wait on this using + * select/poll etc. A '+' at the end indicates an ARS is in progress + */ +static ssize_t scrub_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct nvdimm_bus_descriptor *nd_desc; + ssize_t rc = -ENXIO; + + device_lock(dev); + nd_desc = dev_get_drvdata(dev); + if (nd_desc) { + struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); + + rc = sprintf(buf, "%d%s", acpi_desc->scrub_count, + (work_busy(&acpi_desc->work)) ? "+\n" : "\n"); + } + device_unlock(dev); + return rc; +} + +static ssize_t scrub_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + struct nvdimm_bus_descriptor *nd_desc; + ssize_t rc; + long val; + + rc = kstrtol(buf, 0, &val); + if (rc) + return rc; + if (val != 1) + return -EINVAL; + + device_lock(dev); + nd_desc = dev_get_drvdata(dev); + if (nd_desc) { + struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); + + rc = acpi_nfit_ars_rescan(acpi_desc); + } + device_unlock(dev); + if (rc) + return rc; + return size; +} +static DEVICE_ATTR_RW(scrub); + +static bool ars_supported(struct nvdimm_bus *nvdimm_bus) +{ + struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus); + const unsigned long mask = 1 << ND_CMD_ARS_CAP | 1 << ND_CMD_ARS_START + | 1 << ND_CMD_ARS_STATUS; + + return (nd_desc->cmd_mask & mask) == mask; +} + +static umode_t nfit_visible(struct kobject *kobj, struct attribute *a, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev); + + if (a == &dev_attr_scrub.attr && !ars_supported(nvdimm_bus)) + return 0; + return a->mode; +} + static struct attribute *acpi_nfit_attributes[] = { &dev_attr_revision.attr, + &dev_attr_scrub.attr, NULL, }; static struct attribute_group acpi_nfit_attribute_group = { .name = "nfit", .attrs = acpi_nfit_attributes, + .is_visible = nfit_visible, }; static const struct attribute_group *acpi_nfit_attribute_groups[] = { @@ -1130,11 +1273,11 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, } /* - * Until standardization materializes we need to consider up to 3 + * Until standardization materializes we need to consider 4 * different command sets. Note, that checking for function0 (bit0) * tells us if any commands are reachable through this uuid. */ - for (i = NVDIMM_FAMILY_INTEL; i <= NVDIMM_FAMILY_HPE2; i++) + for (i = NVDIMM_FAMILY_INTEL; i <= NVDIMM_FAMILY_MSFT; i++) if (acpi_check_dsm(adev_dimm->handle, to_nfit_uuid(i), 1, 1)) break; @@ -1144,12 +1287,14 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc, dsm_mask = 0x3fe; if (disable_vendor_specific) dsm_mask &= ~(1 << ND_CMD_VENDOR); - } else if (nfit_mem->family == NVDIMM_FAMILY_HPE1) + } else if (nfit_mem->family == NVDIMM_FAMILY_HPE1) { dsm_mask = 0x1c3c76; - else if (nfit_mem->family == NVDIMM_FAMILY_HPE2) { + } else if (nfit_mem->family == NVDIMM_FAMILY_HPE2) { dsm_mask = 0x1fe; if (disable_vendor_specific) dsm_mask &= ~(1 << 8); + } else if (nfit_mem->family == NVDIMM_FAMILY_MSFT) { + dsm_mask = 0xffffffff; } else { dev_dbg(dev, "unknown dimm command family\n"); nfit_mem->family = -1; @@ -1171,6 +1316,7 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) int dimm_count = 0; list_for_each_entry(nfit_mem, &acpi_desc->dimms, list) { + struct acpi_nfit_flush_address *flush; unsigned long flags = 0, cmd_mask; struct nvdimm *nvdimm; u32 device_handle; @@ -1204,9 +1350,12 @@ static int acpi_nfit_register_dimms(struct acpi_nfit_desc *acpi_desc) if (nfit_mem->family == NVDIMM_FAMILY_INTEL) cmd_mask |= nfit_mem->dsm_mask; + flush = nfit_mem->nfit_flush ? nfit_mem->nfit_flush->flush + : NULL; nvdimm = nvdimm_create(acpi_desc->nvdimm_bus, nfit_mem, acpi_nfit_dimm_attribute_groups, - flags, cmd_mask); + flags, cmd_mask, flush ? flush->hint_count : 0, + nfit_mem->flush_wpq); if (!nvdimm) return -ENOMEM; @@ -1374,24 +1523,6 @@ static u64 to_interleave_offset(u64 offset, struct nfit_blk_mmio *mmio) return mmio->base_offset + line_offset + table_offset + sub_line_offset; } -static void wmb_blk(struct nfit_blk *nfit_blk) -{ - - if (nfit_blk->nvdimm_flush) { - /* - * The first wmb() is needed to 'sfence' all previous writes - * such that they are architecturally visible for the platform - * buffer flush. Note that we've already arranged for pmem - * writes to avoid the cache via arch_memcpy_to_pmem(). The - * final wmb() ensures ordering for the NVDIMM flush write. - */ - wmb(); - writeq(1, nfit_blk->nvdimm_flush); - wmb(); - } else - wmb_pmem(); -} - static u32 read_blk_stat(struct nfit_blk *nfit_blk, unsigned int bw) { struct nfit_blk_mmio *mmio = &nfit_blk->mmio[DCR]; @@ -1426,7 +1557,7 @@ static void write_blk_ctl(struct nfit_blk *nfit_blk, unsigned int bw, offset = to_interleave_offset(offset, mmio); writeq(cmd, mmio->addr.base + offset); - wmb_blk(nfit_blk); + nvdimm_flush(nfit_blk->nd_region); if (nfit_blk->dimm_flags & NFIT_BLK_DCR_LATCH) readq(mmio->addr.base + offset); @@ -1477,7 +1608,7 @@ static int acpi_nfit_blk_single_io(struct nfit_blk *nfit_blk, } if (rw) - wmb_blk(nfit_blk); + nvdimm_flush(nfit_blk->nd_region); rc = read_blk_stat(nfit_blk, lane) ? -EIO : 0; return rc; @@ -1509,125 +1640,6 @@ static int acpi_nfit_blk_region_do_io(struct nd_blk_region *ndbr, return rc; } -static void nfit_spa_mapping_release(struct kref *kref) -{ - struct nfit_spa_mapping *spa_map = to_spa_map(kref); - struct acpi_nfit_system_address *spa = spa_map->spa; - struct acpi_nfit_desc *acpi_desc = spa_map->acpi_desc; - - WARN_ON(!mutex_is_locked(&acpi_desc->spa_map_mutex)); - dev_dbg(acpi_desc->dev, "%s: SPA%d\n", __func__, spa->range_index); - if (spa_map->type == SPA_MAP_APERTURE) - memunmap((void __force *)spa_map->addr.aperture); - else - iounmap(spa_map->addr.base); - release_mem_region(spa->address, spa->length); - list_del(&spa_map->list); - kfree(spa_map); -} - -static struct nfit_spa_mapping *find_spa_mapping( - struct acpi_nfit_desc *acpi_desc, - struct acpi_nfit_system_address *spa) -{ - struct nfit_spa_mapping *spa_map; - - WARN_ON(!mutex_is_locked(&acpi_desc->spa_map_mutex)); - list_for_each_entry(spa_map, &acpi_desc->spa_maps, list) - if (spa_map->spa == spa) - return spa_map; - - return NULL; -} - -static void nfit_spa_unmap(struct acpi_nfit_desc *acpi_desc, - struct acpi_nfit_system_address *spa) -{ - struct nfit_spa_mapping *spa_map; - - mutex_lock(&acpi_desc->spa_map_mutex); - spa_map = find_spa_mapping(acpi_desc, spa); - - if (spa_map) - kref_put(&spa_map->kref, nfit_spa_mapping_release); - mutex_unlock(&acpi_desc->spa_map_mutex); -} - -static void __iomem *__nfit_spa_map(struct acpi_nfit_desc *acpi_desc, - struct acpi_nfit_system_address *spa, enum spa_map_type type) -{ - resource_size_t start = spa->address; - resource_size_t n = spa->length; - struct nfit_spa_mapping *spa_map; - struct resource *res; - - WARN_ON(!mutex_is_locked(&acpi_desc->spa_map_mutex)); - - spa_map = find_spa_mapping(acpi_desc, spa); - if (spa_map) { - kref_get(&spa_map->kref); - return spa_map->addr.base; - } - - spa_map = kzalloc(sizeof(*spa_map), GFP_KERNEL); - if (!spa_map) - return NULL; - - INIT_LIST_HEAD(&spa_map->list); - spa_map->spa = spa; - kref_init(&spa_map->kref); - spa_map->acpi_desc = acpi_desc; - - res = request_mem_region(start, n, dev_name(acpi_desc->dev)); - if (!res) - goto err_mem; - - spa_map->type = type; - if (type == SPA_MAP_APERTURE) - spa_map->addr.aperture = (void __pmem *)memremap(start, n, - ARCH_MEMREMAP_PMEM); - else - spa_map->addr.base = ioremap_nocache(start, n); - - - if (!spa_map->addr.base) - goto err_map; - - list_add_tail(&spa_map->list, &acpi_desc->spa_maps); - return spa_map->addr.base; - - err_map: - release_mem_region(start, n); - err_mem: - kfree(spa_map); - return NULL; -} - -/** - * nfit_spa_map - interleave-aware managed-mappings of acpi_nfit_system_address ranges - * @nvdimm_bus: NFIT-bus that provided the spa table entry - * @nfit_spa: spa table to map - * @type: aperture or control region - * - * In the case where block-data-window apertures and - * dimm-control-regions are interleaved they will end up sharing a - * single request_mem_region() + ioremap() for the address range. In - * the style of devm nfit_spa_map() mappings are automatically dropped - * when all region devices referencing the same mapping are disabled / - * unbound. - */ -static void __iomem *nfit_spa_map(struct acpi_nfit_desc *acpi_desc, - struct acpi_nfit_system_address *spa, enum spa_map_type type) -{ - void __iomem *iomem; - - mutex_lock(&acpi_desc->spa_map_mutex); - iomem = __nfit_spa_map(acpi_desc, spa, type); - mutex_unlock(&acpi_desc->spa_map_mutex); - - return iomem; -} - static int nfit_blk_init_interleave(struct nfit_blk_mmio *mmio, struct acpi_nfit_interleave *idt, u16 interleave_ways) { @@ -1669,9 +1681,7 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus, struct device *dev) { struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus); - struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); struct nd_blk_region *ndbr = to_nd_blk_region(dev); - struct nfit_flush *nfit_flush; struct nfit_blk_mmio *mmio; struct nfit_blk *nfit_blk; struct nfit_mem *nfit_mem; @@ -1697,8 +1707,8 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus, /* map block aperture memory */ nfit_blk->bdw_offset = nfit_mem->bdw->offset; mmio = &nfit_blk->mmio[BDW]; - mmio->addr.base = nfit_spa_map(acpi_desc, nfit_mem->spa_bdw, - SPA_MAP_APERTURE); + mmio->addr.base = devm_nvdimm_memremap(dev, nfit_mem->spa_bdw->address, + nfit_mem->spa_bdw->length, ARCH_MEMREMAP_PMEM); if (!mmio->addr.base) { dev_dbg(dev, "%s: %s failed to map bdw\n", __func__, nvdimm_name(nvdimm)); @@ -1720,8 +1730,8 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus, nfit_blk->cmd_offset = nfit_mem->dcr->command_offset; nfit_blk->stat_offset = nfit_mem->dcr->status_offset; mmio = &nfit_blk->mmio[DCR]; - mmio->addr.base = nfit_spa_map(acpi_desc, nfit_mem->spa_dcr, - SPA_MAP_CONTROL); + mmio->addr.base = devm_nvdimm_ioremap(dev, nfit_mem->spa_dcr->address, + nfit_mem->spa_dcr->length); if (!mmio->addr.base) { dev_dbg(dev, "%s: %s failed to map dcr\n", __func__, nvdimm_name(nvdimm)); @@ -1746,15 +1756,7 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus, return rc; } - nfit_flush = nfit_mem->nfit_flush; - if (nfit_flush && nfit_flush->flush->hint_count != 0) { - nfit_blk->nvdimm_flush = devm_ioremap_nocache(dev, - nfit_flush->flush->hint_address[0], 8); - if (!nfit_blk->nvdimm_flush) - return -ENOMEM; - } - - if (!arch_has_wmb_pmem() && !nfit_blk->nvdimm_flush) + if (nvdimm_has_flush(nfit_blk->nd_region) < 0) dev_warn(dev, "unable to guarantee persistence of writes\n"); if (mmio->line_size == 0) @@ -1773,29 +1775,6 @@ static int acpi_nfit_blk_region_enable(struct nvdimm_bus *nvdimm_bus, return 0; } -static void acpi_nfit_blk_region_disable(struct nvdimm_bus *nvdimm_bus, - struct device *dev) -{ - struct nvdimm_bus_descriptor *nd_desc = to_nd_desc(nvdimm_bus); - struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); - struct nd_blk_region *ndbr = to_nd_blk_region(dev); - struct nfit_blk *nfit_blk = nd_blk_region_provider_data(ndbr); - int i; - - if (!nfit_blk) - return; /* never enabled */ - - /* auto-free BLK spa mappings */ - for (i = 0; i < 2; i++) { - struct nfit_blk_mmio *mmio = &nfit_blk->mmio[i]; - - if (mmio->addr.base) - nfit_spa_unmap(acpi_desc, mmio->spa); - } - nd_blk_region_set_provider_data(ndbr, NULL); - /* devm will free nfit_blk */ -} - static int ars_get_cap(struct acpi_nfit_desc *acpi_desc, struct nd_cmd_ars_cap *cmd, struct nfit_spa *nfit_spa) { @@ -1919,11 +1898,11 @@ static int acpi_nfit_insert_resource(struct acpi_nfit_desc *acpi_desc, if (ret) return ret; - ret = devm_add_action(acpi_desc->dev, acpi_nfit_remove_resource, res); - if (ret) { - remove_resource(res); + ret = devm_add_action_or_reset(acpi_desc->dev, + acpi_nfit_remove_resource, + res); + if (ret) return ret; - } return 0; } @@ -1969,7 +1948,6 @@ static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc, ndr_desc->num_mappings = blk_valid; ndbr_desc = to_blk_region_desc(ndr_desc); ndbr_desc->enable = acpi_nfit_blk_region_enable; - ndbr_desc->disable = acpi_nfit_blk_region_disable; ndbr_desc->do_io = acpi_desc->blk_do_io; nfit_spa->nd_region = nvdimm_blk_region_create(acpi_desc->nvdimm_bus, ndr_desc); @@ -1981,6 +1959,14 @@ static int acpi_nfit_init_mapping(struct acpi_nfit_desc *acpi_desc, return 0; } +static bool nfit_spa_is_virtual(struct acpi_nfit_system_address *spa) +{ + return (nfit_spa_type(spa) == NFIT_SPA_VDISK || + nfit_spa_type(spa) == NFIT_SPA_VCD || + nfit_spa_type(spa) == NFIT_SPA_PDISK || + nfit_spa_type(spa) == NFIT_SPA_PCD); +} + static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, struct nfit_spa *nfit_spa) { @@ -1996,7 +1982,7 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, if (nfit_spa->nd_region) return 0; - if (spa->range_index == 0) { + if (spa->range_index == 0 && !nfit_spa_is_virtual(spa)) { dev_dbg(acpi_desc->dev, "%s: detected invalid spa index\n", __func__); return 0; @@ -2060,6 +2046,11 @@ static int acpi_nfit_register_region(struct acpi_nfit_desc *acpi_desc, ndr_desc); if (!nfit_spa->nd_region) rc = -ENOMEM; + } else if (nfit_spa_is_virtual(spa)) { + nfit_spa->nd_region = nvdimm_pmem_region_create(nvdimm_bus, + ndr_desc); + if (!nfit_spa->nd_region) + rc = -ENOMEM; } out: @@ -2139,7 +2130,7 @@ static void acpi_nfit_async_scrub(struct acpi_nfit_desc *acpi_desc, unsigned int tmo = scrub_timeout; int rc; - if (nfit_spa->ars_done || !nfit_spa->nd_region) + if (!nfit_spa->ars_required || !nfit_spa->nd_region) return; rc = ars_start(acpi_desc, nfit_spa); @@ -2228,7 +2219,9 @@ static void acpi_nfit_scrub(struct work_struct *work) * firmware initiated scrubs to complete and then we go search for the * affected spa regions to mark them scanned. In the second phase we * initiate a directed scrub for every range that was not scrubbed in - * phase 1. + * phase 1. If we're called for a 'rescan', we harmlessly pass through + * the first phase, but really only care about running phase 2, where + * regions can be notified of new poison. */ /* process platform firmware initiated scrubs */ @@ -2331,14 +2324,17 @@ static void acpi_nfit_scrub(struct work_struct *work) * Flag all the ranges that still need scrubbing, but * register them now to make data available. */ - if (nfit_spa->nd_region) - nfit_spa->ars_done = 1; - else + if (!nfit_spa->nd_region) { + nfit_spa->ars_required = 1; acpi_nfit_register_region(acpi_desc, nfit_spa); + } } list_for_each_entry(nfit_spa, &acpi_desc->spas, list) acpi_nfit_async_scrub(acpi_desc, nfit_spa); + acpi_desc->scrub_count++; + if (acpi_desc->scrub_count_state) + sysfs_notify_dirent(acpi_desc->scrub_count_state); mutex_unlock(&acpi_desc->init_mutex); } @@ -2376,14 +2372,89 @@ static int acpi_nfit_check_deletions(struct acpi_nfit_desc *acpi_desc, return 0; } -int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, acpi_size sz) +static int acpi_nfit_desc_init_scrub_attr(struct acpi_nfit_desc *acpi_desc) +{ + struct device *dev = acpi_desc->dev; + struct kernfs_node *nfit; + struct device *bus_dev; + + if (!ars_supported(acpi_desc->nvdimm_bus)) + return 0; + + bus_dev = to_nvdimm_bus_dev(acpi_desc->nvdimm_bus); + nfit = sysfs_get_dirent(bus_dev->kobj.sd, "nfit"); + if (!nfit) { + dev_err(dev, "sysfs_get_dirent 'nfit' failed\n"); + return -ENODEV; + } + acpi_desc->scrub_count_state = sysfs_get_dirent(nfit, "scrub"); + sysfs_put(nfit); + if (!acpi_desc->scrub_count_state) { + dev_err(dev, "sysfs_get_dirent 'scrub' failed\n"); + return -ENODEV; + } + + return 0; +} + +static void acpi_nfit_destruct(void *data) +{ + struct acpi_nfit_desc *acpi_desc = data; + struct device *bus_dev = to_nvdimm_bus_dev(acpi_desc->nvdimm_bus); + + /* + * Destruct under acpi_desc_lock so that nfit_handle_mce does not + * race teardown + */ + mutex_lock(&acpi_desc_lock); + acpi_desc->cancel = 1; + /* + * Bounce the nvdimm bus lock to make sure any in-flight + * acpi_nfit_ars_rescan() submissions have had a chance to + * either submit or see ->cancel set. + */ + device_lock(bus_dev); + device_unlock(bus_dev); + + flush_workqueue(nfit_wq); + if (acpi_desc->scrub_count_state) + sysfs_put(acpi_desc->scrub_count_state); + nvdimm_bus_unregister(acpi_desc->nvdimm_bus); + acpi_desc->nvdimm_bus = NULL; + list_del(&acpi_desc->list); + mutex_unlock(&acpi_desc_lock); +} + +int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *data, acpi_size sz) { struct device *dev = acpi_desc->dev; struct nfit_table_prev prev; const void *end; - u8 *data; int rc; + if (!acpi_desc->nvdimm_bus) { + acpi_nfit_init_dsms(acpi_desc); + + acpi_desc->nvdimm_bus = nvdimm_bus_register(dev, + &acpi_desc->nd_desc); + if (!acpi_desc->nvdimm_bus) + return -ENOMEM; + + rc = devm_add_action_or_reset(dev, acpi_nfit_destruct, + acpi_desc); + if (rc) + return rc; + + rc = acpi_nfit_desc_init_scrub_attr(acpi_desc); + if (rc) + return rc; + + /* register this acpi_desc for mce notifications */ + mutex_lock(&acpi_desc_lock); + list_add_tail(&acpi_desc->list, &acpi_descs); + mutex_unlock(&acpi_desc_lock); + } + mutex_lock(&acpi_desc->init_mutex); INIT_LIST_HEAD(&prev.spas); @@ -2406,7 +2477,6 @@ int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, acpi_size sz) list_cut_position(&prev.flushes, &acpi_desc->flushes, acpi_desc->flushes.prev); - data = (u8 *) acpi_desc->nfit; end = data + sz; while (!IS_ERR_OR_NULL(data)) data = add_table(acpi_desc, &prev, data, end); @@ -2422,12 +2492,9 @@ int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, acpi_size sz) if (rc) goto out_unlock; - if (nfit_mem_init(acpi_desc) != 0) { - rc = -ENOMEM; + rc = nfit_mem_init(acpi_desc); + if (rc) goto out_unlock; - } - - acpi_nfit_init_dsms(acpi_desc); rc = acpi_nfit_register_dimms(acpi_desc); if (rc) @@ -2496,6 +2563,33 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc, return 0; } +int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc) +{ + struct device *dev = acpi_desc->dev; + struct nfit_spa *nfit_spa; + + if (work_busy(&acpi_desc->work)) + return -EBUSY; + + if (acpi_desc->cancel) + return 0; + + mutex_lock(&acpi_desc->init_mutex); + list_for_each_entry(nfit_spa, &acpi_desc->spas, list) { + struct acpi_nfit_system_address *spa = nfit_spa->spa; + + if (nfit_spa_type(spa) != NFIT_SPA_PM) + continue; + + nfit_spa->ars_required = 1; + } + queue_work(nfit_wq, &acpi_desc->work); + dev_dbg(dev, "%s: ars_scan triggered\n", __func__); + mutex_unlock(&acpi_desc->init_mutex); + + return 0; +} + void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev) { struct nvdimm_bus_descriptor *nd_desc; @@ -2505,12 +2599,12 @@ void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev) acpi_desc->blk_do_io = acpi_nfit_blk_region_do_io; nd_desc = &acpi_desc->nd_desc; nd_desc->provider_name = "ACPI.NFIT"; + nd_desc->module = THIS_MODULE; nd_desc->ndctl = acpi_nfit_ctl; nd_desc->flush_probe = acpi_nfit_flush_probe; nd_desc->clear_to_send = acpi_nfit_clear_to_send; nd_desc->attr_groups = acpi_nfit_attribute_groups; - INIT_LIST_HEAD(&acpi_desc->spa_maps); INIT_LIST_HEAD(&acpi_desc->spas); INIT_LIST_HEAD(&acpi_desc->dcrs); INIT_LIST_HEAD(&acpi_desc->bdws); @@ -2518,7 +2612,7 @@ void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev) INIT_LIST_HEAD(&acpi_desc->flushes); INIT_LIST_HEAD(&acpi_desc->memdevs); INIT_LIST_HEAD(&acpi_desc->dimms); - mutex_init(&acpi_desc->spa_map_mutex); + INIT_LIST_HEAD(&acpi_desc->list); mutex_init(&acpi_desc->init_mutex); INIT_WORK(&acpi_desc->work, acpi_nfit_scrub); } @@ -2532,7 +2626,7 @@ static int acpi_nfit_add(struct acpi_device *adev) struct acpi_table_header *tbl; acpi_status status = AE_OK; acpi_size sz; - int rc; + int rc = 0; status = acpi_get_table_with_size(ACPI_SIG_NFIT, 0, &tbl, &sz); if (ACPI_FAILURE(status)) { @@ -2545,50 +2639,33 @@ static int acpi_nfit_add(struct acpi_device *adev) if (!acpi_desc) return -ENOMEM; acpi_nfit_desc_init(acpi_desc, &adev->dev); - acpi_desc->nvdimm_bus = nvdimm_bus_register(dev, &acpi_desc->nd_desc); - if (!acpi_desc->nvdimm_bus) - return -ENOMEM; - /* - * Save the acpi header for later and then skip it, - * making nfit point to the first nfit table header. - */ + /* Save the acpi header for exporting the revision via sysfs */ acpi_desc->acpi_header = *tbl; - acpi_desc->nfit = (void *) tbl + sizeof(struct acpi_table_nfit); - sz -= sizeof(struct acpi_table_nfit); /* Evaluate _FIT and override with that if present */ status = acpi_evaluate_object(adev->handle, "_FIT", NULL, &buf); if (ACPI_SUCCESS(status) && buf.length > 0) { - union acpi_object *obj; - /* - * Adjust for the acpi_object header of the _FIT - */ - obj = buf.pointer; - if (obj->type == ACPI_TYPE_BUFFER) { - acpi_desc->nfit = - (struct acpi_nfit_header *)obj->buffer.pointer; - sz = obj->buffer.length; - } else + union acpi_object *obj = buf.pointer; + + if (obj->type == ACPI_TYPE_BUFFER) + rc = acpi_nfit_init(acpi_desc, obj->buffer.pointer, + obj->buffer.length); + else dev_dbg(dev, "%s invalid type %d, ignoring _FIT\n", __func__, (int) obj->type); - } - - rc = acpi_nfit_init(acpi_desc, sz); - if (rc) { - nvdimm_bus_unregister(acpi_desc->nvdimm_bus); - return rc; - } - return 0; + kfree(buf.pointer); + } else + /* skip over the lead-in header table */ + rc = acpi_nfit_init(acpi_desc, (void *) tbl + + sizeof(struct acpi_table_nfit), + sz - sizeof(struct acpi_table_nfit)); + return rc; } static int acpi_nfit_remove(struct acpi_device *adev) { - struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(&adev->dev); - - acpi_desc->cancel = 1; - flush_workqueue(nfit_wq); - nvdimm_bus_unregister(acpi_desc->nvdimm_bus); + /* see acpi_nfit_destruct */ return 0; } @@ -2596,9 +2673,8 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event) { struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(&adev->dev); struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; - struct acpi_nfit_header *nfit_saved; - union acpi_object *obj; struct device *dev = &adev->dev; + union acpi_object *obj; acpi_status status; int ret; @@ -2616,9 +2692,6 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event) if (!acpi_desc) goto out_unlock; acpi_nfit_desc_init(acpi_desc, &adev->dev); - acpi_desc->nvdimm_bus = nvdimm_bus_register(dev, &acpi_desc->nd_desc); - if (!acpi_desc->nvdimm_bus) - goto out_unlock; } else { /* * Finish previous registration before considering new @@ -2634,21 +2707,14 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event) goto out_unlock; } - nfit_saved = acpi_desc->nfit; obj = buf.pointer; if (obj->type == ACPI_TYPE_BUFFER) { - acpi_desc->nfit = - (struct acpi_nfit_header *)obj->buffer.pointer; - ret = acpi_nfit_init(acpi_desc, obj->buffer.length); - if (ret) { - /* Merge failed, restore old nfit, and exit */ - acpi_desc->nfit = nfit_saved; + ret = acpi_nfit_init(acpi_desc, obj->buffer.pointer, + obj->buffer.length); + if (ret) dev_err(dev, "failed to merge updated NFIT\n"); - } - } else { - /* Bad _FIT, restore old nfit */ + } else dev_err(dev, "Invalid _FIT\n"); - } kfree(buf.pointer); out_unlock: @@ -2693,18 +2759,23 @@ static __init int nfit_init(void) acpi_str_to_uuid(UUID_NFIT_DIMM, nfit_uuid[NFIT_DEV_DIMM]); acpi_str_to_uuid(UUID_NFIT_DIMM_N_HPE1, nfit_uuid[NFIT_DEV_DIMM_N_HPE1]); acpi_str_to_uuid(UUID_NFIT_DIMM_N_HPE2, nfit_uuid[NFIT_DEV_DIMM_N_HPE2]); + acpi_str_to_uuid(UUID_NFIT_DIMM_N_MSFT, nfit_uuid[NFIT_DEV_DIMM_N_MSFT]); nfit_wq = create_singlethread_workqueue("nfit"); if (!nfit_wq) return -ENOMEM; + nfit_mce_register(); + return acpi_bus_register_driver(&acpi_nfit_driver); } static __exit void nfit_exit(void) { + nfit_mce_unregister(); acpi_bus_unregister_driver(&acpi_nfit_driver); destroy_workqueue(nfit_wq); + WARN_ON(!list_empty(&acpi_descs)); } module_init(nfit_init); diff --git a/drivers/acpi/nfit/mce.c b/drivers/acpi/nfit/mce.c new file mode 100644 index 000000000000..4c745bf389fe --- /dev/null +++ b/drivers/acpi/nfit/mce.c @@ -0,0 +1,89 @@ +/* + * NFIT - Machine Check Handler + * + * Copyright(c) 2013-2016 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#include <linux/notifier.h> +#include <linux/acpi.h> +#include <asm/mce.h> +#include "nfit.h" + +static int nfit_handle_mce(struct notifier_block *nb, unsigned long val, + void *data) +{ + struct mce *mce = (struct mce *)data; + struct acpi_nfit_desc *acpi_desc; + struct nfit_spa *nfit_spa; + + /* We only care about memory errors */ + if (!(mce->status & MCACOD)) + return NOTIFY_DONE; + + /* + * mce->addr contains the physical addr accessed that caused the + * machine check. We need to walk through the list of NFITs, and see + * if any of them matches that address, and only then start a scrub. + */ + mutex_lock(&acpi_desc_lock); + list_for_each_entry(acpi_desc, &acpi_descs, list) { + struct device *dev = acpi_desc->dev; + int found_match = 0; + + mutex_lock(&acpi_desc->init_mutex); + list_for_each_entry(nfit_spa, &acpi_desc->spas, list) { + struct acpi_nfit_system_address *spa = nfit_spa->spa; + + if (nfit_spa_type(spa) == NFIT_SPA_PM) + continue; + /* find the spa that covers the mce addr */ + if (spa->address > mce->addr) + continue; + if ((spa->address + spa->length - 1) < mce->addr) + continue; + found_match = 1; + dev_dbg(dev, "%s: addr in SPA %d (0x%llx, 0x%llx)\n", + __func__, spa->range_index, spa->address, + spa->length); + /* + * We can break at the first match because we're going + * to rescan all the SPA ranges. There shouldn't be any + * aliasing anyway. + */ + break; + } + mutex_unlock(&acpi_desc->init_mutex); + + /* + * We can ignore an -EBUSY here because if an ARS is already + * in progress, just let that be the last authoritative one + */ + if (found_match) + acpi_nfit_ars_rescan(acpi_desc); + } + + mutex_unlock(&acpi_desc_lock); + return NOTIFY_DONE; +} + +static struct notifier_block nfit_mce_dec = { + .notifier_call = nfit_handle_mce, +}; + +void nfit_mce_register(void) +{ + mce_register_decode_chain(&nfit_mce_dec); +} + +void nfit_mce_unregister(void) +{ + mce_unregister_decode_chain(&nfit_mce_dec); +} diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit/nfit.h index 02b9ea1e8d2e..e894ded24d99 100644 --- a/drivers/acpi/nfit.h +++ b/drivers/acpi/nfit/nfit.h @@ -16,6 +16,7 @@ #define __NFIT_H__ #include <linux/workqueue.h> #include <linux/libnvdimm.h> +#include <linux/ndctl.h> #include <linux/types.h> #include <linux/uuid.h> #include <linux/acpi.h> @@ -31,6 +32,9 @@ #define UUID_NFIT_DIMM_N_HPE1 "9002c334-acf3-4c0e-9642-a235f0d53bc6" #define UUID_NFIT_DIMM_N_HPE2 "5008664b-b758-41a0-a03c-27c2f2d04f7e" +/* https://msdn.microsoft.com/library/windows/hardware/mt604741 */ +#define UUID_NFIT_DIMM_N_MSFT "1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05" + #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \ | ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \ | ACPI_NFIT_MEM_NOT_ARMED) @@ -40,6 +44,7 @@ enum nfit_uuids { NFIT_DEV_DIMM = NVDIMM_FAMILY_INTEL, NFIT_DEV_DIMM_N_HPE1 = NVDIMM_FAMILY_HPE1, NFIT_DEV_DIMM_N_HPE2 = NVDIMM_FAMILY_HPE2, + NFIT_DEV_DIMM_N_MSFT = NVDIMM_FAMILY_MSFT, NFIT_SPA_VOLATILE, NFIT_SPA_PM, NFIT_SPA_DCR, @@ -74,37 +79,37 @@ enum { }; struct nfit_spa { - struct acpi_nfit_system_address *spa; struct list_head list; struct nd_region *nd_region; - unsigned int ars_done:1; + unsigned int ars_required:1; u32 clear_err_unit; u32 max_ars; + struct acpi_nfit_system_address spa[0]; }; struct nfit_dcr { - struct acpi_nfit_control_region *dcr; struct list_head list; + struct acpi_nfit_control_region dcr[0]; }; struct nfit_bdw { - struct acpi_nfit_data_region *bdw; struct list_head list; + struct acpi_nfit_data_region bdw[0]; }; struct nfit_idt { - struct acpi_nfit_interleave *idt; struct list_head list; + struct acpi_nfit_interleave idt[0]; }; struct nfit_flush { - struct acpi_nfit_flush_address *flush; struct list_head list; + struct acpi_nfit_flush_address flush[0]; }; struct nfit_memdev { - struct acpi_nfit_memory_map *memdev; struct list_head list; + struct acpi_nfit_memory_map memdev[0]; }; /* assembled tables for a given dimm/memory-device */ @@ -123,6 +128,7 @@ struct nfit_mem { struct list_head list; struct acpi_device *adev; struct acpi_nfit_desc *acpi_desc; + struct resource *flush_wpq; unsigned long dsm_mask; int family; }; @@ -130,10 +136,7 @@ struct nfit_mem { struct acpi_nfit_desc { struct nvdimm_bus_descriptor nd_desc; struct acpi_table_header acpi_header; - struct acpi_nfit_header *nfit; - struct mutex spa_map_mutex; struct mutex init_mutex; - struct list_head spa_maps; struct list_head memdevs; struct list_head flushes; struct list_head dimms; @@ -146,6 +149,9 @@ struct acpi_nfit_desc { struct nd_cmd_ars_status *ars_status; size_t ars_status_size; struct work_struct work; + struct list_head list; + struct kernfs_node *scrub_count_state; + unsigned int scrub_count; unsigned int cancel:1; unsigned long dimm_cmd_force_en; unsigned long bus_cmd_force_en; @@ -161,7 +167,7 @@ enum nd_blk_mmio_selector { struct nd_blk_addr { union { void __iomem *base; - void __pmem *aperture; + void *aperture; }; }; @@ -180,28 +186,26 @@ struct nfit_blk { u64 bdw_offset; /* post interleave offset */ u64 stat_offset; u64 cmd_offset; - void __iomem *nvdimm_flush; u32 dimm_flags; }; -enum spa_map_type { - SPA_MAP_CONTROL, - SPA_MAP_APERTURE, -}; - -struct nfit_spa_mapping { - struct acpi_nfit_desc *acpi_desc; - struct acpi_nfit_system_address *spa; - struct list_head list; - struct kref kref; - enum spa_map_type type; - struct nd_blk_addr addr; -}; +extern struct list_head acpi_descs; +extern struct mutex acpi_desc_lock; +int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc); -static inline struct nfit_spa_mapping *to_spa_map(struct kref *kref) +#ifdef CONFIG_X86_MCE +void nfit_mce_register(void); +void nfit_mce_unregister(void); +#else +static inline void nfit_mce_register(void) { - return container_of(kref, struct nfit_spa_mapping, kref); } +static inline void nfit_mce_unregister(void) +{ +} +#endif + +int nfit_spa_type(struct acpi_nfit_system_address *spa); static inline struct acpi_nfit_memory_map *__to_nfit_memdev( struct nfit_mem *nfit_mem) @@ -218,6 +222,6 @@ static inline struct acpi_nfit_desc *to_acpi_desc( } const u8 *to_nfit_uuid(enum nfit_uuids id); -int acpi_nfit_init(struct acpi_nfit_desc *nfit, acpi_size sz); +int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *nfit, acpi_size sz); void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev); #endif /* __NFIT_H__ */ diff --git a/drivers/base/node.c b/drivers/base/node.c index 51c7db2c4ee2..29cd96661b30 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -56,6 +56,7 @@ static ssize_t node_read_meminfo(struct device *dev, { int n; int nid = dev->id; + struct pglist_data *pgdat = NODE_DATA(nid); struct sysinfo i; si_meminfo_node(&i, nid); @@ -74,16 +75,16 @@ static ssize_t node_read_meminfo(struct device *dev, nid, K(i.totalram), nid, K(i.freeram), nid, K(i.totalram - i.freeram), - nid, K(node_page_state(nid, NR_ACTIVE_ANON) + - node_page_state(nid, NR_ACTIVE_FILE)), - nid, K(node_page_state(nid, NR_INACTIVE_ANON) + - node_page_state(nid, NR_INACTIVE_FILE)), - nid, K(node_page_state(nid, NR_ACTIVE_ANON)), - nid, K(node_page_state(nid, NR_INACTIVE_ANON)), - nid, K(node_page_state(nid, NR_ACTIVE_FILE)), - nid, K(node_page_state(nid, NR_INACTIVE_FILE)), - nid, K(node_page_state(nid, NR_UNEVICTABLE)), - nid, K(node_page_state(nid, NR_MLOCK))); + nid, K(node_page_state(pgdat, NR_ACTIVE_ANON) + + node_page_state(pgdat, NR_ACTIVE_FILE)), + nid, K(node_page_state(pgdat, NR_INACTIVE_ANON) + + node_page_state(pgdat, NR_INACTIVE_FILE)), + nid, K(node_page_state(pgdat, NR_ACTIVE_ANON)), + nid, K(node_page_state(pgdat, NR_INACTIVE_ANON)), + nid, K(node_page_state(pgdat, NR_ACTIVE_FILE)), + nid, K(node_page_state(pgdat, NR_INACTIVE_FILE)), + nid, K(node_page_state(pgdat, NR_UNEVICTABLE)), + nid, K(sum_zone_node_page_state(nid, NR_MLOCK))); #ifdef CONFIG_HIGHMEM n += sprintf(buf + n, @@ -117,31 +118,30 @@ static ssize_t node_read_meminfo(struct device *dev, "Node %d ShmemPmdMapped: %8lu kB\n" #endif , - nid, K(node_page_state(nid, NR_FILE_DIRTY)), - nid, K(node_page_state(nid, NR_WRITEBACK)), - nid, K(node_page_state(nid, NR_FILE_PAGES)), - nid, K(node_page_state(nid, NR_FILE_MAPPED)), - nid, K(node_page_state(nid, NR_ANON_PAGES)), + nid, K(node_page_state(pgdat, NR_FILE_DIRTY)), + nid, K(node_page_state(pgdat, NR_WRITEBACK)), + nid, K(node_page_state(pgdat, NR_FILE_PAGES)), + nid, K(node_page_state(pgdat, NR_FILE_MAPPED)), + nid, K(node_page_state(pgdat, NR_ANON_MAPPED)), nid, K(i.sharedram), - nid, node_page_state(nid, NR_KERNEL_STACK) * - THREAD_SIZE / 1024, - nid, K(node_page_state(nid, NR_PAGETABLE)), - nid, K(node_page_state(nid, NR_UNSTABLE_NFS)), - nid, K(node_page_state(nid, NR_BOUNCE)), - nid, K(node_page_state(nid, NR_WRITEBACK_TEMP)), - nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE) + - node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), - nid, K(node_page_state(nid, NR_SLAB_RECLAIMABLE)), + nid, sum_zone_node_page_state(nid, NR_KERNEL_STACK_KB), + nid, K(sum_zone_node_page_state(nid, NR_PAGETABLE)), + nid, K(node_page_state(pgdat, NR_UNSTABLE_NFS)), + nid, K(sum_zone_node_page_state(nid, NR_BOUNCE)), + nid, K(node_page_state(pgdat, NR_WRITEBACK_TEMP)), + nid, K(sum_zone_node_page_state(nid, NR_SLAB_RECLAIMABLE) + + sum_zone_node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), + nid, K(sum_zone_node_page_state(nid, NR_SLAB_RECLAIMABLE)), #ifdef CONFIG_TRANSPARENT_HUGEPAGE - nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), - nid, K(node_page_state(nid, NR_ANON_THPS) * + nid, K(sum_zone_node_page_state(nid, NR_SLAB_UNRECLAIMABLE)), + nid, K(node_page_state(pgdat, NR_ANON_THPS) * HPAGE_PMD_NR), - nid, K(node_page_state(nid, NR_SHMEM_THPS) * + nid, K(node_page_state(pgdat, NR_SHMEM_THPS) * HPAGE_PMD_NR), - nid, K(node_page_state(nid, NR_SHMEM_PMDMAPPED) * + nid, K(node_page_state(pgdat, NR_SHMEM_PMDMAPPED) * HPAGE_PMD_NR)); #else - nid, K(node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); + nid, K(sum_zone_node_page_state(nid, NR_SLAB_UNRECLAIMABLE))); #endif n += hugetlb_report_node_meminfo(nid, buf + n); return n; @@ -160,12 +160,12 @@ static ssize_t node_read_numastat(struct device *dev, "interleave_hit %lu\n" "local_node %lu\n" "other_node %lu\n", - node_page_state(dev->id, NUMA_HIT), - node_page_state(dev->id, NUMA_MISS), - node_page_state(dev->id, NUMA_FOREIGN), - node_page_state(dev->id, NUMA_INTERLEAVE_HIT), - node_page_state(dev->id, NUMA_LOCAL), - node_page_state(dev->id, NUMA_OTHER)); + sum_zone_node_page_state(dev->id, NUMA_HIT), + sum_zone_node_page_state(dev->id, NUMA_MISS), + sum_zone_node_page_state(dev->id, NUMA_FOREIGN), + sum_zone_node_page_state(dev->id, NUMA_INTERLEAVE_HIT), + sum_zone_node_page_state(dev->id, NUMA_LOCAL), + sum_zone_node_page_state(dev->id, NUMA_OTHER)); } static DEVICE_ATTR(numastat, S_IRUGO, node_read_numastat, NULL); @@ -173,12 +173,18 @@ static ssize_t node_read_vmstat(struct device *dev, struct device_attribute *attr, char *buf) { int nid = dev->id; + struct pglist_data *pgdat = NODE_DATA(nid); int i; int n = 0; for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) n += sprintf(buf+n, "%s %lu\n", vmstat_text[i], - node_page_state(nid, i)); + sum_zone_node_page_state(nid, i)); + + for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++) + n += sprintf(buf+n, "%s %lu\n", + vmstat_text[i + NR_VM_ZONE_STAT_ITEMS], + node_page_state(pgdat, i)); return n; } diff --git a/drivers/block/brd.c b/drivers/block/brd.c index ba5145d384d8..3022dad24071 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -379,7 +379,7 @@ static int brd_rw_page(struct block_device *bdev, sector_t sector, #ifdef CONFIG_BLK_DEV_RAM_DAX static long brd_direct_access(struct block_device *bdev, sector_t sector, - void __pmem **kaddr, pfn_t *pfn, long size) + void **kaddr, pfn_t *pfn, long size) { struct brd_device *brd = bdev->bd_disk->private_data; struct page *page; @@ -389,7 +389,7 @@ static long brd_direct_access(struct block_device *bdev, sector_t sector, page = brd_insert_page(brd, sector); if (!page) return -ENOSPC; - *kaddr = (void __pmem *)page_address(page); + *kaddr = page_address(page); *pfn = page_to_pfn_t(page); return PAGE_SIZE; diff --git a/drivers/block/drbd/drbd_debugfs.c b/drivers/block/drbd/drbd_debugfs.c index be91a8d7c22a..de5c3ee8a790 100644 --- a/drivers/block/drbd/drbd_debugfs.c +++ b/drivers/block/drbd/drbd_debugfs.c @@ -425,9 +425,6 @@ static int drbd_single_open(struct file *file, int (*show)(struct seq_file *, vo /* Are we still linked, * or has debugfs_remove() already been called? */ parent = file->f_path.dentry->d_parent; - /* not sure if this can happen: */ - if (!parent || d_really_is_negative(parent)) - goto out; /* serialize with d_delete() */ inode_lock(d_inode(parent)); /* Make sure the object is still alive */ @@ -440,7 +437,6 @@ static int drbd_single_open(struct file *file, int (*show)(struct seq_file *, vo if (ret) kref_put(kref, release); } -out: return ret; } diff --git a/drivers/char/random.c b/drivers/char/random.c index 8d0af74f6569..7f0622426b97 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1668,13 +1668,12 @@ static int rand_initialize(void) #ifdef CONFIG_NUMA pool = kmalloc(num_nodes * sizeof(void *), GFP_KERNEL|__GFP_NOFAIL|__GFP_ZERO); - for (i=0; i < num_nodes; i++) { + for_each_online_node(i) { crng = kmalloc_node(sizeof(struct crng_state), GFP_KERNEL | __GFP_NOFAIL, i); spin_lock_init(&crng->lock); crng_initialize(crng); pool[i] = crng; - } mb(); crng_node_pool = pool; diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c index b891a129b275..803f3953b341 100644 --- a/drivers/dax/dax.c +++ b/drivers/dax/dax.c @@ -211,11 +211,9 @@ int devm_create_dax_dev(struct dax_region *dax_region, struct resource *res, } dax_dev->dev = dev; - rc = devm_add_action(dax_region->dev, unregister_dax_dev, dev); - if (rc) { - unregister_dax_dev(dev); + rc = devm_add_action_or_reset(dax_region->dev, unregister_dax_dev, dev); + if (rc) return rc; - } return 0; diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c index 55d510e36cd1..dfb168568af1 100644 --- a/drivers/dax/pmem.c +++ b/drivers/dax/pmem.c @@ -102,21 +102,19 @@ static int dax_pmem_probe(struct device *dev) if (rc) return rc; - rc = devm_add_action(dev, dax_pmem_percpu_exit, &dax_pmem->ref); - if (rc) { - dax_pmem_percpu_exit(&dax_pmem->ref); + rc = devm_add_action_or_reset(dev, dax_pmem_percpu_exit, + &dax_pmem->ref); + if (rc) return rc; - } addr = devm_memremap_pages(dev, &res, &dax_pmem->ref, altmap); if (IS_ERR(addr)) return PTR_ERR(addr); - rc = devm_add_action(dev, dax_pmem_percpu_kill, &dax_pmem->ref); - if (rc) { - dax_pmem_percpu_kill(&dax_pmem->ref); + rc = devm_add_action_or_reset(dev, dax_pmem_percpu_kill, + &dax_pmem->ref); + if (rc) return rc; - } nd_region = to_nd_region(dev->parent); dax_region = alloc_dax_region(dev, nd_region->id, &res, diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 8c98779a12b1..739f797b40d9 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -339,6 +339,20 @@ config MV_XOR ---help--- Enable support for the Marvell XOR engine. +config MV_XOR_V2 + bool "Marvell XOR engine version 2 support " + depends on ARM64 + select DMA_ENGINE + select DMA_ENGINE_RAID + select ASYNC_TX_ENABLE_CHANNEL_SWITCH + select GENERIC_MSI_IRQ_DOMAIN + ---help--- + Enable support for the Marvell version 2 XOR engine. + + This engine provides acceleration for copy, XOR and RAID6 + operations, and is available on Marvell Armada 7K and 8K + platforms. + config MXS_DMA bool "MXS DMA support" depends on SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q || SOC_IMX6UL @@ -519,19 +533,31 @@ config XGENE_DMA help Enable support for the APM X-Gene SoC DMA engine. -config XILINX_VDMA - tristate "Xilinx AXI VDMA Engine" +config XILINX_DMA + tristate "Xilinx AXI DMAS Engine" depends on (ARCH_ZYNQ || MICROBLAZE || ARM64) select DMA_ENGINE help Enable support for Xilinx AXI VDMA Soft IP. - This engine provides high-bandwidth direct memory access + AXI VDMA engine provides high-bandwidth direct memory access between memory and AXI4-Stream video type target peripherals including peripherals which support AXI4- Stream Video Protocol. It has two stream interfaces/ channels, Memory Mapped to Stream (MM2S) and Stream to Memory Mapped (S2MM) for the data transfers. + AXI CDMA engine provides high-bandwidth direct memory access + between a memory-mapped source address and a memory-mapped + destination address. + AXI DMA engine provides high-bandwidth one dimensional direct + memory access between memory and AXI4-Stream target peripherals. + +config XILINX_ZYNQMP_DMA + tristate "Xilinx ZynqMP DMA Engine" + depends on (ARCH_ZYNQ || MICROBLAZE || ARM64) + select DMA_ENGINE + help + Enable support for Xilinx ZynqMP DMA controller. config ZX_DMA tristate "ZTE ZX296702 DMA support" diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 614f28b0b739..e4dc9cac7ee8 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o obj-$(CONFIG_MOXART_DMA) += moxart-dma.o obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o obj-$(CONFIG_MV_XOR) += mv_xor.o +obj-$(CONFIG_MV_XOR_V2) += mv_xor_v2.o obj-$(CONFIG_MXS_DMA) += mxs-dma.o obj-$(CONFIG_MX3_IPU) += ipu/ obj-$(CONFIG_NBPFAXI_DMA) += nbpfaxi.o diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 81db1c4811ce..939a7c31f760 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -1443,8 +1443,6 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy( dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT); if (!dsg) { pl08x_free_txd(pl08x, txd); - dev_err(&pl08x->adev->dev, "%s no memory for pl080 sg\n", - __func__); return NULL; } list_add_tail(&dsg->node, &txd->dsg_list); @@ -1901,11 +1899,8 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x, */ for (i = 0; i < channels; i++) { chan = kzalloc(sizeof(*chan), GFP_KERNEL); - if (!chan) { - dev_err(&pl08x->adev->dev, - "%s no memory for channel\n", __func__); + if (!chan) return -ENOMEM; - } chan->host = pl08x; chan->state = PL08X_CHAN_IDLE; @@ -2360,9 +2355,6 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) pl08x->phy_chans = kzalloc((vd->channels * sizeof(*pl08x->phy_chans)), GFP_KERNEL); if (!pl08x->phy_chans) { - dev_err(&adev->dev, "%s failed to allocate " - "physical channel holders\n", - __func__); ret = -ENOMEM; goto out_no_phychans; } diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 75bd6621dc5d..e434ffe7bc5c 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -456,7 +456,7 @@ static struct at_xdmac_desc *at_xdmac_alloc_desc(struct dma_chan *chan, return desc; } -void at_xdmac_init_used_desc(struct at_xdmac_desc *desc) +static void at_xdmac_init_used_desc(struct at_xdmac_desc *desc) { memset(&desc->lld, 0, sizeof(desc->lld)); INIT_LIST_HEAD(&desc->descs_list); @@ -1195,14 +1195,14 @@ static struct at_xdmac_desc *at_xdmac_memset_create_desc(struct dma_chan *chan, desc->lld.mbr_cfg = chan_cc; dev_dbg(chan2dev(chan), - "%s: lld: mbr_da=%pad, mbr_ds=%pad, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", - __func__, &desc->lld.mbr_da, &desc->lld.mbr_ds, desc->lld.mbr_ubc, + "%s: lld: mbr_da=%pad, mbr_ds=0x%08x, mbr_ubc=0x%08x, mbr_cfg=0x%08x\n", + __func__, &desc->lld.mbr_da, desc->lld.mbr_ds, desc->lld.mbr_ubc, desc->lld.mbr_cfg); return desc; } -struct dma_async_tx_descriptor * +static struct dma_async_tx_descriptor * at_xdmac_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, size_t len, unsigned long flags) { diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 6149b27c33ad..e18dc596cf24 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -393,11 +393,12 @@ static void bcm2835_dma_fill_cb_chain_with_sg( unsigned int sg_len) { struct bcm2835_chan *c = to_bcm2835_dma_chan(chan); - size_t max_len = bcm2835_dma_max_frame_length(c); - unsigned int i, len; + size_t len, max_len; + unsigned int i; dma_addr_t addr; struct scatterlist *sgent; + max_len = bcm2835_dma_max_frame_length(c); for_each_sg(sgl, sgent, sg_len, i) { for (addr = sg_dma_address(sgent), len = sg_dma_len(sgent); len > 0; @@ -613,7 +614,7 @@ static void bcm2835_dma_issue_pending(struct dma_chan *chan) spin_unlock_irqrestore(&c->vc.lock, flags); } -struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy( +static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_memcpy( struct dma_chan *chan, dma_addr_t dst, dma_addr_t src, size_t len, unsigned long flags) { diff --git a/drivers/dma/bestcomm/bestcomm.c b/drivers/dma/bestcomm/bestcomm.c index 180fedb418cc..7ce843723003 100644 --- a/drivers/dma/bestcomm/bestcomm.c +++ b/drivers/dma/bestcomm/bestcomm.c @@ -397,8 +397,6 @@ static int mpc52xx_bcom_probe(struct platform_device *op) /* Get a clean struct */ bcom_eng = kzalloc(sizeof(struct bcom_engine), GFP_KERNEL); if (!bcom_eng) { - printk(KERN_ERR DRIVER_NAME ": " - "Can't allocate state structure\n"); rv = -ENOMEM; goto error_sramclean; } diff --git a/drivers/dma/coh901318.c b/drivers/dma/coh901318.c index c340ca9bd2b5..e4acd63e42aa 100644 --- a/drivers/dma/coh901318.c +++ b/drivers/dma/coh901318.c @@ -266,7 +266,7 @@ static int dma_memcpy_channels[] = { COH901318_CX_CTRL_DDMA_LEGACY | \ COH901318_CX_CTRL_PRDD_SOURCE) -const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { +static const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = { { .number = U300_DMA_MSL_TX_0, .name = "MSL TX 0", @@ -1280,6 +1280,7 @@ struct coh901318_desc { struct coh901318_base { struct device *dev; void __iomem *virtbase; + unsigned int irq; struct coh901318_pool pool; struct powersave pm; struct dma_device dma_slave; @@ -1364,7 +1365,6 @@ static int coh901318_debugfs_read(struct file *file, char __user *buf, } static const struct file_operations coh901318_debugfs_status_operations = { - .owner = THIS_MODULE, .open = simple_open, .read = coh901318_debugfs_read, .llseek = default_llseek, @@ -2422,7 +2422,7 @@ coh901318_tx_status(struct dma_chan *chan, dma_cookie_t cookie, enum dma_status ret; ret = dma_cookie_status(chan, cookie, txstate); - if (ret == DMA_COMPLETE) + if (ret == DMA_COMPLETE || !txstate) return ret; dma_set_residue(txstate, coh901318_get_bytes_left(chan)); @@ -2680,6 +2680,8 @@ static int __init coh901318_probe(struct platform_device *pdev) if (err) return err; + base->irq = irq; + err = coh901318_pool_create(&base->pool, &pdev->dev, sizeof(struct coh901318_lli), 32); @@ -2755,11 +2757,31 @@ static int __init coh901318_probe(struct platform_device *pdev) coh901318_pool_destroy(&base->pool); return err; } +static void coh901318_base_remove(struct coh901318_base *base, const int *pick_chans) +{ + int chans_i; + int i = 0; + struct coh901318_chan *cohc; + + for (chans_i = 0; pick_chans[chans_i] != -1; chans_i += 2) { + for (i = pick_chans[chans_i]; i <= pick_chans[chans_i+1]; i++) { + cohc = &base->chans[i]; + + tasklet_kill(&cohc->tasklet); + } + } + +} static int coh901318_remove(struct platform_device *pdev) { struct coh901318_base *base = platform_get_drvdata(pdev); + devm_free_irq(&pdev->dev, base->irq, base); + + coh901318_base_remove(base, dma_slave_channels); + coh901318_base_remove(base, dma_memcpy_channels); + of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&base->dma_memcpy); dma_async_device_unregister(&base->dma_slave); @@ -2780,13 +2802,13 @@ static struct platform_driver coh901318_driver = { }, }; -int __init coh901318_init(void) +static int __init coh901318_init(void) { return platform_driver_probe(&coh901318_driver, coh901318_probe); } subsys_initcall(coh901318_init); -void __exit coh901318_exit(void) +static void __exit coh901318_exit(void) { platform_driver_unregister(&coh901318_driver); } diff --git a/drivers/dma/cppi41.c b/drivers/dma/cppi41.c index ceedafbd23e0..4b2317426c8e 100644 --- a/drivers/dma/cppi41.c +++ b/drivers/dma/cppi41.c @@ -497,16 +497,13 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg( struct cppi41_desc *d; struct scatterlist *sg; unsigned int i; - unsigned int num; - num = 0; d = c->desc; for_each_sg(sgl, sg, sg_len, i) { u32 addr; u32 len; /* We need to use more than one desc once musb supports sg */ - BUG_ON(num > 0); addr = lower_32_bits(sg_dma_address(sg)); len = sg_dma_len(sg); diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c index c3468094393e..7f0b9aa15867 100644 --- a/drivers/dma/dma-axi-dmac.c +++ b/drivers/dma/dma-axi-dmac.c @@ -270,6 +270,9 @@ static irqreturn_t axi_dmac_interrupt_handler(int irq, void *devid) unsigned int pending; pending = axi_dmac_read(dmac, AXI_DMAC_REG_IRQ_PENDING); + if (!pending) + return IRQ_NONE; + axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_PENDING, pending); spin_lock(&dmac->chan.vchan.lock); @@ -579,7 +582,9 @@ static int axi_dmac_probe(struct platform_device *pdev) return -ENOMEM; dmac->irq = platform_get_irq(pdev, 0); - if (dmac->irq <= 0) + if (dmac->irq < 0) + return dmac->irq; + if (dmac->irq == 0) return -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -683,6 +688,7 @@ static const struct of_device_id axi_dmac_of_match_table[] = { { .compatible = "adi,axi-dmac-1.00.a" }, { }, }; +MODULE_DEVICE_TABLE(of, axi_dmac_of_match_table); static struct platform_driver axi_dmac_driver = { .driver = { diff --git a/drivers/dma/dma-jz4740.c b/drivers/dma/dma-jz4740.c index 7638b24ce8d0..9689b36c005a 100644 --- a/drivers/dma/dma-jz4740.c +++ b/drivers/dma/dma-jz4740.c @@ -573,12 +573,26 @@ err_unregister: return ret; } +static void jz4740_cleanup_vchan(struct dma_device *dmadev) +{ + struct jz4740_dmaengine_chan *chan, *_chan; + + list_for_each_entry_safe(chan, _chan, + &dmadev->channels, vchan.chan.device_node) { + list_del(&chan->vchan.chan.device_node); + tasklet_kill(&chan->vchan.task); + } +} + + static int jz4740_dma_remove(struct platform_device *pdev) { struct jz4740_dma_dev *dmadev = platform_get_drvdata(pdev); int irq = platform_get_irq(pdev, 0); free_irq(irq, dmadev); + + jz4740_cleanup_vchan(&dmadev->ddev); dma_async_device_unregister(&dmadev->ddev); clk_disable_unprepare(dmadev->clk); diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index b8576fd6bd0e..1245db5438e1 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -51,6 +51,16 @@ module_param(iterations, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(iterations, "Iterations before stopping test (default: infinite)"); +static unsigned int sg_buffers = 1; +module_param(sg_buffers, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(sg_buffers, + "Number of scatter gather buffers (default: 1)"); + +static unsigned int dmatest = 1; +module_param(dmatest, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(dmatest, + "dmatest 0-memcpy 1-slave_sg (default: 1)"); + static unsigned int xor_sources = 3; module_param(xor_sources, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(xor_sources, @@ -431,6 +441,8 @@ static int dmatest_func(void *data) dev = chan->device; if (thread->type == DMA_MEMCPY) src_cnt = dst_cnt = 1; + else if (thread->type == DMA_SG) + src_cnt = dst_cnt = sg_buffers; else if (thread->type == DMA_XOR) { /* force odd to ensure dst = src */ src_cnt = min_odd(params->xor_sources | 1, dev->max_xor); @@ -485,6 +497,8 @@ static int dmatest_func(void *data) dma_addr_t *dsts; unsigned int src_off, dst_off, len; u8 align = 0; + struct scatterlist tx_sg[src_cnt]; + struct scatterlist rx_sg[src_cnt]; total_tests++; @@ -577,10 +591,22 @@ static int dmatest_func(void *data) um->bidi_cnt++; } + sg_init_table(tx_sg, src_cnt); + sg_init_table(rx_sg, src_cnt); + for (i = 0; i < src_cnt; i++) { + sg_dma_address(&rx_sg[i]) = srcs[i]; + sg_dma_address(&tx_sg[i]) = dsts[i] + dst_off; + sg_dma_len(&tx_sg[i]) = len; + sg_dma_len(&rx_sg[i]) = len; + } + if (thread->type == DMA_MEMCPY) tx = dev->device_prep_dma_memcpy(chan, dsts[0] + dst_off, srcs[0], len, flags); + else if (thread->type == DMA_SG) + tx = dev->device_prep_dma_sg(chan, tx_sg, src_cnt, + rx_sg, src_cnt, flags); else if (thread->type == DMA_XOR) tx = dev->device_prep_dma_xor(chan, dsts[0] + dst_off, @@ -748,6 +774,8 @@ static int dmatest_add_threads(struct dmatest_info *info, if (type == DMA_MEMCPY) op = "copy"; + else if (type == DMA_SG) + op = "sg"; else if (type == DMA_XOR) op = "xor"; else if (type == DMA_PQ) @@ -802,9 +830,19 @@ static int dmatest_add_channel(struct dmatest_info *info, INIT_LIST_HEAD(&dtc->threads); if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) { - cnt = dmatest_add_threads(info, dtc, DMA_MEMCPY); - thread_count += cnt > 0 ? cnt : 0; + if (dmatest == 0) { + cnt = dmatest_add_threads(info, dtc, DMA_MEMCPY); + thread_count += cnt > 0 ? cnt : 0; + } } + + if (dma_has_cap(DMA_SG, dma_dev->cap_mask)) { + if (dmatest == 1) { + cnt = dmatest_add_threads(info, dtc, DMA_SG); + thread_count += cnt > 0 ? cnt : 0; + } + } + if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) { cnt = dmatest_add_threads(info, dtc, DMA_XOR); thread_count += cnt > 0 ? cnt : 0; @@ -877,6 +915,7 @@ static void run_threaded_test(struct dmatest_info *info) request_channels(info, DMA_MEMCPY); request_channels(info, DMA_XOR); + request_channels(info, DMA_SG); request_channels(info, DMA_PQ); } diff --git a/drivers/dma/edma.c b/drivers/dma/edma.c index 8181ed131386..3d277fa76c1a 100644 --- a/drivers/dma/edma.c +++ b/drivers/dma/edma.c @@ -239,6 +239,9 @@ struct edma_cc { bool chmap_exist; enum dma_event_q default_queue; + unsigned int ccint; + unsigned int ccerrint; + /* * The slot_inuse bit for each PaRAM slot is clear unless the slot is * in use by Linux or if it is allocated to be used by DSP. @@ -1069,10 +1072,8 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg( edesc = kzalloc(sizeof(*edesc) + sg_len * sizeof(edesc->pset[0]), GFP_ATOMIC); - if (!edesc) { - dev_err(dev, "%s: Failed to allocate a descriptor\n", __func__); + if (!edesc) return NULL; - } edesc->pset_nr = sg_len; edesc->residue = 0; @@ -1114,14 +1115,17 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg( edesc->absync = ret; edesc->residue += sg_dma_len(sg); - /* If this is the last in a current SG set of transactions, - enable interrupts so that next set is processed */ - if (!((i+1) % MAX_NR_SG)) - edesc->pset[i].param.opt |= TCINTEN; - - /* If this is the last set, enable completion interrupt flag */ if (i == sg_len - 1) + /* Enable completion interrupt */ edesc->pset[i].param.opt |= TCINTEN; + else if (!((i+1) % MAX_NR_SG)) + /* + * Enable early completion interrupt for the + * intermediateset. In this case the driver will be + * notified when the paRAM set is submitted to TC. This + * will allow more time to set up the next set of slots. + */ + edesc->pset[i].param.opt |= (TCINTEN | TCCMODE); } edesc->residue_stat = edesc->residue; @@ -1173,10 +1177,8 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]), GFP_ATOMIC); - if (!edesc) { - dev_dbg(dev, "Failed to allocate a descriptor\n"); + if (!edesc) return NULL; - } edesc->pset_nr = nslots; edesc->residue = edesc->residue_stat = len; @@ -1298,10 +1300,8 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]), GFP_ATOMIC); - if (!edesc) { - dev_err(dev, "%s: Failed to allocate a descriptor\n", __func__); + if (!edesc) return NULL; - } edesc->cyclic = 1; edesc->pset_nr = nslots; @@ -2207,10 +2207,8 @@ static int edma_probe(struct platform_device *pdev) return ret; ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); - if (!ecc) { - dev_err(dev, "Can't allocate controller\n"); + if (!ecc) return -ENOMEM; - } ecc->dev = dev; ecc->id = pdev->id; @@ -2288,6 +2286,7 @@ static int edma_probe(struct platform_device *pdev) dev_err(dev, "CCINT (%d) failed --> %d\n", irq, ret); return ret; } + ecc->ccint = irq; } irq = platform_get_irq_byname(pdev, "edma3_ccerrint"); @@ -2303,6 +2302,7 @@ static int edma_probe(struct platform_device *pdev) dev_err(dev, "CCERRINT (%d) failed --> %d\n", irq, ret); return ret; } + ecc->ccerrint = irq; } ecc->dummy_slot = edma_alloc_slot(ecc, EDMA_SLOT_ANY); @@ -2393,11 +2393,27 @@ err_reg1: return ret; } +static void edma_cleanupp_vchan(struct dma_device *dmadev) +{ + struct edma_chan *echan, *_echan; + + list_for_each_entry_safe(echan, _echan, + &dmadev->channels, vchan.chan.device_node) { + list_del(&echan->vchan.chan.device_node); + tasklet_kill(&echan->vchan.task); + } +} + static int edma_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct edma_cc *ecc = dev_get_drvdata(dev); + devm_free_irq(dev, ecc->ccint, ecc); + devm_free_irq(dev, ecc->ccerrint, ecc); + + edma_cleanupp_vchan(&ecc->dma_slave); + if (dev->of_node) of_dma_controller_free(dev->of_node); dma_async_device_unregister(&ecc->dma_slave); diff --git a/drivers/dma/fsl-edma.c b/drivers/dma/fsl-edma.c index be2e62b87948..6775f2c74e25 100644 --- a/drivers/dma/fsl-edma.c +++ b/drivers/dma/fsl-edma.c @@ -852,6 +852,25 @@ fsl_edma_irq_init(struct platform_device *pdev, struct fsl_edma_engine *fsl_edma return 0; } +static void fsl_edma_irq_exit( + struct platform_device *pdev, struct fsl_edma_engine *fsl_edma) +{ + if (fsl_edma->txirq == fsl_edma->errirq) { + devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma); + } else { + devm_free_irq(&pdev->dev, fsl_edma->txirq, fsl_edma); + devm_free_irq(&pdev->dev, fsl_edma->errirq, fsl_edma); + } +} + +static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma) +{ + int i; + + for (i = 0; i < DMAMUX_NR; i++) + clk_disable_unprepare(fsl_edma->muxclk[i]); +} + static int fsl_edma_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -897,6 +916,10 @@ static int fsl_edma_probe(struct platform_device *pdev) ret = clk_prepare_enable(fsl_edma->muxclk[i]); if (ret) { + /* disable only clks which were enabled on error */ + for (; i >= 0; i--) + clk_disable_unprepare(fsl_edma->muxclk[i]); + dev_err(&pdev->dev, "DMAMUX clk block failed.\n"); return ret; } @@ -951,14 +974,18 @@ static int fsl_edma_probe(struct platform_device *pdev) ret = dma_async_device_register(&fsl_edma->dma_dev); if (ret) { - dev_err(&pdev->dev, "Can't register Freescale eDMA engine.\n"); + dev_err(&pdev->dev, + "Can't register Freescale eDMA engine. (%d)\n", ret); + fsl_disable_clocks(fsl_edma); return ret; } ret = of_dma_controller_register(np, fsl_edma_xlate, fsl_edma); if (ret) { - dev_err(&pdev->dev, "Can't register Freescale eDMA of_dma.\n"); + dev_err(&pdev->dev, + "Can't register Freescale eDMA of_dma. (%d)\n", ret); dma_async_device_unregister(&fsl_edma->dma_dev); + fsl_disable_clocks(fsl_edma); return ret; } @@ -968,17 +995,27 @@ static int fsl_edma_probe(struct platform_device *pdev) return 0; } +static void fsl_edma_cleanup_vchan(struct dma_device *dmadev) +{ + struct fsl_edma_chan *chan, *_chan; + + list_for_each_entry_safe(chan, _chan, + &dmadev->channels, vchan.chan.device_node) { + list_del(&chan->vchan.chan.device_node); + tasklet_kill(&chan->vchan.task); + } +} + static int fsl_edma_remove(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct fsl_edma_engine *fsl_edma = platform_get_drvdata(pdev); - int i; + fsl_edma_irq_exit(pdev, fsl_edma); + fsl_edma_cleanup_vchan(&fsl_edma->dma_dev); of_dma_controller_free(np); dma_async_device_unregister(&fsl_edma->dma_dev); - - for (i = 0; i < DMAMUX_NR; i++) - clk_disable_unprepare(fsl_edma->muxclk[i]); + fsl_disable_clocks(fsl_edma); return 0; } diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c index 4d9470f16552..aad167eaaee8 100644 --- a/drivers/dma/fsl_raid.c +++ b/drivers/dma/fsl_raid.c @@ -337,7 +337,7 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_genq( re_chan = container_of(chan, struct fsl_re_chan, chan); if (len > FSL_RE_MAX_DATA_LEN) { - dev_err(re_chan->dev, "genq tx length %lu, max length %d\n", + dev_err(re_chan->dev, "genq tx length %zu, max length %d\n", len, FSL_RE_MAX_DATA_LEN); return NULL; } @@ -424,7 +424,7 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_pq( re_chan = container_of(chan, struct fsl_re_chan, chan); if (len > FSL_RE_MAX_DATA_LEN) { - dev_err(re_chan->dev, "pq tx length is %lu, max length is %d\n", + dev_err(re_chan->dev, "pq tx length is %zu, max length is %d\n", len, FSL_RE_MAX_DATA_LEN); return NULL; } @@ -545,7 +545,7 @@ static struct dma_async_tx_descriptor *fsl_re_prep_dma_memcpy( re_chan = container_of(chan, struct fsl_re_chan, chan); if (len > FSL_RE_MAX_DATA_LEN) { - dev_err(re_chan->dev, "cp tx length is %lu, max length is %d\n", + dev_err(re_chan->dev, "cp tx length is %zu, max length is %d\n", len, FSL_RE_MAX_DATA_LEN); return NULL; } @@ -856,6 +856,8 @@ static int fsl_re_probe(struct platform_device *ofdev) static void fsl_re_remove_chan(struct fsl_re_chan *chan) { + tasklet_kill(&chan->irqtask); + dma_pool_free(chan->re_dev->hw_desc_pool, chan->inb_ring_virt_addr, chan->inb_phys_addr); @@ -890,7 +892,6 @@ static struct of_device_id fsl_re_ids[] = { static struct platform_driver fsl_re_driver = { .driver = { .name = "fsl-raideng", - .owner = THIS_MODULE, .of_match_table = fsl_re_ids, }, .probe = fsl_re_probe, diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index a8828ed639b3..911b7177eb50 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1234,7 +1234,6 @@ static int fsl_dma_chan_probe(struct fsldma_device *fdev, /* alloc channel */ chan = kzalloc(sizeof(*chan), GFP_KERNEL); if (!chan) { - dev_err(fdev->dev, "no free memory for DMA channels!\n"); err = -ENOMEM; goto out_return; } @@ -1340,7 +1339,6 @@ static int fsldma_of_probe(struct platform_device *op) fdev = kzalloc(sizeof(*fdev), GFP_KERNEL); if (!fdev) { - dev_err(&op->dev, "No enough memory for 'priv'\n"); err = -ENOMEM; goto out_return; } diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 48d85f8b95fe..a960608c0a4d 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -167,6 +167,7 @@ struct imxdma_channel { u32 ccr_to_device; bool enabled_2d; int slot_2d; + unsigned int irq; }; enum imx_dma_type { @@ -186,6 +187,9 @@ struct imxdma_engine { struct imx_dma_2d_config slots_2d[IMX_DMA_2D_SLOTS]; struct imxdma_channel channel[IMX_DMA_CHANNELS]; enum imx_dma_type devtype; + unsigned int irq; + unsigned int irq_err; + }; struct imxdma_filter_data { @@ -1048,7 +1052,7 @@ static struct dma_chan *imxdma_xlate(struct of_phandle_args *dma_spec, } static int __init imxdma_probe(struct platform_device *pdev) - { +{ struct imxdma_engine *imxdma; struct resource *res; const struct of_device_id *of_id; @@ -1100,6 +1104,7 @@ static int __init imxdma_probe(struct platform_device *pdev) dev_warn(imxdma->dev, "Can't register IRQ for DMA\n"); goto disable_dma_ahb_clk; } + imxdma->irq = irq; irq_err = platform_get_irq(pdev, 1); if (irq_err < 0) { @@ -1113,6 +1118,7 @@ static int __init imxdma_probe(struct platform_device *pdev) dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n"); goto disable_dma_ahb_clk; } + imxdma->irq_err = irq_err; } /* enable DMA module */ @@ -1150,6 +1156,8 @@ static int __init imxdma_probe(struct platform_device *pdev) irq + i, i); goto disable_dma_ahb_clk; } + + imxdmac->irq = irq + i; init_timer(&imxdmac->watchdog); imxdmac->watchdog.function = &imxdma_watchdog; imxdmac->watchdog.data = (unsigned long)imxdmac; @@ -1217,10 +1225,31 @@ disable_dma_ipg_clk: return ret; } +static void imxdma_free_irq(struct platform_device *pdev, struct imxdma_engine *imxdma) +{ + int i; + + if (is_imx1_dma(imxdma)) { + disable_irq(imxdma->irq); + disable_irq(imxdma->irq_err); + } + + for (i = 0; i < IMX_DMA_CHANNELS; i++) { + struct imxdma_channel *imxdmac = &imxdma->channel[i]; + + if (!is_imx1_dma(imxdma)) + disable_irq(imxdmac->irq); + + tasklet_kill(&imxdmac->dma_tasklet); + } +} + static int imxdma_remove(struct platform_device *pdev) { struct imxdma_engine *imxdma = platform_get_drvdata(pdev); + imxdma_free_irq(pdev, imxdma); + dma_async_device_unregister(&imxdma->dma_device); if (pdev->dev.of_node) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 0f6fd42f55ca..03ec76fc22ff 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -18,6 +18,7 @@ */ #include <linux/init.h> +#include <linux/iopoll.h> #include <linux/module.h> #include <linux/types.h> #include <linux/bitops.h> @@ -385,6 +386,7 @@ struct sdma_engine { const struct sdma_driver_data *drvdata; u32 spba_start_addr; u32 spba_end_addr; + unsigned int irq; }; static struct sdma_driver_data sdma_imx31 = { @@ -571,28 +573,20 @@ static void sdma_enable_channel(struct sdma_engine *sdma, int channel) static int sdma_run_channel0(struct sdma_engine *sdma) { int ret; - unsigned long timeout = 500; + u32 reg; sdma_enable_channel(sdma, 0); - while (!(ret = readl_relaxed(sdma->regs + SDMA_H_INTR) & 1)) { - if (timeout-- <= 0) - break; - udelay(1); - } - - if (ret) { - /* Clear the interrupt status */ - writel_relaxed(ret, sdma->regs + SDMA_H_INTR); - } else { + ret = readl_relaxed_poll_timeout_atomic(sdma->regs + SDMA_H_STATSTOP, + reg, !(reg & 1), 1, 500); + if (ret) dev_err(sdma->dev, "Timeout waiting for CH0 ready\n"); - } /* Set bits of CONFIG register with dynamic context switching */ if (readl(sdma->regs + SDMA_H_CONFIG) == 0) writel_relaxed(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG); - return ret ? 0 : -ETIMEDOUT; + return ret; } static int sdma_load_script(struct sdma_engine *sdma, void *buf, int size, @@ -727,9 +721,9 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id) unsigned long stat; stat = readl_relaxed(sdma->regs + SDMA_H_INTR); - /* not interested in channel 0 interrupts */ - stat &= ~1; writel_relaxed(stat, sdma->regs + SDMA_H_INTR); + /* channel 0 is special and not handled here, see run_channel0() */ + stat &= ~1; while (stat) { int channel = fls(stat) - 1; @@ -758,7 +752,7 @@ static void sdma_get_pc(struct sdma_channel *sdmac, * These are needed once we start to support transfers between * two peripherals or memory-to-memory transfers */ - int per_2_per = 0, emi_2_emi = 0; + int per_2_per = 0; sdmac->pc_from_device = 0; sdmac->pc_to_device = 0; @@ -766,7 +760,6 @@ static void sdma_get_pc(struct sdma_channel *sdmac, switch (peripheral_type) { case IMX_DMATYPE_MEMORY: - emi_2_emi = sdma->script_addrs->ap_2_ap_addr; break; case IMX_DMATYPE_DSP: emi_2_per = sdma->script_addrs->bp_2_ap_addr; @@ -999,8 +992,6 @@ static int sdma_config_channel(struct dma_chan *chan) } else __set_bit(sdmac->event_id0, sdmac->event_mask); - /* Watermark Level */ - sdmac->watermark_level |= sdmac->watermark_level; /* Address */ sdmac->shp_addr = sdmac->per_address; sdmac->per_addr = sdmac->per_address2; @@ -1715,6 +1706,8 @@ static int sdma_probe(struct platform_device *pdev) if (ret) return ret; + sdma->irq = irq; + sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL); if (!sdma->script_addrs) return -ENOMEM; @@ -1840,6 +1833,7 @@ static int sdma_remove(struct platform_device *pdev) struct sdma_engine *sdma = platform_get_drvdata(pdev); int i; + devm_free_irq(&pdev->dev, sdma->irq, sdma); dma_async_device_unregister(&sdma->dma_device); kfree(sdma->script_addrs); /* Kill the tasklet */ diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c index d406056e8892..7145f7716a92 100644 --- a/drivers/dma/ioat/init.c +++ b/drivers/dma/ioat/init.c @@ -1212,7 +1212,7 @@ static void ioat_shutdown(struct pci_dev *pdev) ioat_disable_interrupts(ioat_dma); } -void ioat_resume(struct ioatdma_device *ioat_dma) +static void ioat_resume(struct ioatdma_device *ioat_dma) { struct ioatdma_chan *ioat_chan; u32 chanerr; diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 1ba2fd73852d..39de8980128c 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -102,6 +102,7 @@ struct k3_dma_dev { struct clk *clk; u32 dma_channels; u32 dma_requests; + unsigned int irq; }; #define to_k3_dma(dmadev) container_of(dmadev, struct k3_dma_dev, slave) @@ -425,10 +426,9 @@ static struct dma_async_tx_descriptor *k3_dma_prep_memcpy( num = DIV_ROUND_UP(len, DMA_MAX_SIZE); ds = kzalloc(sizeof(*ds) + num * sizeof(ds->desc_hw[0]), GFP_ATOMIC); - if (!ds) { - dev_dbg(chan->device->dev, "vchan %p: kzalloc fail\n", &c->vc); + if (!ds) return NULL; - } + ds->desc_hw_lli = __virt_to_phys((unsigned long)&ds->desc_hw[0]); ds->size = len; ds->desc_num = num; @@ -481,10 +481,9 @@ static struct dma_async_tx_descriptor *k3_dma_prep_slave_sg( } ds = kzalloc(sizeof(*ds) + num * sizeof(ds->desc_hw[0]), GFP_ATOMIC); - if (!ds) { - dev_dbg(chan->device->dev, "vchan %p: kzalloc fail\n", &c->vc); + if (!ds) return NULL; - } + ds->desc_hw_lli = __virt_to_phys((unsigned long)&ds->desc_hw[0]); ds->desc_num = num; num = 0; @@ -705,6 +704,8 @@ static int k3_dma_probe(struct platform_device *op) if (ret) return ret; + d->irq = irq; + /* init phy channel */ d->phy = devm_kzalloc(&op->dev, d->dma_channels * sizeof(struct k3_dma_phy), GFP_KERNEL); @@ -759,7 +760,7 @@ static int k3_dma_probe(struct platform_device *op) ret = dma_async_device_register(&d->slave); if (ret) - return ret; + goto dma_async_register_fail; ret = of_dma_controller_register((&op->dev)->of_node, k3_of_dma_simple_xlate, d); @@ -776,6 +777,8 @@ static int k3_dma_probe(struct platform_device *op) of_dma_register_fail: dma_async_device_unregister(&d->slave); +dma_async_register_fail: + clk_disable_unprepare(d->clk); return ret; } @@ -787,6 +790,8 @@ static int k3_dma_remove(struct platform_device *op) dma_async_device_unregister(&d->slave); of_dma_controller_free((&op->dev)->of_node); + devm_free_irq(&op->dev, d->irq, d); + list_for_each_entry_safe(c, cn, &d->slave.channels, vc.chan.device_node) { list_del(&c->vc.chan.device_node); tasklet_kill(&c->vc.task); diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c index 56f1fd68b620..f4b25fb0d040 100644 --- a/drivers/dma/mmp_pdma.c +++ b/drivers/dma/mmp_pdma.c @@ -931,6 +931,25 @@ static void dma_do_tasklet(unsigned long data) static int mmp_pdma_remove(struct platform_device *op) { struct mmp_pdma_device *pdev = platform_get_drvdata(op); + struct mmp_pdma_phy *phy; + int i, irq = 0, irq_num = 0; + + + for (i = 0; i < pdev->dma_channels; i++) { + if (platform_get_irq(op, i) > 0) + irq_num++; + } + + if (irq_num != pdev->dma_channels) { + irq = platform_get_irq(op, 0); + devm_free_irq(&op->dev, irq, pdev); + } else { + for (i = 0; i < pdev->dma_channels; i++) { + phy = &pdev->phy[i]; + irq = platform_get_irq(op, i); + devm_free_irq(&op->dev, irq, phy); + } + } dma_async_device_unregister(&pdev->device); return 0; diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index 3df0422607d5..b3441f57a364 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c @@ -404,7 +404,7 @@ static void mmp_tdma_free_chan_resources(struct dma_chan *chan) return; } -struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac) +static struct mmp_tdma_desc *mmp_tdma_alloc_descriptor(struct mmp_tdma_chan *tdmac) { struct gen_pool *gpool; int size = tdmac->desc_num * sizeof(struct mmp_tdma_desc); @@ -551,10 +551,9 @@ static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev, /* alloc channel */ tdmac = devm_kzalloc(tdev->dev, sizeof(*tdmac), GFP_KERNEL); - if (!tdmac) { - dev_err(tdev->dev, "no free memory for DMA channels!\n"); + if (!tdmac) return -ENOMEM; - } + if (irq) tdmac->irq = irq; tdmac->dev = tdev->dev; @@ -593,7 +592,7 @@ static bool mmp_tdma_filter_fn(struct dma_chan *chan, void *fn_param) return true; } -struct dma_chan *mmp_tdma_xlate(struct of_phandle_args *dma_spec, +static struct dma_chan *mmp_tdma_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { struct mmp_tdma_device *tdev = ofdma->of_dma_data; diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c index 631c4435e075..a6e642792e5a 100644 --- a/drivers/dma/moxart-dma.c +++ b/drivers/dma/moxart-dma.c @@ -148,6 +148,7 @@ struct moxart_chan { struct moxart_dmadev { struct dma_device dma_slave; struct moxart_chan slave_chans[APB_DMA_MAX_CHANNEL]; + unsigned int irq; }; struct moxart_filter_data { @@ -574,10 +575,8 @@ static int moxart_probe(struct platform_device *pdev) struct moxart_dmadev *mdc; mdc = devm_kzalloc(dev, sizeof(*mdc), GFP_KERNEL); - if (!mdc) { - dev_err(dev, "can't allocate DMA container\n"); + if (!mdc) return -ENOMEM; - } irq = irq_of_parse_and_map(node, 0); if (irq == NO_IRQ) { @@ -617,6 +616,7 @@ static int moxart_probe(struct platform_device *pdev) dev_err(dev, "devm_request_irq failed\n"); return ret; } + mdc->irq = irq; ret = dma_async_device_register(&mdc->dma_slave); if (ret) { @@ -640,6 +640,8 @@ static int moxart_remove(struct platform_device *pdev) { struct moxart_dmadev *m = platform_get_drvdata(pdev); + devm_free_irq(&pdev->dev, m->irq, m); + dma_async_device_unregister(&m->dma_slave); if (pdev->dev.of_node) diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index ccadafa51d5e..fa86592c7ae1 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -1110,6 +1110,7 @@ static int mpc_dma_remove(struct platform_device *op) } free_irq(mdma->irq, mdma); irq_dispose_mapping(mdma->irq); + tasklet_kill(&mdma->tasklet); return 0; } diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index d0446a75990a..f4c9f98ec35e 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -1057,7 +1057,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev, err_free_irq: free_irq(mv_chan->irq, mv_chan); - err_free_dma: +err_free_dma: dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE, mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool); return ERR_PTR(ret); diff --git a/drivers/dma/mv_xor_v2.c b/drivers/dma/mv_xor_v2.c new file mode 100644 index 000000000000..a28a01fcba67 --- /dev/null +++ b/drivers/dma/mv_xor_v2.c @@ -0,0 +1,878 @@ +/* + * Copyright (C) 2015-2016 Marvell International Ltd. + + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/msi.h> +#include <linux/of.h> +#include <linux/of_irq.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> + +#include "dmaengine.h" + +/* DMA Engine Registers */ +#define MV_XOR_V2_DMA_DESQ_BALR_OFF 0x000 +#define MV_XOR_V2_DMA_DESQ_BAHR_OFF 0x004 +#define MV_XOR_V2_DMA_DESQ_SIZE_OFF 0x008 +#define MV_XOR_V2_DMA_DESQ_DONE_OFF 0x00C +#define MV_XOR_V2_DMA_DESQ_DONE_PENDING_MASK 0x7FFF +#define MV_XOR_V2_DMA_DESQ_DONE_PENDING_SHIFT 0 +#define MV_XOR_V2_DMA_DESQ_DONE_READ_PTR_MASK 0x1FFF +#define MV_XOR_V2_DMA_DESQ_DONE_READ_PTR_SHIFT 16 +#define MV_XOR_V2_DMA_DESQ_ARATTR_OFF 0x010 +#define MV_XOR_V2_DMA_DESQ_ATTR_CACHE_MASK 0x3F3F +#define MV_XOR_V2_DMA_DESQ_ATTR_OUTER_SHAREABLE 0x202 +#define MV_XOR_V2_DMA_DESQ_ATTR_CACHEABLE 0x3C3C +#define MV_XOR_V2_DMA_IMSG_CDAT_OFF 0x014 +#define MV_XOR_V2_DMA_IMSG_THRD_OFF 0x018 +#define MV_XOR_V2_DMA_IMSG_THRD_MASK 0x7FFF +#define MV_XOR_V2_DMA_IMSG_THRD_SHIFT 0x0 +#define MV_XOR_V2_DMA_DESQ_AWATTR_OFF 0x01C + /* Same flags as MV_XOR_V2_DMA_DESQ_ARATTR_OFF */ +#define MV_XOR_V2_DMA_DESQ_ALLOC_OFF 0x04C +#define MV_XOR_V2_DMA_DESQ_ALLOC_WRPTR_MASK 0xFFFF +#define MV_XOR_V2_DMA_DESQ_ALLOC_WRPTR_SHIFT 16 +#define MV_XOR_V2_DMA_IMSG_BALR_OFF 0x050 +#define MV_XOR_V2_DMA_IMSG_BAHR_OFF 0x054 +#define MV_XOR_V2_DMA_DESQ_CTRL_OFF 0x100 +#define MV_XOR_V2_DMA_DESQ_CTRL_32B 1 +#define MV_XOR_V2_DMA_DESQ_CTRL_128B 7 +#define MV_XOR_V2_DMA_DESQ_STOP_OFF 0x800 +#define MV_XOR_V2_DMA_DESQ_DEALLOC_OFF 0x804 +#define MV_XOR_V2_DMA_DESQ_ADD_OFF 0x808 + +/* XOR Global registers */ +#define MV_XOR_V2_GLOB_BW_CTRL 0x4 +#define MV_XOR_V2_GLOB_BW_CTRL_NUM_OSTD_RD_SHIFT 0 +#define MV_XOR_V2_GLOB_BW_CTRL_NUM_OSTD_RD_VAL 64 +#define MV_XOR_V2_GLOB_BW_CTRL_NUM_OSTD_WR_SHIFT 8 +#define MV_XOR_V2_GLOB_BW_CTRL_NUM_OSTD_WR_VAL 8 +#define MV_XOR_V2_GLOB_BW_CTRL_RD_BURST_LEN_SHIFT 12 +#define MV_XOR_V2_GLOB_BW_CTRL_RD_BURST_LEN_VAL 4 +#define MV_XOR_V2_GLOB_BW_CTRL_WR_BURST_LEN_SHIFT 16 +#define MV_XOR_V2_GLOB_BW_CTRL_WR_BURST_LEN_VAL 4 +#define MV_XOR_V2_GLOB_PAUSE 0x014 +#define MV_XOR_V2_GLOB_PAUSE_AXI_TIME_DIS_VAL 0x8 +#define MV_XOR_V2_GLOB_SYS_INT_CAUSE 0x200 +#define MV_XOR_V2_GLOB_SYS_INT_MASK 0x204 +#define MV_XOR_V2_GLOB_MEM_INT_CAUSE 0x220 +#define MV_XOR_V2_GLOB_MEM_INT_MASK 0x224 + +#define MV_XOR_V2_MIN_DESC_SIZE 32 +#define MV_XOR_V2_EXT_DESC_SIZE 128 + +#define MV_XOR_V2_DESC_RESERVED_SIZE 12 +#define MV_XOR_V2_DESC_BUFF_D_ADDR_SIZE 12 + +#define MV_XOR_V2_CMD_LINE_NUM_MAX_D_BUF 8 + +/* + * Descriptors queue size. With 32 bytes descriptors, up to 2^14 + * descriptors are allowed, with 128 bytes descriptors, up to 2^12 + * descriptors are allowed. This driver uses 128 bytes descriptors, + * but experimentation has shown that a set of 1024 descriptors is + * sufficient to reach a good level of performance. + */ +#define MV_XOR_V2_DESC_NUM 1024 + +/** + * struct mv_xor_v2_descriptor - DMA HW descriptor + * @desc_id: used by S/W and is not affected by H/W. + * @flags: error and status flags + * @crc32_result: CRC32 calculation result + * @desc_ctrl: operation mode and control flags + * @buff_size: amount of bytes to be processed + * @fill_pattern_src_addr: Fill-Pattern or Source-Address and + * AW-Attributes + * @data_buff_addr: Source (and might be RAID6 destination) + * addresses of data buffers in RAID5 and RAID6 + * @reserved: reserved + */ +struct mv_xor_v2_descriptor { + u16 desc_id; + u16 flags; + u32 crc32_result; + u32 desc_ctrl; + + /* Definitions for desc_ctrl */ +#define DESC_NUM_ACTIVE_D_BUF_SHIFT 22 +#define DESC_OP_MODE_SHIFT 28 +#define DESC_OP_MODE_NOP 0 /* Idle operation */ +#define DESC_OP_MODE_MEMCPY 1 /* Pure-DMA operation */ +#define DESC_OP_MODE_MEMSET 2 /* Mem-Fill operation */ +#define DESC_OP_MODE_MEMINIT 3 /* Mem-Init operation */ +#define DESC_OP_MODE_MEM_COMPARE 4 /* Mem-Compare operation */ +#define DESC_OP_MODE_CRC32 5 /* CRC32 calculation */ +#define DESC_OP_MODE_XOR 6 /* RAID5 (XOR) operation */ +#define DESC_OP_MODE_RAID6 7 /* RAID6 P&Q-generation */ +#define DESC_OP_MODE_RAID6_REC 8 /* RAID6 Recovery */ +#define DESC_Q_BUFFER_ENABLE BIT(16) +#define DESC_P_BUFFER_ENABLE BIT(17) +#define DESC_IOD BIT(27) + + u32 buff_size; + u32 fill_pattern_src_addr[4]; + u32 data_buff_addr[MV_XOR_V2_DESC_BUFF_D_ADDR_SIZE]; + u32 reserved[MV_XOR_V2_DESC_RESERVED_SIZE]; +}; + +/** + * struct mv_xor_v2_device - implements a xor device + * @lock: lock for the engine + * @dma_base: memory mapped DMA register base + * @glob_base: memory mapped global register base + * @irq_tasklet: + * @free_sw_desc: linked list of free SW descriptors + * @dmadev: dma device + * @dmachan: dma channel + * @hw_desq: HW descriptors queue + * @hw_desq_virt: virtual address of DESCQ + * @sw_desq: SW descriptors queue + * @desc_size: HW descriptor size + * @npendings: number of pending descriptors (for which tx_submit has + * been called, but not yet issue_pending) + */ +struct mv_xor_v2_device { + spinlock_t lock; + void __iomem *dma_base; + void __iomem *glob_base; + struct clk *clk; + struct tasklet_struct irq_tasklet; + struct list_head free_sw_desc; + struct dma_device dmadev; + struct dma_chan dmachan; + dma_addr_t hw_desq; + struct mv_xor_v2_descriptor *hw_desq_virt; + struct mv_xor_v2_sw_desc *sw_desq; + int desc_size; + unsigned int npendings; +}; + +/** + * struct mv_xor_v2_sw_desc - implements a xor SW descriptor + * @idx: descriptor index + * @async_tx: support for the async_tx api + * @hw_desc: assosiated HW descriptor + * @free_list: node of the free SW descriprots list +*/ +struct mv_xor_v2_sw_desc { + int idx; + struct dma_async_tx_descriptor async_tx; + struct mv_xor_v2_descriptor hw_desc; + struct list_head free_list; +}; + +/* + * Fill the data buffers to a HW descriptor + */ +static void mv_xor_v2_set_data_buffers(struct mv_xor_v2_device *xor_dev, + struct mv_xor_v2_descriptor *desc, + dma_addr_t src, int index) +{ + int arr_index = ((index >> 1) * 3); + + /* + * Fill the buffer's addresses to the descriptor. + * + * The format of the buffers address for 2 sequential buffers + * X and X + 1: + * + * First word: Buffer-DX-Address-Low[31:0] + * Second word: Buffer-DX+1-Address-Low[31:0] + * Third word: DX+1-Buffer-Address-High[47:32] [31:16] + * DX-Buffer-Address-High[47:32] [15:0] + */ + if ((index & 0x1) == 0) { + desc->data_buff_addr[arr_index] = lower_32_bits(src); + + desc->data_buff_addr[arr_index + 2] &= ~0xFFFF; + desc->data_buff_addr[arr_index + 2] |= + upper_32_bits(src) & 0xFFFF; + } else { + desc->data_buff_addr[arr_index + 1] = + lower_32_bits(src); + + desc->data_buff_addr[arr_index + 2] &= ~0xFFFF0000; + desc->data_buff_addr[arr_index + 2] |= + (upper_32_bits(src) & 0xFFFF) << 16; + } +} + +/* + * Return the next available index in the DESQ. + */ +static int mv_xor_v2_get_desq_write_ptr(struct mv_xor_v2_device *xor_dev) +{ + /* read the index for the next available descriptor in the DESQ */ + u32 reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_ALLOC_OFF); + + return ((reg >> MV_XOR_V2_DMA_DESQ_ALLOC_WRPTR_SHIFT) + & MV_XOR_V2_DMA_DESQ_ALLOC_WRPTR_MASK); +} + +/* + * notify the engine of new descriptors, and update the available index. + */ +static void mv_xor_v2_add_desc_to_desq(struct mv_xor_v2_device *xor_dev, + int num_of_desc) +{ + /* write the number of new descriptors in the DESQ. */ + writel(num_of_desc, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_ADD_OFF); +} + +/* + * free HW descriptors + */ +static void mv_xor_v2_free_desc_from_desq(struct mv_xor_v2_device *xor_dev, + int num_of_desc) +{ + /* write the number of new descriptors in the DESQ. */ + writel(num_of_desc, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_DEALLOC_OFF); +} + +/* + * Set descriptor size + * Return the HW descriptor size in bytes + */ +static int mv_xor_v2_set_desc_size(struct mv_xor_v2_device *xor_dev) +{ + writel(MV_XOR_V2_DMA_DESQ_CTRL_128B, + xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_CTRL_OFF); + + return MV_XOR_V2_EXT_DESC_SIZE; +} + +/* + * Set the IMSG threshold + */ +static inline +void mv_xor_v2_set_imsg_thrd(struct mv_xor_v2_device *xor_dev, int thrd_val) +{ + u32 reg; + + reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF); + + reg &= (~MV_XOR_V2_DMA_IMSG_THRD_MASK << MV_XOR_V2_DMA_IMSG_THRD_SHIFT); + reg |= (thrd_val << MV_XOR_V2_DMA_IMSG_THRD_SHIFT); + + writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_THRD_OFF); +} + +static irqreturn_t mv_xor_v2_interrupt_handler(int irq, void *data) +{ + struct mv_xor_v2_device *xor_dev = data; + unsigned int ndescs; + u32 reg; + + reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_DONE_OFF); + + ndescs = ((reg >> MV_XOR_V2_DMA_DESQ_DONE_PENDING_SHIFT) & + MV_XOR_V2_DMA_DESQ_DONE_PENDING_MASK); + + /* No descriptors to process */ + if (!ndescs) + return IRQ_NONE; + + /* + * Update IMSG threshold, to disable new IMSG interrupts until + * end of the tasklet + */ + mv_xor_v2_set_imsg_thrd(xor_dev, MV_XOR_V2_DESC_NUM); + + /* schedule a tasklet to handle descriptors callbacks */ + tasklet_schedule(&xor_dev->irq_tasklet); + + return IRQ_HANDLED; +} + +/* + * submit a descriptor to the DMA engine + */ +static dma_cookie_t +mv_xor_v2_tx_submit(struct dma_async_tx_descriptor *tx) +{ + int desq_ptr; + void *dest_hw_desc; + dma_cookie_t cookie; + struct mv_xor_v2_sw_desc *sw_desc = + container_of(tx, struct mv_xor_v2_sw_desc, async_tx); + struct mv_xor_v2_device *xor_dev = + container_of(tx->chan, struct mv_xor_v2_device, dmachan); + + dev_dbg(xor_dev->dmadev.dev, + "%s sw_desc %p: async_tx %p\n", + __func__, sw_desc, &sw_desc->async_tx); + + /* assign coookie */ + spin_lock_bh(&xor_dev->lock); + cookie = dma_cookie_assign(tx); + + /* get the next available slot in the DESQ */ + desq_ptr = mv_xor_v2_get_desq_write_ptr(xor_dev); + + /* copy the HW descriptor from the SW descriptor to the DESQ */ + dest_hw_desc = xor_dev->hw_desq_virt + desq_ptr; + + memcpy(dest_hw_desc, &sw_desc->hw_desc, xor_dev->desc_size); + + xor_dev->npendings++; + + spin_unlock_bh(&xor_dev->lock); + + return cookie; +} + +/* + * Prepare a SW descriptor + */ +static struct mv_xor_v2_sw_desc * +mv_xor_v2_prep_sw_desc(struct mv_xor_v2_device *xor_dev) +{ + struct mv_xor_v2_sw_desc *sw_desc; + + /* Lock the channel */ + spin_lock_bh(&xor_dev->lock); + + if (list_empty(&xor_dev->free_sw_desc)) { + spin_unlock_bh(&xor_dev->lock); + /* schedule tasklet to free some descriptors */ + tasklet_schedule(&xor_dev->irq_tasklet); + return NULL; + } + + /* get a free SW descriptor from the SW DESQ */ + sw_desc = list_first_entry(&xor_dev->free_sw_desc, + struct mv_xor_v2_sw_desc, free_list); + list_del(&sw_desc->free_list); + + /* Release the channel */ + spin_unlock_bh(&xor_dev->lock); + + /* set the async tx descriptor */ + dma_async_tx_descriptor_init(&sw_desc->async_tx, &xor_dev->dmachan); + sw_desc->async_tx.tx_submit = mv_xor_v2_tx_submit; + async_tx_ack(&sw_desc->async_tx); + + return sw_desc; +} + +/* + * Prepare a HW descriptor for a memcpy operation + */ +static struct dma_async_tx_descriptor * +mv_xor_v2_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, + dma_addr_t src, size_t len, unsigned long flags) +{ + struct mv_xor_v2_sw_desc *sw_desc; + struct mv_xor_v2_descriptor *hw_descriptor; + struct mv_xor_v2_device *xor_dev; + + xor_dev = container_of(chan, struct mv_xor_v2_device, dmachan); + + dev_dbg(xor_dev->dmadev.dev, + "%s len: %zu src %pad dest %pad flags: %ld\n", + __func__, len, &src, &dest, flags); + + sw_desc = mv_xor_v2_prep_sw_desc(xor_dev); + + sw_desc->async_tx.flags = flags; + + /* set the HW descriptor */ + hw_descriptor = &sw_desc->hw_desc; + + /* save the SW descriptor ID to restore when operation is done */ + hw_descriptor->desc_id = sw_desc->idx; + + /* Set the MEMCPY control word */ + hw_descriptor->desc_ctrl = + DESC_OP_MODE_MEMCPY << DESC_OP_MODE_SHIFT; + + if (flags & DMA_PREP_INTERRUPT) + hw_descriptor->desc_ctrl |= DESC_IOD; + + /* Set source address */ + hw_descriptor->fill_pattern_src_addr[0] = lower_32_bits(src); + hw_descriptor->fill_pattern_src_addr[1] = + upper_32_bits(src) & 0xFFFF; + + /* Set Destination address */ + hw_descriptor->fill_pattern_src_addr[2] = lower_32_bits(dest); + hw_descriptor->fill_pattern_src_addr[3] = + upper_32_bits(dest) & 0xFFFF; + + /* Set buffers size */ + hw_descriptor->buff_size = len; + + /* return the async tx descriptor */ + return &sw_desc->async_tx; +} + +/* + * Prepare a HW descriptor for a XOR operation + */ +static struct dma_async_tx_descriptor * +mv_xor_v2_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, + unsigned int src_cnt, size_t len, unsigned long flags) +{ + struct mv_xor_v2_sw_desc *sw_desc; + struct mv_xor_v2_descriptor *hw_descriptor; + struct mv_xor_v2_device *xor_dev = + container_of(chan, struct mv_xor_v2_device, dmachan); + int i; + + if (src_cnt > MV_XOR_V2_CMD_LINE_NUM_MAX_D_BUF || src_cnt < 1) + return NULL; + + dev_dbg(xor_dev->dmadev.dev, + "%s src_cnt: %d len: %zu dest %pad flags: %ld\n", + __func__, src_cnt, len, &dest, flags); + + sw_desc = mv_xor_v2_prep_sw_desc(xor_dev); + + sw_desc->async_tx.flags = flags; + + /* set the HW descriptor */ + hw_descriptor = &sw_desc->hw_desc; + + /* save the SW descriptor ID to restore when operation is done */ + hw_descriptor->desc_id = sw_desc->idx; + + /* Set the XOR control word */ + hw_descriptor->desc_ctrl = + DESC_OP_MODE_XOR << DESC_OP_MODE_SHIFT; + hw_descriptor->desc_ctrl |= DESC_P_BUFFER_ENABLE; + + if (flags & DMA_PREP_INTERRUPT) + hw_descriptor->desc_ctrl |= DESC_IOD; + + /* Set the data buffers */ + for (i = 0; i < src_cnt; i++) + mv_xor_v2_set_data_buffers(xor_dev, hw_descriptor, src[i], i); + + hw_descriptor->desc_ctrl |= + src_cnt << DESC_NUM_ACTIVE_D_BUF_SHIFT; + + /* Set Destination address */ + hw_descriptor->fill_pattern_src_addr[2] = lower_32_bits(dest); + hw_descriptor->fill_pattern_src_addr[3] = + upper_32_bits(dest) & 0xFFFF; + + /* Set buffers size */ + hw_descriptor->buff_size = len; + + /* return the async tx descriptor */ + return &sw_desc->async_tx; +} + +/* + * Prepare a HW descriptor for interrupt operation. + */ +static struct dma_async_tx_descriptor * +mv_xor_v2_prep_dma_interrupt(struct dma_chan *chan, unsigned long flags) +{ + struct mv_xor_v2_sw_desc *sw_desc; + struct mv_xor_v2_descriptor *hw_descriptor; + struct mv_xor_v2_device *xor_dev = + container_of(chan, struct mv_xor_v2_device, dmachan); + + sw_desc = mv_xor_v2_prep_sw_desc(xor_dev); + + /* set the HW descriptor */ + hw_descriptor = &sw_desc->hw_desc; + + /* save the SW descriptor ID to restore when operation is done */ + hw_descriptor->desc_id = sw_desc->idx; + + /* Set the INTERRUPT control word */ + hw_descriptor->desc_ctrl = + DESC_OP_MODE_NOP << DESC_OP_MODE_SHIFT; + hw_descriptor->desc_ctrl |= DESC_IOD; + + /* return the async tx descriptor */ + return &sw_desc->async_tx; +} + +/* + * push pending transactions to hardware + */ +static void mv_xor_v2_issue_pending(struct dma_chan *chan) +{ + struct mv_xor_v2_device *xor_dev = + container_of(chan, struct mv_xor_v2_device, dmachan); + + spin_lock_bh(&xor_dev->lock); + + /* + * update the engine with the number of descriptors to + * process + */ + mv_xor_v2_add_desc_to_desq(xor_dev, xor_dev->npendings); + xor_dev->npendings = 0; + + /* Activate the channel */ + writel(0, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_STOP_OFF); + + spin_unlock_bh(&xor_dev->lock); +} + +static inline +int mv_xor_v2_get_pending_params(struct mv_xor_v2_device *xor_dev, + int *pending_ptr) +{ + u32 reg; + + reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_DONE_OFF); + + /* get the next pending descriptor index */ + *pending_ptr = ((reg >> MV_XOR_V2_DMA_DESQ_DONE_READ_PTR_SHIFT) & + MV_XOR_V2_DMA_DESQ_DONE_READ_PTR_MASK); + + /* get the number of descriptors pending handle */ + return ((reg >> MV_XOR_V2_DMA_DESQ_DONE_PENDING_SHIFT) & + MV_XOR_V2_DMA_DESQ_DONE_PENDING_MASK); +} + +/* + * handle the descriptors after HW process + */ +static void mv_xor_v2_tasklet(unsigned long data) +{ + struct mv_xor_v2_device *xor_dev = (struct mv_xor_v2_device *) data; + int pending_ptr, num_of_pending, i; + struct mv_xor_v2_descriptor *next_pending_hw_desc = NULL; + struct mv_xor_v2_sw_desc *next_pending_sw_desc = NULL; + + dev_dbg(xor_dev->dmadev.dev, "%s %d\n", __func__, __LINE__); + + /* get the pending descriptors parameters */ + num_of_pending = mv_xor_v2_get_pending_params(xor_dev, &pending_ptr); + + /* next HW descriptor */ + next_pending_hw_desc = xor_dev->hw_desq_virt + pending_ptr; + + /* loop over free descriptors */ + for (i = 0; i < num_of_pending; i++) { + + if (pending_ptr > MV_XOR_V2_DESC_NUM) + pending_ptr = 0; + + if (next_pending_sw_desc != NULL) + next_pending_hw_desc++; + + /* get the SW descriptor related to the HW descriptor */ + next_pending_sw_desc = + &xor_dev->sw_desq[next_pending_hw_desc->desc_id]; + + /* call the callback */ + if (next_pending_sw_desc->async_tx.cookie > 0) { + /* + * update the channel's completed cookie - no + * lock is required the IMSG threshold provide + * the locking + */ + dma_cookie_complete(&next_pending_sw_desc->async_tx); + + if (next_pending_sw_desc->async_tx.callback) + next_pending_sw_desc->async_tx.callback( + next_pending_sw_desc->async_tx.callback_param); + + dma_descriptor_unmap(&next_pending_sw_desc->async_tx); + } + + dma_run_dependencies(&next_pending_sw_desc->async_tx); + + /* Lock the channel */ + spin_lock_bh(&xor_dev->lock); + + /* add the SW descriptor to the free descriptors list */ + list_add(&next_pending_sw_desc->free_list, + &xor_dev->free_sw_desc); + + /* Release the channel */ + spin_unlock_bh(&xor_dev->lock); + + /* increment the next descriptor */ + pending_ptr++; + } + + if (num_of_pending != 0) { + /* free the descriptores */ + mv_xor_v2_free_desc_from_desq(xor_dev, num_of_pending); + } + + /* Update IMSG threshold, to enable new IMSG interrupts */ + mv_xor_v2_set_imsg_thrd(xor_dev, 0); +} + +/* + * Set DMA Interrupt-message (IMSG) parameters + */ +static void mv_xor_v2_set_msi_msg(struct msi_desc *desc, struct msi_msg *msg) +{ + struct mv_xor_v2_device *xor_dev = dev_get_drvdata(desc->dev); + + writel(msg->address_lo, + xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_BALR_OFF); + writel(msg->address_hi & 0xFFFF, + xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_BAHR_OFF); + writel(msg->data, + xor_dev->dma_base + MV_XOR_V2_DMA_IMSG_CDAT_OFF); +} + +static int mv_xor_v2_descq_init(struct mv_xor_v2_device *xor_dev) +{ + u32 reg; + + /* write the DESQ size to the DMA engine */ + writel(MV_XOR_V2_DESC_NUM, + xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_SIZE_OFF); + + /* write the DESQ address to the DMA enngine*/ + writel(xor_dev->hw_desq & 0xFFFFFFFF, + xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_BALR_OFF); + writel((xor_dev->hw_desq & 0xFFFF00000000) >> 32, + xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_BAHR_OFF); + + /* enable the DMA engine */ + writel(0, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_STOP_OFF); + + /* + * This is a temporary solution, until we activate the + * SMMU. Set the attributes for reading & writing data buffers + * & descriptors to: + * + * - OuterShareable - Snoops will be performed on CPU caches + * - Enable cacheable - Bufferable, Modifiable, Other Allocate + * and Allocate + */ + reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_ARATTR_OFF); + reg &= ~MV_XOR_V2_DMA_DESQ_ATTR_CACHE_MASK; + reg |= MV_XOR_V2_DMA_DESQ_ATTR_OUTER_SHAREABLE | + MV_XOR_V2_DMA_DESQ_ATTR_CACHEABLE; + writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_ARATTR_OFF); + + reg = readl(xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_AWATTR_OFF); + reg &= ~MV_XOR_V2_DMA_DESQ_ATTR_CACHE_MASK; + reg |= MV_XOR_V2_DMA_DESQ_ATTR_OUTER_SHAREABLE | + MV_XOR_V2_DMA_DESQ_ATTR_CACHEABLE; + writel(reg, xor_dev->dma_base + MV_XOR_V2_DMA_DESQ_AWATTR_OFF); + + /* BW CTRL - set values to optimize the XOR performance: + * + * - Set WrBurstLen & RdBurstLen - the unit will issue + * maximum of 256B write/read transactions. + * - Limit the number of outstanding write & read data + * (OBB/IBB) requests to the maximal value. + */ + reg = ((MV_XOR_V2_GLOB_BW_CTRL_NUM_OSTD_RD_VAL << + MV_XOR_V2_GLOB_BW_CTRL_NUM_OSTD_RD_SHIFT) | + (MV_XOR_V2_GLOB_BW_CTRL_NUM_OSTD_WR_VAL << + MV_XOR_V2_GLOB_BW_CTRL_NUM_OSTD_WR_SHIFT) | + (MV_XOR_V2_GLOB_BW_CTRL_RD_BURST_LEN_VAL << + MV_XOR_V2_GLOB_BW_CTRL_RD_BURST_LEN_SHIFT) | + (MV_XOR_V2_GLOB_BW_CTRL_WR_BURST_LEN_VAL << + MV_XOR_V2_GLOB_BW_CTRL_WR_BURST_LEN_SHIFT)); + writel(reg, xor_dev->glob_base + MV_XOR_V2_GLOB_BW_CTRL); + + /* Disable the AXI timer feature */ + reg = readl(xor_dev->glob_base + MV_XOR_V2_GLOB_PAUSE); + reg |= MV_XOR_V2_GLOB_PAUSE_AXI_TIME_DIS_VAL; + writel(reg, xor_dev->glob_base + MV_XOR_V2_GLOB_PAUSE); + + return 0; +} + +static int mv_xor_v2_probe(struct platform_device *pdev) +{ + struct mv_xor_v2_device *xor_dev; + struct resource *res; + int i, ret = 0; + struct dma_device *dma_dev; + struct mv_xor_v2_sw_desc *sw_desc; + struct msi_desc *msi_desc; + + BUILD_BUG_ON(sizeof(struct mv_xor_v2_descriptor) != + MV_XOR_V2_EXT_DESC_SIZE); + + xor_dev = devm_kzalloc(&pdev->dev, sizeof(*xor_dev), GFP_KERNEL); + if (!xor_dev) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + xor_dev->dma_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(xor_dev->dma_base)) + return PTR_ERR(xor_dev->dma_base); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + xor_dev->glob_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(xor_dev->glob_base)) + return PTR_ERR(xor_dev->glob_base); + + platform_set_drvdata(pdev, xor_dev); + + xor_dev->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) + return -EPROBE_DEFER; + if (!IS_ERR(xor_dev->clk)) { + ret = clk_prepare_enable(xor_dev->clk); + if (ret) + return ret; + } + + ret = platform_msi_domain_alloc_irqs(&pdev->dev, 1, + mv_xor_v2_set_msi_msg); + if (ret) + goto disable_clk; + + msi_desc = first_msi_entry(&pdev->dev); + if (!msi_desc) + goto free_msi_irqs; + + ret = devm_request_irq(&pdev->dev, msi_desc->irq, + mv_xor_v2_interrupt_handler, 0, + dev_name(&pdev->dev), xor_dev); + if (ret) + goto free_msi_irqs; + + tasklet_init(&xor_dev->irq_tasklet, mv_xor_v2_tasklet, + (unsigned long) xor_dev); + + xor_dev->desc_size = mv_xor_v2_set_desc_size(xor_dev); + + dma_cookie_init(&xor_dev->dmachan); + + /* + * allocate coherent memory for hardware descriptors + * note: writecombine gives slightly better performance, but + * requires that we explicitly flush the writes + */ + xor_dev->hw_desq_virt = + dma_alloc_coherent(&pdev->dev, + xor_dev->desc_size * MV_XOR_V2_DESC_NUM, + &xor_dev->hw_desq, GFP_KERNEL); + if (!xor_dev->hw_desq_virt) { + ret = -ENOMEM; + goto free_msi_irqs; + } + + /* alloc memory for the SW descriptors */ + xor_dev->sw_desq = devm_kzalloc(&pdev->dev, sizeof(*sw_desc) * + MV_XOR_V2_DESC_NUM, GFP_KERNEL); + if (!xor_dev->sw_desq) { + ret = -ENOMEM; + goto free_hw_desq; + } + + spin_lock_init(&xor_dev->lock); + + /* init the free SW descriptors list */ + INIT_LIST_HEAD(&xor_dev->free_sw_desc); + + /* add all SW descriptors to the free list */ + for (i = 0; i < MV_XOR_V2_DESC_NUM; i++) { + xor_dev->sw_desq[i].idx = i; + list_add(&xor_dev->sw_desq[i].free_list, + &xor_dev->free_sw_desc); + } + + dma_dev = &xor_dev->dmadev; + + /* set DMA capabilities */ + dma_cap_zero(dma_dev->cap_mask); + dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); + dma_cap_set(DMA_XOR, dma_dev->cap_mask); + dma_cap_set(DMA_INTERRUPT, dma_dev->cap_mask); + + /* init dma link list */ + INIT_LIST_HEAD(&dma_dev->channels); + + /* set base routines */ + dma_dev->device_tx_status = dma_cookie_status; + dma_dev->device_issue_pending = mv_xor_v2_issue_pending; + dma_dev->dev = &pdev->dev; + + dma_dev->device_prep_dma_memcpy = mv_xor_v2_prep_dma_memcpy; + dma_dev->device_prep_dma_interrupt = mv_xor_v2_prep_dma_interrupt; + dma_dev->max_xor = 8; + dma_dev->device_prep_dma_xor = mv_xor_v2_prep_dma_xor; + + xor_dev->dmachan.device = dma_dev; + + list_add_tail(&xor_dev->dmachan.device_node, + &dma_dev->channels); + + mv_xor_v2_descq_init(xor_dev); + + ret = dma_async_device_register(dma_dev); + if (ret) + goto free_hw_desq; + + dev_notice(&pdev->dev, "Marvell Version 2 XOR driver\n"); + + return 0; + +free_hw_desq: + dma_free_coherent(&pdev->dev, + xor_dev->desc_size * MV_XOR_V2_DESC_NUM, + xor_dev->hw_desq_virt, xor_dev->hw_desq); +free_msi_irqs: + platform_msi_domain_free_irqs(&pdev->dev); +disable_clk: + if (!IS_ERR(xor_dev->clk)) + clk_disable_unprepare(xor_dev->clk); + return ret; +} + +static int mv_xor_v2_remove(struct platform_device *pdev) +{ + struct mv_xor_v2_device *xor_dev = platform_get_drvdata(pdev); + + dma_async_device_unregister(&xor_dev->dmadev); + + dma_free_coherent(&pdev->dev, + xor_dev->desc_size * MV_XOR_V2_DESC_NUM, + xor_dev->hw_desq_virt, xor_dev->hw_desq); + + platform_msi_domain_free_irqs(&pdev->dev); + + clk_disable_unprepare(xor_dev->clk); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id mv_xor_v2_dt_ids[] = { + { .compatible = "marvell,xor-v2", }, + {}, +}; +MODULE_DEVICE_TABLE(of, mv_xor_v2_dt_ids); +#endif + +static struct platform_driver mv_xor_v2_driver = { + .probe = mv_xor_v2_probe, + .remove = mv_xor_v2_remove, + .driver = { + .name = "mv_xor_v2", + .of_match_table = of_match_ptr(mv_xor_v2_dt_ids), + }, +}; + +module_platform_driver(mv_xor_v2_driver); + +MODULE_DESCRIPTION("DMA engine driver for Marvell's Version 2 of XOR engine"); +MODULE_LICENSE("GPL"); diff --git a/drivers/dma/nbpfaxi.c b/drivers/dma/nbpfaxi.c index 2b5a198ac77e..08c45c185549 100644 --- a/drivers/dma/nbpfaxi.c +++ b/drivers/dma/nbpfaxi.c @@ -227,6 +227,7 @@ struct nbpf_device { void __iomem *base; struct clk *clk; const struct nbpf_config *config; + unsigned int eirq; struct nbpf_channel chan[]; }; @@ -1300,10 +1301,9 @@ static int nbpf_probe(struct platform_device *pdev) nbpf = devm_kzalloc(dev, sizeof(*nbpf) + num_channels * sizeof(nbpf->chan[0]), GFP_KERNEL); - if (!nbpf) { - dev_err(dev, "Memory allocation failed\n"); + if (!nbpf) return -ENOMEM; - } + dma_dev = &nbpf->dma_dev; dma_dev->dev = dev; @@ -1376,6 +1376,7 @@ static int nbpf_probe(struct platform_device *pdev) IRQF_SHARED, "dma error", nbpf); if (ret < 0) return ret; + nbpf->eirq = eirq; INIT_LIST_HEAD(&dma_dev->channels); @@ -1447,6 +1448,17 @@ e_clk_off: static int nbpf_remove(struct platform_device *pdev) { struct nbpf_device *nbpf = platform_get_drvdata(pdev); + int i; + + devm_free_irq(&pdev->dev, nbpf->eirq, nbpf); + + for (i = 0; i < nbpf->config->num_channels; i++) { + struct nbpf_channel *chan = nbpf->chan + i; + + devm_free_irq(&pdev->dev, chan->irq, chan); + + tasklet_kill(&chan->tasklet); + } of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&nbpf->dma_dev); diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index 1e984e18c126..d99ca2b511c4 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c @@ -59,6 +59,8 @@ struct omap_sg { dma_addr_t addr; uint32_t en; /* number of elements (24-bit) */ uint32_t fn; /* number of frames (16-bit) */ + int32_t fi; /* for double indexing */ + int16_t ei; /* for double indexing */ }; struct omap_desc { @@ -66,7 +68,8 @@ struct omap_desc { enum dma_transfer_direction dir; dma_addr_t dev_addr; - int16_t fi; /* for OMAP_DMA_SYNC_PACKET */ + int32_t fi; /* for OMAP_DMA_SYNC_PACKET / double indexing */ + int16_t ei; /* for double indexing */ uint8_t es; /* CSDP_DATA_TYPE_xxx */ uint32_t ccr; /* CCR value */ uint16_t clnk_ctrl; /* CLNK_CTRL value */ @@ -379,8 +382,8 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d, } omap_dma_chan_write(c, cxsa, sg->addr); - omap_dma_chan_write(c, cxei, 0); - omap_dma_chan_write(c, cxfi, 0); + omap_dma_chan_write(c, cxei, sg->ei); + omap_dma_chan_write(c, cxfi, sg->fi); omap_dma_chan_write(c, CEN, sg->en); omap_dma_chan_write(c, CFN, sg->fn); @@ -425,7 +428,7 @@ static void omap_dma_start_desc(struct omap_chan *c) } omap_dma_chan_write(c, cxsa, d->dev_addr); - omap_dma_chan_write(c, cxei, 0); + omap_dma_chan_write(c, cxei, d->ei); omap_dma_chan_write(c, cxfi, d->fi); omap_dma_chan_write(c, CSDP, d->csdp); omap_dma_chan_write(c, CLNK_CTRL, d->clnk_ctrl); @@ -971,6 +974,89 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_memcpy( return vchan_tx_prep(&c->vc, &d->vd, tx_flags); } +static struct dma_async_tx_descriptor *omap_dma_prep_dma_interleaved( + struct dma_chan *chan, struct dma_interleaved_template *xt, + unsigned long flags) +{ + struct omap_chan *c = to_omap_dma_chan(chan); + struct omap_desc *d; + struct omap_sg *sg; + uint8_t data_type; + size_t src_icg, dst_icg; + + /* Slave mode is not supported */ + if (is_slave_direction(xt->dir)) + return NULL; + + if (xt->frame_size != 1 || xt->numf == 0) + return NULL; + + d = kzalloc(sizeof(*d) + sizeof(d->sg[0]), GFP_ATOMIC); + if (!d) + return NULL; + + data_type = __ffs((xt->src_start | xt->dst_start | xt->sgl[0].size)); + if (data_type > CSDP_DATA_TYPE_32) + data_type = CSDP_DATA_TYPE_32; + + sg = &d->sg[0]; + d->dir = DMA_MEM_TO_MEM; + d->dev_addr = xt->src_start; + d->es = data_type; + sg->en = xt->sgl[0].size / BIT(data_type); + sg->fn = xt->numf; + sg->addr = xt->dst_start; + d->sglen = 1; + d->ccr = c->ccr; + + src_icg = dmaengine_get_src_icg(xt, &xt->sgl[0]); + dst_icg = dmaengine_get_dst_icg(xt, &xt->sgl[0]); + if (src_icg) { + d->ccr |= CCR_SRC_AMODE_DBLIDX; + d->ei = 1; + d->fi = src_icg; + } else if (xt->src_inc) { + d->ccr |= CCR_SRC_AMODE_POSTINC; + d->fi = 0; + } else { + dev_err(chan->device->dev, + "%s: SRC constant addressing is not supported\n", + __func__); + kfree(d); + return NULL; + } + + if (dst_icg) { + d->ccr |= CCR_DST_AMODE_DBLIDX; + sg->ei = 1; + sg->fi = dst_icg; + } else if (xt->dst_inc) { + d->ccr |= CCR_DST_AMODE_POSTINC; + sg->fi = 0; + } else { + dev_err(chan->device->dev, + "%s: DST constant addressing is not supported\n", + __func__); + kfree(d); + return NULL; + } + + d->cicr = CICR_DROP_IE | CICR_FRAME_IE; + + d->csdp = data_type; + + if (dma_omap1()) { + d->cicr |= CICR_TOUT_IE; + d->csdp |= CSDP_DST_PORT_EMIFF | CSDP_SRC_PORT_EMIFF; + } else { + d->csdp |= CSDP_DST_PACKED | CSDP_SRC_PACKED; + d->cicr |= CICR_MISALIGNED_ERR_IE | CICR_TRANS_ERR_IE; + d->csdp |= CSDP_DST_BURST_64 | CSDP_SRC_BURST_64; + } + + return vchan_tx_prep(&c->vc, &d->vd, flags); +} + static int omap_dma_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg) { struct omap_chan *c = to_omap_dma_chan(chan); @@ -1116,6 +1202,7 @@ static int omap_dma_probe(struct platform_device *pdev) dma_cap_set(DMA_SLAVE, od->ddev.cap_mask); dma_cap_set(DMA_CYCLIC, od->ddev.cap_mask); dma_cap_set(DMA_MEMCPY, od->ddev.cap_mask); + dma_cap_set(DMA_INTERLEAVE, od->ddev.cap_mask); od->ddev.device_alloc_chan_resources = omap_dma_alloc_chan_resources; od->ddev.device_free_chan_resources = omap_dma_free_chan_resources; od->ddev.device_tx_status = omap_dma_tx_status; @@ -1123,6 +1210,7 @@ static int omap_dma_probe(struct platform_device *pdev) od->ddev.device_prep_slave_sg = omap_dma_prep_slave_sg; od->ddev.device_prep_dma_cyclic = omap_dma_prep_dma_cyclic; od->ddev.device_prep_dma_memcpy = omap_dma_prep_dma_memcpy; + od->ddev.device_prep_interleaved_dma = omap_dma_prep_dma_interleaved; od->ddev.device_config = omap_dma_slave_config; od->ddev.device_pause = omap_dma_pause; od->ddev.device_resume = omap_dma_resume; @@ -1204,10 +1292,14 @@ static int omap_dma_probe(struct platform_device *pdev) static int omap_dma_remove(struct platform_device *pdev) { struct omap_dmadev *od = platform_get_drvdata(pdev); + int irq; if (pdev->dev.of_node) of_dma_controller_free(pdev->dev.of_node); + irq = platform_get_irq(pdev, 1); + devm_free_irq(&pdev->dev, irq, od); + dma_async_device_unregister(&od->ddev); if (!od->legacy) { diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 372b4359da97..4fc3ffbd5ca0 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -2828,10 +2828,8 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) /* Allocate a new DMAC and its Channels */ pl330 = devm_kzalloc(&adev->dev, sizeof(*pl330), GFP_KERNEL); - if (!pl330) { - dev_err(&adev->dev, "unable to allocate mem\n"); + if (!pl330) return -ENOMEM; - } pd = &pl330->ddma; pd->dev = &adev->dev; @@ -2890,7 +2888,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pl330->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); if (!pl330->peripherals) { ret = -ENOMEM; - dev_err(&adev->dev, "unable to allocate pl330->peripherals\n"); goto probe_err2; } @@ -3005,12 +3002,18 @@ static int pl330_remove(struct amba_device *adev) { struct pl330_dmac *pl330 = amba_get_drvdata(adev); struct dma_pl330_chan *pch, *_p; + int i, irq; pm_runtime_get_noresume(pl330->ddma.dev); if (adev->dev.of_node) of_dma_controller_free(adev->dev.of_node); + for (i = 0; i < AMBA_NR_IRQS; i++) { + irq = adev->irq[i]; + devm_free_irq(&adev->dev, irq, pl330); + } + dma_async_device_unregister(&pl330->ddma); /* Idle the DMAC */ diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 9217f893b0d1..da3688b94bdc 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -4084,7 +4084,6 @@ static int ppc440spe_adma_probe(struct platform_device *ofdev) /* create a device */ adev = kzalloc(sizeof(*adev), GFP_KERNEL); if (!adev) { - dev_err(&ofdev->dev, "failed to allocate device\n"); initcode = PPC_ADMA_INIT_ALLOC; ret = -ENOMEM; goto err_adev_alloc; @@ -4145,7 +4144,6 @@ static int ppc440spe_adma_probe(struct platform_device *ofdev) /* create a channel */ chan = kzalloc(sizeof(*chan), GFP_KERNEL); if (!chan) { - dev_err(&ofdev->dev, "can't allocate channel structure\n"); initcode = PPC_ADMA_INIT_CHANNEL; ret = -ENOMEM; goto err_chan_alloc; diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index e756a30ccba2..dc7850a422b8 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -21,6 +21,7 @@ #include <linux/of_device.h> #include <linux/of_dma.h> #include <linux/of.h> +#include <linux/wait.h> #include <linux/dma/pxa-dma.h> #include "dmaengine.h" @@ -118,6 +119,8 @@ struct pxad_chan { struct pxad_phy *phy; struct dma_pool *desc_pool; /* Descriptors pool */ dma_cookie_t bus_error; + + wait_queue_head_t wq_state; }; struct pxad_device { @@ -318,7 +321,6 @@ static int dbg_open_##name(struct inode *inode, struct file *file) \ return single_open(file, dbg_show_##name, inode->i_private); \ } \ static const struct file_operations dbg_fops_##name = { \ - .owner = THIS_MODULE, \ .open = dbg_open_##name, \ .llseek = seq_lseek, \ .read = seq_read, \ @@ -572,6 +574,7 @@ static void pxad_launch_chan(struct pxad_chan *chan, */ phy_writel(chan->phy, desc->first, DDADR); phy_enable(chan->phy, chan->misaligned); + wake_up(&chan->wq_state); } static void set_updater_desc(struct pxad_desc_sw *sw_desc, @@ -717,6 +720,7 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id) } } spin_unlock_irqrestore(&chan->vc.lock, flags); + wake_up(&chan->wq_state); return IRQ_HANDLED; } @@ -1268,6 +1272,14 @@ static enum dma_status pxad_tx_status(struct dma_chan *dchan, return ret; } +static void pxad_synchronize(struct dma_chan *dchan) +{ + struct pxad_chan *chan = to_pxad_chan(dchan); + + wait_event(chan->wq_state, !is_chan_running(chan)); + vchan_synchronize(&chan->vc); +} + static void pxad_free_channels(struct dma_device *dmadev) { struct pxad_chan *c, *cn; @@ -1372,6 +1384,7 @@ static int pxad_init_dmadev(struct platform_device *op, pdev->slave.device_tx_status = pxad_tx_status; pdev->slave.device_issue_pending = pxad_issue_pending; pdev->slave.device_config = pxad_config; + pdev->slave.device_synchronize = pxad_synchronize; pdev->slave.device_terminate_all = pxad_terminate_all; if (op->dev.coherent_dma_mask) @@ -1389,6 +1402,7 @@ static int pxad_init_dmadev(struct platform_device *op, return -ENOMEM; c->vc.desc_free = pxad_free_desc; vchan_init(&c->vc, &pdev->slave); + init_waitqueue_head(&c->wq_state); } return dma_async_device_register(&pdev->slave); diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index 969b48176745..03c4eb3fd314 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -48,6 +48,7 @@ #include <linux/of_dma.h> #include <linux/clk.h> #include <linux/dmaengine.h> +#include <linux/pm_runtime.h> #include "../dmaengine.h" #include "../virt-dma.h" @@ -58,6 +59,8 @@ struct bam_desc_hw { __le16 flags; }; +#define BAM_DMA_AUTOSUSPEND_DELAY 100 + #define DESC_FLAG_INT BIT(15) #define DESC_FLAG_EOT BIT(14) #define DESC_FLAG_EOB BIT(13) @@ -527,12 +530,17 @@ static void bam_free_chan(struct dma_chan *chan) struct bam_device *bdev = bchan->bdev; u32 val; unsigned long flags; + int ret; + + ret = pm_runtime_get_sync(bdev->dev); + if (ret < 0) + return; vchan_free_chan_resources(to_virt_chan(chan)); if (bchan->curr_txd) { dev_err(bchan->bdev->dev, "Cannot free busy channel\n"); - return; + goto err; } spin_lock_irqsave(&bchan->vc.lock, flags); @@ -550,6 +558,10 @@ static void bam_free_chan(struct dma_chan *chan) /* disable irq */ writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_IRQ_EN)); + +err: + pm_runtime_mark_last_busy(bdev->dev); + pm_runtime_put_autosuspend(bdev->dev); } /** @@ -696,11 +708,18 @@ static int bam_pause(struct dma_chan *chan) struct bam_chan *bchan = to_bam_chan(chan); struct bam_device *bdev = bchan->bdev; unsigned long flag; + int ret; + + ret = pm_runtime_get_sync(bdev->dev); + if (ret < 0) + return ret; spin_lock_irqsave(&bchan->vc.lock, flag); writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT)); bchan->paused = 1; spin_unlock_irqrestore(&bchan->vc.lock, flag); + pm_runtime_mark_last_busy(bdev->dev); + pm_runtime_put_autosuspend(bdev->dev); return 0; } @@ -715,11 +734,18 @@ static int bam_resume(struct dma_chan *chan) struct bam_chan *bchan = to_bam_chan(chan); struct bam_device *bdev = bchan->bdev; unsigned long flag; + int ret; + + ret = pm_runtime_get_sync(bdev->dev); + if (ret < 0) + return ret; spin_lock_irqsave(&bchan->vc.lock, flag); writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT)); bchan->paused = 0; spin_unlock_irqrestore(&bchan->vc.lock, flag); + pm_runtime_mark_last_busy(bdev->dev); + pm_runtime_put_autosuspend(bdev->dev); return 0; } @@ -795,6 +821,7 @@ static irqreturn_t bam_dma_irq(int irq, void *data) { struct bam_device *bdev = data; u32 clr_mask = 0, srcs = 0; + int ret; srcs |= process_channel_irqs(bdev); @@ -802,6 +829,10 @@ static irqreturn_t bam_dma_irq(int irq, void *data) if (srcs & P_IRQ) tasklet_schedule(&bdev->task); + ret = pm_runtime_get_sync(bdev->dev); + if (ret < 0) + return ret; + if (srcs & BAM_IRQ) { clr_mask = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_STTS)); @@ -814,6 +845,9 @@ static irqreturn_t bam_dma_irq(int irq, void *data) writel_relaxed(clr_mask, bam_addr(bdev, 0, BAM_IRQ_CLR)); } + pm_runtime_mark_last_busy(bdev->dev); + pm_runtime_put_autosuspend(bdev->dev); + return IRQ_HANDLED; } @@ -893,6 +927,7 @@ static void bam_start_dma(struct bam_chan *bchan) struct bam_desc_hw *desc; struct bam_desc_hw *fifo = PTR_ALIGN(bchan->fifo_virt, sizeof(struct bam_desc_hw)); + int ret; lockdep_assert_held(&bchan->vc.lock); @@ -904,6 +939,10 @@ static void bam_start_dma(struct bam_chan *bchan) async_desc = container_of(vd, struct bam_async_desc, vd); bchan->curr_txd = async_desc; + ret = pm_runtime_get_sync(bdev->dev); + if (ret < 0) + return; + /* on first use, initialize the channel hardware */ if (!bchan->initialized) bam_chan_init_hw(bchan, async_desc->dir); @@ -946,6 +985,9 @@ static void bam_start_dma(struct bam_chan *bchan) wmb(); writel_relaxed(bchan->tail * sizeof(struct bam_desc_hw), bam_addr(bdev, bchan->id, BAM_P_EVNT_REG)); + + pm_runtime_mark_last_busy(bdev->dev); + pm_runtime_put_autosuspend(bdev->dev); } /** @@ -970,6 +1012,7 @@ static void dma_tasklet(unsigned long data) bam_start_dma(bchan); spin_unlock_irqrestore(&bchan->vc.lock, flags); } + } /** @@ -1213,6 +1256,13 @@ static int bam_dma_probe(struct platform_device *pdev) if (ret) goto err_unregister_dma; + pm_runtime_irq_safe(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, BAM_DMA_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_mark_last_busy(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return 0; err_unregister_dma: @@ -1233,6 +1283,8 @@ static int bam_dma_remove(struct platform_device *pdev) struct bam_device *bdev = platform_get_drvdata(pdev); u32 i; + pm_runtime_force_suspend(&pdev->dev); + of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&bdev->common); @@ -1260,11 +1312,66 @@ static int bam_dma_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused bam_dma_runtime_suspend(struct device *dev) +{ + struct bam_device *bdev = dev_get_drvdata(dev); + + clk_disable(bdev->bamclk); + + return 0; +} + +static int __maybe_unused bam_dma_runtime_resume(struct device *dev) +{ + struct bam_device *bdev = dev_get_drvdata(dev); + int ret; + + ret = clk_enable(bdev->bamclk); + if (ret < 0) { + dev_err(dev, "clk_enable failed: %d\n", ret); + return ret; + } + + return 0; +} + +static int __maybe_unused bam_dma_suspend(struct device *dev) +{ + struct bam_device *bdev = dev_get_drvdata(dev); + + pm_runtime_force_suspend(dev); + + clk_unprepare(bdev->bamclk); + + return 0; +} + +static int __maybe_unused bam_dma_resume(struct device *dev) +{ + struct bam_device *bdev = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare(bdev->bamclk); + if (ret) + return ret; + + pm_runtime_force_resume(dev); + + return 0; +} + +static const struct dev_pm_ops bam_dma_pm_ops = { + SET_LATE_SYSTEM_SLEEP_PM_OPS(bam_dma_suspend, bam_dma_resume) + SET_RUNTIME_PM_OPS(bam_dma_runtime_suspend, bam_dma_runtime_resume, + NULL) +}; + static struct platform_driver bam_dma_driver = { .probe = bam_dma_probe, .remove = bam_dma_remove, .driver = { .name = "bam-dma-engine", + .pm = &bam_dma_pm_ops, .of_match_table = bam_of_match, }, }; diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c index 41b5c6dee713..b2374cd91e45 100644 --- a/drivers/dma/qcom/hidma.c +++ b/drivers/dma/qcom/hidma.c @@ -708,6 +708,7 @@ static int hidma_remove(struct platform_device *pdev) pm_runtime_get_sync(dmadev->ddev.dev); dma_async_device_unregister(&dmadev->ddev); devm_free_irq(dmadev->ddev.dev, dmadev->irq, dmadev->lldev); + tasklet_kill(&dmadev->task); hidma_debug_uninit(dmadev); hidma_ll_uninit(dmadev->lldev); hidma_free(dmadev); diff --git a/drivers/dma/qcom/hidma_ll.c b/drivers/dma/qcom/hidma_ll.c index f3929001539b..ad20dfb64c71 100644 --- a/drivers/dma/qcom/hidma_ll.c +++ b/drivers/dma/qcom/hidma_ll.c @@ -831,6 +831,7 @@ int hidma_ll_uninit(struct hidma_lldev *lldev) required_bytes = sizeof(struct hidma_tre) * lldev->nr_tres; tasklet_kill(&lldev->task); + tasklet_kill(&lldev->rst_task); memset(lldev->trepool, 0, required_bytes); lldev->trepool = NULL; lldev->pending_tre_count = 0; diff --git a/drivers/dma/qcom/hidma_mgmt.c b/drivers/dma/qcom/hidma_mgmt.c index c0e365321310..82f36e466083 100644 --- a/drivers/dma/qcom/hidma_mgmt.c +++ b/drivers/dma/qcom/hidma_mgmt.c @@ -371,8 +371,8 @@ static int __init hidma_mgmt_of_populate_channels(struct device_node *np) pdevinfo.size_data = 0; pdevinfo.dma_mask = DMA_BIT_MASK(64); new_pdev = platform_device_register_full(&pdevinfo); - if (!new_pdev) { - ret = -ENODEV; + if (IS_ERR(new_pdev)) { + ret = PTR_ERR(new_pdev); goto out; } of_dma_configure(&new_pdev->dev, child); @@ -392,8 +392,7 @@ static int __init hidma_mgmt_init(void) #if defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) struct device_node *child; - for (child = of_find_matching_node(NULL, hidma_mgmt_match); child; - child = of_find_matching_node(child, hidma_mgmt_match)) { + for_each_matching_node(child, hidma_mgmt_match) { /* device tree based firmware here */ hidma_mgmt_of_populate_channels(child); of_node_put(child); diff --git a/drivers/dma/s3c24xx-dma.c b/drivers/dma/s3c24xx-dma.c index 17ccdfd28f37..ce67075589f5 100644 --- a/drivers/dma/s3c24xx-dma.c +++ b/drivers/dma/s3c24xx-dma.c @@ -768,16 +768,12 @@ static enum dma_status s3c24xx_dma_tx_status(struct dma_chan *chan, spin_lock_irqsave(&s3cchan->vc.lock, flags); ret = dma_cookie_status(chan, cookie, txstate); - if (ret == DMA_COMPLETE) { - spin_unlock_irqrestore(&s3cchan->vc.lock, flags); - return ret; - } /* * There's no point calculating the residue if there's * no txstate to store the value. */ - if (!txstate) { + if (ret == DMA_COMPLETE || !txstate) { spin_unlock_irqrestore(&s3cchan->vc.lock, flags); return ret; } @@ -1105,11 +1101,8 @@ static int s3c24xx_dma_init_virtual_channels(struct s3c24xx_dma_engine *s3cdma, */ for (i = 0; i < channels; i++) { chan = devm_kzalloc(dmadev->dev, sizeof(*chan), GFP_KERNEL); - if (!chan) { - dev_err(dmadev->dev, - "%s no memory for channel\n", __func__); + if (!chan) return -ENOMEM; - } chan->id = i; chan->host = s3cdma; @@ -1143,8 +1136,10 @@ static void s3c24xx_dma_free_virtual_channels(struct dma_device *dmadev) struct s3c24xx_dma_chan *next; list_for_each_entry_safe(chan, - next, &dmadev->channels, vc.chan.device_node) + next, &dmadev->channels, vc.chan.device_node) { list_del(&chan->vc.chan.device_node); + tasklet_kill(&chan->vc.task); + } } /* s3c2410, s3c2440 and s3c2442 have a 0x40 stride without separate clocks */ @@ -1366,6 +1361,18 @@ err_memcpy: return ret; } +static void s3c24xx_dma_free_irq(struct platform_device *pdev, + struct s3c24xx_dma_engine *s3cdma) +{ + int i; + + for (i = 0; i < s3cdma->pdata->num_phy_channels; i++) { + struct s3c24xx_dma_phy *phy = &s3cdma->phy_chans[i]; + + devm_free_irq(&pdev->dev, phy->irq, phy); + } +} + static int s3c24xx_dma_remove(struct platform_device *pdev) { const struct s3c24xx_dma_platdata *pdata = dev_get_platdata(&pdev->dev); @@ -1376,6 +1383,8 @@ static int s3c24xx_dma_remove(struct platform_device *pdev) dma_async_device_unregister(&s3cdma->slave); dma_async_device_unregister(&s3cdma->memcpy); + s3c24xx_dma_free_irq(pdev, s3cdma); + s3c24xx_dma_free_virtual_channels(&s3cdma->slave); s3c24xx_dma_free_virtual_channels(&s3cdma->memcpy); diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index dfb17926297b..0dd953884d1d 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -311,7 +311,7 @@ static bool rcar_dmac_chan_is_busy(struct rcar_dmac_chan *chan) { u32 chcr = rcar_dmac_chan_read(chan, RCAR_DMACHCR); - return (chcr & (RCAR_DMACHCR_DE | RCAR_DMACHCR_TE)) == RCAR_DMACHCR_DE; + return !!(chcr & (RCAR_DMACHCR_DE | RCAR_DMACHCR_TE)); } static void rcar_dmac_chan_start_xfer(struct rcar_dmac_chan *chan) @@ -510,7 +510,7 @@ static void rcar_dmac_desc_put(struct rcar_dmac_chan *chan, spin_lock_irqsave(&chan->lock, flags); list_splice_tail_init(&desc->chunks, &chan->desc.chunks_free); - list_add_tail(&desc->node, &chan->desc.free); + list_add(&desc->node, &chan->desc.free); spin_unlock_irqrestore(&chan->lock, flags); } @@ -990,6 +990,8 @@ static void rcar_dmac_free_chan_resources(struct dma_chan *chan) list_splice_init(&rchan->desc.done, &list); list_splice_init(&rchan->desc.wait, &list); + rchan->desc.running = NULL; + list_for_each_entry(desc, &list, node) rcar_dmac_realloc_hwdesc(rchan, desc, 0); @@ -1143,6 +1145,7 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan, struct rcar_dmac_desc *desc = chan->desc.running; struct rcar_dmac_xfer_chunk *running = NULL; struct rcar_dmac_xfer_chunk *chunk; + enum dma_status status; unsigned int residue = 0; unsigned int dptr = 0; @@ -1150,12 +1153,38 @@ static unsigned int rcar_dmac_chan_get_residue(struct rcar_dmac_chan *chan, return 0; /* + * If the cookie corresponds to a descriptor that has been completed + * there is no residue. The same check has already been performed by the + * caller but without holding the channel lock, so the descriptor could + * now be complete. + */ + status = dma_cookie_status(&chan->chan, cookie, NULL); + if (status == DMA_COMPLETE) + return 0; + + /* * If the cookie doesn't correspond to the currently running transfer * then the descriptor hasn't been processed yet, and the residue is * equal to the full descriptor size. */ - if (cookie != desc->async_tx.cookie) - return desc->size; + if (cookie != desc->async_tx.cookie) { + list_for_each_entry(desc, &chan->desc.pending, node) { + if (cookie == desc->async_tx.cookie) + return desc->size; + } + list_for_each_entry(desc, &chan->desc.active, node) { + if (cookie == desc->async_tx.cookie) + return desc->size; + } + + /* + * No descriptor found for the cookie, there's thus no residue. + * This shouldn't happen if the calling driver passes a correct + * cookie value. + */ + WARN(1, "No descriptor for cookie!"); + return 0; + } /* * In descriptor mode the descriptor running pointer is not maintained @@ -1202,6 +1231,10 @@ static enum dma_status rcar_dmac_tx_status(struct dma_chan *chan, residue = rcar_dmac_chan_get_residue(rchan, cookie); spin_unlock_irqrestore(&rchan->lock, flags); + /* if there's no residue, the cookie is complete */ + if (!residue) + return DMA_COMPLETE; + dma_set_residue(txstate, residue); return status; diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c index 80d86402490e..c94ffab0d25c 100644 --- a/drivers/dma/sh/shdmac.c +++ b/drivers/dma/sh/shdmac.c @@ -532,11 +532,8 @@ static int sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, sh_chan = devm_kzalloc(sdev->dma_dev.dev, sizeof(struct sh_dmae_chan), GFP_KERNEL); - if (!sh_chan) { - dev_err(sdev->dma_dev.dev, - "No free memory for allocating dma channels!\n"); + if (!sh_chan) return -ENOMEM; - } schan = &sh_chan->shdma_chan; schan->max_xfer_len = SH_DMA_TCR_MAX + 1; @@ -732,10 +729,8 @@ static int sh_dmae_probe(struct platform_device *pdev) shdev = devm_kzalloc(&pdev->dev, sizeof(struct sh_dmae_device), GFP_KERNEL); - if (!shdev) { - dev_err(&pdev->dev, "Not enough memory\n"); + if (!shdev) return -ENOMEM; - } dma_dev = &shdev->shdma_dev.dma_dev; diff --git a/drivers/dma/sh/sudmac.c b/drivers/dma/sh/sudmac.c index 6da2eaa6c294..69b9564dc9d9 100644 --- a/drivers/dma/sh/sudmac.c +++ b/drivers/dma/sh/sudmac.c @@ -245,11 +245,8 @@ static int sudmac_chan_probe(struct sudmac_device *su_dev, int id, int irq, int err; sc = devm_kzalloc(&pdev->dev, sizeof(struct sudmac_chan), GFP_KERNEL); - if (!sc) { - dev_err(sdev->dma_dev.dev, - "No free memory for allocating dma channels!\n"); + if (!sc) return -ENOMEM; - } schan = &sc->shdma_chan; schan->max_xfer_len = 64 * 1024 * 1024 - 1; @@ -349,10 +346,8 @@ static int sudmac_probe(struct platform_device *pdev) err = -ENOMEM; su_dev = devm_kzalloc(&pdev->dev, sizeof(struct sudmac_device), GFP_KERNEL); - if (!su_dev) { - dev_err(&pdev->dev, "Not enough memory\n"); + if (!su_dev) return err; - } dma_dev = &su_dev->shdma_dev.dma_dev; diff --git a/drivers/dma/sirf-dma.c b/drivers/dma/sirf-dma.c index e48350e65089..d8bc3f2a71db 100644 --- a/drivers/dma/sirf-dma.c +++ b/drivers/dma/sirf-dma.c @@ -854,10 +854,9 @@ static int sirfsoc_dma_probe(struct platform_device *op) int ret, i; sdma = devm_kzalloc(dev, sizeof(*sdma), GFP_KERNEL); - if (!sdma) { - dev_err(dev, "Memory exhausted!\n"); + if (!sdma) return -ENOMEM; - } + data = (struct sirfsoc_dmadata *) (of_match_device(op->dev.driver->of_match_table, &op->dev)->data); @@ -981,6 +980,7 @@ static int sirfsoc_dma_remove(struct platform_device *op) of_dma_controller_free(op->dev.of_node); dma_async_device_unregister(&sdma->dma); free_irq(sdma->irq, sdma); + tasklet_kill(&sdma->tasklet); irq_dispose_mapping(sdma->irq); pm_runtime_disable(&op->dev); if (!pm_runtime_status_suspended(&op->dev)) @@ -1126,17 +1126,17 @@ static const struct dev_pm_ops sirfsoc_dma_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(sirfsoc_dma_pm_suspend, sirfsoc_dma_pm_resume) }; -struct sirfsoc_dmadata sirfsoc_dmadata_a6 = { +static struct sirfsoc_dmadata sirfsoc_dmadata_a6 = { .exec = sirfsoc_dma_execute_hw_a6, .type = SIRFSOC_DMA_VER_A6, }; -struct sirfsoc_dmadata sirfsoc_dmadata_a7v1 = { +static struct sirfsoc_dmadata sirfsoc_dmadata_a7v1 = { .exec = sirfsoc_dma_execute_hw_a7v1, .type = SIRFSOC_DMA_VER_A7V1, }; -struct sirfsoc_dmadata sirfsoc_dmadata_a7v2 = { +static struct sirfsoc_dmadata sirfsoc_dmadata_a7v2 = { .exec = sirfsoc_dma_execute_hw_a7v2, .type = SIRFSOC_DMA_VER_A7V2, }; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index 6fb8307468ab..8b18e44a02d5 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -2588,7 +2588,7 @@ static enum dma_status d40_tx_status(struct dma_chan *chan, } ret = dma_cookie_status(chan, cookie, txstate); - if (ret != DMA_COMPLETE) + if (ret != DMA_COMPLETE && txstate) dma_set_residue(txstate, stedma40_residue(chan)); if (d40_is_paused(d40c)) @@ -3237,10 +3237,8 @@ static struct d40_base * __init d40_hw_detect_init(struct platform_device *pdev) (num_phy_chans + num_log_chans + num_memcpy_chans) * sizeof(struct d40_chan), GFP_KERNEL); - if (base == NULL) { - d40_err(&pdev->dev, "Out of memory\n"); + if (base == NULL) goto failure; - } base->rev = rev; base->clk = clk; diff --git a/drivers/dma/ste_dma40_ll.c b/drivers/dma/ste_dma40_ll.c index 27b818dee7c7..13b42dd9900c 100644 --- a/drivers/dma/ste_dma40_ll.c +++ b/drivers/dma/ste_dma40_ll.c @@ -10,7 +10,7 @@ #include "ste_dma40_ll.h" -u8 d40_width_to_bits(enum dma_slave_buswidth width) +static u8 d40_width_to_bits(enum dma_slave_buswidth width) { if (width == DMA_SLAVE_BUSWIDTH_1_BYTE) return STEDMA40_ESIZE_8_BIT; diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index 5065ca43face..3835fcde3545 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c @@ -865,7 +865,7 @@ static enum dma_status sun6i_dma_tx_status(struct dma_chan *chan, size_t bytes = 0; ret = dma_cookie_status(chan, cookie, state); - if (ret == DMA_COMPLETE) + if (ret == DMA_COMPLETE || !state) return ret; spin_lock_irqsave(&vchan->vc.lock, flags); diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 01e316f73559..6ab9eb98588a 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -300,10 +300,8 @@ static struct tegra_dma_desc *tegra_dma_desc_get( /* Allocate DMA desc */ dma_desc = kzalloc(sizeof(*dma_desc), GFP_NOWAIT); - if (!dma_desc) { - dev_err(tdc2dev(tdc), "dma_desc alloc failed\n"); + if (!dma_desc) return NULL; - } dma_async_tx_descriptor_init(&dma_desc->txd, &tdc->dma_chan); dma_desc->txd.tx_submit = tegra_dma_tx_submit; @@ -340,8 +338,7 @@ static struct tegra_dma_sg_req *tegra_dma_sg_req_get( spin_unlock_irqrestore(&tdc->lock, flags); sg_req = kzalloc(sizeof(struct tegra_dma_sg_req), GFP_NOWAIT); - if (!sg_req) - dev_err(tdc2dev(tdc), "sg_req alloc failed\n"); + return sg_req; } @@ -484,7 +481,7 @@ static void tegra_dma_configure_for_next(struct tegra_dma_channel *tdc, * load new configuration. */ tegra_dma_pause(tdc, false); - status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS); + status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS); /* * If interrupt is pending then do nothing as the ISR will handle @@ -822,13 +819,8 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc, /* Check on wait_ack desc status */ list_for_each_entry(dma_desc, &tdc->free_dma_desc, node) { if (dma_desc->txd.cookie == cookie) { - residual = dma_desc->bytes_requested - - (dma_desc->bytes_transferred % - dma_desc->bytes_requested); - dma_set_residue(txstate, residual); ret = dma_desc->dma_status; - spin_unlock_irqrestore(&tdc->lock, flags); - return ret; + goto found; } } @@ -836,17 +828,22 @@ static enum dma_status tegra_dma_tx_status(struct dma_chan *dc, list_for_each_entry(sg_req, &tdc->pending_sg_req, node) { dma_desc = sg_req->dma_desc; if (dma_desc->txd.cookie == cookie) { - residual = dma_desc->bytes_requested - - (dma_desc->bytes_transferred % - dma_desc->bytes_requested); - dma_set_residue(txstate, residual); ret = dma_desc->dma_status; - spin_unlock_irqrestore(&tdc->lock, flags); - return ret; + goto found; } } - dev_dbg(tdc2dev(tdc), "cookie %d does not found\n", cookie); + dev_dbg(tdc2dev(tdc), "cookie %d not found\n", cookie); + dma_desc = NULL; + +found: + if (dma_desc && txstate) { + residual = dma_desc->bytes_requested - + (dma_desc->bytes_transferred % + dma_desc->bytes_requested); + dma_set_residue(txstate, residual); + } + spin_unlock_irqrestore(&tdc->lock, flags); return ret; } @@ -905,7 +902,6 @@ static int get_transfer_param(struct tegra_dma_channel *tdc, unsigned long *apb_seq, unsigned long *csr, unsigned int *burst_size, enum dma_slave_buswidth *slave_bw) { - switch (direction) { case DMA_MEM_TO_DEV: *apb_addr = tdc->dma_sconfig.dst_addr; @@ -948,8 +944,8 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_slave_sg( { struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); struct tegra_dma_desc *dma_desc; - unsigned int i; - struct scatterlist *sg; + unsigned int i; + struct scatterlist *sg; unsigned long csr, ahb_seq, apb_ptr, apb_seq; struct list_head req_list; struct tegra_dma_sg_req *sg_req = NULL; @@ -1062,7 +1058,7 @@ static struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( { struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); struct tegra_dma_desc *dma_desc = NULL; - struct tegra_dma_sg_req *sg_req = NULL; + struct tegra_dma_sg_req *sg_req = NULL; unsigned long csr, ahb_seq, apb_ptr, apb_seq; int len; size_t remain_len; @@ -1204,7 +1200,6 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) { struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); struct tegra_dma *tdma = tdc->tdma; - struct tegra_dma_desc *dma_desc; struct tegra_dma_sg_req *sg_req; struct list_head dma_desc_list; @@ -1305,7 +1300,7 @@ static const struct tegra_dma_chip_data tegra148_dma_chip_data = { static int tegra_dma_probe(struct platform_device *pdev) { - struct resource *res; + struct resource *res; struct tegra_dma *tdma; int ret; int i; @@ -1319,10 +1314,8 @@ static int tegra_dma_probe(struct platform_device *pdev) tdma = devm_kzalloc(&pdev->dev, sizeof(*tdma) + cdata->nr_channels * sizeof(struct tegra_dma_channel), GFP_KERNEL); - if (!tdma) { - dev_err(&pdev->dev, "Error: memory allocation failed\n"); + if (!tdma) return -ENOMEM; - } tdma->dev = &pdev->dev; tdma->chip_data = cdata; diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c index e107779b1a2e..5ae294b256a7 100644 --- a/drivers/dma/ti-dma-crossbar.c +++ b/drivers/dma/ti-dma-crossbar.c @@ -452,7 +452,7 @@ static struct platform_driver ti_dma_xbar_driver = { .probe = ti_dma_xbar_probe, }; -int omap_dmaxbar_init(void) +static int omap_dmaxbar_init(void) { return platform_driver_register(&ti_dma_xbar_driver); } diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index 559cd4073698..e82745aa42a8 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -337,18 +337,14 @@ static struct timb_dma_desc *td_alloc_init_desc(struct timb_dma_chan *td_chan) int err; td_desc = kzalloc(sizeof(struct timb_dma_desc), GFP_KERNEL); - if (!td_desc) { - dev_err(chan2dev(chan), "Failed to alloc descriptor\n"); + if (!td_desc) goto out; - } td_desc->desc_list_len = td_chan->desc_elems * TIMB_DMA_DESC_SIZE; td_desc->desc_list = kzalloc(td_desc->desc_list_len, GFP_KERNEL); - if (!td_desc->desc_list) { - dev_err(chan2dev(chan), "Failed to alloc descriptor\n"); + if (!td_desc->desc_list) goto err; - } dma_async_tx_descriptor_init(&td_desc->txd, chan); td_desc->txd.tx_submit = td_tx_submit; diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 8849318b32b7..7632290e7c14 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -1165,9 +1165,12 @@ static int txx9dmac_chan_remove(struct platform_device *pdev) { struct txx9dmac_chan *dc = platform_get_drvdata(pdev); + dma_async_device_unregister(&dc->dma); - if (dc->irq >= 0) + if (dc->irq >= 0) { + devm_free_irq(&pdev->dev, dc->irq, dc); tasklet_kill(&dc->tasklet); + } dc->ddev->chan[pdev->id % TXX9_DMA_MAX_NR_CHANNELS] = NULL; return 0; } @@ -1228,8 +1231,10 @@ static int txx9dmac_remove(struct platform_device *pdev) struct txx9dmac_dev *ddev = platform_get_drvdata(pdev); txx9dmac_off(ddev); - if (ddev->irq >= 0) + if (ddev->irq >= 0) { + devm_free_irq(&pdev->dev, ddev->irq, ddev); tasklet_kill(&ddev->tasklet); + } return 0; } diff --git a/drivers/dma/xilinx/Makefile b/drivers/dma/xilinx/Makefile index 3c4e9f2fea28..9e91f8f5b087 100644 --- a/drivers/dma/xilinx/Makefile +++ b/drivers/dma/xilinx/Makefile @@ -1 +1,2 @@ -obj-$(CONFIG_XILINX_VDMA) += xilinx_vdma.o +obj-$(CONFIG_XILINX_DMA) += xilinx_dma.o +obj-$(CONFIG_XILINX_ZYNQMP_DMA) += zynqmp_dma.o diff --git a/drivers/dma/xilinx/xilinx_vdma.c b/drivers/dma/xilinx/xilinx_dma.c index df9118540b91..4e223d094433 100644 --- a/drivers/dma/xilinx/xilinx_vdma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -45,6 +45,7 @@ #include <linux/of_irq.h> #include <linux/slab.h> #include <linux/clk.h> +#include <linux/io-64-nonatomic-lo-hi.h> #include "../dmaengine.h" @@ -113,7 +114,7 @@ #define XILINX_VDMA_REG_START_ADDRESS_64(n) (0x000c + 8 * (n)) /* HW specific definitions */ -#define XILINX_DMA_MAX_CHANS_PER_DEVICE 0x2 +#define XILINX_DMA_MAX_CHANS_PER_DEVICE 0x20 #define XILINX_DMA_DMAXR_ALL_IRQ_MASK \ (XILINX_DMA_DMASR_FRM_CNT_IRQ | \ @@ -157,12 +158,25 @@ /* AXI DMA Specific Masks/Bit fields */ #define XILINX_DMA_MAX_TRANS_LEN GENMASK(22, 0) #define XILINX_DMA_CR_COALESCE_MAX GENMASK(23, 16) +#define XILINX_DMA_CR_CYCLIC_BD_EN_MASK BIT(4) #define XILINX_DMA_CR_COALESCE_SHIFT 16 #define XILINX_DMA_BD_SOP BIT(27) #define XILINX_DMA_BD_EOP BIT(26) #define XILINX_DMA_COALESCE_MAX 255 #define XILINX_DMA_NUM_APP_WORDS 5 +/* Multi-Channel DMA Descriptor offsets*/ +#define XILINX_DMA_MCRX_CDESC(x) (0x40 + (x-1) * 0x20) +#define XILINX_DMA_MCRX_TDESC(x) (0x48 + (x-1) * 0x20) + +/* Multi-Channel DMA Masks/Shifts */ +#define XILINX_DMA_BD_HSIZE_MASK GENMASK(15, 0) +#define XILINX_DMA_BD_STRIDE_MASK GENMASK(15, 0) +#define XILINX_DMA_BD_VSIZE_MASK GENMASK(31, 19) +#define XILINX_DMA_BD_TDEST_MASK GENMASK(4, 0) +#define XILINX_DMA_BD_STRIDE_SHIFT 0 +#define XILINX_DMA_BD_VSIZE_SHIFT 19 + /* AXI CDMA Specific Registers/Offsets */ #define XILINX_CDMA_REG_SRCADDR 0x18 #define XILINX_CDMA_REG_DSTADDR 0x20 @@ -194,22 +208,22 @@ struct xilinx_vdma_desc_hw { /** * struct xilinx_axidma_desc_hw - Hardware Descriptor for AXI DMA * @next_desc: Next Descriptor Pointer @0x00 - * @pad1: Reserved @0x04 + * @next_desc_msb: MSB of Next Descriptor Pointer @0x04 * @buf_addr: Buffer address @0x08 - * @pad2: Reserved @0x0C - * @pad3: Reserved @0x10 - * @pad4: Reserved @0x14 + * @buf_addr_msb: MSB of Buffer address @0x0C + * @pad1: Reserved @0x10 + * @pad2: Reserved @0x14 * @control: Control field @0x18 * @status: Status field @0x1C * @app: APP Fields @0x20 - 0x30 */ struct xilinx_axidma_desc_hw { u32 next_desc; - u32 pad1; + u32 next_desc_msb; u32 buf_addr; - u32 pad2; - u32 pad3; - u32 pad4; + u32 buf_addr_msb; + u32 mcdma_control; + u32 vsize_stride; u32 control; u32 status; u32 app[XILINX_DMA_NUM_APP_WORDS]; @@ -218,21 +232,21 @@ struct xilinx_axidma_desc_hw { /** * struct xilinx_cdma_desc_hw - Hardware Descriptor * @next_desc: Next Descriptor Pointer @0x00 - * @pad1: Reserved @0x04 + * @next_descmsb: Next Descriptor Pointer MSB @0x04 * @src_addr: Source address @0x08 - * @pad2: Reserved @0x0C + * @src_addrmsb: Source address MSB @0x0C * @dest_addr: Destination address @0x10 - * @pad3: Reserved @0x14 + * @dest_addrmsb: Destination address MSB @0x14 * @control: Control field @0x18 * @status: Status field @0x1C */ struct xilinx_cdma_desc_hw { u32 next_desc; - u32 pad1; + u32 next_desc_msb; u32 src_addr; - u32 pad2; + u32 src_addr_msb; u32 dest_addr; - u32 pad3; + u32 dest_addr_msb; u32 control; u32 status; } __aligned(64); @@ -278,11 +292,13 @@ struct xilinx_cdma_tx_segment { * @async_tx: Async transaction descriptor * @segments: TX segments list * @node: Node in the channel descriptors list + * @cyclic: Check for cyclic transfers. */ struct xilinx_dma_tx_descriptor { struct dma_async_tx_descriptor async_tx; struct list_head segments; struct list_head node; + bool cyclic; }; /** @@ -302,6 +318,7 @@ struct xilinx_dma_tx_descriptor { * @direction: Transfer direction * @num_frms: Number of frames * @has_sg: Support scatter transfers + * @cyclic: Check for cyclic transfers. * @genlock: Support genlock mode * @err: Channel has errors * @tasklet: Cleanup work after irq @@ -312,6 +329,7 @@ struct xilinx_dma_tx_descriptor { * @desc_submitcount: Descriptor h/w submitted count * @residue: Residue for AXI DMA * @seg_v: Statically allocated segments base + * @cyclic_seg_v: Statically allocated segment base for cyclic transfers * @start_transfer: Differentiate b/w DMA IP's transfer */ struct xilinx_dma_chan { @@ -330,6 +348,7 @@ struct xilinx_dma_chan { enum dma_transfer_direction direction; int num_frms; bool has_sg; + bool cyclic; bool genlock; bool err; struct tasklet_struct tasklet; @@ -340,7 +359,9 @@ struct xilinx_dma_chan { u32 desc_submitcount; u32 residue; struct xilinx_axidma_tx_segment *seg_v; + struct xilinx_axidma_tx_segment *cyclic_seg_v; void (*start_transfer)(struct xilinx_dma_chan *chan); + u16 tdest; }; struct xilinx_dma_config { @@ -357,6 +378,7 @@ struct xilinx_dma_config { * @common: DMA device structure * @chan: Driver specific DMA channel * @has_sg: Specifies whether Scatter-Gather is present or not + * @mcdma: Specifies whether Multi-Channel is present or not * @flush_on_fsync: Flush on frame sync * @ext_addr: Indicates 64 bit addressing is supported by dma device * @pdev: Platform device structure pointer @@ -366,6 +388,8 @@ struct xilinx_dma_config { * @txs_clk: DMA mm2s stream clock * @rx_clk: DMA s2mm clock * @rxs_clk: DMA s2mm stream clock + * @nr_channels: Number of channels DMA device supports + * @chan_id: DMA channel identifier */ struct xilinx_dma_device { void __iomem *regs; @@ -373,6 +397,7 @@ struct xilinx_dma_device { struct dma_device common; struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE]; bool has_sg; + bool mcdma; u32 flush_on_fsync; bool ext_addr; struct platform_device *pdev; @@ -382,6 +407,8 @@ struct xilinx_dma_device { struct clk *txs_clk; struct clk *rx_clk; struct clk *rxs_clk; + u32 nr_channels; + u32 chan_id; }; /* Macros */ @@ -454,6 +481,34 @@ static inline void vdma_desc_write_64(struct xilinx_dma_chan *chan, u32 reg, writel(value_msb, chan->xdev->regs + chan->desc_offset + reg + 4); } +static inline void dma_writeq(struct xilinx_dma_chan *chan, u32 reg, u64 value) +{ + lo_hi_writeq(value, chan->xdev->regs + chan->ctrl_offset + reg); +} + +static inline void xilinx_write(struct xilinx_dma_chan *chan, u32 reg, + dma_addr_t addr) +{ + if (chan->ext_addr) + dma_writeq(chan, reg, addr); + else + dma_ctrl_write(chan, reg, addr); +} + +static inline void xilinx_axidma_buf(struct xilinx_dma_chan *chan, + struct xilinx_axidma_desc_hw *hw, + dma_addr_t buf_addr, size_t sg_used, + size_t period_len) +{ + if (chan->ext_addr) { + hw->buf_addr = lower_32_bits(buf_addr + sg_used + period_len); + hw->buf_addr_msb = upper_32_bits(buf_addr + sg_used + + period_len); + } else { + hw->buf_addr = buf_addr + sg_used + period_len; + } +} + /* ----------------------------------------------------------------------------- * Descriptors and segments alloc and free */ @@ -491,11 +546,10 @@ xilinx_cdma_alloc_tx_segment(struct xilinx_dma_chan *chan) struct xilinx_cdma_tx_segment *segment; dma_addr_t phys; - segment = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &phys); + segment = dma_pool_zalloc(chan->desc_pool, GFP_ATOMIC, &phys); if (!segment) return NULL; - memset(segment, 0, sizeof(*segment)); segment->phys = phys; return segment; @@ -513,11 +567,10 @@ xilinx_axidma_alloc_tx_segment(struct xilinx_dma_chan *chan) struct xilinx_axidma_tx_segment *segment; dma_addr_t phys; - segment = dma_pool_alloc(chan->desc_pool, GFP_ATOMIC, &phys); + segment = dma_pool_zalloc(chan->desc_pool, GFP_ATOMIC, &phys); if (!segment) return NULL; - memset(segment, 0, sizeof(*segment)); segment->phys = phys; return segment; @@ -660,13 +713,37 @@ static void xilinx_dma_free_chan_resources(struct dma_chan *dchan) dev_dbg(chan->dev, "Free all channel resources.\n"); xilinx_dma_free_descriptors(chan); - if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) + if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { + xilinx_dma_free_tx_segment(chan, chan->cyclic_seg_v); xilinx_dma_free_tx_segment(chan, chan->seg_v); + } dma_pool_destroy(chan->desc_pool); chan->desc_pool = NULL; } /** + * xilinx_dma_chan_handle_cyclic - Cyclic dma callback + * @chan: Driver specific dma channel + * @desc: dma transaction descriptor + * @flags: flags for spin lock + */ +static void xilinx_dma_chan_handle_cyclic(struct xilinx_dma_chan *chan, + struct xilinx_dma_tx_descriptor *desc, + unsigned long *flags) +{ + dma_async_tx_callback callback; + void *callback_param; + + callback = desc->async_tx.callback; + callback_param = desc->async_tx.callback_param; + if (callback) { + spin_unlock_irqrestore(&chan->lock, *flags); + callback(callback_param); + spin_lock_irqsave(&chan->lock, *flags); + } +} + +/** * xilinx_dma_chan_desc_cleanup - Clean channel descriptors * @chan: Driver specific DMA channel */ @@ -681,6 +758,11 @@ static void xilinx_dma_chan_desc_cleanup(struct xilinx_dma_chan *chan) dma_async_tx_callback callback; void *callback_param; + if (desc->cyclic) { + xilinx_dma_chan_handle_cyclic(chan, desc, &flags); + break; + } + /* Remove from the list of running transactions */ list_del(&desc->node); @@ -757,7 +839,7 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) return -ENOMEM; } - if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) + if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { /* * For AXI DMA case after submitting a pending_list, keep * an extra segment allocated so that the "next descriptor" @@ -768,6 +850,15 @@ static int xilinx_dma_alloc_chan_resources(struct dma_chan *dchan) */ chan->seg_v = xilinx_axidma_alloc_tx_segment(chan); + /* + * For cyclic DMA mode we need to program the tail Descriptor + * register with a value which is not a part of the BD chain + * so allocating a desc segment during channel allocation for + * programming tail descriptor. + */ + chan->cyclic_seg_v = xilinx_axidma_alloc_tx_segment(chan); + } + dma_cookie_init(dchan); if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { @@ -1065,12 +1156,12 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) } if (chan->has_sg) { - dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC, - head_desc->async_tx.phys); + xilinx_write(chan, XILINX_DMA_REG_CURDESC, + head_desc->async_tx.phys); /* Update tail ptr register which will start the transfer */ - dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC, - tail_segment->phys); + xilinx_write(chan, XILINX_DMA_REG_TAILDESC, + tail_segment->phys); } else { /* In simple mode */ struct xilinx_cdma_tx_segment *segment; @@ -1082,8 +1173,8 @@ static void xilinx_cdma_start_transfer(struct xilinx_dma_chan *chan) hw = &segment->hw; - dma_ctrl_write(chan, XILINX_CDMA_REG_SRCADDR, hw->src_addr); - dma_ctrl_write(chan, XILINX_CDMA_REG_DSTADDR, hw->dest_addr); + xilinx_write(chan, XILINX_CDMA_REG_SRCADDR, hw->src_addr); + xilinx_write(chan, XILINX_CDMA_REG_DSTADDR, hw->dest_addr); /* Start the transfer */ dma_ctrl_write(chan, XILINX_DMA_REG_BTT, @@ -1124,18 +1215,20 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) tail_segment = list_last_entry(&tail_desc->segments, struct xilinx_axidma_tx_segment, node); - old_head = list_first_entry(&head_desc->segments, - struct xilinx_axidma_tx_segment, node); - new_head = chan->seg_v; - /* Copy Buffer Descriptor fields. */ - new_head->hw = old_head->hw; + if (chan->has_sg && !chan->xdev->mcdma) { + old_head = list_first_entry(&head_desc->segments, + struct xilinx_axidma_tx_segment, node); + new_head = chan->seg_v; + /* Copy Buffer Descriptor fields. */ + new_head->hw = old_head->hw; - /* Swap and save new reserve */ - list_replace_init(&old_head->node, &new_head->node); - chan->seg_v = old_head; + /* Swap and save new reserve */ + list_replace_init(&old_head->node, &new_head->node); + chan->seg_v = old_head; - tail_segment->hw.next_desc = chan->seg_v->phys; - head_desc->async_tx.phys = new_head->phys; + tail_segment->hw.next_desc = chan->seg_v->phys; + head_desc->async_tx.phys = new_head->phys; + } reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR); @@ -1146,9 +1239,25 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) dma_ctrl_write(chan, XILINX_DMA_REG_DMACR, reg); } - if (chan->has_sg) - dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC, - head_desc->async_tx.phys); + if (chan->has_sg && !chan->xdev->mcdma) + xilinx_write(chan, XILINX_DMA_REG_CURDESC, + head_desc->async_tx.phys); + + if (chan->has_sg && chan->xdev->mcdma) { + if (chan->direction == DMA_MEM_TO_DEV) { + dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC, + head_desc->async_tx.phys); + } else { + if (!chan->tdest) { + dma_ctrl_write(chan, XILINX_DMA_REG_CURDESC, + head_desc->async_tx.phys); + } else { + dma_ctrl_write(chan, + XILINX_DMA_MCRX_CDESC(chan->tdest), + head_desc->async_tx.phys); + } + } + } xilinx_dma_start(chan); @@ -1156,9 +1265,27 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) return; /* Start the transfer */ - if (chan->has_sg) { - dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC, + if (chan->has_sg && !chan->xdev->mcdma) { + if (chan->cyclic) + xilinx_write(chan, XILINX_DMA_REG_TAILDESC, + chan->cyclic_seg_v->phys); + else + xilinx_write(chan, XILINX_DMA_REG_TAILDESC, + tail_segment->phys); + } else if (chan->has_sg && chan->xdev->mcdma) { + if (chan->direction == DMA_MEM_TO_DEV) { + dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC, tail_segment->phys); + } else { + if (!chan->tdest) { + dma_ctrl_write(chan, XILINX_DMA_REG_TAILDESC, + tail_segment->phys); + } else { + dma_ctrl_write(chan, + XILINX_DMA_MCRX_TDESC(chan->tdest), + tail_segment->phys); + } + } } else { struct xilinx_axidma_tx_segment *segment; struct xilinx_axidma_desc_hw *hw; @@ -1168,7 +1295,7 @@ static void xilinx_dma_start_transfer(struct xilinx_dma_chan *chan) node); hw = &segment->hw; - dma_ctrl_write(chan, XILINX_DMA_REG_SRCDSTADDR, hw->buf_addr); + xilinx_write(chan, XILINX_DMA_REG_SRCDSTADDR, hw->buf_addr); /* Start the transfer */ dma_ctrl_write(chan, XILINX_DMA_REG_BTT, @@ -1209,7 +1336,8 @@ static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan) list_for_each_entry_safe(desc, next, &chan->active_list, node) { list_del(&desc->node); - dma_cookie_complete(&desc->async_tx); + if (!desc->cyclic) + dma_cookie_complete(&desc->async_tx); list_add_tail(&desc->node, &chan->done_list); } } @@ -1397,6 +1525,11 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx) unsigned long flags; int err; + if (chan->cyclic) { + xilinx_dma_free_tx_descriptor(chan, desc); + return -EBUSY; + } + if (chan->err) { /* * If reset fails, need to hard reset the system. @@ -1414,6 +1547,9 @@ static dma_cookie_t xilinx_dma_tx_submit(struct dma_async_tx_descriptor *tx) /* Put this transaction onto the tail of the pending queue */ append_desc_queue(chan, desc); + if (desc->cyclic) + chan->cyclic = true; + spin_unlock_irqrestore(&chan->lock, flags); return cookie; @@ -1541,6 +1677,10 @@ xilinx_cdma_prep_memcpy(struct dma_chan *dchan, dma_addr_t dma_dst, hw->control = len; hw->src_addr = dma_src; hw->dest_addr = dma_dst; + if (chan->ext_addr) { + hw->src_addr_msb = upper_32_bits(dma_src); + hw->dest_addr_msb = upper_32_bits(dma_dst); + } /* Fill the previous next descriptor with current */ prev = list_last_entry(&desc->segments, @@ -1623,7 +1763,8 @@ static struct dma_async_tx_descriptor *xilinx_dma_prep_slave_sg( hw = &segment->hw; /* Fill in the descriptor */ - hw->buf_addr = sg_dma_address(sg) + sg_used; + xilinx_axidma_buf(chan, hw, sg_dma_address(sg), + sg_used, 0); hw->control = copy; @@ -1669,12 +1810,204 @@ error: } /** + * xilinx_dma_prep_dma_cyclic - prepare descriptors for a DMA_SLAVE transaction + * @chan: DMA channel + * @sgl: scatterlist to transfer to/from + * @sg_len: number of entries in @scatterlist + * @direction: DMA direction + * @flags: transfer ack flags + */ +static struct dma_async_tx_descriptor *xilinx_dma_prep_dma_cyclic( + struct dma_chan *dchan, dma_addr_t buf_addr, size_t buf_len, + size_t period_len, enum dma_transfer_direction direction, + unsigned long flags) +{ + struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); + struct xilinx_dma_tx_descriptor *desc; + struct xilinx_axidma_tx_segment *segment, *head_segment, *prev = NULL; + size_t copy, sg_used; + unsigned int num_periods; + int i; + u32 reg; + + if (!period_len) + return NULL; + + num_periods = buf_len / period_len; + + if (!num_periods) + return NULL; + + if (!is_slave_direction(direction)) + return NULL; + + /* Allocate a transaction descriptor. */ + desc = xilinx_dma_alloc_tx_descriptor(chan); + if (!desc) + return NULL; + + chan->direction = direction; + dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); + desc->async_tx.tx_submit = xilinx_dma_tx_submit; + + for (i = 0; i < num_periods; ++i) { + sg_used = 0; + + while (sg_used < period_len) { + struct xilinx_axidma_desc_hw *hw; + + /* Get a free segment */ + segment = xilinx_axidma_alloc_tx_segment(chan); + if (!segment) + goto error; + + /* + * Calculate the maximum number of bytes to transfer, + * making sure it is less than the hw limit + */ + copy = min_t(size_t, period_len - sg_used, + XILINX_DMA_MAX_TRANS_LEN); + hw = &segment->hw; + xilinx_axidma_buf(chan, hw, buf_addr, sg_used, + period_len * i); + hw->control = copy; + + if (prev) + prev->hw.next_desc = segment->phys; + + prev = segment; + sg_used += copy; + + /* + * Insert the segment into the descriptor segments + * list. + */ + list_add_tail(&segment->node, &desc->segments); + } + } + + head_segment = list_first_entry(&desc->segments, + struct xilinx_axidma_tx_segment, node); + desc->async_tx.phys = head_segment->phys; + + desc->cyclic = true; + reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR); + reg |= XILINX_DMA_CR_CYCLIC_BD_EN_MASK; + dma_ctrl_write(chan, XILINX_DMA_REG_DMACR, reg); + + segment = list_last_entry(&desc->segments, + struct xilinx_axidma_tx_segment, + node); + segment->hw.next_desc = (u32) head_segment->phys; + + /* For the last DMA_MEM_TO_DEV transfer, set EOP */ + if (direction == DMA_MEM_TO_DEV) { + head_segment->hw.control |= XILINX_DMA_BD_SOP; + segment->hw.control |= XILINX_DMA_BD_EOP; + } + + return &desc->async_tx; + +error: + xilinx_dma_free_tx_descriptor(chan, desc); + return NULL; +} + +/** + * xilinx_dma_prep_interleaved - prepare a descriptor for a + * DMA_SLAVE transaction + * @dchan: DMA channel + * @xt: Interleaved template pointer + * @flags: transfer ack flags + * + * Return: Async transaction descriptor on success and NULL on failure + */ +static struct dma_async_tx_descriptor * +xilinx_dma_prep_interleaved(struct dma_chan *dchan, + struct dma_interleaved_template *xt, + unsigned long flags) +{ + struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); + struct xilinx_dma_tx_descriptor *desc; + struct xilinx_axidma_tx_segment *segment; + struct xilinx_axidma_desc_hw *hw; + + if (!is_slave_direction(xt->dir)) + return NULL; + + if (!xt->numf || !xt->sgl[0].size) + return NULL; + + if (xt->frame_size != 1) + return NULL; + + /* Allocate a transaction descriptor. */ + desc = xilinx_dma_alloc_tx_descriptor(chan); + if (!desc) + return NULL; + + chan->direction = xt->dir; + dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); + desc->async_tx.tx_submit = xilinx_dma_tx_submit; + + /* Get a free segment */ + segment = xilinx_axidma_alloc_tx_segment(chan); + if (!segment) + goto error; + + hw = &segment->hw; + + /* Fill in the descriptor */ + if (xt->dir != DMA_MEM_TO_DEV) + hw->buf_addr = xt->dst_start; + else + hw->buf_addr = xt->src_start; + + hw->mcdma_control = chan->tdest & XILINX_DMA_BD_TDEST_MASK; + hw->vsize_stride = (xt->numf << XILINX_DMA_BD_VSIZE_SHIFT) & + XILINX_DMA_BD_VSIZE_MASK; + hw->vsize_stride |= (xt->sgl[0].icg + xt->sgl[0].size) & + XILINX_DMA_BD_STRIDE_MASK; + hw->control = xt->sgl[0].size & XILINX_DMA_BD_HSIZE_MASK; + + /* + * Insert the segment into the descriptor segments + * list. + */ + list_add_tail(&segment->node, &desc->segments); + + + segment = list_first_entry(&desc->segments, + struct xilinx_axidma_tx_segment, node); + desc->async_tx.phys = segment->phys; + + /* For the last DMA_MEM_TO_DEV transfer, set EOP */ + if (xt->dir == DMA_MEM_TO_DEV) { + segment->hw.control |= XILINX_DMA_BD_SOP; + segment = list_last_entry(&desc->segments, + struct xilinx_axidma_tx_segment, + node); + segment->hw.control |= XILINX_DMA_BD_EOP; + } + + return &desc->async_tx; + +error: + xilinx_dma_free_tx_descriptor(chan, desc); + return NULL; +} + +/** * xilinx_dma_terminate_all - Halt the channel and free descriptors * @chan: Driver specific DMA Channel pointer */ static int xilinx_dma_terminate_all(struct dma_chan *dchan) { struct xilinx_dma_chan *chan = to_xilinx_chan(dchan); + u32 reg; + + if (chan->cyclic) + xilinx_dma_chan_reset(chan); /* Halt the DMA engine */ xilinx_dma_halt(chan); @@ -1682,6 +2015,13 @@ static int xilinx_dma_terminate_all(struct dma_chan *dchan) /* Remove and free all of the descriptors in the lists */ xilinx_dma_free_descriptors(chan); + if (chan->cyclic) { + reg = dma_ctrl_read(chan, XILINX_DMA_REG_DMACR); + reg &= ~XILINX_DMA_CR_CYCLIC_BD_EN_MASK; + dma_ctrl_write(chan, XILINX_DMA_REG_DMACR, reg); + chan->cyclic = false; + } + return 0; } @@ -1972,7 +2312,7 @@ static void xdma_disable_allclks(struct xilinx_dma_device *xdev) * Return: '0' on success and failure value on error */ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, - struct device_node *node) + struct device_node *node, int chan_id) { struct xilinx_dma_chan *chan; bool has_dre = false; @@ -2014,9 +2354,12 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, if (!has_dre) xdev->common.copy_align = fls(width - 1); - if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel")) { + if (of_device_is_compatible(node, "xlnx,axi-vdma-mm2s-channel") || + of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel") || + of_device_is_compatible(node, "xlnx,axi-cdma-channel")) { chan->direction = DMA_MEM_TO_DEV; - chan->id = 0; + chan->id = chan_id; + chan->tdest = chan_id; chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET; if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { @@ -2027,9 +2370,12 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, chan->flush_on_fsync = true; } } else if (of_device_is_compatible(node, - "xlnx,axi-vdma-s2mm-channel")) { + "xlnx,axi-vdma-s2mm-channel") || + of_device_is_compatible(node, + "xlnx,axi-dma-s2mm-channel")) { chan->direction = DMA_DEV_TO_MEM; - chan->id = 1; + chan->id = chan_id; + chan->tdest = chan_id - xdev->nr_channels; chan->ctrl_offset = XILINX_DMA_S2MM_CTRL_OFFSET; if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { @@ -2084,6 +2430,32 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, } /** + * xilinx_dma_child_probe - Per child node probe + * It get number of dma-channels per child node from + * device-tree and initializes all the channels. + * + * @xdev: Driver specific device structure + * @node: Device node + * + * Return: 0 always. + */ +static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev, + struct device_node *node) { + int ret, i, nr_channels = 1; + + ret = of_property_read_u32(node, "dma-channels", &nr_channels); + if ((ret < 0) && xdev->mcdma) + dev_warn(xdev->dev, "missing dma-channels property\n"); + + for (i = 0; i < nr_channels; i++) + xilinx_dma_chan_probe(xdev, node, xdev->chan_id++); + + xdev->nr_channels += nr_channels; + + return 0; +} + +/** * of_dma_xilinx_xlate - Translation function * @dma_spec: Pointer to DMA specifier as found in the device tree * @ofdma: Pointer to DMA controller data @@ -2096,7 +2468,7 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec, struct xilinx_dma_device *xdev = ofdma->of_dma_data; int chan_id = dma_spec->args[0]; - if (chan_id >= XILINX_DMA_MAX_CHANS_PER_DEVICE || !xdev->chan[chan_id]) + if (chan_id >= xdev->nr_channels || !xdev->chan[chan_id]) return NULL; return dma_get_slave_channel(&xdev->chan[chan_id]->common); @@ -2172,6 +2544,8 @@ static int xilinx_dma_probe(struct platform_device *pdev) /* Retrieve the DMA engine properties from the device tree */ xdev->has_sg = of_property_read_bool(node, "xlnx,include-sg"); + if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) + xdev->mcdma = of_property_read_bool(node, "xlnx,mcdma"); if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { err = of_property_read_u32(node, "xlnx,num-fstores", @@ -2218,7 +2592,12 @@ static int xilinx_dma_probe(struct platform_device *pdev) xdev->common.device_tx_status = xilinx_dma_tx_status; xdev->common.device_issue_pending = xilinx_dma_issue_pending; if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA) { + dma_cap_set(DMA_CYCLIC, xdev->common.cap_mask); xdev->common.device_prep_slave_sg = xilinx_dma_prep_slave_sg; + xdev->common.device_prep_dma_cyclic = + xilinx_dma_prep_dma_cyclic; + xdev->common.device_prep_interleaved_dma = + xilinx_dma_prep_interleaved; /* Residue calculation is supported by only AXI DMA */ xdev->common.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; @@ -2234,13 +2613,13 @@ static int xilinx_dma_probe(struct platform_device *pdev) /* Initialize the channels */ for_each_child_of_node(node, child) { - err = xilinx_dma_chan_probe(xdev, child); + err = xilinx_dma_child_probe(xdev, child); if (err < 0) goto disable_clks; } if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { - for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) + for (i = 0; i < xdev->nr_channels; i++) if (xdev->chan[i]) xdev->chan[i]->num_frms = num_frames; } @@ -2263,7 +2642,7 @@ static int xilinx_dma_probe(struct platform_device *pdev) disable_clks: xdma_disable_allclks(xdev); error: - for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) + for (i = 0; i < xdev->nr_channels; i++) if (xdev->chan[i]) xilinx_dma_chan_remove(xdev->chan[i]); @@ -2285,7 +2664,7 @@ static int xilinx_dma_remove(struct platform_device *pdev) dma_async_device_unregister(&xdev->common); - for (i = 0; i < XILINX_DMA_MAX_CHANS_PER_DEVICE; i++) + for (i = 0; i < xdev->nr_channels; i++) if (xdev->chan[i]) xilinx_dma_chan_remove(xdev->chan[i]); diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c new file mode 100644 index 000000000000..6d221e5c72ee --- /dev/null +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -0,0 +1,1151 @@ +/* + * DMA driver for Xilinx ZynqMP DMA Engine + * + * Copyright (C) 2016 Xilinx, Inc. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + */ + +#include <linux/bitops.h> +#include <linux/dmapool.h> +#include <linux/dma/xilinx_dma.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/of_dma.h> +#include <linux/of_irq.h> +#include <linux/of_platform.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/io-64-nonatomic-lo-hi.h> + +#include "../dmaengine.h" + +/* Register Offsets */ +#define ZYNQMP_DMA_ISR 0x100 +#define ZYNQMP_DMA_IMR 0x104 +#define ZYNQMP_DMA_IER 0x108 +#define ZYNQMP_DMA_IDS 0x10C +#define ZYNQMP_DMA_CTRL0 0x110 +#define ZYNQMP_DMA_CTRL1 0x114 +#define ZYNQMP_DMA_DATA_ATTR 0x120 +#define ZYNQMP_DMA_DSCR_ATTR 0x124 +#define ZYNQMP_DMA_SRC_DSCR_WRD0 0x128 +#define ZYNQMP_DMA_SRC_DSCR_WRD1 0x12C +#define ZYNQMP_DMA_SRC_DSCR_WRD2 0x130 +#define ZYNQMP_DMA_SRC_DSCR_WRD3 0x134 +#define ZYNQMP_DMA_DST_DSCR_WRD0 0x138 +#define ZYNQMP_DMA_DST_DSCR_WRD1 0x13C +#define ZYNQMP_DMA_DST_DSCR_WRD2 0x140 +#define ZYNQMP_DMA_DST_DSCR_WRD3 0x144 +#define ZYNQMP_DMA_SRC_START_LSB 0x158 +#define ZYNQMP_DMA_SRC_START_MSB 0x15C +#define ZYNQMP_DMA_DST_START_LSB 0x160 +#define ZYNQMP_DMA_DST_START_MSB 0x164 +#define ZYNQMP_DMA_RATE_CTRL 0x18C +#define ZYNQMP_DMA_IRQ_SRC_ACCT 0x190 +#define ZYNQMP_DMA_IRQ_DST_ACCT 0x194 +#define ZYNQMP_DMA_CTRL2 0x200 + +/* Interrupt registers bit field definitions */ +#define ZYNQMP_DMA_DONE BIT(10) +#define ZYNQMP_DMA_AXI_WR_DATA BIT(9) +#define ZYNQMP_DMA_AXI_RD_DATA BIT(8) +#define ZYNQMP_DMA_AXI_RD_DST_DSCR BIT(7) +#define ZYNQMP_DMA_AXI_RD_SRC_DSCR BIT(6) +#define ZYNQMP_DMA_IRQ_DST_ACCT_ERR BIT(5) +#define ZYNQMP_DMA_IRQ_SRC_ACCT_ERR BIT(4) +#define ZYNQMP_DMA_BYTE_CNT_OVRFL BIT(3) +#define ZYNQMP_DMA_DST_DSCR_DONE BIT(2) +#define ZYNQMP_DMA_INV_APB BIT(0) + +/* Control 0 register bit field definitions */ +#define ZYNQMP_DMA_OVR_FETCH BIT(7) +#define ZYNQMP_DMA_POINT_TYPE_SG BIT(6) +#define ZYNQMP_DMA_RATE_CTRL_EN BIT(3) + +/* Control 1 register bit field definitions */ +#define ZYNQMP_DMA_SRC_ISSUE GENMASK(4, 0) + +/* Data Attribute register bit field definitions */ +#define ZYNQMP_DMA_ARBURST GENMASK(27, 26) +#define ZYNQMP_DMA_ARCACHE GENMASK(25, 22) +#define ZYNQMP_DMA_ARCACHE_OFST 22 +#define ZYNQMP_DMA_ARQOS GENMASK(21, 18) +#define ZYNQMP_DMA_ARQOS_OFST 18 +#define ZYNQMP_DMA_ARLEN GENMASK(17, 14) +#define ZYNQMP_DMA_ARLEN_OFST 14 +#define ZYNQMP_DMA_AWBURST GENMASK(13, 12) +#define ZYNQMP_DMA_AWCACHE GENMASK(11, 8) +#define ZYNQMP_DMA_AWCACHE_OFST 8 +#define ZYNQMP_DMA_AWQOS GENMASK(7, 4) +#define ZYNQMP_DMA_AWQOS_OFST 4 +#define ZYNQMP_DMA_AWLEN GENMASK(3, 0) +#define ZYNQMP_DMA_AWLEN_OFST 0 + +/* Descriptor Attribute register bit field definitions */ +#define ZYNQMP_DMA_AXCOHRNT BIT(8) +#define ZYNQMP_DMA_AXCACHE GENMASK(7, 4) +#define ZYNQMP_DMA_AXCACHE_OFST 4 +#define ZYNQMP_DMA_AXQOS GENMASK(3, 0) +#define ZYNQMP_DMA_AXQOS_OFST 0 + +/* Control register 2 bit field definitions */ +#define ZYNQMP_DMA_ENABLE BIT(0) + +/* Buffer Descriptor definitions */ +#define ZYNQMP_DMA_DESC_CTRL_STOP 0x10 +#define ZYNQMP_DMA_DESC_CTRL_COMP_INT 0x4 +#define ZYNQMP_DMA_DESC_CTRL_SIZE_256 0x2 +#define ZYNQMP_DMA_DESC_CTRL_COHRNT 0x1 + +/* Interrupt Mask specific definitions */ +#define ZYNQMP_DMA_INT_ERR (ZYNQMP_DMA_AXI_RD_DATA | \ + ZYNQMP_DMA_AXI_WR_DATA | \ + ZYNQMP_DMA_AXI_RD_DST_DSCR | \ + ZYNQMP_DMA_AXI_RD_SRC_DSCR | \ + ZYNQMP_DMA_INV_APB) +#define ZYNQMP_DMA_INT_OVRFL (ZYNQMP_DMA_BYTE_CNT_OVRFL | \ + ZYNQMP_DMA_IRQ_SRC_ACCT_ERR | \ + ZYNQMP_DMA_IRQ_DST_ACCT_ERR) +#define ZYNQMP_DMA_INT_DONE (ZYNQMP_DMA_DONE | ZYNQMP_DMA_DST_DSCR_DONE) +#define ZYNQMP_DMA_INT_EN_DEFAULT_MASK (ZYNQMP_DMA_INT_DONE | \ + ZYNQMP_DMA_INT_ERR | \ + ZYNQMP_DMA_INT_OVRFL | \ + ZYNQMP_DMA_DST_DSCR_DONE) + +/* Max number of descriptors per channel */ +#define ZYNQMP_DMA_NUM_DESCS 32 + +/* Max transfer size per descriptor */ +#define ZYNQMP_DMA_MAX_TRANS_LEN 0x40000000 + +/* Reset values for data attributes */ +#define ZYNQMP_DMA_AXCACHE_VAL 0xF +#define ZYNQMP_DMA_ARLEN_RST_VAL 0xF +#define ZYNQMP_DMA_AWLEN_RST_VAL 0xF + +#define ZYNQMP_DMA_SRC_ISSUE_RST_VAL 0x1F + +#define ZYNQMP_DMA_IDS_DEFAULT_MASK 0xFFF + +/* Bus width in bits */ +#define ZYNQMP_DMA_BUS_WIDTH_64 64 +#define ZYNQMP_DMA_BUS_WIDTH_128 128 + +#define ZYNQMP_DMA_DESC_SIZE(chan) (chan->desc_size) + +#define to_chan(chan) container_of(chan, struct zynqmp_dma_chan, \ + common) +#define tx_to_desc(tx) container_of(tx, struct zynqmp_dma_desc_sw, \ + async_tx) + +/** + * struct zynqmp_dma_desc_ll - Hw linked list descriptor + * @addr: Buffer address + * @size: Size of the buffer + * @ctrl: Control word + * @nxtdscraddr: Next descriptor base address + * @rsvd: Reserved field and for Hw internal use. + */ +struct zynqmp_dma_desc_ll { + u64 addr; + u32 size; + u32 ctrl; + u64 nxtdscraddr; + u64 rsvd; +}; __aligned(64) + +/** + * struct zynqmp_dma_desc_sw - Per Transaction structure + * @src: Source address for simple mode dma + * @dst: Destination address for simple mode dma + * @len: Transfer length for simple mode dma + * @node: Node in the channel descriptor list + * @tx_list: List head for the current transfer + * @async_tx: Async transaction descriptor + * @src_v: Virtual address of the src descriptor + * @src_p: Physical address of the src descriptor + * @dst_v: Virtual address of the dst descriptor + * @dst_p: Physical address of the dst descriptor + */ +struct zynqmp_dma_desc_sw { + u64 src; + u64 dst; + u32 len; + struct list_head node; + struct list_head tx_list; + struct dma_async_tx_descriptor async_tx; + struct zynqmp_dma_desc_ll *src_v; + dma_addr_t src_p; + struct zynqmp_dma_desc_ll *dst_v; + dma_addr_t dst_p; +}; + +/** + * struct zynqmp_dma_chan - Driver specific DMA channel structure + * @zdev: Driver specific device structure + * @regs: Control registers offset + * @lock: Descriptor operation lock + * @pending_list: Descriptors waiting + * @free_list: Descriptors free + * @active_list: Descriptors active + * @sw_desc_pool: SW descriptor pool + * @done_list: Complete descriptors + * @common: DMA common channel + * @desc_pool_v: Statically allocated descriptor base + * @desc_pool_p: Physical allocated descriptor base + * @desc_free_cnt: Descriptor available count + * @dev: The dma device + * @irq: Channel IRQ + * @is_dmacoherent: Tells whether dma operations are coherent or not + * @tasklet: Cleanup work after irq + * @idle : Channel status; + * @desc_size: Size of the low level descriptor + * @err: Channel has errors + * @bus_width: Bus width + * @src_burst_len: Source burst length + * @dst_burst_len: Dest burst length + * @clk_main: Pointer to main clock + * @clk_apb: Pointer to apb clock + */ +struct zynqmp_dma_chan { + struct zynqmp_dma_device *zdev; + void __iomem *regs; + spinlock_t lock; + struct list_head pending_list; + struct list_head free_list; + struct list_head active_list; + struct zynqmp_dma_desc_sw *sw_desc_pool; + struct list_head done_list; + struct dma_chan common; + void *desc_pool_v; + dma_addr_t desc_pool_p; + u32 desc_free_cnt; + struct device *dev; + int irq; + bool is_dmacoherent; + struct tasklet_struct tasklet; + bool idle; + u32 desc_size; + bool err; + u32 bus_width; + u32 src_burst_len; + u32 dst_burst_len; + struct clk *clk_main; + struct clk *clk_apb; +}; + +/** + * struct zynqmp_dma_device - DMA device structure + * @dev: Device Structure + * @common: DMA device structure + * @chan: Driver specific DMA channel + */ +struct zynqmp_dma_device { + struct device *dev; + struct dma_device common; + struct zynqmp_dma_chan *chan; +}; + +static inline void zynqmp_dma_writeq(struct zynqmp_dma_chan *chan, u32 reg, + u64 value) +{ + lo_hi_writeq(value, chan->regs + reg); +} + +/** + * zynqmp_dma_update_desc_to_ctrlr - Updates descriptor to the controller + * @chan: ZynqMP DMA DMA channel pointer + * @desc: Transaction descriptor pointer + */ +static void zynqmp_dma_update_desc_to_ctrlr(struct zynqmp_dma_chan *chan, + struct zynqmp_dma_desc_sw *desc) +{ + dma_addr_t addr; + + addr = desc->src_p; + zynqmp_dma_writeq(chan, ZYNQMP_DMA_SRC_START_LSB, addr); + addr = desc->dst_p; + zynqmp_dma_writeq(chan, ZYNQMP_DMA_DST_START_LSB, addr); +} + +/** + * zynqmp_dma_desc_config_eod - Mark the descriptor as end descriptor + * @chan: ZynqMP DMA channel pointer + * @desc: Hw descriptor pointer + */ +static void zynqmp_dma_desc_config_eod(struct zynqmp_dma_chan *chan, + void *desc) +{ + struct zynqmp_dma_desc_ll *hw = (struct zynqmp_dma_desc_ll *)desc; + + hw->ctrl |= ZYNQMP_DMA_DESC_CTRL_STOP; + hw++; + hw->ctrl |= ZYNQMP_DMA_DESC_CTRL_COMP_INT | ZYNQMP_DMA_DESC_CTRL_STOP; +} + +/** + * zynqmp_dma_config_sg_ll_desc - Configure the linked list descriptor + * @chan: ZynqMP DMA channel pointer + * @sdesc: Hw descriptor pointer + * @src: Source buffer address + * @dst: Destination buffer address + * @len: Transfer length + * @prev: Previous hw descriptor pointer + */ +static void zynqmp_dma_config_sg_ll_desc(struct zynqmp_dma_chan *chan, + struct zynqmp_dma_desc_ll *sdesc, + dma_addr_t src, dma_addr_t dst, size_t len, + struct zynqmp_dma_desc_ll *prev) +{ + struct zynqmp_dma_desc_ll *ddesc = sdesc + 1; + + sdesc->size = ddesc->size = len; + sdesc->addr = src; + ddesc->addr = dst; + + sdesc->ctrl = ddesc->ctrl = ZYNQMP_DMA_DESC_CTRL_SIZE_256; + if (chan->is_dmacoherent) { + sdesc->ctrl |= ZYNQMP_DMA_DESC_CTRL_COHRNT; + ddesc->ctrl |= ZYNQMP_DMA_DESC_CTRL_COHRNT; + } + + if (prev) { + dma_addr_t addr = chan->desc_pool_p + + ((uintptr_t)sdesc - (uintptr_t)chan->desc_pool_v); + ddesc = prev + 1; + prev->nxtdscraddr = addr; + ddesc->nxtdscraddr = addr + ZYNQMP_DMA_DESC_SIZE(chan); + } +} + +/** + * zynqmp_dma_init - Initialize the channel + * @chan: ZynqMP DMA channel pointer + */ +static void zynqmp_dma_init(struct zynqmp_dma_chan *chan) +{ + u32 val; + + writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS); + val = readl(chan->regs + ZYNQMP_DMA_ISR); + writel(val, chan->regs + ZYNQMP_DMA_ISR); + + if (chan->is_dmacoherent) { + val = ZYNQMP_DMA_AXCOHRNT; + val = (val & ~ZYNQMP_DMA_AXCACHE) | + (ZYNQMP_DMA_AXCACHE_VAL << ZYNQMP_DMA_AXCACHE_OFST); + writel(val, chan->regs + ZYNQMP_DMA_DSCR_ATTR); + } + + val = readl(chan->regs + ZYNQMP_DMA_DATA_ATTR); + if (chan->is_dmacoherent) { + val = (val & ~ZYNQMP_DMA_ARCACHE) | + (ZYNQMP_DMA_AXCACHE_VAL << ZYNQMP_DMA_ARCACHE_OFST); + val = (val & ~ZYNQMP_DMA_AWCACHE) | + (ZYNQMP_DMA_AXCACHE_VAL << ZYNQMP_DMA_AWCACHE_OFST); + } + writel(val, chan->regs + ZYNQMP_DMA_DATA_ATTR); + + /* Clearing the interrupt account rgisters */ + val = readl(chan->regs + ZYNQMP_DMA_IRQ_SRC_ACCT); + val = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT); + + chan->idle = true; +} + +/** + * zynqmp_dma_tx_submit - Submit DMA transaction + * @tx: Async transaction descriptor pointer + * + * Return: cookie value + */ +static dma_cookie_t zynqmp_dma_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct zynqmp_dma_chan *chan = to_chan(tx->chan); + struct zynqmp_dma_desc_sw *desc, *new; + dma_cookie_t cookie; + + new = tx_to_desc(tx); + spin_lock_bh(&chan->lock); + cookie = dma_cookie_assign(tx); + + if (!list_empty(&chan->pending_list)) { + desc = list_last_entry(&chan->pending_list, + struct zynqmp_dma_desc_sw, node); + if (!list_empty(&desc->tx_list)) + desc = list_last_entry(&desc->tx_list, + struct zynqmp_dma_desc_sw, node); + desc->src_v->nxtdscraddr = new->src_p; + desc->src_v->ctrl &= ~ZYNQMP_DMA_DESC_CTRL_STOP; + desc->dst_v->nxtdscraddr = new->dst_p; + desc->dst_v->ctrl &= ~ZYNQMP_DMA_DESC_CTRL_STOP; + } + + list_add_tail(&new->node, &chan->pending_list); + spin_unlock_bh(&chan->lock); + + return cookie; +} + +/** + * zynqmp_dma_get_descriptor - Get the sw descriptor from the pool + * @chan: ZynqMP DMA channel pointer + * + * Return: The sw descriptor + */ +static struct zynqmp_dma_desc_sw * +zynqmp_dma_get_descriptor(struct zynqmp_dma_chan *chan) +{ + struct zynqmp_dma_desc_sw *desc; + + spin_lock_bh(&chan->lock); + desc = list_first_entry(&chan->free_list, + struct zynqmp_dma_desc_sw, node); + list_del(&desc->node); + spin_unlock_bh(&chan->lock); + + INIT_LIST_HEAD(&desc->tx_list); + /* Clear the src and dst descriptor memory */ + memset((void *)desc->src_v, 0, ZYNQMP_DMA_DESC_SIZE(chan)); + memset((void *)desc->dst_v, 0, ZYNQMP_DMA_DESC_SIZE(chan)); + + return desc; +} + +/** + * zynqmp_dma_free_descriptor - Issue pending transactions + * @chan: ZynqMP DMA channel pointer + * @sdesc: Transaction descriptor pointer + */ +static void zynqmp_dma_free_descriptor(struct zynqmp_dma_chan *chan, + struct zynqmp_dma_desc_sw *sdesc) +{ + struct zynqmp_dma_desc_sw *child, *next; + + chan->desc_free_cnt++; + list_add_tail(&sdesc->node, &chan->free_list); + list_for_each_entry_safe(child, next, &sdesc->tx_list, node) { + chan->desc_free_cnt++; + list_move_tail(&child->node, &chan->free_list); + } +} + +/** + * zynqmp_dma_free_desc_list - Free descriptors list + * @chan: ZynqMP DMA channel pointer + * @list: List to parse and delete the descriptor + */ +static void zynqmp_dma_free_desc_list(struct zynqmp_dma_chan *chan, + struct list_head *list) +{ + struct zynqmp_dma_desc_sw *desc, *next; + + list_for_each_entry_safe(desc, next, list, node) + zynqmp_dma_free_descriptor(chan, desc); +} + +/** + * zynqmp_dma_alloc_chan_resources - Allocate channel resources + * @dchan: DMA channel + * + * Return: Number of descriptors on success and failure value on error + */ +static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) +{ + struct zynqmp_dma_chan *chan = to_chan(dchan); + struct zynqmp_dma_desc_sw *desc; + int i; + + chan->sw_desc_pool = kzalloc(sizeof(*desc) * ZYNQMP_DMA_NUM_DESCS, + GFP_KERNEL); + if (!chan->sw_desc_pool) + return -ENOMEM; + + chan->idle = true; + chan->desc_free_cnt = ZYNQMP_DMA_NUM_DESCS; + + INIT_LIST_HEAD(&chan->free_list); + + for (i = 0; i < ZYNQMP_DMA_NUM_DESCS; i++) { + desc = chan->sw_desc_pool + i; + dma_async_tx_descriptor_init(&desc->async_tx, &chan->common); + desc->async_tx.tx_submit = zynqmp_dma_tx_submit; + list_add_tail(&desc->node, &chan->free_list); + } + + chan->desc_pool_v = dma_zalloc_coherent(chan->dev, + (2 * chan->desc_size * ZYNQMP_DMA_NUM_DESCS), + &chan->desc_pool_p, GFP_KERNEL); + if (!chan->desc_pool_v) + return -ENOMEM; + + for (i = 0; i < ZYNQMP_DMA_NUM_DESCS; i++) { + desc = chan->sw_desc_pool + i; + desc->src_v = (struct zynqmp_dma_desc_ll *) (chan->desc_pool_v + + (i * ZYNQMP_DMA_DESC_SIZE(chan) * 2)); + desc->dst_v = (struct zynqmp_dma_desc_ll *) (desc->src_v + 1); + desc->src_p = chan->desc_pool_p + + (i * ZYNQMP_DMA_DESC_SIZE(chan) * 2); + desc->dst_p = desc->src_p + ZYNQMP_DMA_DESC_SIZE(chan); + } + + return ZYNQMP_DMA_NUM_DESCS; +} + +/** + * zynqmp_dma_start - Start DMA channel + * @chan: ZynqMP DMA channel pointer + */ +static void zynqmp_dma_start(struct zynqmp_dma_chan *chan) +{ + writel(ZYNQMP_DMA_INT_EN_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IER); + chan->idle = false; + writel(ZYNQMP_DMA_ENABLE, chan->regs + ZYNQMP_DMA_CTRL2); +} + +/** + * zynqmp_dma_handle_ovfl_int - Process the overflow interrupt + * @chan: ZynqMP DMA channel pointer + * @status: Interrupt status value + */ +static void zynqmp_dma_handle_ovfl_int(struct zynqmp_dma_chan *chan, u32 status) +{ + u32 val; + + if (status & ZYNQMP_DMA_IRQ_DST_ACCT_ERR) + val = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT); + if (status & ZYNQMP_DMA_IRQ_SRC_ACCT_ERR) + val = readl(chan->regs + ZYNQMP_DMA_IRQ_SRC_ACCT); +} + +static void zynqmp_dma_config(struct zynqmp_dma_chan *chan) +{ + u32 val; + + val = readl(chan->regs + ZYNQMP_DMA_CTRL0); + val |= ZYNQMP_DMA_POINT_TYPE_SG; + writel(val, chan->regs + ZYNQMP_DMA_CTRL0); + + val = readl(chan->regs + ZYNQMP_DMA_DATA_ATTR); + val = (val & ~ZYNQMP_DMA_ARLEN) | + (chan->src_burst_len << ZYNQMP_DMA_ARLEN_OFST); + val = (val & ~ZYNQMP_DMA_AWLEN) | + (chan->dst_burst_len << ZYNQMP_DMA_AWLEN_OFST); + writel(val, chan->regs + ZYNQMP_DMA_DATA_ATTR); +} + +/** + * zynqmp_dma_device_config - Zynqmp dma device configuration + * @dchan: DMA channel + * @config: DMA device config + */ +static int zynqmp_dma_device_config(struct dma_chan *dchan, + struct dma_slave_config *config) +{ + struct zynqmp_dma_chan *chan = to_chan(dchan); + + chan->src_burst_len = config->src_maxburst; + chan->dst_burst_len = config->dst_maxburst; + + return 0; +} + +/** + * zynqmp_dma_start_transfer - Initiate the new transfer + * @chan: ZynqMP DMA channel pointer + */ +static void zynqmp_dma_start_transfer(struct zynqmp_dma_chan *chan) +{ + struct zynqmp_dma_desc_sw *desc; + + if (!chan->idle) + return; + + zynqmp_dma_config(chan); + + desc = list_first_entry_or_null(&chan->pending_list, + struct zynqmp_dma_desc_sw, node); + if (!desc) + return; + + list_splice_tail_init(&chan->pending_list, &chan->active_list); + zynqmp_dma_update_desc_to_ctrlr(chan, desc); + zynqmp_dma_start(chan); +} + + +/** + * zynqmp_dma_chan_desc_cleanup - Cleanup the completed descriptors + * @chan: ZynqMP DMA channel + */ +static void zynqmp_dma_chan_desc_cleanup(struct zynqmp_dma_chan *chan) +{ + struct zynqmp_dma_desc_sw *desc, *next; + + list_for_each_entry_safe(desc, next, &chan->done_list, node) { + dma_async_tx_callback callback; + void *callback_param; + + list_del(&desc->node); + + callback = desc->async_tx.callback; + callback_param = desc->async_tx.callback_param; + if (callback) { + spin_unlock(&chan->lock); + callback(callback_param); + spin_lock(&chan->lock); + } + + /* Run any dependencies, then free the descriptor */ + zynqmp_dma_free_descriptor(chan, desc); + } +} + +/** + * zynqmp_dma_complete_descriptor - Mark the active descriptor as complete + * @chan: ZynqMP DMA channel pointer + */ +static void zynqmp_dma_complete_descriptor(struct zynqmp_dma_chan *chan) +{ + struct zynqmp_dma_desc_sw *desc; + + desc = list_first_entry_or_null(&chan->active_list, + struct zynqmp_dma_desc_sw, node); + if (!desc) + return; + list_del(&desc->node); + dma_cookie_complete(&desc->async_tx); + list_add_tail(&desc->node, &chan->done_list); +} + +/** + * zynqmp_dma_issue_pending - Issue pending transactions + * @dchan: DMA channel pointer + */ +static void zynqmp_dma_issue_pending(struct dma_chan *dchan) +{ + struct zynqmp_dma_chan *chan = to_chan(dchan); + + spin_lock_bh(&chan->lock); + zynqmp_dma_start_transfer(chan); + spin_unlock_bh(&chan->lock); +} + +/** + * zynqmp_dma_free_descriptors - Free channel descriptors + * @dchan: DMA channel pointer + */ +static void zynqmp_dma_free_descriptors(struct zynqmp_dma_chan *chan) +{ + zynqmp_dma_free_desc_list(chan, &chan->active_list); + zynqmp_dma_free_desc_list(chan, &chan->pending_list); + zynqmp_dma_free_desc_list(chan, &chan->done_list); +} + +/** + * zynqmp_dma_free_chan_resources - Free channel resources + * @dchan: DMA channel pointer + */ +static void zynqmp_dma_free_chan_resources(struct dma_chan *dchan) +{ + struct zynqmp_dma_chan *chan = to_chan(dchan); + + spin_lock_bh(&chan->lock); + zynqmp_dma_free_descriptors(chan); + spin_unlock_bh(&chan->lock); + dma_free_coherent(chan->dev, + (2 * ZYNQMP_DMA_DESC_SIZE(chan) * ZYNQMP_DMA_NUM_DESCS), + chan->desc_pool_v, chan->desc_pool_p); + kfree(chan->sw_desc_pool); +} + +/** + * zynqmp_dma_reset - Reset the channel + * @chan: ZynqMP DMA channel pointer + */ +static void zynqmp_dma_reset(struct zynqmp_dma_chan *chan) +{ + writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS); + + zynqmp_dma_complete_descriptor(chan); + zynqmp_dma_chan_desc_cleanup(chan); + zynqmp_dma_free_descriptors(chan); + zynqmp_dma_init(chan); +} + +/** + * zynqmp_dma_irq_handler - ZynqMP DMA Interrupt handler + * @irq: IRQ number + * @data: Pointer to the ZynqMP DMA channel structure + * + * Return: IRQ_HANDLED/IRQ_NONE + */ +static irqreturn_t zynqmp_dma_irq_handler(int irq, void *data) +{ + struct zynqmp_dma_chan *chan = (struct zynqmp_dma_chan *)data; + u32 isr, imr, status; + irqreturn_t ret = IRQ_NONE; + + isr = readl(chan->regs + ZYNQMP_DMA_ISR); + imr = readl(chan->regs + ZYNQMP_DMA_IMR); + status = isr & ~imr; + + writel(isr, chan->regs + ZYNQMP_DMA_ISR); + if (status & ZYNQMP_DMA_INT_DONE) { + tasklet_schedule(&chan->tasklet); + ret = IRQ_HANDLED; + } + + if (status & ZYNQMP_DMA_DONE) + chan->idle = true; + + if (status & ZYNQMP_DMA_INT_ERR) { + chan->err = true; + tasklet_schedule(&chan->tasklet); + dev_err(chan->dev, "Channel %p has errors\n", chan); + ret = IRQ_HANDLED; + } + + if (status & ZYNQMP_DMA_INT_OVRFL) { + zynqmp_dma_handle_ovfl_int(chan, status); + dev_info(chan->dev, "Channel %p overflow interrupt\n", chan); + ret = IRQ_HANDLED; + } + + return ret; +} + +/** + * zynqmp_dma_do_tasklet - Schedule completion tasklet + * @data: Pointer to the ZynqMP DMA channel structure + */ +static void zynqmp_dma_do_tasklet(unsigned long data) +{ + struct zynqmp_dma_chan *chan = (struct zynqmp_dma_chan *)data; + u32 count; + + spin_lock(&chan->lock); + + if (chan->err) { + zynqmp_dma_reset(chan); + chan->err = false; + goto unlock; + } + + count = readl(chan->regs + ZYNQMP_DMA_IRQ_DST_ACCT); + + while (count) { + zynqmp_dma_complete_descriptor(chan); + zynqmp_dma_chan_desc_cleanup(chan); + count--; + } + + if (chan->idle) + zynqmp_dma_start_transfer(chan); + +unlock: + spin_unlock(&chan->lock); +} + +/** + * zynqmp_dma_device_terminate_all - Aborts all transfers on a channel + * @dchan: DMA channel pointer + * + * Return: Always '0' + */ +static int zynqmp_dma_device_terminate_all(struct dma_chan *dchan) +{ + struct zynqmp_dma_chan *chan = to_chan(dchan); + + spin_lock_bh(&chan->lock); + writel(ZYNQMP_DMA_IDS_DEFAULT_MASK, chan->regs + ZYNQMP_DMA_IDS); + zynqmp_dma_free_descriptors(chan); + spin_unlock_bh(&chan->lock); + + return 0; +} + +/** + * zynqmp_dma_prep_memcpy - prepare descriptors for memcpy transaction + * @dchan: DMA channel + * @dma_dst: Destination buffer address + * @dma_src: Source buffer address + * @len: Transfer length + * @flags: transfer ack flags + * + * Return: Async transaction descriptor on success and NULL on failure + */ +static struct dma_async_tx_descriptor *zynqmp_dma_prep_memcpy( + struct dma_chan *dchan, dma_addr_t dma_dst, + dma_addr_t dma_src, size_t len, ulong flags) +{ + struct zynqmp_dma_chan *chan; + struct zynqmp_dma_desc_sw *new, *first = NULL; + void *desc = NULL, *prev = NULL; + size_t copy; + u32 desc_cnt; + + chan = to_chan(dchan); + + if (len > ZYNQMP_DMA_MAX_TRANS_LEN) + return NULL; + + desc_cnt = DIV_ROUND_UP(len, ZYNQMP_DMA_MAX_TRANS_LEN); + + spin_lock_bh(&chan->lock); + if (desc_cnt > chan->desc_free_cnt) { + spin_unlock_bh(&chan->lock); + dev_dbg(chan->dev, "chan %p descs are not available\n", chan); + return NULL; + } + chan->desc_free_cnt = chan->desc_free_cnt - desc_cnt; + spin_unlock_bh(&chan->lock); + + do { + /* Allocate and populate the descriptor */ + new = zynqmp_dma_get_descriptor(chan); + + copy = min_t(size_t, len, ZYNQMP_DMA_MAX_TRANS_LEN); + desc = (struct zynqmp_dma_desc_ll *)new->src_v; + zynqmp_dma_config_sg_ll_desc(chan, desc, dma_src, + dma_dst, copy, prev); + prev = desc; + len -= copy; + dma_src += copy; + dma_dst += copy; + if (!first) + first = new; + else + list_add_tail(&new->node, &first->tx_list); + } while (len); + + zynqmp_dma_desc_config_eod(chan, desc); + async_tx_ack(&first->async_tx); + first->async_tx.flags = flags; + return &first->async_tx; +} + +/** + * zynqmp_dma_prep_slave_sg - prepare descriptors for a memory sg transaction + * @dchan: DMA channel + * @dst_sg: Destination scatter list + * @dst_sg_len: Number of entries in destination scatter list + * @src_sg: Source scatter list + * @src_sg_len: Number of entries in source scatter list + * @flags: transfer ack flags + * + * Return: Async transaction descriptor on success and NULL on failure + */ +static struct dma_async_tx_descriptor *zynqmp_dma_prep_sg( + struct dma_chan *dchan, struct scatterlist *dst_sg, + unsigned int dst_sg_len, struct scatterlist *src_sg, + unsigned int src_sg_len, unsigned long flags) +{ + struct zynqmp_dma_desc_sw *new, *first = NULL; + struct zynqmp_dma_chan *chan = to_chan(dchan); + void *desc = NULL, *prev = NULL; + size_t len, dst_avail, src_avail; + dma_addr_t dma_dst, dma_src; + u32 desc_cnt = 0, i; + struct scatterlist *sg; + + for_each_sg(src_sg, sg, src_sg_len, i) + desc_cnt += DIV_ROUND_UP(sg_dma_len(sg), + ZYNQMP_DMA_MAX_TRANS_LEN); + + spin_lock_bh(&chan->lock); + if (desc_cnt > chan->desc_free_cnt) { + spin_unlock_bh(&chan->lock); + dev_dbg(chan->dev, "chan %p descs are not available\n", chan); + return NULL; + } + chan->desc_free_cnt = chan->desc_free_cnt - desc_cnt; + spin_unlock_bh(&chan->lock); + + dst_avail = sg_dma_len(dst_sg); + src_avail = sg_dma_len(src_sg); + + /* Run until we are out of scatterlist entries */ + while (true) { + /* Allocate and populate the descriptor */ + new = zynqmp_dma_get_descriptor(chan); + desc = (struct zynqmp_dma_desc_ll *)new->src_v; + len = min_t(size_t, src_avail, dst_avail); + len = min_t(size_t, len, ZYNQMP_DMA_MAX_TRANS_LEN); + if (len == 0) + goto fetch; + dma_dst = sg_dma_address(dst_sg) + sg_dma_len(dst_sg) - + dst_avail; + dma_src = sg_dma_address(src_sg) + sg_dma_len(src_sg) - + src_avail; + + zynqmp_dma_config_sg_ll_desc(chan, desc, dma_src, dma_dst, + len, prev); + prev = desc; + dst_avail -= len; + src_avail -= len; + + if (!first) + first = new; + else + list_add_tail(&new->node, &first->tx_list); +fetch: + /* Fetch the next dst scatterlist entry */ + if (dst_avail == 0) { + if (dst_sg_len == 0) + break; + dst_sg = sg_next(dst_sg); + if (dst_sg == NULL) + break; + dst_sg_len--; + dst_avail = sg_dma_len(dst_sg); + } + /* Fetch the next src scatterlist entry */ + if (src_avail == 0) { + if (src_sg_len == 0) + break; + src_sg = sg_next(src_sg); + if (src_sg == NULL) + break; + src_sg_len--; + src_avail = sg_dma_len(src_sg); + } + } + + zynqmp_dma_desc_config_eod(chan, desc); + first->async_tx.flags = flags; + return &first->async_tx; +} + +/** + * zynqmp_dma_chan_remove - Channel remove function + * @chan: ZynqMP DMA channel pointer + */ +static void zynqmp_dma_chan_remove(struct zynqmp_dma_chan *chan) +{ + if (!chan) + return; + + devm_free_irq(chan->zdev->dev, chan->irq, chan); + tasklet_kill(&chan->tasklet); + list_del(&chan->common.device_node); + clk_disable_unprepare(chan->clk_apb); + clk_disable_unprepare(chan->clk_main); +} + +/** + * zynqmp_dma_chan_probe - Per Channel Probing + * @zdev: Driver specific device structure + * @pdev: Pointer to the platform_device structure + * + * Return: '0' on success and failure value on error + */ +static int zynqmp_dma_chan_probe(struct zynqmp_dma_device *zdev, + struct platform_device *pdev) +{ + struct zynqmp_dma_chan *chan; + struct resource *res; + struct device_node *node = pdev->dev.of_node; + int err; + + chan = devm_kzalloc(zdev->dev, sizeof(*chan), GFP_KERNEL); + if (!chan) + return -ENOMEM; + chan->dev = zdev->dev; + chan->zdev = zdev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + chan->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(chan->regs)) + return PTR_ERR(chan->regs); + + chan->bus_width = ZYNQMP_DMA_BUS_WIDTH_64; + chan->dst_burst_len = ZYNQMP_DMA_AWLEN_RST_VAL; + chan->src_burst_len = ZYNQMP_DMA_ARLEN_RST_VAL; + err = of_property_read_u32(node, "xlnx,bus-width", &chan->bus_width); + if (err < 0) { + dev_err(&pdev->dev, "missing xlnx,bus-width property\n"); + return err; + } + + if (chan->bus_width != ZYNQMP_DMA_BUS_WIDTH_64 && + chan->bus_width != ZYNQMP_DMA_BUS_WIDTH_128) { + dev_err(zdev->dev, "invalid bus-width value"); + return -EINVAL; + } + + chan->is_dmacoherent = of_property_read_bool(node, "dma-coherent"); + zdev->chan = chan; + tasklet_init(&chan->tasklet, zynqmp_dma_do_tasklet, (ulong)chan); + spin_lock_init(&chan->lock); + INIT_LIST_HEAD(&chan->active_list); + INIT_LIST_HEAD(&chan->pending_list); + INIT_LIST_HEAD(&chan->done_list); + INIT_LIST_HEAD(&chan->free_list); + + dma_cookie_init(&chan->common); + chan->common.device = &zdev->common; + list_add_tail(&chan->common.device_node, &zdev->common.channels); + + zynqmp_dma_init(chan); + chan->irq = platform_get_irq(pdev, 0); + if (chan->irq < 0) + return -ENXIO; + err = devm_request_irq(&pdev->dev, chan->irq, zynqmp_dma_irq_handler, 0, + "zynqmp-dma", chan); + if (err) + return err; + chan->clk_main = devm_clk_get(&pdev->dev, "clk_main"); + if (IS_ERR(chan->clk_main)) { + dev_err(&pdev->dev, "main clock not found.\n"); + return PTR_ERR(chan->clk_main); + } + + chan->clk_apb = devm_clk_get(&pdev->dev, "clk_apb"); + if (IS_ERR(chan->clk_apb)) { + dev_err(&pdev->dev, "apb clock not found.\n"); + return PTR_ERR(chan->clk_apb); + } + + err = clk_prepare_enable(chan->clk_main); + if (err) { + dev_err(&pdev->dev, "Unable to enable main clock.\n"); + return err; + } + + err = clk_prepare_enable(chan->clk_apb); + if (err) { + clk_disable_unprepare(chan->clk_main); + dev_err(&pdev->dev, "Unable to enable apb clock.\n"); + return err; + } + + chan->desc_size = sizeof(struct zynqmp_dma_desc_ll); + chan->idle = true; + return 0; +} + +/** + * of_zynqmp_dma_xlate - Translation function + * @dma_spec: Pointer to DMA specifier as found in the device tree + * @ofdma: Pointer to DMA controller data + * + * Return: DMA channel pointer on success and NULL on error + */ +static struct dma_chan *of_zynqmp_dma_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct zynqmp_dma_device *zdev = ofdma->of_dma_data; + + return dma_get_slave_channel(&zdev->chan->common); +} + +/** + * zynqmp_dma_probe - Driver probe function + * @pdev: Pointer to the platform_device structure + * + * Return: '0' on success and failure value on error + */ +static int zynqmp_dma_probe(struct platform_device *pdev) +{ + struct zynqmp_dma_device *zdev; + struct dma_device *p; + int ret; + + zdev = devm_kzalloc(&pdev->dev, sizeof(*zdev), GFP_KERNEL); + if (!zdev) + return -ENOMEM; + + zdev->dev = &pdev->dev; + INIT_LIST_HEAD(&zdev->common.channels); + + dma_set_mask(&pdev->dev, DMA_BIT_MASK(44)); + dma_cap_set(DMA_SG, zdev->common.cap_mask); + dma_cap_set(DMA_MEMCPY, zdev->common.cap_mask); + + p = &zdev->common; + p->device_prep_dma_sg = zynqmp_dma_prep_sg; + p->device_prep_dma_memcpy = zynqmp_dma_prep_memcpy; + p->device_terminate_all = zynqmp_dma_device_terminate_all; + p->device_issue_pending = zynqmp_dma_issue_pending; + p->device_alloc_chan_resources = zynqmp_dma_alloc_chan_resources; + p->device_free_chan_resources = zynqmp_dma_free_chan_resources; + p->device_tx_status = dma_cookie_status; + p->device_config = zynqmp_dma_device_config; + p->dev = &pdev->dev; + + platform_set_drvdata(pdev, zdev); + + ret = zynqmp_dma_chan_probe(zdev, pdev); + if (ret) { + dev_err(&pdev->dev, "Probing channel failed\n"); + goto free_chan_resources; + } + + p->dst_addr_widths = BIT(zdev->chan->bus_width / 8); + p->src_addr_widths = BIT(zdev->chan->bus_width / 8); + + dma_async_device_register(&zdev->common); + + ret = of_dma_controller_register(pdev->dev.of_node, + of_zynqmp_dma_xlate, zdev); + if (ret) { + dev_err(&pdev->dev, "Unable to register DMA to DT\n"); + dma_async_device_unregister(&zdev->common); + goto free_chan_resources; + } + + dev_info(&pdev->dev, "ZynqMP DMA driver Probe success\n"); + + return 0; + +free_chan_resources: + zynqmp_dma_chan_remove(zdev->chan); + return ret; +} + +/** + * zynqmp_dma_remove - Driver remove function + * @pdev: Pointer to the platform_device structure + * + * Return: Always '0' + */ +static int zynqmp_dma_remove(struct platform_device *pdev) +{ + struct zynqmp_dma_device *zdev = platform_get_drvdata(pdev); + + of_dma_controller_free(pdev->dev.of_node); + dma_async_device_unregister(&zdev->common); + + zynqmp_dma_chan_remove(zdev->chan); + + return 0; +} + +static const struct of_device_id zynqmp_dma_of_match[] = { + { .compatible = "xlnx,zynqmp-dma-1.0", }, + {} +}; +MODULE_DEVICE_TABLE(of, zynqmp_dma_of_match); + +static struct platform_driver zynqmp_dma_driver = { + .driver = { + .name = "xilinx-zynqmp-dma", + .of_match_table = zynqmp_dma_of_match, + }, + .probe = zynqmp_dma_probe, + .remove = zynqmp_dma_remove, +}; + +module_platform_driver(zynqmp_dma_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Xilinx, Inc."); +MODULE_DESCRIPTION("Xilinx ZynqMP DMA driver"); diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 88e7fc797721..cb8f0347b934 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -231,7 +231,7 @@ struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev, obj->dev_addr = DMA_ERROR_CODE; - mapping = file_inode(obj->obj.filp)->i_mapping; + mapping = obj->obj.filp->f_mapping; mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE); DRM_DEBUG_DRIVER("alloc obj %p size %zu\n", obj, size); @@ -441,7 +441,7 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, if (sg_alloc_table(sgt, count, GFP_KERNEL)) goto free_sgt; - mapping = file_inode(dobj->obj.filp)->i_mapping; + mapping = dobj->obj.filp->f_mapping; for_each_sg(sgt->sgl, sg, count, i) { struct page *page; diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 32156060b9c9..ad89db36ca25 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -511,7 +511,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj) int i, npages; /* This is the shared memory object that backs the GEM resource */ - mapping = file_inode(obj->filp)->i_mapping; + mapping = obj->filp->f_mapping; /* We already BUG_ON() for non-page-aligned sizes in * drm_gem_object_init(), so we should never hit this unless diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index df9bcbab922f..8c6f750634af 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -660,7 +660,7 @@ static struct drm_gem_object *__etnaviv_gem_new(struct drm_device *dev, * why this is required _and_ expected if you're * going to pin these pages. */ - mapping = file_inode(obj->filp)->i_mapping; + mapping = obj->filp->f_mapping; mapping_set_gfp_mask(mapping, GFP_HIGHUSER); } diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index aad26851cee3..ed6117a0ee84 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -151,7 +151,7 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) { - struct address_space *mapping = file_inode(obj->base.filp)->i_mapping; + struct address_space *mapping = obj->base.filp->f_mapping; char *vaddr = obj->phys_handle->vaddr; struct sg_table *st; struct scatterlist *sg; @@ -218,7 +218,7 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj) obj->dirty = 0; if (obj->dirty) { - struct address_space *mapping = file_inode(obj->base.filp)->i_mapping; + struct address_space *mapping = obj->base.filp->f_mapping; char *vaddr = obj->phys_handle->vaddr; int i; @@ -2155,7 +2155,7 @@ i915_gem_object_invalidate(struct drm_i915_gem_object *obj) if (obj->base.filp == NULL) return; - mapping = file_inode(obj->base.filp)->i_mapping, + mapping = obj->base.filp->f_mapping, invalidate_mapping_pages(mapping, 0, (loff_t)-1); } @@ -2271,7 +2271,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) * * Fail silently without starting the shrinker */ - mapping = file_inode(obj->base.filp)->i_mapping; + mapping = obj->base.filp->f_mapping; gfp = mapping_gfp_constraint(mapping, ~(__GFP_IO | __GFP_RECLAIM)); gfp |= __GFP_NORETRY | __GFP_NOWARN; sg = st->sgl; @@ -4522,7 +4522,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, mask |= __GFP_DMA32; } - mapping = file_inode(obj->base.filp)->i_mapping; + mapping = obj->base.filp->f_mapping; mapping_set_gfp_mask(mapping, mask); i915_gem_object_init(obj, &i915_gem_object_ops); diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 03698b6c806c..0dbd0f03f9bd 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -1407,7 +1407,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, if (ret) goto err_free; - mapping = file_inode(obj->filp)->i_mapping; + mapping = obj->filp->f_mapping; mapping_set_gfp_mask(mapping, GFP_USER | __GFP_DMA32); } diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 077ae9b2865d..97542c35d6ef 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -298,7 +298,7 @@ int ttm_tt_swapin(struct ttm_tt *ttm) swap_storage = ttm->swap_storage; BUG_ON(swap_storage == NULL); - swap_space = file_inode(swap_storage)->i_mapping; + swap_space = swap_storage->f_mapping; for (i = 0; i < ttm->num_pages; ++i) { from_page = shmem_read_mapping_page(swap_space, i); @@ -347,7 +347,7 @@ int ttm_tt_swapout(struct ttm_tt *ttm, struct file *persistent_swap_storage) } else swap_storage = persistent_swap_storage; - swap_space = file_inode(swap_storage)->i_mapping; + swap_space = swap_storage->f_mapping; for (i = 0; i < ttm->num_pages; ++i) { from_page = ttm->pages[i]; diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 5646ca4b95de..78ac4811bd3c 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -388,6 +388,21 @@ config HID_LCPOWER ---help--- Support for LC-Power RC1000MCE RF remote control. +config HID_LED + tristate "Simple RGB LED support" + depends on HID + depends on LEDS_CLASS + ---help--- + Support for simple RGB LED devices. Currently supported are: + - Riso Kagaku Webmail Notifier + - Dream Cheeky Webmail Notifier and Friends Alert + - ThingM blink(1) + - Delcom Visual Signal Indicator Generation 2 + - Greynut Luxafor + + To compile this driver as a module, choose M here: the + module will be called hid-led. + config HID_LENOVO tristate "Lenovo / Thinkpad devices" depends on HID @@ -819,11 +834,11 @@ config HID_THINGM tristate "ThingM blink(1) USB RGB LED" depends on HID depends on LEDS_CLASS + select HID_LED ---help--- - Support for the ThingM blink(1) USB RGB LED. This driver registers a - Linux LED class instance, plus additional sysfs attributes to control - RGB colors, fade time and playing. The device is exposed through hidraw - to access other functions. + Support for the ThingM blink(1) USB RGB LED. This driver has been + merged into the generic hid led driver. Config symbol HID_THINGM + just selects HID_LED and will be removed soon. config HID_THRUSTMASTER tristate "ThrustMaster devices support" @@ -936,6 +951,14 @@ config HID_SENSOR_CUSTOM_SENSOR standard sensors. Select this config option for custom/generic sensor support. +config HID_ALPS + tristate "Alps HID device support" + depends on HID + ---help--- + Support for Alps I2C HID touchpads and StickPointer. + Say Y here if you have a Alps touchpads over i2c-hid or usbhid + and want support for its special functionalities. + endmenu endif # HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index a2fb562de748..fc4b2aa47f2e 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -21,6 +21,7 @@ hid-wiimote-y := hid-wiimote-core.o hid-wiimote-modules.o hid-wiimote-$(CONFIG_DEBUG_FS) += hid-wiimote-debug.o obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o +obj-$(CONFIG_HID_ALPS) += hid-alps.o obj-$(CONFIG_HID_ACRUX) += hid-axff.o obj-$(CONFIG_HID_APPLE) += hid-apple.o obj-$(CONFIG_HID_APPLEIR) += hid-appleir.o @@ -90,12 +91,12 @@ obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o obj-$(CONFIG_HID_STEELSERIES) += hid-steelseries.o obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o -obj-$(CONFIG_HID_THINGM) += hid-thingm.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o obj-$(CONFIG_HID_TIVO) += hid-tivo.o obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o +obj-$(CONFIG_HID_LED) += hid-led.o obj-$(CONFIG_HID_XINMO) += hid-xinmo.o obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o diff --git a/drivers/hid/hid-alps.c b/drivers/hid/hid-alps.c new file mode 100644 index 000000000000..048befde295a --- /dev/null +++ b/drivers/hid/hid-alps.c @@ -0,0 +1,506 @@ +/* + * Copyright (c) 2016 Masaki Ota <masaki.ota@jp.alps.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + */ + +#include <linux/kernel.h> +#include <linux/hid.h> +#include <linux/input.h> +#include <linux/input/mt.h> +#include <linux/module.h> +#include <asm/unaligned.h> +#include "hid-ids.h" + +/* ALPS Device Product ID */ +#define HID_PRODUCT_ID_T3_BTNLESS 0xD0C0 +#define HID_PRODUCT_ID_COSMO 0x1202 +#define HID_PRODUCT_ID_U1_PTP_1 0x1207 +#define HID_PRODUCT_ID_U1 0x1209 +#define HID_PRODUCT_ID_U1_PTP_2 0x120A +#define HID_PRODUCT_ID_U1_DUAL 0x120B +#define HID_PRODUCT_ID_T4_BTNLESS 0x120C + +#define DEV_SINGLEPOINT 0x01 +#define DEV_DUALPOINT 0x02 + +#define U1_MOUSE_REPORT_ID 0x01 /* Mouse data ReportID */ +#define U1_ABSOLUTE_REPORT_ID 0x03 /* Absolute data ReportID */ +#define U1_FEATURE_REPORT_ID 0x05 /* Feature ReportID */ +#define U1_SP_ABSOLUTE_REPORT_ID 0x06 /* Feature ReportID */ + +#define U1_FEATURE_REPORT_LEN 0x08 /* Feature Report Length */ +#define U1_FEATURE_REPORT_LEN_ALL 0x0A +#define U1_CMD_REGISTER_READ 0xD1 +#define U1_CMD_REGISTER_WRITE 0xD2 + +#define U1_DEVTYPE_SP_SUPPORT 0x10 /* SP Support */ +#define U1_DISABLE_DEV 0x01 +#define U1_TP_ABS_MODE 0x02 +#define U1_SP_ABS_MODE 0x80 + +#define ADDRESS_U1_DEV_CTRL_1 0x00800040 +#define ADDRESS_U1_DEVICE_TYP 0x00800043 +#define ADDRESS_U1_NUM_SENS_X 0x00800047 +#define ADDRESS_U1_NUM_SENS_Y 0x00800048 +#define ADDRESS_U1_PITCH_SENS_X 0x00800049 +#define ADDRESS_U1_PITCH_SENS_Y 0x0080004A +#define ADDRESS_U1_RESO_DWN_ABS 0x0080004E +#define ADDRESS_U1_PAD_BTN 0x00800052 +#define ADDRESS_U1_SP_BTN 0x0080009F + +#define MAX_TOUCHES 5 + +/** + * struct u1_data + * + * @input: pointer to the kernel input device + * @input2: pointer to the kernel input2 device + * @hdev: pointer to the struct hid_device + * + * @dev_ctrl: device control parameter + * @dev_type: device type + * @sen_line_num_x: number of sensor line of X + * @sen_line_num_y: number of sensor line of Y + * @pitch_x: sensor pitch of X + * @pitch_y: sensor pitch of Y + * @resolution: resolution + * @btn_info: button information + * @x_active_len_mm: active area length of X (mm) + * @y_active_len_mm: active area length of Y (mm) + * @x_max: maximum x coordinate value + * @y_max: maximum y coordinate value + * @btn_cnt: number of buttons + * @sp_btn_cnt: number of stick buttons + */ +struct u1_dev { + struct input_dev *input; + struct input_dev *input2; + struct hid_device *hdev; + + u8 dev_ctrl; + u8 dev_type; + u8 sen_line_num_x; + u8 sen_line_num_y; + u8 pitch_x; + u8 pitch_y; + u8 resolution; + u8 btn_info; + u8 sp_btn_info; + u32 x_active_len_mm; + u32 y_active_len_mm; + u32 x_max; + u32 y_max; + u32 btn_cnt; + u32 sp_btn_cnt; +}; + +static int u1_read_write_register(struct hid_device *hdev, u32 address, + u8 *read_val, u8 write_val, bool read_flag) +{ + int ret, i; + u8 check_sum; + u8 *input; + u8 *readbuf; + + input = kzalloc(U1_FEATURE_REPORT_LEN, GFP_KERNEL); + if (!input) + return -ENOMEM; + + input[0] = U1_FEATURE_REPORT_ID; + if (read_flag) { + input[1] = U1_CMD_REGISTER_READ; + input[6] = 0x00; + } else { + input[1] = U1_CMD_REGISTER_WRITE; + input[6] = write_val; + } + + put_unaligned_le32(address, input + 2); + + /* Calculate the checksum */ + check_sum = U1_FEATURE_REPORT_LEN_ALL; + for (i = 0; i < U1_FEATURE_REPORT_LEN - 1; i++) + check_sum += input[i]; + + input[7] = check_sum; + ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, input, + U1_FEATURE_REPORT_LEN, + HID_FEATURE_REPORT, HID_REQ_SET_REPORT); + + if (ret < 0) { + dev_err(&hdev->dev, "failed to read command (%d)\n", ret); + goto exit; + } + + if (read_flag) { + readbuf = kzalloc(U1_FEATURE_REPORT_LEN, GFP_KERNEL); + if (!readbuf) { + kfree(input); + return -ENOMEM; + } + + ret = hid_hw_raw_request(hdev, U1_FEATURE_REPORT_ID, readbuf, + U1_FEATURE_REPORT_LEN, + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); + + if (ret < 0) { + dev_err(&hdev->dev, "failed read register (%d)\n", ret); + goto exit; + } + + *read_val = readbuf[6]; + + kfree(readbuf); + } + + ret = 0; + +exit: + kfree(input); + return ret; +} + +static int alps_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) +{ + unsigned int x, y, z; + int i; + short sp_x, sp_y; + struct u1_dev *hdata = hid_get_drvdata(hdev); + + switch (data[0]) { + case U1_MOUSE_REPORT_ID: + break; + case U1_FEATURE_REPORT_ID: + break; + case U1_ABSOLUTE_REPORT_ID: + for (i = 0; i < MAX_TOUCHES; i++) { + u8 *contact = &data[i * 5]; + + x = get_unaligned_le16(contact + 3); + y = get_unaligned_le16(contact + 5); + z = contact[7] & 0x7F; + + input_mt_slot(hdata->input, i); + + if (z != 0) { + input_mt_report_slot_state(hdata->input, + MT_TOOL_FINGER, 1); + } else { + input_mt_report_slot_state(hdata->input, + MT_TOOL_FINGER, 0); + break; + } + + input_report_abs(hdata->input, ABS_MT_POSITION_X, x); + input_report_abs(hdata->input, ABS_MT_POSITION_Y, y); + input_report_abs(hdata->input, ABS_MT_PRESSURE, z); + + } + + input_mt_sync_frame(hdata->input); + + input_report_key(hdata->input, BTN_LEFT, + data[1] & 0x1); + input_report_key(hdata->input, BTN_RIGHT, + (data[1] & 0x2)); + input_report_key(hdata->input, BTN_MIDDLE, + (data[1] & 0x4)); + + input_sync(hdata->input); + + return 1; + + case U1_SP_ABSOLUTE_REPORT_ID: + sp_x = get_unaligned_le16(data+2); + sp_y = get_unaligned_le16(data+4); + + sp_x = sp_x / 8; + sp_y = sp_y / 8; + + input_report_rel(hdata->input2, REL_X, sp_x); + input_report_rel(hdata->input2, REL_Y, sp_y); + + input_report_key(hdata->input2, BTN_LEFT, + data[1] & 0x1); + input_report_key(hdata->input2, BTN_RIGHT, + (data[1] & 0x2)); + input_report_key(hdata->input2, BTN_MIDDLE, + (data[1] & 0x4)); + + input_sync(hdata->input2); + + return 1; + } + + return 0; +} + +#ifdef CONFIG_PM +static int alps_post_reset(struct hid_device *hdev) +{ + return u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + NULL, U1_TP_ABS_MODE, false); +} + +static int alps_post_resume(struct hid_device *hdev) +{ + return u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + NULL, U1_TP_ABS_MODE, false); +} +#endif /* CONFIG_PM */ + +static int alps_input_configured(struct hid_device *hdev, struct hid_input *hi) +{ + struct u1_dev *data = hid_get_drvdata(hdev); + struct input_dev *input = hi->input, *input2; + struct u1_dev devInfo; + int ret; + int res_x, res_y, i; + + data->input = input; + + hid_dbg(hdev, "Opening low level driver\n"); + ret = hid_hw_open(hdev); + if (ret) + return ret; + + /* Allow incoming hid reports */ + hid_device_io_start(hdev); + + /* Device initialization */ + ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + &devInfo.dev_ctrl, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_DEV_CTRL_1 (%d)\n", ret); + goto exit; + } + + devInfo.dev_ctrl &= ~U1_DISABLE_DEV; + devInfo.dev_ctrl |= U1_TP_ABS_MODE; + ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + NULL, devInfo.dev_ctrl, false); + if (ret < 0) { + dev_err(&hdev->dev, "failed to change TP mode (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_X, + &devInfo.sen_line_num_x, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_NUM_SENS_X (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_NUM_SENS_Y, + &devInfo.sen_line_num_y, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_NUM_SENS_Y (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_X, + &devInfo.pitch_x, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_PITCH_SENS_X (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_PITCH_SENS_Y, + &devInfo.pitch_y, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_PITCH_SENS_Y (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_RESO_DWN_ABS, + &devInfo.resolution, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_RESO_DWN_ABS (%d)\n", ret); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_PAD_BTN, + &devInfo.btn_info, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_PAD_BTN (%d)\n", ret); + goto exit; + } + + /* Check StickPointer device */ + ret = u1_read_write_register(hdev, ADDRESS_U1_DEVICE_TYP, + &devInfo.dev_type, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_DEVICE_TYP (%d)\n", ret); + goto exit; + } + + devInfo.x_active_len_mm = + (devInfo.pitch_x * (devInfo.sen_line_num_x - 1)) / 10; + devInfo.y_active_len_mm = + (devInfo.pitch_y * (devInfo.sen_line_num_y - 1)) / 10; + + devInfo.x_max = + (devInfo.resolution << 2) * (devInfo.sen_line_num_x - 1); + devInfo.y_max = + (devInfo.resolution << 2) * (devInfo.sen_line_num_y - 1); + + __set_bit(EV_ABS, input->evbit); + input_set_abs_params(input, ABS_MT_POSITION_X, 1, devInfo.x_max, 0, 0); + input_set_abs_params(input, ABS_MT_POSITION_Y, 1, devInfo.y_max, 0, 0); + + if (devInfo.x_active_len_mm && devInfo.y_active_len_mm) { + res_x = (devInfo.x_max - 1) / devInfo.x_active_len_mm; + res_y = (devInfo.y_max - 1) / devInfo.y_active_len_mm; + + input_abs_set_res(input, ABS_MT_POSITION_X, res_x); + input_abs_set_res(input, ABS_MT_POSITION_Y, res_y); + } + + input_set_abs_params(input, ABS_MT_PRESSURE, 0, 64, 0, 0); + + input_mt_init_slots(input, MAX_TOUCHES, INPUT_MT_POINTER); + + __set_bit(EV_KEY, input->evbit); + if ((devInfo.btn_info & 0x0F) == (devInfo.btn_info & 0xF0) >> 4) { + devInfo.btn_cnt = (devInfo.btn_info & 0x0F); + } else { + /* Button pad */ + devInfo.btn_cnt = 1; + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + } + + for (i = 0; i < devInfo.btn_cnt; i++) + __set_bit(BTN_LEFT + i, input->keybit); + + + /* Stick device initialization */ + if (devInfo.dev_type & U1_DEVTYPE_SP_SUPPORT) { + + input2 = input_allocate_device(); + if (!input2) { + input_free_device(input2); + goto exit; + } + + data->input2 = input2; + + devInfo.dev_ctrl |= U1_SP_ABS_MODE; + ret = u1_read_write_register(hdev, ADDRESS_U1_DEV_CTRL_1, + NULL, devInfo.dev_ctrl, false); + if (ret < 0) { + dev_err(&hdev->dev, "failed SP mode (%d)\n", ret); + input_free_device(input2); + goto exit; + } + + ret = u1_read_write_register(hdev, ADDRESS_U1_SP_BTN, + &devInfo.sp_btn_info, 0, true); + if (ret < 0) { + dev_err(&hdev->dev, "failed U1_SP_BTN (%d)\n", ret); + input_free_device(input2); + goto exit; + } + + input2->phys = input->phys; + input2->name = "DualPoint Stick"; + input2->id.bustype = BUS_I2C; + input2->id.vendor = input->id.vendor; + input2->id.product = input->id.product; + input2->id.version = input->id.version; + input2->dev.parent = input->dev.parent; + + __set_bit(EV_KEY, input2->evbit); + devInfo.sp_btn_cnt = (devInfo.sp_btn_info & 0x0F); + for (i = 0; i < devInfo.sp_btn_cnt; i++) + __set_bit(BTN_LEFT + i, input2->keybit); + + __set_bit(EV_REL, input2->evbit); + __set_bit(REL_X, input2->relbit); + __set_bit(REL_Y, input2->relbit); + __set_bit(INPUT_PROP_POINTER, input2->propbit); + __set_bit(INPUT_PROP_POINTING_STICK, input2->propbit); + + if (input_register_device(data->input2)) { + input_free_device(input2); + goto exit; + } + } + +exit: + hid_device_io_stop(hdev); + hid_hw_close(hdev); + return ret; +} + +static int alps_input_mapping(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +{ + return -1; +} + +static int alps_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + struct u1_dev *data = NULL; + int ret; + + data = devm_kzalloc(&hdev->dev, sizeof(struct u1_dev), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->hdev = hdev; + hid_set_drvdata(hdev, data); + + hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed\n"); + return ret; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed\n"); + return ret; + } + + return 0; +} + +static void alps_remove(struct hid_device *hdev) +{ + hid_hw_stop(hdev); +} + +static const struct hid_device_id alps_id[] = { + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, + USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) }, + { } +}; +MODULE_DEVICE_TABLE(hid, alps_id); + +static struct hid_driver alps_driver = { + .name = "hid-alps", + .id_table = alps_id, + .probe = alps_probe, + .remove = alps_remove, + .raw_event = alps_raw_event, + .input_mapping = alps_input_mapping, + .input_configured = alps_input_configured, +#ifdef CONFIG_PM + .resume = alps_post_resume, + .reset_resume = alps_post_reset, +#endif +}; + +module_hid_driver(alps_driver); + +MODULE_AUTHOR("Masaki Ota <masaki.ota@jp.alps.com>"); +MODULE_DESCRIPTION("ALPS HID driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 884d82f9190e..2e046082210f 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -474,6 +474,8 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI), + .driver_data = APPLE_HAS_FN }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), .driver_data = APPLE_HAS_FN }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO), diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 8ea3a26360e9..08f53c7fd513 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1772,6 +1772,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) }, + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_ALPS_JP, HID_DEVICE_ID_ALPS_U1_DUAL) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, @@ -1851,6 +1852,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_NOTEBOOK_KEYBOARD) }, @@ -1877,8 +1879,11 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DELCOM, USB_DEVICE_ID_DELCOM_VISUAL_IND) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) }, + { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_FA) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) }, { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) }, @@ -1962,6 +1967,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_LUXAFOR) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_KEYBOARD) }, { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, @@ -2008,6 +2014,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) }, #if IS_ENABLED(CONFIG_HID_ROCCAT) { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, @@ -2348,8 +2355,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DEALEXTREAME, USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701) }, { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) }, { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x0004) }, - { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, 0x000a) }, { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, 0x0400) }, { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, 0x0401) }, { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, @@ -2486,7 +2491,6 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DPAD) }, #endif { HID_USB_DEVICE(USB_VENDOR_ID_YEALINK, USB_DEVICE_ID_YEALINK_P1K_P4K_B2K) }, - { HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, USB_DEVICE_ID_RI_KA_WEBMAIL) }, { } }; diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3eec09a134cb..4ed9a4fdfea7 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -70,6 +70,9 @@ #define USB_VENDOR_ID_ALPS 0x0433 #define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 +#define USB_VENDOR_ID_ALPS_JP 0x044E +#define HID_DEVICE_ID_ALPS_U1_DUAL 0x120B + #define USB_VENDOR_ID_ANTON 0x1130 #define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101 @@ -142,6 +145,7 @@ #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ANSI 0x0255 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS 0x0257 +#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI 0x0267 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290 #define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291 #define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292 @@ -296,6 +300,9 @@ #define USB_VENDOR_ID_DEALEXTREAME 0x10c5 #define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a +#define USB_VENDOR_ID_DELCOM 0x0fc5 +#define USB_DEVICE_ID_DELCOM_VISUAL_IND 0xb080 + #define USB_VENDOR_ID_DELORME 0x1163 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 @@ -334,6 +341,8 @@ #define USB_DEVICE_ID_ELECOM_BM084 0x0061 #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 +#define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004 +#define USB_DEVICE_ID_DREAM_CHEEKY_FA 0x000a #define USB_VENDOR_ID_ELITEGROUP 0x03fc #define USB_DEVICE_ID_ELITEGROUP_05D8 0x05d8 @@ -680,6 +689,7 @@ #define USB_DEVICE_ID_PICOLCD_BOOTLOADER 0xf002 #define USB_DEVICE_ID_PICK16F1454 0x0042 #define USB_DEVICE_ID_PICK16F1454_V2 0xf2f7 +#define USB_DEVICE_ID_LUXAFOR 0xf372 #define USB_VENDOR_ID_MICROSOFT 0x045e #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b diff --git a/drivers/hid/hid-led.c b/drivers/hid/hid-led.c new file mode 100644 index 000000000000..d8d55f37b4f5 --- /dev/null +++ b/drivers/hid/hid-led.c @@ -0,0 +1,523 @@ +/* + * Simple USB RGB LED driver + * + * Copyright 2016 Heiner Kallweit <hkallweit1@gmail.com> + * Based on drivers/hid/hid-thingm.c and + * drivers/usb/misc/usbled.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + */ + +#include <linux/hid.h> +#include <linux/hidraw.h> +#include <linux/leds.h> +#include <linux/module.h> +#include <linux/mutex.h> + +#include "hid-ids.h" + +enum hidled_report_type { + RAW_REQUEST, + OUTPUT_REPORT +}; + +enum hidled_type { + RISO_KAGAKU, + DREAM_CHEEKY, + THINGM, + DELCOM, + LUXAFOR, +}; + +static unsigned const char riso_kagaku_tbl[] = { +/* R+2G+4B -> riso kagaku color index */ + [0] = 0, /* black */ + [1] = 2, /* red */ + [2] = 1, /* green */ + [3] = 5, /* yellow */ + [4] = 3, /* blue */ + [5] = 6, /* magenta */ + [6] = 4, /* cyan */ + [7] = 7 /* white */ +}; + +#define RISO_KAGAKU_IX(r, g, b) riso_kagaku_tbl[((r)?1:0)+((g)?2:0)+((b)?4:0)] + +union delcom_packet { + __u8 data[8]; + struct { + __u8 major_cmd; + __u8 minor_cmd; + __u8 data_lsb; + __u8 data_msb; + } tx; + struct { + __u8 cmd; + } rx; + struct { + __le16 family_code; + __le16 security_code; + __u8 fw_version; + } fw; +}; + +#define DELCOM_GREEN_LED 0 +#define DELCOM_RED_LED 1 +#define DELCOM_BLUE_LED 2 + +struct hidled_device; +struct hidled_rgb; + +struct hidled_config { + enum hidled_type type; + const char *name; + const char *short_name; + enum led_brightness max_brightness; + int num_leds; + size_t report_size; + enum hidled_report_type report_type; + int (*init)(struct hidled_device *ldev); + int (*write)(struct led_classdev *cdev, enum led_brightness br); +}; + +struct hidled_led { + struct led_classdev cdev; + struct hidled_rgb *rgb; + char name[32]; +}; + +struct hidled_rgb { + struct hidled_device *ldev; + struct hidled_led red; + struct hidled_led green; + struct hidled_led blue; + u8 num; +}; + +struct hidled_device { + const struct hidled_config *config; + struct hid_device *hdev; + struct hidled_rgb *rgb; + struct mutex lock; +}; + +#define MAX_REPORT_SIZE 16 + +#define to_hidled_led(arg) container_of(arg, struct hidled_led, cdev) + +static bool riso_kagaku_switch_green_blue; +module_param(riso_kagaku_switch_green_blue, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(riso_kagaku_switch_green_blue, + "switch green and blue RGB component for Riso Kagaku devices"); + +static int hidled_send(struct hidled_device *ldev, __u8 *buf) +{ + int ret; + + mutex_lock(&ldev->lock); + + if (ldev->config->report_type == RAW_REQUEST) + ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, + ldev->config->report_size, + HID_FEATURE_REPORT, + HID_REQ_SET_REPORT); + else if (ldev->config->report_type == OUTPUT_REPORT) + ret = hid_hw_output_report(ldev->hdev, buf, + ldev->config->report_size); + else + ret = -EINVAL; + + mutex_unlock(&ldev->lock); + + if (ret < 0) + return ret; + + return ret == ldev->config->report_size ? 0 : -EMSGSIZE; +} + +/* reading data is supported for report type RAW_REQUEST only */ +static int hidled_recv(struct hidled_device *ldev, __u8 *buf) +{ + int ret; + + if (ldev->config->report_type != RAW_REQUEST) + return -EINVAL; + + mutex_lock(&ldev->lock); + + ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, + ldev->config->report_size, + HID_FEATURE_REPORT, + HID_REQ_SET_REPORT); + if (ret < 0) + goto err; + + ret = hid_hw_raw_request(ldev->hdev, buf[0], buf, + ldev->config->report_size, + HID_FEATURE_REPORT, + HID_REQ_GET_REPORT); +err: + mutex_unlock(&ldev->lock); + + return ret < 0 ? ret : 0; +} + +static u8 riso_kagaku_index(struct hidled_rgb *rgb) +{ + enum led_brightness r, g, b; + + r = rgb->red.cdev.brightness; + g = rgb->green.cdev.brightness; + b = rgb->blue.cdev.brightness; + + if (riso_kagaku_switch_green_blue) + return RISO_KAGAKU_IX(r, b, g); + else + return RISO_KAGAKU_IX(r, g, b); +} + +static int riso_kagaku_write(struct led_classdev *cdev, enum led_brightness br) +{ + struct hidled_led *led = to_hidled_led(cdev); + struct hidled_rgb *rgb = led->rgb; + __u8 buf[MAX_REPORT_SIZE] = {}; + + buf[1] = riso_kagaku_index(rgb); + + return hidled_send(rgb->ldev, buf); +} + +static int dream_cheeky_write(struct led_classdev *cdev, enum led_brightness br) +{ + struct hidled_led *led = to_hidled_led(cdev); + struct hidled_rgb *rgb = led->rgb; + __u8 buf[MAX_REPORT_SIZE] = {}; + + buf[1] = rgb->red.cdev.brightness; + buf[2] = rgb->green.cdev.brightness; + buf[3] = rgb->blue.cdev.brightness; + buf[7] = 0x1a; + buf[8] = 0x05; + + return hidled_send(rgb->ldev, buf); +} + +static int dream_cheeky_init(struct hidled_device *ldev) +{ + __u8 buf[MAX_REPORT_SIZE] = {}; + + /* Dream Cheeky magic */ + buf[1] = 0x1f; + buf[2] = 0x02; + buf[4] = 0x5f; + buf[7] = 0x1a; + buf[8] = 0x03; + + return hidled_send(ldev, buf); +} + +static int _thingm_write(struct led_classdev *cdev, enum led_brightness br, + u8 offset) +{ + struct hidled_led *led = to_hidled_led(cdev); + __u8 buf[MAX_REPORT_SIZE] = { 1, 'c' }; + + buf[2] = led->rgb->red.cdev.brightness; + buf[3] = led->rgb->green.cdev.brightness; + buf[4] = led->rgb->blue.cdev.brightness; + buf[7] = led->rgb->num + offset; + + return hidled_send(led->rgb->ldev, buf); +} + +static int thingm_write_v1(struct led_classdev *cdev, enum led_brightness br) +{ + return _thingm_write(cdev, br, 0); +} + +static int thingm_write(struct led_classdev *cdev, enum led_brightness br) +{ + return _thingm_write(cdev, br, 1); +} + +static const struct hidled_config hidled_config_thingm_v1 = { + .name = "ThingM blink(1) v1", + .short_name = "thingm", + .max_brightness = 255, + .num_leds = 1, + .report_size = 9, + .report_type = RAW_REQUEST, + .write = thingm_write_v1, +}; + +static int thingm_init(struct hidled_device *ldev) +{ + __u8 buf[MAX_REPORT_SIZE] = { 1, 'v' }; + int ret; + + ret = hidled_recv(ldev, buf); + if (ret) + return ret; + + /* Check for firmware major version 1 */ + if (buf[3] == '1') + ldev->config = &hidled_config_thingm_v1; + + return 0; +} + +static inline int delcom_get_lednum(const struct hidled_led *led) +{ + if (led == &led->rgb->red) + return DELCOM_RED_LED; + else if (led == &led->rgb->green) + return DELCOM_GREEN_LED; + else + return DELCOM_BLUE_LED; +} + +static int delcom_enable_led(struct hidled_led *led) +{ + union delcom_packet dp = { .tx.major_cmd = 101, .tx.minor_cmd = 12 }; + + dp.tx.data_lsb = 1 << delcom_get_lednum(led); + dp.tx.data_msb = 0; + + return hidled_send(led->rgb->ldev, dp.data); +} + +static int delcom_set_pwm(struct hidled_led *led) +{ + union delcom_packet dp = { .tx.major_cmd = 101, .tx.minor_cmd = 34 }; + + dp.tx.data_lsb = delcom_get_lednum(led); + dp.tx.data_msb = led->cdev.brightness; + + return hidled_send(led->rgb->ldev, dp.data); +} + +static int delcom_write(struct led_classdev *cdev, enum led_brightness br) +{ + struct hidled_led *led = to_hidled_led(cdev); + int ret; + + /* + * enable LED + * We can't do this in the init function already because the device + * is internally reset later. + */ + ret = delcom_enable_led(led); + if (ret) + return ret; + + return delcom_set_pwm(led); +} + +static int delcom_init(struct hidled_device *ldev) +{ + union delcom_packet dp = { .rx.cmd = 104 }; + int ret; + + ret = hidled_recv(ldev, dp.data); + if (ret) + return ret; + /* + * Several Delcom devices share the same USB VID/PID + * Check for family id 2 for Visual Signal Indicator + */ + return le16_to_cpu(dp.fw.family_code) == 2 ? 0 : -ENODEV; +} + +static int luxafor_write(struct led_classdev *cdev, enum led_brightness br) +{ + struct hidled_led *led = to_hidled_led(cdev); + __u8 buf[MAX_REPORT_SIZE] = { [1] = 1 }; + + buf[2] = led->rgb->num + 1; + buf[3] = led->rgb->red.cdev.brightness; + buf[4] = led->rgb->green.cdev.brightness; + buf[5] = led->rgb->blue.cdev.brightness; + + return hidled_send(led->rgb->ldev, buf); +} + +static const struct hidled_config hidled_configs[] = { + { + .type = RISO_KAGAKU, + .name = "Riso Kagaku Webmail Notifier", + .short_name = "riso_kagaku", + .max_brightness = 1, + .num_leds = 1, + .report_size = 6, + .report_type = OUTPUT_REPORT, + .write = riso_kagaku_write, + }, + { + .type = DREAM_CHEEKY, + .name = "Dream Cheeky Webmail Notifier", + .short_name = "dream_cheeky", + .max_brightness = 31, + .num_leds = 1, + .report_size = 9, + .report_type = RAW_REQUEST, + .init = dream_cheeky_init, + .write = dream_cheeky_write, + }, + { + .type = THINGM, + .name = "ThingM blink(1)", + .short_name = "thingm", + .max_brightness = 255, + .num_leds = 2, + .report_size = 9, + .report_type = RAW_REQUEST, + .init = thingm_init, + .write = thingm_write, + }, + { + .type = DELCOM, + .name = "Delcom Visual Signal Indicator G2", + .short_name = "delcom", + .max_brightness = 100, + .num_leds = 1, + .report_size = 8, + .report_type = RAW_REQUEST, + .init = delcom_init, + .write = delcom_write, + }, + { + .type = LUXAFOR, + .name = "Greynut Luxafor", + .short_name = "luxafor", + .max_brightness = 255, + .num_leds = 6, + .report_size = 9, + .report_type = OUTPUT_REPORT, + .write = luxafor_write, + }, +}; + +static int hidled_init_led(struct hidled_led *led, const char *color_name, + struct hidled_rgb *rgb, unsigned int minor) +{ + const struct hidled_config *config = rgb->ldev->config; + + if (config->num_leds > 1) + snprintf(led->name, sizeof(led->name), "%s%u:%s:led%u", + config->short_name, minor, color_name, rgb->num); + else + snprintf(led->name, sizeof(led->name), "%s%u:%s", + config->short_name, minor, color_name); + led->cdev.name = led->name; + led->cdev.max_brightness = config->max_brightness; + led->cdev.brightness_set_blocking = config->write; + led->cdev.flags = LED_HW_PLUGGABLE; + led->rgb = rgb; + + return devm_led_classdev_register(&rgb->ldev->hdev->dev, &led->cdev); +} + +static int hidled_init_rgb(struct hidled_rgb *rgb, unsigned int minor) +{ + int ret; + + /* Register the red diode */ + ret = hidled_init_led(&rgb->red, "red", rgb, minor); + if (ret) + return ret; + + /* Register the green diode */ + ret = hidled_init_led(&rgb->green, "green", rgb, minor); + if (ret) + return ret; + + /* Register the blue diode */ + return hidled_init_led(&rgb->blue, "blue", rgb, minor); +} + +static int hidled_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + struct hidled_device *ldev; + unsigned int minor; + int ret, i; + + ldev = devm_kzalloc(&hdev->dev, sizeof(*ldev), GFP_KERNEL); + if (!ldev) + return -ENOMEM; + + ret = hid_parse(hdev); + if (ret) + return ret; + + ldev->hdev = hdev; + mutex_init(&ldev->lock); + + for (i = 0; !ldev->config && i < ARRAY_SIZE(hidled_configs); i++) + if (hidled_configs[i].type == id->driver_data) + ldev->config = &hidled_configs[i]; + + if (!ldev->config) + return -EINVAL; + + if (ldev->config->init) { + ret = ldev->config->init(ldev); + if (ret) + return ret; + } + + ldev->rgb = devm_kcalloc(&hdev->dev, ldev->config->num_leds, + sizeof(struct hidled_rgb), GFP_KERNEL); + if (!ldev->rgb) + return -ENOMEM; + + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); + if (ret) + return ret; + + minor = ((struct hidraw *) hdev->hidraw)->minor; + + for (i = 0; i < ldev->config->num_leds; i++) { + ldev->rgb[i].ldev = ldev; + ldev->rgb[i].num = i; + ret = hidled_init_rgb(&ldev->rgb[i], minor); + if (ret) { + hid_hw_stop(hdev); + return ret; + } + } + + hid_info(hdev, "%s initialized\n", ldev->config->name); + + return 0; +} + +static const struct hid_device_id hidled_table[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_RISO_KAGAKU, + USB_DEVICE_ID_RI_KA_WEBMAIL), .driver_data = RISO_KAGAKU }, + { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, + USB_DEVICE_ID_DREAM_CHEEKY_WN), .driver_data = DREAM_CHEEKY }, + { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, + USB_DEVICE_ID_DREAM_CHEEKY_FA), .driver_data = DREAM_CHEEKY }, + { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, + USB_DEVICE_ID_BLINK1), .driver_data = THINGM }, + { HID_USB_DEVICE(USB_VENDOR_ID_DELCOM, + USB_DEVICE_ID_DELCOM_VISUAL_IND), .driver_data = DELCOM }, + { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, + USB_DEVICE_ID_LUXAFOR), .driver_data = LUXAFOR }, + { } +}; +MODULE_DEVICE_TABLE(hid, hidled_table); + +static struct hid_driver hidled_driver = { + .name = "hid-led", + .probe = hidled_probe, + .id_table = hidled_table, +}; + +module_hid_driver(hidled_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Heiner Kallweit <hkallweit1@gmail.com>"); +MODULE_DESCRIPTION("Simple USB RGB LED driver"); diff --git a/drivers/hid/hid-thingm.c b/drivers/hid/hid-thingm.c deleted file mode 100644 index 9ad9c6ec5bba..000000000000 --- a/drivers/hid/hid-thingm.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * ThingM blink(1) USB RGB LED driver - * - * Copyright 2013-2014 Savoir-faire Linux Inc. - * Vivien Didelot <vivien.didelot@savoirfairelinux.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - */ - -#include <linux/hid.h> -#include <linux/hidraw.h> -#include <linux/leds.h> -#include <linux/module.h> -#include <linux/mutex.h> - -#include "hid-ids.h" - -#define REPORT_ID 1 -#define REPORT_SIZE 9 - -/* Firmware major number of supported devices */ -#define THINGM_MAJOR_MK1 '1' -#define THINGM_MAJOR_MK2 '2' - -struct thingm_fwinfo { - char major; - unsigned numrgb; - unsigned first; -}; - -static const struct thingm_fwinfo thingm_fwinfo[] = { - { - .major = THINGM_MAJOR_MK1, - .numrgb = 1, - .first = 0, - }, { - .major = THINGM_MAJOR_MK2, - .numrgb = 2, - .first = 1, - } -}; - -/* A red, green or blue channel, part of an RGB chip */ -struct thingm_led { - struct thingm_rgb *rgb; - struct led_classdev ldev; - char name[32]; -}; - -/* Basically a WS2812 5050 RGB LED chip */ -struct thingm_rgb { - struct thingm_device *tdev; - struct thingm_led red; - struct thingm_led green; - struct thingm_led blue; - u8 num; -}; - -struct thingm_device { - struct hid_device *hdev; - struct { - char major; - char minor; - } version; - const struct thingm_fwinfo *fwinfo; - struct mutex lock; - struct thingm_rgb *rgb; -}; - -static int thingm_send(struct thingm_device *tdev, u8 buf[REPORT_SIZE]) -{ - int ret; - - hid_dbg(tdev->hdev, "-> %d %c %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n", - buf[0], buf[1], buf[2], buf[3], buf[4], - buf[5], buf[6], buf[7], buf[8]); - - mutex_lock(&tdev->lock); - - ret = hid_hw_raw_request(tdev->hdev, buf[0], buf, REPORT_SIZE, - HID_FEATURE_REPORT, HID_REQ_SET_REPORT); - - mutex_unlock(&tdev->lock); - - return ret < 0 ? ret : 0; -} - -static int thingm_recv(struct thingm_device *tdev, u8 buf[REPORT_SIZE]) -{ - int ret; - - /* - * A read consists of two operations: sending the read command - * and the actual read from the device. Use the mutex to protect - * the full sequence of both operations. - */ - mutex_lock(&tdev->lock); - - ret = hid_hw_raw_request(tdev->hdev, buf[0], buf, REPORT_SIZE, - HID_FEATURE_REPORT, HID_REQ_SET_REPORT); - if (ret < 0) - goto err; - - ret = hid_hw_raw_request(tdev->hdev, buf[0], buf, REPORT_SIZE, - HID_FEATURE_REPORT, HID_REQ_GET_REPORT); - if (ret < 0) - goto err; - - ret = 0; - - hid_dbg(tdev->hdev, "<- %d %c %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx\n", - buf[0], buf[1], buf[2], buf[3], buf[4], - buf[5], buf[6], buf[7], buf[8]); -err: - mutex_unlock(&tdev->lock); - return ret; -} - -static int thingm_version(struct thingm_device *tdev) -{ - u8 buf[REPORT_SIZE] = { REPORT_ID, 'v', 0, 0, 0, 0, 0, 0, 0 }; - int err; - - err = thingm_recv(tdev, buf); - if (err) - return err; - - tdev->version.major = buf[3]; - tdev->version.minor = buf[4]; - - return 0; -} - -static int thingm_write_color(struct thingm_rgb *rgb) -{ - u8 buf[REPORT_SIZE] = { REPORT_ID, 'c', 0, 0, 0, 0, 0, rgb->num, 0 }; - - buf[2] = rgb->red.ldev.brightness; - buf[3] = rgb->green.ldev.brightness; - buf[4] = rgb->blue.ldev.brightness; - - return thingm_send(rgb->tdev, buf); -} - -static int thingm_led_set(struct led_classdev *ldev, - enum led_brightness brightness) -{ - struct thingm_led *led = container_of(ldev, struct thingm_led, ldev); - - return thingm_write_color(led->rgb); -} - -static int thingm_init_led(struct thingm_led *led, const char *color_name, - struct thingm_rgb *rgb, int minor) -{ - snprintf(led->name, sizeof(led->name), "thingm%d:%s:led%d", - minor, color_name, rgb->num); - led->ldev.name = led->name; - led->ldev.max_brightness = 255; - led->ldev.brightness_set_blocking = thingm_led_set; - led->ldev.flags = LED_HW_PLUGGABLE; - led->rgb = rgb; - return devm_led_classdev_register(&rgb->tdev->hdev->dev, &led->ldev); -} - -static int thingm_init_rgb(struct thingm_rgb *rgb) -{ - const int minor = ((struct hidraw *) rgb->tdev->hdev->hidraw)->minor; - int err; - - /* Register the red diode */ - err = thingm_init_led(&rgb->red, "red", rgb, minor); - if (err) - return err; - - /* Register the green diode */ - err = thingm_init_led(&rgb->green, "green", rgb, minor); - if (err) - return err; - - /* Register the blue diode */ - return thingm_init_led(&rgb->blue, "blue", rgb, minor); -} - -static int thingm_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - struct thingm_device *tdev; - int i, err; - - tdev = devm_kzalloc(&hdev->dev, sizeof(struct thingm_device), - GFP_KERNEL); - if (!tdev) - return -ENOMEM; - - tdev->hdev = hdev; - hid_set_drvdata(hdev, tdev); - - err = hid_parse(hdev); - if (err) - return err; - - mutex_init(&tdev->lock); - - err = thingm_version(tdev); - if (err) - return err; - - hid_dbg(hdev, "firmware version: %c.%c\n", - tdev->version.major, tdev->version.minor); - - for (i = 0; i < ARRAY_SIZE(thingm_fwinfo) && !tdev->fwinfo; ++i) - if (thingm_fwinfo[i].major == tdev->version.major) - tdev->fwinfo = &thingm_fwinfo[i]; - - if (!tdev->fwinfo) { - hid_err(hdev, "unsupported firmware %c\n", tdev->version.major); - return -ENODEV; - } - - tdev->rgb = devm_kzalloc(&hdev->dev, - sizeof(struct thingm_rgb) * tdev->fwinfo->numrgb, - GFP_KERNEL); - if (!tdev->rgb) - return -ENOMEM; - - err = hid_hw_start(hdev, HID_CONNECT_HIDRAW); - if (err) - return err; - - for (i = 0; i < tdev->fwinfo->numrgb; ++i) { - struct thingm_rgb *rgb = tdev->rgb + i; - - rgb->tdev = tdev; - rgb->num = tdev->fwinfo->first + i; - err = thingm_init_rgb(rgb); - if (err) { - hid_hw_stop(hdev); - return err; - } - } - - return 0; -} - -static const struct hid_device_id thingm_table[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, - { } -}; -MODULE_DEVICE_TABLE(hid, thingm_table); - -static struct hid_driver thingm_driver = { - .name = "thingm", - .probe = thingm_probe, - .id_table = thingm_table, -}; - -module_hid_driver(thingm_driver); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Vivien Didelot <vivien.didelot@savoirfairelinux.com>"); -MODULE_DESCRIPTION("ThingM blink(1) USB RGB LED driver"); diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index 2e021ba8ff05..b3ec4f2de875 100644 --- a/drivers/hid/i2c-hid/i2c-hid.c +++ b/drivers/hid/i2c-hid/i2c-hid.c @@ -1020,6 +1020,7 @@ static int i2c_hid_probe(struct i2c_client *client, pm_runtime_get_noresume(&client->dev); pm_runtime_set_active(&client->dev); pm_runtime_enable(&client->dev); + device_enable_async_suspend(&client->dev); ret = i2c_hid_fetch_hid_descriptor(ihid); if (ret < 0) @@ -1106,6 +1107,14 @@ static int i2c_hid_remove(struct i2c_client *client) return 0; } +static void i2c_hid_shutdown(struct i2c_client *client) +{ + struct i2c_hid *ihid = i2c_get_clientdata(client); + + i2c_hid_set_power(client, I2C_HID_PWR_SLEEP); + free_irq(client->irq, ihid); +} + #ifdef CONFIG_PM_SLEEP static int i2c_hid_suspend(struct device *dev) { @@ -1230,7 +1239,7 @@ static struct i2c_driver i2c_hid_driver = { .probe = i2c_hid_probe, .remove = i2c_hid_remove, - + .shutdown = i2c_hid_shutdown, .id_table = i2c_hid_id_table, }; diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 16b6f11a0700..99ec3ff7563b 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -51,10 +51,26 @@ struct uhid_device { u32 report_id; u32 report_type; struct uhid_event report_buf; + struct work_struct worker; }; static struct miscdevice uhid_misc; +static void uhid_device_add_worker(struct work_struct *work) +{ + struct uhid_device *uhid = container_of(work, struct uhid_device, worker); + int ret; + + ret = hid_add_device(uhid->hid); + if (ret) { + hid_err(uhid->hid, "Cannot register HID device: error %d\n", ret); + + hid_destroy_device(uhid->hid); + uhid->hid = NULL; + uhid->running = false; + } +} + static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev) { __u8 newhead; @@ -498,18 +514,14 @@ static int uhid_dev_create2(struct uhid_device *uhid, uhid->hid = hid; uhid->running = true; - ret = hid_add_device(hid); - if (ret) { - hid_err(hid, "Cannot register HID device\n"); - goto err_hid; - } + /* Adding of a HID device is done through a worker, to allow HID drivers + * which use feature requests during .probe to work, without they would + * be blocked on devlock, which is held by uhid_char_write. + */ + schedule_work(&uhid->worker); return 0; -err_hid: - hid_destroy_device(hid); - uhid->hid = NULL; - uhid->running = false; err_free: kfree(uhid->rd_data); uhid->rd_data = NULL; @@ -550,6 +562,8 @@ static int uhid_dev_destroy(struct uhid_device *uhid) uhid->running = false; wake_up_interruptible(&uhid->report_wait); + cancel_work_sync(&uhid->worker); + hid_destroy_device(uhid->hid); kfree(uhid->rd_data); @@ -612,6 +626,7 @@ static int uhid_char_open(struct inode *inode, struct file *file) init_waitqueue_head(&uhid->waitq); init_waitqueue_head(&uhid->report_wait); uhid->running = false; + INIT_WORK(&uhid->worker, uhid_device_add_worker); file->private_data = uhid; nonseekable_open(inode, file); diff --git a/drivers/hwspinlock/qcom_hwspinlock.c b/drivers/hwspinlock/qcom_hwspinlock.c index c752447fbac7..fa6880b8060a 100644 --- a/drivers/hwspinlock/qcom_hwspinlock.c +++ b/drivers/hwspinlock/qcom_hwspinlock.c @@ -98,6 +98,7 @@ static int qcom_hwspinlock_probe(struct platform_device *pdev) } regmap = syscon_node_to_regmap(syscon); + of_node_put(syscon); if (IS_ERR(regmap)) return PTR_ERR(regmap); diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 6d35dd4e9efb..4788b0b989a9 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -142,7 +142,7 @@ static int linear_iterate_devices(struct dm_target *ti, } static long linear_direct_access(struct dm_target *ti, sector_t sector, - void __pmem **kaddr, pfn_t *pfn, long size) + void **kaddr, pfn_t *pfn, long size) { struct linear_c *lc = ti->private; struct block_device *bdev = lc->dev->bdev; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index 731e1f5bd895..ce2a910709f7 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -2303,7 +2303,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio) } static long origin_direct_access(struct dm_target *ti, sector_t sector, - void __pmem **kaddr, pfn_t *pfn, long size) + void **kaddr, pfn_t *pfn, long size) { DMWARN("device does not support dax."); return -EIO; diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index 01bb9cf2a8c2..83f1d4667195 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -309,7 +309,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio) } static long stripe_direct_access(struct dm_target *ti, sector_t sector, - void __pmem **kaddr, pfn_t *pfn, long size) + void **kaddr, pfn_t *pfn, long size) { struct stripe_c *sc = ti->private; uint32_t stripe; diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c index 6eecd6b36f76..710ae28fd618 100644 --- a/drivers/md/dm-target.c +++ b/drivers/md/dm-target.c @@ -149,7 +149,7 @@ static void io_err_release_clone_rq(struct request *clone) } static long io_err_direct_access(struct dm_target *ti, sector_t sector, - void __pmem **kaddr, pfn_t *pfn, long size) + void **kaddr, pfn_t *pfn, long size) { return -EIO; } diff --git a/drivers/md/dm.c b/drivers/md/dm.c index ceb69fc0b10b..25d1d97154a8 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -906,7 +906,7 @@ int dm_set_target_max_io_len(struct dm_target *ti, sector_t len) EXPORT_SYMBOL_GPL(dm_set_target_max_io_len); static long dm_blk_direct_access(struct block_device *bdev, sector_t sector, - void __pmem **kaddr, pfn_t *pfn, long size) + void **kaddr, pfn_t *pfn, long size) { struct mapped_device *md = bdev->bd_disk->private_data; struct dm_table *map; diff --git a/drivers/nvdimm/Kconfig b/drivers/nvdimm/Kconfig index 7c8a3bf07884..124c2432ac9c 100644 --- a/drivers/nvdimm/Kconfig +++ b/drivers/nvdimm/Kconfig @@ -1,6 +1,7 @@ menuconfig LIBNVDIMM tristate "NVDIMM (Non-Volatile Memory Device) Support" depends on PHYS_ADDR_T_64BIT + depends on HAS_IOMEM depends on BLK_DEV help Generic support for non-volatile memory devices including @@ -19,7 +20,6 @@ if LIBNVDIMM config BLK_DEV_PMEM tristate "PMEM: Persistent memory block device support" default LIBNVDIMM - depends on HAS_IOMEM select ND_BTT if BTT select ND_PFN if NVDIMM_PFN help diff --git a/drivers/nvdimm/blk.c b/drivers/nvdimm/blk.c index 7e262ef06ede..9faaa9694d87 100644 --- a/drivers/nvdimm/blk.c +++ b/drivers/nvdimm/blk.c @@ -267,10 +267,8 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) q = blk_alloc_queue(GFP_KERNEL); if (!q) return -ENOMEM; - if (devm_add_action(dev, nd_blk_release_queue, q)) { - blk_cleanup_queue(q); + if (devm_add_action_or_reset(dev, nd_blk_release_queue, q)) return -ENOMEM; - } blk_queue_make_request(q, nd_blk_make_request); blk_queue_max_hw_sectors(q, UINT_MAX); @@ -282,10 +280,6 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) disk = alloc_disk(0); if (!disk) return -ENOMEM; - if (devm_add_action(dev, nd_blk_release_disk, disk)) { - put_disk(disk); - return -ENOMEM; - } disk->first_minor = 0; disk->fops = &nd_blk_fops; @@ -295,6 +289,9 @@ static int nsblk_attach_disk(struct nd_namespace_blk *nsblk) set_capacity(disk, 0); device_add_disk(dev, disk); + if (devm_add_action_or_reset(dev, nd_blk_release_disk, disk)) + return -ENOMEM; + if (nsblk_meta_size(nsblk)) { int rc = nd_integrity_init(disk, nsblk_meta_size(nsblk)); diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c index 816d0dae6398..3fa7919f94a8 100644 --- a/drivers/nvdimm/btt_devs.c +++ b/drivers/nvdimm/btt_devs.c @@ -198,8 +198,7 @@ struct device *nd_btt_create(struct nd_region *nd_region) { struct device *dev = __nd_btt_create(nd_region, 0, NULL, NULL); - if (dev) - __nd_device_register(dev); + __nd_device_register(dev); return dev; } diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 5e4e5c772ea5..458daf927336 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -31,6 +31,7 @@ int nvdimm_major; static int nvdimm_bus_major; static struct class *nd_class; +static DEFINE_IDA(nd_ida); static int to_nd_device_type(struct device *dev) { @@ -60,20 +61,13 @@ static int nvdimm_bus_uevent(struct device *dev, struct kobj_uevent_env *env) to_nd_device_type(dev)); } -static int nvdimm_bus_match(struct device *dev, struct device_driver *drv) -{ - struct nd_device_driver *nd_drv = to_nd_device_driver(drv); - - return !!test_bit(to_nd_device_type(dev), &nd_drv->type); -} - static struct module *to_bus_provider(struct device *dev) { /* pin bus providers while regions are enabled */ if (is_nd_pmem(dev) || is_nd_blk(dev)) { struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); - return nvdimm_bus->module; + return nvdimm_bus->nd_desc->module; } return NULL; } @@ -136,6 +130,21 @@ static int nvdimm_bus_remove(struct device *dev) return rc; } +static void nvdimm_bus_shutdown(struct device *dev) +{ + struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); + struct nd_device_driver *nd_drv = NULL; + + if (dev->driver) + nd_drv = to_nd_device_driver(dev->driver); + + if (nd_drv && nd_drv->shutdown) { + nd_drv->shutdown(dev); + dev_dbg(&nvdimm_bus->dev, "%s.shutdown(%s)\n", + dev->driver->name, dev_name(dev)); + } +} + void nd_device_notify(struct device *dev, enum nvdimm_event event) { device_lock(dev); @@ -208,14 +217,187 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys, } EXPORT_SYMBOL_GPL(nvdimm_clear_poison); +static int nvdimm_bus_match(struct device *dev, struct device_driver *drv); + static struct bus_type nvdimm_bus_type = { .name = "nd", .uevent = nvdimm_bus_uevent, .match = nvdimm_bus_match, .probe = nvdimm_bus_probe, .remove = nvdimm_bus_remove, + .shutdown = nvdimm_bus_shutdown, +}; + +static void nvdimm_bus_release(struct device *dev) +{ + struct nvdimm_bus *nvdimm_bus; + + nvdimm_bus = container_of(dev, struct nvdimm_bus, dev); + ida_simple_remove(&nd_ida, nvdimm_bus->id); + kfree(nvdimm_bus); +} + +static bool is_nvdimm_bus(struct device *dev) +{ + return dev->release == nvdimm_bus_release; +} + +struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev) +{ + struct device *dev; + + for (dev = nd_dev; dev; dev = dev->parent) + if (is_nvdimm_bus(dev)) + break; + dev_WARN_ONCE(nd_dev, !dev, "invalid dev, not on nd bus\n"); + if (dev) + return to_nvdimm_bus(dev); + return NULL; +} + +struct nvdimm_bus *to_nvdimm_bus(struct device *dev) +{ + struct nvdimm_bus *nvdimm_bus; + + nvdimm_bus = container_of(dev, struct nvdimm_bus, dev); + WARN_ON(!is_nvdimm_bus(dev)); + return nvdimm_bus; +} +EXPORT_SYMBOL_GPL(to_nvdimm_bus); + +struct nvdimm_bus *nvdimm_bus_register(struct device *parent, + struct nvdimm_bus_descriptor *nd_desc) +{ + struct nvdimm_bus *nvdimm_bus; + int rc; + + nvdimm_bus = kzalloc(sizeof(*nvdimm_bus), GFP_KERNEL); + if (!nvdimm_bus) + return NULL; + INIT_LIST_HEAD(&nvdimm_bus->list); + INIT_LIST_HEAD(&nvdimm_bus->mapping_list); + INIT_LIST_HEAD(&nvdimm_bus->poison_list); + init_waitqueue_head(&nvdimm_bus->probe_wait); + nvdimm_bus->id = ida_simple_get(&nd_ida, 0, 0, GFP_KERNEL); + mutex_init(&nvdimm_bus->reconfig_mutex); + if (nvdimm_bus->id < 0) { + kfree(nvdimm_bus); + return NULL; + } + nvdimm_bus->nd_desc = nd_desc; + nvdimm_bus->dev.parent = parent; + nvdimm_bus->dev.release = nvdimm_bus_release; + nvdimm_bus->dev.groups = nd_desc->attr_groups; + nvdimm_bus->dev.bus = &nvdimm_bus_type; + dev_set_name(&nvdimm_bus->dev, "ndbus%d", nvdimm_bus->id); + rc = device_register(&nvdimm_bus->dev); + if (rc) { + dev_dbg(&nvdimm_bus->dev, "registration failed: %d\n", rc); + goto err; + } + + return nvdimm_bus; + err: + put_device(&nvdimm_bus->dev); + return NULL; +} +EXPORT_SYMBOL_GPL(nvdimm_bus_register); + +void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus) +{ + if (!nvdimm_bus) + return; + device_unregister(&nvdimm_bus->dev); +} +EXPORT_SYMBOL_GPL(nvdimm_bus_unregister); + +static int child_unregister(struct device *dev, void *data) +{ + /* + * the singular ndctl class device per bus needs to be + * "device_destroy"ed, so skip it here + * + * i.e. remove classless children + */ + if (dev->class) + /* pass */; + else + nd_device_unregister(dev, ND_SYNC); + return 0; +} + +static void free_poison_list(struct list_head *poison_list) +{ + struct nd_poison *pl, *next; + + list_for_each_entry_safe(pl, next, poison_list, list) { + list_del(&pl->list); + kfree(pl); + } + list_del_init(poison_list); +} + +static int nd_bus_remove(struct device *dev) +{ + struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev); + + mutex_lock(&nvdimm_bus_list_mutex); + list_del_init(&nvdimm_bus->list); + mutex_unlock(&nvdimm_bus_list_mutex); + + nd_synchronize(); + device_for_each_child(&nvdimm_bus->dev, NULL, child_unregister); + + nvdimm_bus_lock(&nvdimm_bus->dev); + free_poison_list(&nvdimm_bus->poison_list); + nvdimm_bus_unlock(&nvdimm_bus->dev); + + nvdimm_bus_destroy_ndctl(nvdimm_bus); + + return 0; +} + +static int nd_bus_probe(struct device *dev) +{ + struct nvdimm_bus *nvdimm_bus = to_nvdimm_bus(dev); + int rc; + + rc = nvdimm_bus_create_ndctl(nvdimm_bus); + if (rc) + return rc; + + mutex_lock(&nvdimm_bus_list_mutex); + list_add_tail(&nvdimm_bus->list, &nvdimm_bus_list); + mutex_unlock(&nvdimm_bus_list_mutex); + + /* enable bus provider attributes to look up their local context */ + dev_set_drvdata(dev, nvdimm_bus->nd_desc); + + return 0; +} + +static struct nd_device_driver nd_bus_driver = { + .probe = nd_bus_probe, + .remove = nd_bus_remove, + .drv = { + .name = "nd_bus", + .suppress_bind_attrs = true, + .bus = &nvdimm_bus_type, + .owner = THIS_MODULE, + .mod_name = KBUILD_MODNAME, + }, }; +static int nvdimm_bus_match(struct device *dev, struct device_driver *drv) +{ + struct nd_device_driver *nd_drv = to_nd_device_driver(drv); + + if (is_nvdimm_bus(dev) && nd_drv == &nd_bus_driver) + return true; + + return !!test_bit(to_nd_device_type(dev), &nd_drv->type); +} + static ASYNC_DOMAIN_EXCLUSIVE(nd_async_domain); void nd_synchronize(void) @@ -395,12 +577,10 @@ int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus) dev = device_create(nd_class, &nvdimm_bus->dev, devt, nvdimm_bus, "ndctl%d", nvdimm_bus->id); - if (IS_ERR(dev)) { + if (IS_ERR(dev)) dev_dbg(&nvdimm_bus->dev, "failed to register ndctl%d: %ld\n", nvdimm_bus->id, PTR_ERR(dev)); - return PTR_ERR(dev); - } - return 0; + return PTR_ERR_OR_ZERO(dev); } void nvdimm_bus_destroy_ndctl(struct nvdimm_bus *nvdimm_bus) @@ -850,8 +1030,14 @@ int __init nvdimm_bus_init(void) goto err_class; } + rc = driver_register(&nd_bus_driver.drv); + if (rc) + goto err_nd_bus; + return 0; + err_nd_bus: + class_destroy(nd_class); err_class: unregister_chrdev(nvdimm_major, "dimmctl"); err_dimm_chrdev: @@ -864,8 +1050,10 @@ int __init nvdimm_bus_init(void) void nvdimm_bus_exit(void) { + driver_unregister(&nd_bus_driver.drv); class_destroy(nd_class); unregister_chrdev(nvdimm_bus_major, "ndctl"); unregister_chrdev(nvdimm_major, "dimmctl"); bus_unregister(&nvdimm_bus_type); + ida_destroy(&nd_ida); } diff --git a/drivers/nvdimm/claim.c b/drivers/nvdimm/claim.c index 8b2e3c4fb0ad..d5dc80c48b4c 100644 --- a/drivers/nvdimm/claim.c +++ b/drivers/nvdimm/claim.c @@ -240,7 +240,7 @@ static int nsio_rw_bytes(struct nd_namespace_common *ndns, return memcpy_from_pmem(buf, nsio->addr + offset, size); } else { memcpy_to_pmem(nsio->addr + offset, buf, size); - wmb_pmem(); + nvdimm_flush(to_nd_region(ndns->dev.parent)); } return 0; @@ -266,9 +266,8 @@ int devm_nsio_enable(struct device *dev, struct nd_namespace_io *nsio) nsio->addr = devm_memremap(dev, res->start, resource_size(res), ARCH_MEMREMAP_PMEM); - if (IS_ERR(nsio->addr)) - return PTR_ERR(nsio->addr); - return 0; + + return PTR_ERR_OR_ZERO(nsio->addr); } EXPORT_SYMBOL_GPL(devm_nsio_enable); diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index be89764315c2..715583f69d28 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -20,12 +20,12 @@ #include <linux/ndctl.h> #include <linux/mutex.h> #include <linux/slab.h> +#include <linux/io.h> #include "nd-core.h" #include "nd.h" LIST_HEAD(nvdimm_bus_list); DEFINE_MUTEX(nvdimm_bus_list_mutex); -static DEFINE_IDA(nd_ida); void nvdimm_bus_lock(struct device *dev) { @@ -57,6 +57,127 @@ bool is_nvdimm_bus_locked(struct device *dev) } EXPORT_SYMBOL(is_nvdimm_bus_locked); +struct nvdimm_map { + struct nvdimm_bus *nvdimm_bus; + struct list_head list; + resource_size_t offset; + unsigned long flags; + size_t size; + union { + void *mem; + void __iomem *iomem; + }; + struct kref kref; +}; + +static struct nvdimm_map *find_nvdimm_map(struct device *dev, + resource_size_t offset) +{ + struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); + struct nvdimm_map *nvdimm_map; + + list_for_each_entry(nvdimm_map, &nvdimm_bus->mapping_list, list) + if (nvdimm_map->offset == offset) + return nvdimm_map; + return NULL; +} + +static struct nvdimm_map *alloc_nvdimm_map(struct device *dev, + resource_size_t offset, size_t size, unsigned long flags) +{ + struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); + struct nvdimm_map *nvdimm_map; + + nvdimm_map = kzalloc(sizeof(*nvdimm_map), GFP_KERNEL); + if (!nvdimm_map) + return NULL; + + INIT_LIST_HEAD(&nvdimm_map->list); + nvdimm_map->nvdimm_bus = nvdimm_bus; + nvdimm_map->offset = offset; + nvdimm_map->flags = flags; + nvdimm_map->size = size; + kref_init(&nvdimm_map->kref); + + if (!request_mem_region(offset, size, dev_name(&nvdimm_bus->dev))) + goto err_request_region; + + if (flags) + nvdimm_map->mem = memremap(offset, size, flags); + else + nvdimm_map->iomem = ioremap(offset, size); + + if (!nvdimm_map->mem) + goto err_map; + + dev_WARN_ONCE(dev, !is_nvdimm_bus_locked(dev), "%s: bus unlocked!", + __func__); + list_add(&nvdimm_map->list, &nvdimm_bus->mapping_list); + + return nvdimm_map; + + err_map: + release_mem_region(offset, size); + err_request_region: + kfree(nvdimm_map); + return NULL; +} + +static void nvdimm_map_release(struct kref *kref) +{ + struct nvdimm_bus *nvdimm_bus; + struct nvdimm_map *nvdimm_map; + + nvdimm_map = container_of(kref, struct nvdimm_map, kref); + nvdimm_bus = nvdimm_map->nvdimm_bus; + + dev_dbg(&nvdimm_bus->dev, "%s: %pa\n", __func__, &nvdimm_map->offset); + list_del(&nvdimm_map->list); + if (nvdimm_map->flags) + memunmap(nvdimm_map->mem); + else + iounmap(nvdimm_map->iomem); + release_mem_region(nvdimm_map->offset, nvdimm_map->size); + kfree(nvdimm_map); +} + +static void nvdimm_map_put(void *data) +{ + struct nvdimm_map *nvdimm_map = data; + struct nvdimm_bus *nvdimm_bus = nvdimm_map->nvdimm_bus; + + nvdimm_bus_lock(&nvdimm_bus->dev); + kref_put(&nvdimm_map->kref, nvdimm_map_release); + nvdimm_bus_unlock(&nvdimm_bus->dev); +} + +/** + * devm_nvdimm_memremap - map a resource that is shared across regions + * @dev: device that will own a reference to the shared mapping + * @offset: physical base address of the mapping + * @size: mapping size + * @flags: memremap flags, or, if zero, perform an ioremap instead + */ +void *devm_nvdimm_memremap(struct device *dev, resource_size_t offset, + size_t size, unsigned long flags) +{ + struct nvdimm_map *nvdimm_map; + + nvdimm_bus_lock(dev); + nvdimm_map = find_nvdimm_map(dev, offset); + if (!nvdimm_map) + nvdimm_map = alloc_nvdimm_map(dev, offset, size, flags); + else + kref_get(&nvdimm_map->kref); + nvdimm_bus_unlock(dev); + + if (devm_add_action_or_reset(dev, nvdimm_map_put, nvdimm_map)) + return NULL; + + return nvdimm_map->mem; +} +EXPORT_SYMBOL_GPL(devm_nvdimm_memremap); + u64 nd_fletcher64(void *addr, size_t len, bool le) { u32 *buf = addr; @@ -73,25 +194,6 @@ u64 nd_fletcher64(void *addr, size_t len, bool le) } EXPORT_SYMBOL_GPL(nd_fletcher64); -static void nvdimm_bus_release(struct device *dev) -{ - struct nvdimm_bus *nvdimm_bus; - - nvdimm_bus = container_of(dev, struct nvdimm_bus, dev); - ida_simple_remove(&nd_ida, nvdimm_bus->id); - kfree(nvdimm_bus); -} - -struct nvdimm_bus *to_nvdimm_bus(struct device *dev) -{ - struct nvdimm_bus *nvdimm_bus; - - nvdimm_bus = container_of(dev, struct nvdimm_bus, dev); - WARN_ON(nvdimm_bus->dev.release != nvdimm_bus_release); - return nvdimm_bus; -} -EXPORT_SYMBOL_GPL(to_nvdimm_bus); - struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus) { /* struct nvdimm_bus definition is private to libnvdimm */ @@ -99,18 +201,12 @@ struct nvdimm_bus_descriptor *to_nd_desc(struct nvdimm_bus *nvdimm_bus) } EXPORT_SYMBOL_GPL(to_nd_desc); -struct nvdimm_bus *walk_to_nvdimm_bus(struct device *nd_dev) +struct device *to_nvdimm_bus_dev(struct nvdimm_bus *nvdimm_bus) { - struct device *dev; - - for (dev = nd_dev; dev; dev = dev->parent) - if (dev->release == nvdimm_bus_release) - break; - dev_WARN_ONCE(nd_dev, !dev, "invalid dev, not on nd bus\n"); - if (dev) - return to_nvdimm_bus(dev); - return NULL; + /* struct nvdimm_bus definition is private to libnvdimm */ + return &nvdimm_bus->dev; } +EXPORT_SYMBOL_GPL(to_nvdimm_bus_dev); static bool is_uuid_sep(char sep) { @@ -325,51 +421,6 @@ struct attribute_group nvdimm_bus_attribute_group = { }; EXPORT_SYMBOL_GPL(nvdimm_bus_attribute_group); -struct nvdimm_bus *__nvdimm_bus_register(struct device *parent, - struct nvdimm_bus_descriptor *nd_desc, struct module *module) -{ - struct nvdimm_bus *nvdimm_bus; - int rc; - - nvdimm_bus = kzalloc(sizeof(*nvdimm_bus), GFP_KERNEL); - if (!nvdimm_bus) - return NULL; - INIT_LIST_HEAD(&nvdimm_bus->list); - INIT_LIST_HEAD(&nvdimm_bus->poison_list); - init_waitqueue_head(&nvdimm_bus->probe_wait); - nvdimm_bus->id = ida_simple_get(&nd_ida, 0, 0, GFP_KERNEL); - mutex_init(&nvdimm_bus->reconfig_mutex); - if (nvdimm_bus->id < 0) { - kfree(nvdimm_bus); - return NULL; - } - nvdimm_bus->nd_desc = nd_desc; - nvdimm_bus->module = module; - nvdimm_bus->dev.parent = parent; - nvdimm_bus->dev.release = nvdimm_bus_release; - nvdimm_bus->dev.groups = nd_desc->attr_groups; - dev_set_name(&nvdimm_bus->dev, "ndbus%d", nvdimm_bus->id); - rc = device_register(&nvdimm_bus->dev); - if (rc) { - dev_dbg(&nvdimm_bus->dev, "registration failed: %d\n", rc); - goto err; - } - - rc = nvdimm_bus_create_ndctl(nvdimm_bus); - if (rc) - goto err; - - mutex_lock(&nvdimm_bus_list_mutex); - list_add_tail(&nvdimm_bus->list, &nvdimm_bus_list); - mutex_unlock(&nvdimm_bus_list_mutex); - - return nvdimm_bus; - err: - put_device(&nvdimm_bus->dev); - return NULL; -} -EXPORT_SYMBOL_GPL(__nvdimm_bus_register); - static void set_badblock(struct badblocks *bb, sector_t s, int num) { dev_dbg(bb->dev, "Found a poison range (0x%llx, 0x%llx)\n", @@ -545,54 +596,6 @@ int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length) } EXPORT_SYMBOL_GPL(nvdimm_bus_add_poison); -static void free_poison_list(struct list_head *poison_list) -{ - struct nd_poison *pl, *next; - - list_for_each_entry_safe(pl, next, poison_list, list) { - list_del(&pl->list); - kfree(pl); - } - list_del_init(poison_list); -} - -static int child_unregister(struct device *dev, void *data) -{ - /* - * the singular ndctl class device per bus needs to be - * "device_destroy"ed, so skip it here - * - * i.e. remove classless children - */ - if (dev->class) - /* pass */; - else - nd_device_unregister(dev, ND_SYNC); - return 0; -} - -void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus) -{ - if (!nvdimm_bus) - return; - - mutex_lock(&nvdimm_bus_list_mutex); - list_del_init(&nvdimm_bus->list); - mutex_unlock(&nvdimm_bus_list_mutex); - - nd_synchronize(); - device_for_each_child(&nvdimm_bus->dev, NULL, child_unregister); - - nvdimm_bus_lock(&nvdimm_bus->dev); - free_poison_list(&nvdimm_bus->poison_list); - nvdimm_bus_unlock(&nvdimm_bus->dev); - - nvdimm_bus_destroy_ndctl(nvdimm_bus); - - device_unregister(&nvdimm_bus->dev); -} -EXPORT_SYMBOL_GPL(nvdimm_bus_unregister); - #ifdef CONFIG_BLK_DEV_INTEGRITY int nd_integrity_init(struct gendisk *disk, unsigned long meta_size) { @@ -601,7 +604,8 @@ int nd_integrity_init(struct gendisk *disk, unsigned long meta_size) if (meta_size == 0) return 0; - bi.profile = NULL; + memset(&bi, 0, sizeof(bi)); + bi.tuple_size = meta_size; bi.tag_size = meta_size; @@ -650,7 +654,6 @@ static __exit void libnvdimm_exit(void) nvdimm_bus_exit(); nd_region_devs_exit(); nvdimm_devs_exit(); - ida_destroy(&nd_ida); } MODULE_LICENSE("GPL v2"); diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index bbde28d3dec5..d9bba5edd8dc 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -346,7 +346,8 @@ EXPORT_SYMBOL_GPL(nvdimm_attribute_group); struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, const struct attribute_group **groups, unsigned long flags, - unsigned long cmd_mask) + unsigned long cmd_mask, int num_flush, + struct resource *flush_wpq) { struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL); struct device *dev; @@ -362,6 +363,8 @@ struct nvdimm *nvdimm_create(struct nvdimm_bus *nvdimm_bus, void *provider_data, nvdimm->provider_data = provider_data; nvdimm->flags = flags; nvdimm->cmd_mask = cmd_mask; + nvdimm->num_flush = num_flush; + nvdimm->flush_wpq = flush_wpq; atomic_set(&nvdimm->busy, 0); dev = &nvdimm->dev; dev_set_name(dev, "nmem%d", nvdimm->id); diff --git a/drivers/nvdimm/e820.c b/drivers/nvdimm/e820.c index 95825b38559a..11ea90120542 100644 --- a/drivers/nvdimm/e820.c +++ b/drivers/nvdimm/e820.c @@ -47,6 +47,7 @@ static int e820_pmem_probe(struct platform_device *pdev) nd_desc.attr_groups = e820_pmem_attribute_groups; nd_desc.provider_name = "e820"; + nd_desc.module = THIS_MODULE; nvdimm_bus = nvdimm_bus_register(dev, &nd_desc); if (!nvdimm_bus) goto err; diff --git a/drivers/nvdimm/nd-core.h b/drivers/nvdimm/nd-core.h index 284cdaa268cf..38ce6bbbc170 100644 --- a/drivers/nvdimm/nd-core.h +++ b/drivers/nvdimm/nd-core.h @@ -26,11 +26,11 @@ extern int nvdimm_major; struct nvdimm_bus { struct nvdimm_bus_descriptor *nd_desc; wait_queue_head_t probe_wait; - struct module *module; struct list_head list; struct device dev; int id, probe_active; struct list_head poison_list; + struct list_head mapping_list; struct mutex reconfig_mutex; }; @@ -40,7 +40,8 @@ struct nvdimm { unsigned long cmd_mask; struct device dev; atomic_t busy; - int id; + int id, num_flush; + struct resource *flush_wpq; }; bool is_nvdimm(struct device *dev); diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index d0ac93c31dda..40476399d227 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -49,9 +49,11 @@ struct nvdimm_drvdata { struct kref kref; }; -struct nd_region_namespaces { - int count; - int active; +struct nd_region_data { + int ns_count; + int ns_active; + unsigned int flush_mask; + void __iomem *flush_wpq[0][0]; }; static inline struct nd_namespace_index *to_namespace_index( @@ -119,7 +121,6 @@ struct nd_region { struct nd_blk_region { int (*enable)(struct nvdimm_bus *nvdimm_bus, struct device *dev); - void (*disable)(struct nvdimm_bus *nvdimm_bus, struct device *dev); int (*do_io)(struct nd_blk_region *ndbr, resource_size_t dpa, void *iobuf, u64 len, int rw); void *blk_provider_data; @@ -325,6 +326,7 @@ static inline void devm_nsio_disable(struct device *dev, } #endif int nd_blk_region_init(struct nd_region *nd_region); +int nd_region_activate(struct nd_region *nd_region); void __nd_iostat_start(struct bio *bio, unsigned long *start); static inline bool nd_iostat_start(struct bio *bio, unsigned long *start) { diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 36cb39047d5b..b511099457db 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -29,27 +29,28 @@ #include <linux/slab.h> #include <linux/pmem.h> #include <linux/nd.h> +#include "pmem.h" #include "pfn.h" #include "nd.h" -struct pmem_device { - /* One contiguous memory region per device */ - phys_addr_t phys_addr; - /* when non-zero this device is hosting a 'pfn' instance */ - phys_addr_t data_offset; - u64 pfn_flags; - void __pmem *virt_addr; - /* immutable base size of the namespace */ - size_t size; - /* trim size when namespace capacity has been section aligned */ - u32 pfn_pad; - struct badblocks bb; -}; +static struct device *to_dev(struct pmem_device *pmem) +{ + /* + * nvdimm bus services need a 'dev' parameter, and we record the device + * at init in bb.dev. + */ + return pmem->bb.dev; +} + +static struct nd_region *to_region(struct pmem_device *pmem) +{ + return to_nd_region(to_dev(pmem)->parent); +} static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, unsigned int len) { - struct device *dev = pmem->bb.dev; + struct device *dev = to_dev(pmem); sector_t sector; long cleared; @@ -57,7 +58,7 @@ static void pmem_clear_poison(struct pmem_device *pmem, phys_addr_t offset, cleared = nvdimm_clear_poison(dev, pmem->phys_addr + offset, len); if (cleared > 0 && cleared / 512) { - dev_dbg(dev, "%s: %llx clear %ld sector%s\n", + dev_dbg(dev, "%s: %#llx clear %ld sector%s\n", __func__, (unsigned long long) sector, cleared / 512, cleared / 512 > 1 ? "s" : ""); badblocks_clear(&pmem->bb, sector, cleared / 512); @@ -73,7 +74,7 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, bool bad_pmem = false; void *mem = kmap_atomic(page); phys_addr_t pmem_off = sector * 512 + pmem->data_offset; - void __pmem *pmem_addr = pmem->virt_addr + pmem_off; + void *pmem_addr = pmem->virt_addr + pmem_off; if (unlikely(is_bad_pmem(&pmem->bb, sector, len))) bad_pmem = true; @@ -112,6 +113,11 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page, return rc; } +/* account for REQ_FLUSH rename, replace with REQ_PREFLUSH after v4.8-rc1 */ +#ifndef REQ_FLUSH +#define REQ_FLUSH REQ_PREFLUSH +#endif + static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio) { int rc = 0; @@ -120,6 +126,10 @@ static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio) struct bio_vec bvec; struct bvec_iter iter; struct pmem_device *pmem = q->queuedata; + struct nd_region *nd_region = to_region(pmem); + + if (bio->bi_rw & REQ_FLUSH) + nvdimm_flush(nd_region); do_acct = nd_iostat_start(bio, &start); bio_for_each_segment(bvec, bio, iter) { @@ -134,8 +144,8 @@ static blk_qc_t pmem_make_request(struct request_queue *q, struct bio *bio) if (do_acct) nd_iostat_end(bio, start); - if (bio_data_dir(bio)) - wmb_pmem(); + if (bio->bi_rw & REQ_FUA) + nvdimm_flush(nd_region); bio_endio(bio); return BLK_QC_T_NONE; @@ -148,8 +158,6 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector, int rc; rc = pmem_do_bvec(pmem, page, PAGE_SIZE, 0, rw, sector); - if (rw & WRITE) - wmb_pmem(); /* * The ->rw_page interface is subtle and tricky. The core @@ -163,8 +171,9 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector, return rc; } -static long pmem_direct_access(struct block_device *bdev, sector_t sector, - void __pmem **kaddr, pfn_t *pfn, long size) +/* see "strong" declaration in tools/testing/nvdimm/pmem-dax.c */ +__weak long pmem_direct_access(struct block_device *bdev, sector_t sector, + void **kaddr, pfn_t *pfn, long size) { struct pmem_device *pmem = bdev->bd_queue->queuedata; resource_size_t offset = sector * 512 + pmem->data_offset; @@ -195,7 +204,7 @@ static void pmem_release_queue(void *q) blk_cleanup_queue(q); } -void pmem_release_disk(void *disk) +static void pmem_release_disk(void *disk) { del_gendisk(disk); put_disk(disk); @@ -205,6 +214,7 @@ static int pmem_attach_disk(struct device *dev, struct nd_namespace_common *ndns) { struct nd_namespace_io *nsio = to_nd_namespace_io(&ndns->dev); + struct nd_region *nd_region = to_nd_region(dev->parent); struct vmem_altmap __altmap, *altmap = NULL; struct resource *res = &nsio->res; struct nd_pfn *nd_pfn = NULL; @@ -234,7 +244,7 @@ static int pmem_attach_disk(struct device *dev, dev_set_drvdata(dev, pmem); pmem->phys_addr = res->start; pmem->size = resource_size(res); - if (!arch_has_wmb_pmem()) + if (nvdimm_has_flush(nd_region) < 0) dev_warn(dev, "unable to guarantee persistence of writes\n"); if (!devm_request_mem_region(dev, res->start, resource_size(res), @@ -269,15 +279,14 @@ static int pmem_attach_disk(struct device *dev, * At release time the queue must be dead before * devm_memremap_pages is unwound */ - if (devm_add_action(dev, pmem_release_queue, q)) { - blk_cleanup_queue(q); + if (devm_add_action_or_reset(dev, pmem_release_queue, q)) return -ENOMEM; - } if (IS_ERR(addr)) return PTR_ERR(addr); - pmem->virt_addr = (void __pmem *) addr; + pmem->virt_addr = addr; + blk_queue_write_cache(q, true, true); blk_queue_make_request(q, pmem_make_request); blk_queue_physical_block_size(q, PAGE_SIZE); blk_queue_max_hw_sectors(q, UINT_MAX); @@ -289,10 +298,6 @@ static int pmem_attach_disk(struct device *dev, disk = alloc_disk_node(0, nid); if (!disk) return -ENOMEM; - if (devm_add_action(dev, pmem_release_disk, disk)) { - put_disk(disk); - return -ENOMEM; - } disk->fops = &pmem_fops; disk->queue = q; @@ -302,9 +307,13 @@ static int pmem_attach_disk(struct device *dev, / 512); if (devm_init_badblocks(dev, &pmem->bb)) return -ENOMEM; - nvdimm_badblocks_populate(to_nd_region(dev->parent), &pmem->bb, res); + nvdimm_badblocks_populate(nd_region, &pmem->bb, res); disk->bb = &pmem->bb; device_add_disk(dev, disk); + + if (devm_add_action_or_reset(dev, pmem_release_disk, disk)) + return -ENOMEM; + revalidate_disk(disk); return 0; @@ -340,13 +349,20 @@ static int nd_pmem_remove(struct device *dev) { if (is_nd_btt(dev)) nvdimm_namespace_detach_btt(to_nd_btt(dev)); + nvdimm_flush(to_nd_region(dev->parent)); + return 0; } +static void nd_pmem_shutdown(struct device *dev) +{ + nvdimm_flush(to_nd_region(dev->parent)); +} + static void nd_pmem_notify(struct device *dev, enum nvdimm_event event) { - struct nd_region *nd_region = to_nd_region(dev->parent); struct pmem_device *pmem = dev_get_drvdata(dev); + struct nd_region *nd_region = to_region(pmem); resource_size_t offset = 0, end_trunc = 0; struct nd_namespace_common *ndns; struct nd_namespace_io *nsio; @@ -382,6 +398,7 @@ static struct nd_device_driver nd_pmem_driver = { .probe = nd_pmem_probe, .remove = nd_pmem_remove, .notify = nd_pmem_notify, + .shutdown = nd_pmem_shutdown, .drv = { .name = "nd_pmem", }, diff --git a/drivers/nvdimm/pmem.h b/drivers/nvdimm/pmem.h new file mode 100644 index 000000000000..b4ee4f71b4a1 --- /dev/null +++ b/drivers/nvdimm/pmem.h @@ -0,0 +1,24 @@ +#ifndef __NVDIMM_PMEM_H__ +#define __NVDIMM_PMEM_H__ +#include <linux/badblocks.h> +#include <linux/types.h> +#include <linux/pfn_t.h> +#include <linux/fs.h> + +long pmem_direct_access(struct block_device *bdev, sector_t sector, + void **kaddr, pfn_t *pfn, long size); +/* this definition is in it's own header for tools/testing/nvdimm to consume */ +struct pmem_device { + /* One contiguous memory region per device */ + phys_addr_t phys_addr; + /* when non-zero this device is hosting a 'pfn' instance */ + phys_addr_t data_offset; + u64 pfn_flags; + void *virt_addr; + /* immutable base size of the namespace */ + size_t size; + /* trim size when namespace capacity has been section aligned */ + u32 pfn_pad; + struct badblocks bb; +}; +#endif /* __NVDIMM_PMEM_H__ */ diff --git a/drivers/nvdimm/region.c b/drivers/nvdimm/region.c index 05a912359939..8f241772ec0b 100644 --- a/drivers/nvdimm/region.c +++ b/drivers/nvdimm/region.c @@ -20,7 +20,7 @@ static int nd_region_probe(struct device *dev) { int err, rc; static unsigned long once; - struct nd_region_namespaces *num_ns; + struct nd_region_data *ndrd; struct nd_region *nd_region = to_nd_region(dev); if (nd_region->num_lanes > num_online_cpus() @@ -33,21 +33,21 @@ static int nd_region_probe(struct device *dev) nd_region->num_lanes); } + rc = nd_region_activate(nd_region); + if (rc) + return rc; + rc = nd_blk_region_init(nd_region); if (rc) return rc; rc = nd_region_register_namespaces(nd_region, &err); - num_ns = devm_kzalloc(dev, sizeof(*num_ns), GFP_KERNEL); - if (!num_ns) - return -ENOMEM; - if (rc < 0) return rc; - num_ns->active = rc; - num_ns->count = rc + err; - dev_set_drvdata(dev, num_ns); + ndrd = dev_get_drvdata(dev); + ndrd->ns_active = rc; + ndrd->ns_count = rc + err; if (rc && err && rc == err) return -ENODEV; @@ -82,6 +82,8 @@ static int nd_region_remove(struct device *dev) { struct nd_region *nd_region = to_nd_region(dev); + device_for_each_child(dev, NULL, child_unregister); + /* flush attribute readers and disable */ nvdimm_bus_lock(dev); nd_region->ns_seed = NULL; @@ -91,7 +93,6 @@ static int nd_region_remove(struct device *dev) dev_set_drvdata(dev, NULL); nvdimm_bus_unlock(dev); - device_for_each_child(dev, NULL, child_unregister); return 0; } diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 40fcfea26fbb..e8d5ba7b29af 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -14,13 +14,97 @@ #include <linux/highmem.h> #include <linux/sched.h> #include <linux/slab.h> +#include <linux/hash.h> +#include <linux/pmem.h> #include <linux/sort.h> #include <linux/io.h> #include <linux/nd.h> #include "nd-core.h" #include "nd.h" +/* + * For readq() and writeq() on 32-bit builds, the hi-lo, lo-hi order is + * irrelevant. + */ +#include <linux/io-64-nonatomic-hi-lo.h> + static DEFINE_IDA(region_ida); +static DEFINE_PER_CPU(int, flush_idx); + +static int nvdimm_map_flush(struct device *dev, struct nvdimm *nvdimm, int dimm, + struct nd_region_data *ndrd) +{ + int i, j; + + dev_dbg(dev, "%s: map %d flush address%s\n", nvdimm_name(nvdimm), + nvdimm->num_flush, nvdimm->num_flush == 1 ? "" : "es"); + for (i = 0; i < nvdimm->num_flush; i++) { + struct resource *res = &nvdimm->flush_wpq[i]; + unsigned long pfn = PHYS_PFN(res->start); + void __iomem *flush_page; + + /* check if flush hints share a page */ + for (j = 0; j < i; j++) { + struct resource *res_j = &nvdimm->flush_wpq[j]; + unsigned long pfn_j = PHYS_PFN(res_j->start); + + if (pfn == pfn_j) + break; + } + + if (j < i) + flush_page = (void __iomem *) ((unsigned long) + ndrd->flush_wpq[dimm][j] & PAGE_MASK); + else + flush_page = devm_nvdimm_ioremap(dev, + PHYS_PFN(pfn), PAGE_SIZE); + if (!flush_page) + return -ENXIO; + ndrd->flush_wpq[dimm][i] = flush_page + + (res->start & ~PAGE_MASK); + } + + return 0; +} + +int nd_region_activate(struct nd_region *nd_region) +{ + int i, num_flush = 0; + struct nd_region_data *ndrd; + struct device *dev = &nd_region->dev; + size_t flush_data_size = sizeof(void *); + + nvdimm_bus_lock(&nd_region->dev); + for (i = 0; i < nd_region->ndr_mappings; i++) { + struct nd_mapping *nd_mapping = &nd_region->mapping[i]; + struct nvdimm *nvdimm = nd_mapping->nvdimm; + + /* at least one null hint slot per-dimm for the "no-hint" case */ + flush_data_size += sizeof(void *); + num_flush = min_not_zero(num_flush, nvdimm->num_flush); + if (!nvdimm->num_flush) + continue; + flush_data_size += nvdimm->num_flush * sizeof(void *); + } + nvdimm_bus_unlock(&nd_region->dev); + + ndrd = devm_kzalloc(dev, sizeof(*ndrd) + flush_data_size, GFP_KERNEL); + if (!ndrd) + return -ENOMEM; + dev_set_drvdata(dev, ndrd); + + ndrd->flush_mask = (1 << ilog2(num_flush)) - 1; + for (i = 0; i < nd_region->ndr_mappings; i++) { + struct nd_mapping *nd_mapping = &nd_region->mapping[i]; + struct nvdimm *nvdimm = nd_mapping->nvdimm; + int rc = nvdimm_map_flush(&nd_region->dev, nvdimm, i, ndrd); + + if (rc) + return rc; + } + + return 0; +} static void nd_region_release(struct device *dev) { @@ -242,12 +326,12 @@ static DEVICE_ATTR_RO(available_size); static ssize_t init_namespaces_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct nd_region_namespaces *num_ns = dev_get_drvdata(dev); + struct nd_region_data *ndrd = dev_get_drvdata(dev); ssize_t rc; nvdimm_bus_lock(dev); - if (num_ns) - rc = sprintf(buf, "%d/%d\n", num_ns->active, num_ns->count); + if (ndrd) + rc = sprintf(buf, "%d/%d\n", ndrd->ns_active, ndrd->ns_count); else rc = -ENXIO; nvdimm_bus_unlock(dev); @@ -433,8 +517,6 @@ static void nd_region_notify_driver_action(struct nvdimm_bus *nvdimm_bus, if (is_nd_pmem(dev)) return; - - to_nd_blk_region(dev)->disable(nvdimm_bus, dev); } if (dev->parent && is_nd_blk(dev->parent) && probe) { nd_region = to_nd_region(dev->parent); @@ -698,7 +780,6 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, if (ndbr) { nd_region = &ndbr->nd_region; ndbr->enable = ndbr_desc->enable; - ndbr->disable = ndbr_desc->disable; ndbr->do_io = ndbr_desc->do_io; } region_buf = ndbr; @@ -794,6 +875,67 @@ struct nd_region *nvdimm_volatile_region_create(struct nvdimm_bus *nvdimm_bus, } EXPORT_SYMBOL_GPL(nvdimm_volatile_region_create); +/** + * nvdimm_flush - flush any posted write queues between the cpu and pmem media + * @nd_region: blk or interleaved pmem region + */ +void nvdimm_flush(struct nd_region *nd_region) +{ + struct nd_region_data *ndrd = dev_get_drvdata(&nd_region->dev); + int i, idx; + + /* + * Try to encourage some diversity in flush hint addresses + * across cpus assuming a limited number of flush hints. + */ + idx = this_cpu_read(flush_idx); + idx = this_cpu_add_return(flush_idx, hash_32(current->pid + idx, 8)); + + /* + * The first wmb() is needed to 'sfence' all previous writes + * such that they are architecturally visible for the platform + * buffer flush. Note that we've already arranged for pmem + * writes to avoid the cache via arch_memcpy_to_pmem(). The + * final wmb() ensures ordering for the NVDIMM flush write. + */ + wmb(); + for (i = 0; i < nd_region->ndr_mappings; i++) + if (ndrd->flush_wpq[i][0]) + writeq(1, ndrd->flush_wpq[i][idx & ndrd->flush_mask]); + wmb(); +} +EXPORT_SYMBOL_GPL(nvdimm_flush); + +/** + * nvdimm_has_flush - determine write flushing requirements + * @nd_region: blk or interleaved pmem region + * + * Returns 1 if writes require flushing + * Returns 0 if writes do not require flushing + * Returns -ENXIO if flushing capability can not be determined + */ +int nvdimm_has_flush(struct nd_region *nd_region) +{ + struct nd_region_data *ndrd = dev_get_drvdata(&nd_region->dev); + int i; + + /* no nvdimm == flushing capability unknown */ + if (nd_region->ndr_mappings == 0) + return -ENXIO; + + for (i = 0; i < nd_region->ndr_mappings; i++) + /* flush hints present, flushing required */ + if (ndrd->flush_wpq[i][0]) + return 1; + + /* + * The platform defines dimm devices without hints, assume + * platform persistence mechanism like ADR + */ + return 0; +} +EXPORT_SYMBOL_GPL(nvdimm_has_flush); + void __exit nd_region_devs_exit(void) { ida_destroy(®ion_ida); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index fb8200b8e8ec..b3fe1d339632 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -35,7 +35,7 @@ config PINCTRL_ADI2 machine and arch are selected to build. config PINCTRL_AS3722 - bool "Pinctrl and GPIO driver for ams AS3722 PMIC" + tristate "Pinctrl and GPIO driver for ams AS3722 PMIC" depends on MFD_AS3722 && GPIOLIB select PINMUX select GENERIC_PINCONF @@ -129,6 +129,17 @@ config PINCTRL_MESON select OF_GPIO select REGMAP_MMIO +config PINCTRL_OXNAS + bool + depends on OF + select PINMUX + select PINCONF + select GENERIC_PINCONF + select GPIOLIB + select OF_GPIO + select GPIOLIB_IRQCHIP + select MFD_SYSCON + config PINCTRL_ROCKCHIP bool select PINMUX @@ -196,8 +207,19 @@ config PINCTRL_COH901 COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 ports of 8 GPIO pins each. +config PINCTRL_MAX77620 + tristate "MAX77620/MAX20024 Pincontrol support" + depends on MFD_MAX77620 + select PINMUX + select GENERIC_PINCONF + help + Say Yes here to enable Pin control support for Maxim PMIC MAX77620. + This PMIC has 8 GPIO pins that work as GPIO as well as special + function in alternate mode. This driver also configure push-pull, + open drain, FPS slots etc. + config PINCTRL_PALMAS - bool "Pinctrl driver for the PALMAS Series MFD devices" + tristate "Pinctrl driver for the PALMAS Series MFD devices" depends on OF && MFD_PALMAS select PINMUX select GENERIC_PINCONF diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 42a5c1dddfef..8ebd7b8e1621 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -16,7 +16,9 @@ obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o obj-$(CONFIG_PINCTRL_DIGICOLOR) += pinctrl-digicolor.o obj-$(CONFIG_PINCTRL_FALCON) += pinctrl-falcon.o +obj-$(CONFIG_PINCTRL_MAX77620) += pinctrl-max77620.o obj-$(CONFIG_PINCTRL_MESON) += meson/ +obj-$(CONFIG_PINCTRL_OXNAS) += pinctrl-oxnas.o obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o @@ -35,7 +37,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o -obj-$(CONFIG_ARCH_BCM) += bcm/ +obj-y += bcm/ obj-$(CONFIG_PINCTRL_BERLIN) += berlin/ obj-y += freescale/ obj-$(CONFIG_X86) += intel/ diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index c356223e1c9c..63246770bd74 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -60,6 +60,7 @@ config PINCTRL_IPROC_GPIO config PINCTRL_CYGNUS_MUX bool "Broadcom Cygnus IOMUX driver" depends on (ARCH_BCM_CYGNUS || COMPILE_TEST) + depends on OF select PINMUX select GENERIC_PINCONF default ARCH_BCM_CYGNUS @@ -99,3 +100,17 @@ config PINCTRL_NS2_MUX The Broadcom Northstar2 IOMUX driver supports group based IOMUX configuration. + +config PINCTRL_NSP_MUX + bool "Broadcom NSP IOMUX driver" + depends on (ARCH_BCM_NSP || COMPILE_TEST) + depends on OF + select PINMUX + select GENERIC_PINCONF + default ARCH_BCM_NSP + help + Say yes here to enable the Broadcom NSP SOC IOMUX driver. + + The Broadcom Northstar Plus IOMUX driver supports pin based IOMUX + configuration, with certain individual pins can be overridden + to GPIO function. diff --git a/drivers/pinctrl/bcm/Makefile b/drivers/pinctrl/bcm/Makefile index 3861a1c1f8ff..2a65111f3c70 100644 --- a/drivers/pinctrl/bcm/Makefile +++ b/drivers/pinctrl/bcm/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL_IPROC_GPIO) += pinctrl-iproc-gpio.o obj-$(CONFIG_PINCTRL_CYGNUS_MUX) += pinctrl-cygnus-mux.o obj-$(CONFIG_PINCTRL_NSP_GPIO) += pinctrl-nsp-gpio.o obj-$(CONFIG_PINCTRL_NS2_MUX) += pinctrl-ns2-mux.o +obj-$(CONFIG_PINCTRL_NSP_MUX) += pinctrl-nsp-mux.o diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c index 3670f5ea7a12..7f7700716398 100644 --- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c @@ -66,6 +66,14 @@ #define GPIO_DRV_STRENGTH_BITS 3 #define GPIO_DRV_STRENGTH_BIT_MASK ((1 << GPIO_DRV_STRENGTH_BITS) - 1) +enum iproc_pinconf_param { + IPROC_PINCONF_DRIVE_STRENGTH = 0, + IPROC_PINCONF_BIAS_DISABLE, + IPROC_PINCONF_BIAS_PULL_UP, + IPROC_PINCONF_BIAS_PULL_DOWN, + IPROC_PINCON_MAX, +}; + /* * Iproc GPIO core * @@ -78,6 +86,10 @@ * @num_banks: number of GPIO banks, each bank supports up to 32 GPIOs * @pinmux_is_supported: flag to indicate this GPIO controller contains pins * that can be individually muxed to GPIO + * @pinconf_disable: contains a list of PINCONF parameters that need to be + * disabled + * @nr_pinconf_disable: total number of PINCONF parameters that need to be + * disabled * @pctl: pointer to pinctrl_dev * @pctldesc: pinctrl descriptor */ @@ -94,6 +106,9 @@ struct iproc_gpio { bool pinmux_is_supported; + enum pin_config_param *pinconf_disable; + unsigned int nr_pinconf_disable; + struct pinctrl_dev *pctl; struct pinctrl_desc pctldesc; }; @@ -360,6 +375,65 @@ static int iproc_gpio_get(struct gpio_chip *gc, unsigned gpio) return !!(readl(chip->base + offset) & BIT(shift)); } +/* + * Mapping of the iProc PINCONF parameters to the generic pin configuration + * parameters + */ +static const enum pin_config_param iproc_pinconf_disable_map[] = { + [IPROC_PINCONF_DRIVE_STRENGTH] = PIN_CONFIG_DRIVE_STRENGTH, + [IPROC_PINCONF_BIAS_DISABLE] = PIN_CONFIG_BIAS_DISABLE, + [IPROC_PINCONF_BIAS_PULL_UP] = PIN_CONFIG_BIAS_PULL_UP, + [IPROC_PINCONF_BIAS_PULL_DOWN] = PIN_CONFIG_BIAS_PULL_DOWN, +}; + +static bool iproc_pinconf_param_is_disabled(struct iproc_gpio *chip, + enum pin_config_param param) +{ + unsigned int i; + + if (!chip->nr_pinconf_disable) + return false; + + for (i = 0; i < chip->nr_pinconf_disable; i++) + if (chip->pinconf_disable[i] == param) + return true; + + return false; +} + +static int iproc_pinconf_disable_map_create(struct iproc_gpio *chip, + unsigned long disable_mask) +{ + unsigned int map_size = ARRAY_SIZE(iproc_pinconf_disable_map); + unsigned int bit, nbits = 0; + + /* figure out total number of PINCONF parameters to disable */ + for_each_set_bit(bit, &disable_mask, map_size) + nbits++; + + if (!nbits) + return 0; + + /* + * Allocate an array to store PINCONF parameters that need to be + * disabled + */ + chip->pinconf_disable = devm_kcalloc(chip->dev, nbits, + sizeof(*chip->pinconf_disable), + GFP_KERNEL); + if (!chip->pinconf_disable) + return -ENOMEM; + + chip->nr_pinconf_disable = nbits; + + /* now store these parameters */ + nbits = 0; + for_each_set_bit(bit, &disable_mask, map_size) + chip->pinconf_disable[nbits++] = iproc_pinconf_disable_map[bit]; + + return 0; +} + static int iproc_get_groups_count(struct pinctrl_dev *pctldev) { return 1; @@ -500,6 +574,9 @@ static int iproc_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, bool disable, pull_up; int ret; + if (iproc_pinconf_param_is_disabled(chip, param)) + return -ENOTSUPP; + switch (param) { case PIN_CONFIG_BIAS_DISABLE: iproc_gpio_get_pull(chip, gpio, &disable, &pull_up); @@ -548,6 +625,10 @@ static int iproc_pin_config_set(struct pinctrl_dev *pctldev, unsigned pin, for (i = 0; i < num_configs; i++) { param = pinconf_to_config_param(configs[i]); + + if (iproc_pinconf_param_is_disabled(chip, param)) + return -ENOTSUPP; + arg = pinconf_to_config_argument(configs[i]); switch (param) { @@ -633,11 +714,13 @@ static int iproc_gpio_register_pinconf(struct iproc_gpio *chip) } static const struct of_device_id iproc_gpio_of_match[] = { + { .compatible = "brcm,iproc-gpio" }, { .compatible = "brcm,cygnus-ccm-gpio" }, { .compatible = "brcm,cygnus-asiu-gpio" }, { .compatible = "brcm,cygnus-crmu-gpio" }, - { .compatible = "brcm,iproc-gpio" }, - { } + { .compatible = "brcm,iproc-nsp-gpio" }, + { .compatible = "brcm,iproc-stingray-gpio" }, + { /* sentinel */ } }; static int iproc_gpio_probe(struct platform_device *pdev) @@ -646,8 +729,17 @@ static int iproc_gpio_probe(struct platform_device *pdev) struct resource *res; struct iproc_gpio *chip; struct gpio_chip *gc; - u32 ngpios; + u32 ngpios, pinconf_disable_mask = 0; int irq, ret; + bool no_pinconf = false; + + /* NSP does not support drive strength config */ + if (of_device_is_compatible(dev->of_node, "brcm,iproc-nsp-gpio")) + pinconf_disable_mask = BIT(IPROC_PINCONF_DRIVE_STRENGTH); + /* Stingray does not support pinconf in this controller */ + else if (of_device_is_compatible(dev->of_node, + "brcm,iproc-stingray-gpio")) + no_pinconf = true; chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); if (!chip) @@ -702,10 +794,22 @@ static int iproc_gpio_probe(struct platform_device *pdev) return ret; } - ret = iproc_gpio_register_pinconf(chip); - if (ret) { - dev_err(dev, "unable to register pinconf\n"); - goto err_rm_gpiochip; + if (!no_pinconf) { + ret = iproc_gpio_register_pinconf(chip); + if (ret) { + dev_err(dev, "unable to register pinconf\n"); + goto err_rm_gpiochip; + } + + if (pinconf_disable_mask) { + ret = iproc_pinconf_disable_map_create(chip, + pinconf_disable_mask); + if (ret) { + dev_err(dev, + "unable to create pinconf disable map\n"); + goto err_rm_gpiochip; + } + } } /* optional GPIO interrupt support */ diff --git a/drivers/pinctrl/bcm/pinctrl-ns2-mux.c b/drivers/pinctrl/bcm/pinctrl-ns2-mux.c index 3fefd14acc3e..ca817896ed24 100644 --- a/drivers/pinctrl/bcm/pinctrl-ns2-mux.c +++ b/drivers/pinctrl/bcm/pinctrl-ns2-mux.c @@ -1044,10 +1044,8 @@ static int ns2_pinmux_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pinctrl->base0)) { - dev_err(&pdev->dev, "unable to map I/O space\n"); + if (IS_ERR(pinctrl->base0)) return PTR_ERR(pinctrl->base0); - } res = platform_get_resource(pdev, IORESOURCE_MEM, 1); pinctrl->base1 = devm_ioremap_nocache(&pdev->dev, res->start, @@ -1059,10 +1057,8 @@ static int ns2_pinmux_probe(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 2); pinctrl->pinconf_base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(pinctrl->pinconf_base)) { - dev_err(&pdev->dev, "unable to map I/O space\n"); + if (IS_ERR(pinctrl->pinconf_base)) return PTR_ERR(pinctrl->pinconf_base); - } ret = ns2_mux_log_init(pinctrl); if (ret) { @@ -1089,9 +1085,9 @@ static int ns2_pinmux_probe(struct platform_device *pdev) pinctrl->pctl = pinctrl_register(&ns2_pinctrl_desc, &pdev->dev, pinctrl); - if (!pinctrl->pctl) { + if (IS_ERR(pinctrl->pctl)) { dev_err(&pdev->dev, "unable to register IOMUX pinctrl\n"); - return -EINVAL; + return PTR_ERR(pinctrl->pctl); } return 0; diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c index a8b37a9a8230..35783db1c10b 100644 --- a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c @@ -458,13 +458,15 @@ static int nsp_gpio_get_strength(struct nsp_gpio *chip, unsigned gpio, return 0; } -int nsp_pin_config_group_get(struct pinctrl_dev *pctldev, unsigned selector, +static int nsp_pin_config_group_get(struct pinctrl_dev *pctldev, + unsigned selector, unsigned long *config) { return 0; } -int nsp_pin_config_group_set(struct pinctrl_dev *pctldev, unsigned selector, +static int nsp_pin_config_group_set(struct pinctrl_dev *pctldev, + unsigned selector, unsigned long *configs, unsigned num_configs) { return 0; diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-mux.c b/drivers/pinctrl/bcm/pinctrl-nsp-mux.c new file mode 100644 index 000000000000..4149db309c8b --- /dev/null +++ b/drivers/pinctrl/bcm/pinctrl-nsp-mux.c @@ -0,0 +1,642 @@ +/* Copyright (C) 2015 Broadcom Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * This file contains the Northstar plus (NSP) IOMUX driver that supports + * group based PINMUX configuration. The Northstar plus IOMUX controller + * allows pins to be individually muxed to GPIO function. The NAND and MMC is + * a group based selection. The gpio_a 8 - 11 are muxed with gpio_b and pwm. + * To select PWM, one need to enable the corresponding gpio_b as well. + * + * gpio_a (8 - 11) + * +---------- + * | + * gpio_a (8-11) | gpio_b (0 - 3) + * ------------------------+-------+---------- + * | + * | pwm (0 - 3) + * +---------- + */ + +#include <linux/err.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/slab.h> + +#include "../core.h" +#include "../pinctrl-utils.h" + +#define NSP_MUX_BASE0 0x00 +#define NSP_MUX_BASE1 0x01 +#define NSP_MUX_BASE2 0x02 +/* + * nsp IOMUX register description + * + * @base: base 0 or base 1 + * @shift: bit shift for mux configuration of a group + * @mask: bit mask of the function + * @alt: alternate function to set to + */ +struct nsp_mux { + unsigned int base; + unsigned int shift; + unsigned int mask; + unsigned int alt; +}; + +/* + * Keep track of nsp IOMUX configuration and prevent double configuration + * + * @nsp_mux: nsp IOMUX register description + * @is_configured: flag to indicate whether a mux setting has already been + * configured + */ +struct nsp_mux_log { + struct nsp_mux mux; + bool is_configured; +}; + +/* + * Group based IOMUX configuration + * + * @name: name of the group + * @pins: array of pins used by this group + * @num_pins: total number of pins used by this group + * @mux: nsp group based IOMUX configuration + */ +struct nsp_pin_group { + const char *name; + const unsigned int *pins; + const unsigned int num_pins; + const struct nsp_mux mux; +}; + +/* + * nsp mux function and supported pin groups + * + * @name: name of the function + * @groups: array of groups that can be supported by this function + * @num_groups: total number of groups that can be supported by this function + */ +struct nsp_pin_function { + const char *name; + const char * const *groups; + const unsigned int num_groups; +}; + +/* + * nsp IOMUX pinctrl core + * + * @pctl: pointer to pinctrl_dev + * @dev: pointer to device + * @base0: first mux register + * @base1: second mux register + * @base2: third mux register + * @groups: pointer to array of groups + * @num_groups: total number of groups + * @functions: pointer to array of functions + * @num_functions: total number of functions + * @mux_log: pointer to the array of mux logs + * @lock: lock to protect register access + */ +struct nsp_pinctrl { + struct pinctrl_dev *pctl; + struct device *dev; + void __iomem *base0; + void __iomem *base1; + void __iomem *base2; + const struct nsp_pin_group *groups; + unsigned int num_groups; + const struct nsp_pin_function *functions; + unsigned int num_functions; + struct nsp_mux_log *mux_log; + spinlock_t lock; +}; + +/* + * Description of a pin in nsp + * + * @pin: pin number + * @name: pin name + * @gpio_select: reg data to select GPIO + */ +struct nsp_pin { + unsigned int pin; + char *name; + unsigned int gpio_select; +}; + +#define NSP_PIN_DESC(p, n, g) \ +{ \ + .pin = p, \ + .name = n, \ + .gpio_select = g, \ +} + +/* + * List of muxable pins in nsp + */ +static struct nsp_pin nsp_pins[] = { + NSP_PIN_DESC(0, "spi_clk", 1), + NSP_PIN_DESC(1, "spi_ss", 1), + NSP_PIN_DESC(2, "spi_mosi", 1), + NSP_PIN_DESC(3, "spi_miso", 1), + NSP_PIN_DESC(4, "scl", 1), + NSP_PIN_DESC(5, "sda", 1), + NSP_PIN_DESC(6, "mdc", 1), + NSP_PIN_DESC(7, "mdio", 1), + NSP_PIN_DESC(8, "pwm0", 1), + NSP_PIN_DESC(9, "pwm1", 1), + NSP_PIN_DESC(10, "pwm2", 1), + NSP_PIN_DESC(11, "pwm3", 1), + NSP_PIN_DESC(12, "uart1_rx", 1), + NSP_PIN_DESC(13, "uart1_tx", 1), + NSP_PIN_DESC(14, "uart1_cts", 1), + NSP_PIN_DESC(15, "uart1_rts", 1), + NSP_PIN_DESC(16, "uart2_rx", 1), + NSP_PIN_DESC(17, "uart2_tx", 1), + NSP_PIN_DESC(18, "synce", 0), + NSP_PIN_DESC(19, "sata0_led", 0), + NSP_PIN_DESC(20, "sata1_led", 0), + NSP_PIN_DESC(21, "xtal_out", 1), + NSP_PIN_DESC(22, "sdio_pwr", 1), + NSP_PIN_DESC(23, "sdio_en_1p8v", 1), + NSP_PIN_DESC(24, "gpio_24", 1), + NSP_PIN_DESC(25, "gpio_25", 1), + NSP_PIN_DESC(26, "p5_led0", 0), + NSP_PIN_DESC(27, "p5_led1", 0), + NSP_PIN_DESC(28, "gpio_28", 1), + NSP_PIN_DESC(29, "gpio_29", 1), + NSP_PIN_DESC(30, "gpio_30", 1), + NSP_PIN_DESC(31, "gpio_31", 1), + NSP_PIN_DESC(32, "nand_ale", 0), + NSP_PIN_DESC(33, "nand_ce0", 0), + NSP_PIN_DESC(34, "nand_r/b", 0), + NSP_PIN_DESC(35, "nand_dq0", 0), + NSP_PIN_DESC(36, "nand_dq1", 0), + NSP_PIN_DESC(37, "nand_dq2", 0), + NSP_PIN_DESC(38, "nand_dq3", 0), + NSP_PIN_DESC(39, "nand_dq4", 0), + NSP_PIN_DESC(40, "nand_dq5", 0), + NSP_PIN_DESC(41, "nand_dq6", 0), + NSP_PIN_DESC(42, "nand_dq7", 0), +}; + +/* + * List of groups of pins + */ + +static const unsigned int spi_pins[] = {0, 1, 2, 3}; +static const unsigned int i2c_pins[] = {4, 5}; +static const unsigned int mdio_pins[] = {6, 7}; +static const unsigned int pwm0_pins[] = {8}; +static const unsigned int gpio_b_0_pins[] = {8}; +static const unsigned int pwm1_pins[] = {9}; +static const unsigned int gpio_b_1_pins[] = {9}; +static const unsigned int pwm2_pins[] = {10}; +static const unsigned int gpio_b_2_pins[] = {10}; +static const unsigned int pwm3_pins[] = {11}; +static const unsigned int gpio_b_3_pins[] = {11}; +static const unsigned int uart1_pins[] = {12, 13, 14, 15}; +static const unsigned int uart2_pins[] = {16, 17}; +static const unsigned int synce_pins[] = {18}; +static const unsigned int sata0_led_pins[] = {19}; +static const unsigned int sata1_led_pins[] = {20}; +static const unsigned int xtal_out_pins[] = {21}; +static const unsigned int sdio_pwr_pins[] = {22}; +static const unsigned int sdio_1p8v_pins[] = {23}; +static const unsigned int switch_p05_led0_pins[] = {26}; +static const unsigned int switch_p05_led1_pins[] = {27}; +static const unsigned int nand_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42}; +static const unsigned int emmc_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42}; + +#define NSP_PIN_GROUP(group_name, ba, sh, ma, al) \ +{ \ + .name = __stringify(group_name) "_grp", \ + .pins = group_name ## _pins, \ + .num_pins = ARRAY_SIZE(group_name ## _pins), \ + .mux = { \ + .base = ba, \ + .shift = sh, \ + .mask = ma, \ + .alt = al, \ + } \ +} + +/* + * List of nsp pin groups + */ +static const struct nsp_pin_group nsp_pin_groups[] = { + NSP_PIN_GROUP(spi, NSP_MUX_BASE0, 0, 0x0f, 0x00), + NSP_PIN_GROUP(i2c, NSP_MUX_BASE0, 3, 0x03, 0x00), + NSP_PIN_GROUP(mdio, NSP_MUX_BASE0, 5, 0x03, 0x00), + NSP_PIN_GROUP(gpio_b_0, NSP_MUX_BASE0, 7, 0x01, 0x00), + NSP_PIN_GROUP(pwm0, NSP_MUX_BASE1, 0, 0x01, 0x01), + NSP_PIN_GROUP(gpio_b_1, NSP_MUX_BASE0, 8, 0x01, 0x00), + NSP_PIN_GROUP(pwm1, NSP_MUX_BASE1, 1, 0x01, 0x01), + NSP_PIN_GROUP(gpio_b_2, NSP_MUX_BASE0, 9, 0x01, 0x00), + NSP_PIN_GROUP(pwm2, NSP_MUX_BASE1, 2, 0x01, 0x01), + NSP_PIN_GROUP(gpio_b_3, NSP_MUX_BASE0, 10, 0x01, 0x00), + NSP_PIN_GROUP(pwm3, NSP_MUX_BASE1, 3, 0x01, 0x01), + NSP_PIN_GROUP(uart1, NSP_MUX_BASE0, 11, 0x0f, 0x00), + NSP_PIN_GROUP(uart2, NSP_MUX_BASE0, 15, 0x03, 0x00), + NSP_PIN_GROUP(synce, NSP_MUX_BASE0, 17, 0x01, 0x01), + NSP_PIN_GROUP(sata0_led, NSP_MUX_BASE0, 18, 0x01, 0x01), + NSP_PIN_GROUP(sata1_led, NSP_MUX_BASE0, 19, 0x01, 0x01), + NSP_PIN_GROUP(xtal_out, NSP_MUX_BASE0, 20, 0x01, 0x00), + NSP_PIN_GROUP(sdio_pwr, NSP_MUX_BASE0, 21, 0x01, 0x00), + NSP_PIN_GROUP(sdio_1p8v, NSP_MUX_BASE0, 22, 0x01, 0x00), + NSP_PIN_GROUP(switch_p05_led0, NSP_MUX_BASE0, 26, 0x01, 0x01), + NSP_PIN_GROUP(switch_p05_led1, NSP_MUX_BASE0, 27, 0x01, 0x01), + NSP_PIN_GROUP(nand, NSP_MUX_BASE2, 0, 0x01, 0x00), + NSP_PIN_GROUP(emmc, NSP_MUX_BASE2, 0, 0x01, 0x01) +}; + +/* + * List of groups supported by functions + */ + +static const char * const spi_grps[] = {"spi_grp"}; +static const char * const i2c_grps[] = {"i2c_grp"}; +static const char * const mdio_grps[] = {"mdio_grp"}; +static const char * const pwm_grps[] = {"pwm0_grp", "pwm1_grp", "pwm2_grp" + , "pwm3_grp"}; +static const char * const gpio_b_grps[] = {"gpio_b_0_grp", "gpio_b_1_grp", + "gpio_b_2_grp", "gpio_b_3_grp"}; +static const char * const uart1_grps[] = {"uart1_grp"}; +static const char * const uart2_grps[] = {"uart2_grp"}; +static const char * const synce_grps[] = {"synce_grp"}; +static const char * const sata_led_grps[] = {"sata0_led_grp", "sata1_led_grp"}; +static const char * const xtal_out_grps[] = {"xtal_out_grp"}; +static const char * const sdio_grps[] = {"sdio_pwr_grp", "sdio_1p8v_grp"}; +static const char * const switch_led_grps[] = {"switch_p05_led0_grp", + "switch_p05_led1_grp"}; +static const char * const nand_grps[] = {"nand_grp"}; +static const char * const emmc_grps[] = {"emmc_grp"}; + +#define NSP_PIN_FUNCTION(func) \ +{ \ + .name = #func, \ + .groups = func ## _grps, \ + .num_groups = ARRAY_SIZE(func ## _grps), \ +} + +/* + * List of supported functions in nsp + */ +static const struct nsp_pin_function nsp_pin_functions[] = { + NSP_PIN_FUNCTION(spi), + NSP_PIN_FUNCTION(i2c), + NSP_PIN_FUNCTION(mdio), + NSP_PIN_FUNCTION(pwm), + NSP_PIN_FUNCTION(gpio_b), + NSP_PIN_FUNCTION(uart1), + NSP_PIN_FUNCTION(uart2), + NSP_PIN_FUNCTION(synce), + NSP_PIN_FUNCTION(sata_led), + NSP_PIN_FUNCTION(xtal_out), + NSP_PIN_FUNCTION(sdio), + NSP_PIN_FUNCTION(switch_led), + NSP_PIN_FUNCTION(nand), + NSP_PIN_FUNCTION(emmc) +}; + +static int nsp_get_groups_count(struct pinctrl_dev *pctrl_dev) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pinctrl->num_groups; +} + +static const char *nsp_get_group_name(struct pinctrl_dev *pctrl_dev, + unsigned int selector) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pinctrl->groups[selector].name; +} + +static int nsp_get_group_pins(struct pinctrl_dev *pctrl_dev, + unsigned int selector, const unsigned int **pins, + unsigned int *num_pins) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + *pins = pinctrl->groups[selector].pins; + *num_pins = pinctrl->groups[selector].num_pins; + + return 0; +} + +static void nsp_pin_dbg_show(struct pinctrl_dev *pctrl_dev, + struct seq_file *s, unsigned int offset) +{ + seq_printf(s, " %s", dev_name(pctrl_dev->dev)); +} + +static struct pinctrl_ops nsp_pinctrl_ops = { + .get_groups_count = nsp_get_groups_count, + .get_group_name = nsp_get_group_name, + .get_group_pins = nsp_get_group_pins, + .pin_dbg_show = nsp_pin_dbg_show, + .dt_node_to_map = pinconf_generic_dt_node_to_map_group, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int nsp_get_functions_count(struct pinctrl_dev *pctrl_dev) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pinctrl->num_functions; +} + +static const char *nsp_get_function_name(struct pinctrl_dev *pctrl_dev, + unsigned int selector) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + return pinctrl->functions[selector].name; +} + +static int nsp_get_function_groups(struct pinctrl_dev *pctrl_dev, + unsigned int selector, + const char * const **groups, + unsigned * const num_groups) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + + *groups = pinctrl->functions[selector].groups; + *num_groups = pinctrl->functions[selector].num_groups; + + return 0; +} + +static int nsp_pinmux_set(struct nsp_pinctrl *pinctrl, + const struct nsp_pin_function *func, + const struct nsp_pin_group *grp, + struct nsp_mux_log *mux_log) +{ + const struct nsp_mux *mux = &grp->mux; + int i; + u32 val, mask; + unsigned long flags; + void __iomem *base_address; + + for (i = 0; i < pinctrl->num_groups; i++) { + if ((mux->shift != mux_log[i].mux.shift) || + (mux->base != mux_log[i].mux.base)) + continue; + + /* if this is a new configuration, just do it! */ + if (!mux_log[i].is_configured) + break; + + /* + * IOMUX has been configured previously and one is trying to + * configure it to a different function + */ + if (mux_log[i].mux.alt != mux->alt) { + dev_err(pinctrl->dev, + "double configuration error detected!\n"); + dev_err(pinctrl->dev, "func:%s grp:%s\n", + func->name, grp->name); + return -EINVAL; + } + + return 0; + } + if (i == pinctrl->num_groups) + return -EINVAL; + + mask = mux->mask; + mux_log[i].mux.alt = mux->alt; + mux_log[i].is_configured = true; + + switch (mux->base) { + case NSP_MUX_BASE0: + base_address = pinctrl->base0; + break; + + case NSP_MUX_BASE1: + base_address = pinctrl->base1; + break; + + case NSP_MUX_BASE2: + base_address = pinctrl->base2; + break; + + default: + return -EINVAL; + } + + spin_lock_irqsave(&pinctrl->lock, flags); + val = readl(base_address); + val &= ~(mask << grp->mux.shift); + val |= grp->mux.alt << grp->mux.shift; + writel(val, base_address); + spin_unlock_irqrestore(&pinctrl->lock, flags); + + return 0; +} + +static int nsp_pinmux_enable(struct pinctrl_dev *pctrl_dev, + unsigned int func_select, unsigned int grp_select) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + const struct nsp_pin_function *func; + const struct nsp_pin_group *grp; + + if (grp_select > pinctrl->num_groups || + func_select > pinctrl->num_functions) + return -EINVAL; + + func = &pinctrl->functions[func_select]; + grp = &pinctrl->groups[grp_select]; + + dev_dbg(pctrl_dev->dev, "func:%u name:%s grp:%u name:%s\n", + func_select, func->name, grp_select, grp->name); + + dev_dbg(pctrl_dev->dev, "shift:%u alt:%u\n", grp->mux.shift, + grp->mux.alt); + + return nsp_pinmux_set(pinctrl, func, grp, pinctrl->mux_log); +} + + +static int nsp_gpio_request_enable(struct pinctrl_dev *pctrl_dev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + u32 *gpio_select = pctrl_dev->desc->pins[pin].drv_data; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&pinctrl->lock, flags); + val = readl(pinctrl->base0); + if ((val & BIT(pin)) != (*gpio_select << pin)) { + val &= ~BIT(pin); + val |= *gpio_select << pin; + writel(val, pinctrl->base0); + } + spin_unlock_irqrestore(&pinctrl->lock, flags); + + return 0; +} + +static void nsp_gpio_disable_free(struct pinctrl_dev *pctrl_dev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct nsp_pinctrl *pinctrl = pinctrl_dev_get_drvdata(pctrl_dev); + u32 *gpio_select = pctrl_dev->desc->pins[pin].drv_data; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&pinctrl->lock, flags); + val = readl(pinctrl->base0); + if ((val & (1 << pin)) == (*gpio_select << pin)) { + val &= ~(1 << pin); + if (!(*gpio_select)) + val |= (1 << pin); + writel(val, pinctrl->base0); + } + spin_unlock_irqrestore(&pinctrl->lock, flags); +} + +static struct pinmux_ops nsp_pinmux_ops = { + .get_functions_count = nsp_get_functions_count, + .get_function_name = nsp_get_function_name, + .get_function_groups = nsp_get_function_groups, + .set_mux = nsp_pinmux_enable, + .gpio_request_enable = nsp_gpio_request_enable, + .gpio_disable_free = nsp_gpio_disable_free, +}; + +static struct pinctrl_desc nsp_pinctrl_desc = { + .name = "nsp-pinmux", + .pctlops = &nsp_pinctrl_ops, + .pmxops = &nsp_pinmux_ops, +}; + +static int nsp_mux_log_init(struct nsp_pinctrl *pinctrl) +{ + struct nsp_mux_log *log; + unsigned int i; + u32 no_of_groups = ARRAY_SIZE(nsp_pin_groups); + + pinctrl->mux_log = devm_kcalloc(pinctrl->dev, no_of_groups, + sizeof(struct nsp_mux_log), + GFP_KERNEL); + if (!pinctrl->mux_log) + return -ENOMEM; + + for (i = 0; i < no_of_groups; i++) { + log = &pinctrl->mux_log[i]; + log->mux.base = nsp_pin_groups[i].mux.base; + log->mux.shift = nsp_pin_groups[i].mux.shift; + log->mux.alt = 0; + log->is_configured = false; + } + + return 0; +} + +static int nsp_pinmux_probe(struct platform_device *pdev) +{ + struct nsp_pinctrl *pinctrl; + struct resource *res; + int i, ret; + struct pinctrl_pin_desc *pins; + unsigned int num_pins = ARRAY_SIZE(nsp_pins); + + pinctrl = devm_kzalloc(&pdev->dev, sizeof(*pinctrl), GFP_KERNEL); + if (!pinctrl) + return -ENOMEM; + pinctrl->dev = &pdev->dev; + platform_set_drvdata(pdev, pinctrl); + spin_lock_init(&pinctrl->lock); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + pinctrl->base0 = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pinctrl->base0)) + return PTR_ERR(pinctrl->base0); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + pinctrl->base1 = devm_ioremap_nocache(&pdev->dev, res->start, + resource_size(res)); + if (!pinctrl->base1) { + dev_err(&pdev->dev, "unable to map I/O space\n"); + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + pinctrl->base2 = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(pinctrl->base2)) + return PTR_ERR(pinctrl->base2); + + ret = nsp_mux_log_init(pinctrl); + if (ret) { + dev_err(&pdev->dev, "unable to initialize IOMUX log\n"); + return ret; + } + + pins = devm_kcalloc(&pdev->dev, num_pins, sizeof(*pins), GFP_KERNEL); + if (!pins) + return -ENOMEM; + + for (i = 0; i < num_pins; i++) { + pins[i].number = nsp_pins[i].pin; + pins[i].name = nsp_pins[i].name; + pins[i].drv_data = &nsp_pins[i].gpio_select; + } + + pinctrl->groups = nsp_pin_groups; + pinctrl->num_groups = ARRAY_SIZE(nsp_pin_groups); + pinctrl->functions = nsp_pin_functions; + pinctrl->num_functions = ARRAY_SIZE(nsp_pin_functions); + nsp_pinctrl_desc.pins = pins; + nsp_pinctrl_desc.npins = num_pins; + + pinctrl->pctl = devm_pinctrl_register(&pdev->dev, &nsp_pinctrl_desc, + pinctrl); + if (IS_ERR(pinctrl->pctl)) { + dev_err(&pdev->dev, "unable to register nsp IOMUX pinctrl\n"); + return PTR_ERR(pinctrl->pctl); + } + + return 0; +} + +static const struct of_device_id nsp_pinmux_of_match[] = { + { .compatible = "brcm,nsp-pinmux" }, + { } +}; + +static struct platform_driver nsp_pinmux_driver = { + .driver = { + .name = "nsp-pinmux", + .of_match_table = nsp_pinmux_of_match, + }, + .probe = nsp_pinmux_probe, +}; + +static int __init nsp_pinmux_init(void) +{ + return platform_driver_register(&nsp_pinmux_driver); +} +arch_initcall(nsp_pinmux_init); diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 98d2a1bb44cb..fb38e208f32d 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -225,13 +225,14 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, } static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, - unsigned number, const char *name) + const struct pinctrl_pin_desc *pin) { struct pin_desc *pindesc; - pindesc = pin_desc_get(pctldev, number); + pindesc = pin_desc_get(pctldev, pin->number); if (pindesc != NULL) { - dev_err(pctldev->dev, "pin %d already registered\n", number); + dev_err(pctldev->dev, "pin %d already registered\n", + pin->number); return -EINVAL; } @@ -245,10 +246,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->pctldev = pctldev; /* Copy basic pin info */ - if (name) { - pindesc->name = name; + if (pin->name) { + pindesc->name = pin->name; } else { - pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number); + pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", pin->number); if (pindesc->name == NULL) { kfree(pindesc); return -ENOMEM; @@ -256,9 +257,11 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->dynamic_name = true; } - radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc); + pindesc->drv_data = pin->drv_data; + + radix_tree_insert(&pctldev->pin_desc_tree, pin->number, pindesc); pr_debug("registered pin %d (%s) on %s\n", - number, pindesc->name, pctldev->desc->name); + pin->number, pindesc->name, pctldev->desc->name); return 0; } @@ -270,8 +273,7 @@ static int pinctrl_register_pins(struct pinctrl_dev *pctldev, int ret = 0; for (i = 0; i < num_descs; i++) { - ret = pinctrl_register_one_pin(pctldev, - pins[i].number, pins[i].name); + ret = pinctrl_register_one_pin(pctldev, &pins[i]); if (ret) return ret; } @@ -1367,8 +1369,7 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) if (desc == NULL) continue; - seq_printf(s, "pin %d (%s) ", pin, - desc->name ? desc->name : "unnamed"); + seq_printf(s, "pin %d (%s) ", pin, desc->name); /* Driver-specific info per pin */ if (ops->pin_dbg_show) diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index ca08723b9ee1..747c423c11f3 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -134,6 +134,7 @@ struct pinctrl_setting { * @name: a name for the pin, e.g. the name of the pin/pad/finger on a * datasheet or such * @dynamic_name: if the name of this pin was dynamically allocated + * @drv_data: driver-defined per-pin data. pinctrl core does not touch this * @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL. * If non-zero, this pin is claimed by @owner. This field is an integer * rather than a boolean, since pinctrl_get() might process multiple @@ -148,6 +149,7 @@ struct pin_desc { struct pinctrl_dev *pctldev; const char *name; bool dynamic_name; + void *drv_data; /* These fields only added when supporting pinmux drivers */ #ifdef CONFIG_PINMUX unsigned mux_usecount; diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index fe04e748dfe4..54dad89fc9bf 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -195,8 +195,13 @@ int pinctrl_dt_to_map(struct pinctrl *p) propname = kasprintf(GFP_KERNEL, "pinctrl-%d", state); prop = of_find_property(np, propname, &size); kfree(propname); - if (!prop) + if (!prop) { + if (state == 0) { + of_node_put(np); + return -ENODEV; + } break; + } list = prop->value; size /= sizeof(*list); diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index eccb47480e1d..71391757938b 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -16,7 +16,6 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/mfd/syscon.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/of_address.h> @@ -46,7 +45,7 @@ struct imx_pinctrl { const struct imx_pinctrl_soc_info *info; }; -static const inline struct imx_pin_group *imx_pinctrl_find_group_by_name( +static inline const struct imx_pin_group *imx_pinctrl_find_group_by_name( const struct imx_pinctrl_soc_info *info, const char *name) { @@ -513,13 +512,6 @@ static const struct pinconf_ops imx_pinconf_ops = { .pin_config_group_dbg_show = imx_pinconf_group_dbg_show, }; -static struct pinctrl_desc imx_pinctrl_desc = { - .pctlops = &imx_pctrl_ops, - .pmxops = &imx_pmx_ops, - .confops = &imx_pinconf_ops, - .owner = THIS_MODULE, -}; - /* * Each pin represented in fsl,pins consists of 5 u32 PIN_FUNC_ID and * 1 u32 CONFIG, so 24 types in total for each pin. @@ -722,6 +714,7 @@ int imx_pinctrl_probe(struct platform_device *pdev, { struct regmap_config config = { .name = "gpr" }; struct device_node *dev_np = pdev->dev.of_node; + struct pinctrl_desc *imx_pinctrl_desc; struct device_node *np; struct imx_pinctrl *ipctl; struct resource *res; @@ -776,9 +769,18 @@ int imx_pinctrl_probe(struct platform_device *pdev, } } - imx_pinctrl_desc.name = dev_name(&pdev->dev); - imx_pinctrl_desc.pins = info->pins; - imx_pinctrl_desc.npins = info->npins; + imx_pinctrl_desc = devm_kzalloc(&pdev->dev, sizeof(*imx_pinctrl_desc), + GFP_KERNEL); + if (!imx_pinctrl_desc) + return -ENOMEM; + + imx_pinctrl_desc->name = dev_name(&pdev->dev); + imx_pinctrl_desc->pins = info->pins; + imx_pinctrl_desc->npins = info->npins; + imx_pinctrl_desc->pctlops = &imx_pctrl_ops, + imx_pinctrl_desc->pmxops = &imx_pmx_ops, + imx_pinctrl_desc->confops = &imx_pinconf_ops, + imx_pinctrl_desc->owner = THIS_MODULE, ret = imx_pinctrl_probe_dt(pdev, info); if (ret) { @@ -789,7 +791,8 @@ int imx_pinctrl_probe(struct platform_device *pdev, ipctl->info = info; ipctl->dev = info->dev; platform_set_drvdata(pdev, ipctl); - ipctl->pctl = devm_pinctrl_register(&pdev->dev, &imx_pinctrl_desc, ipctl); + ipctl->pctl = devm_pinctrl_register(&pdev->dev, + imx_pinctrl_desc, ipctl); if (IS_ERR(ipctl->pctl)) { dev_err(&pdev->dev, "could not register IMX pinctrl driver\n"); return PTR_ERR(ipctl->pctl); diff --git a/drivers/pinctrl/freescale/pinctrl-imx1-core.c b/drivers/pinctrl/freescale/pinctrl-imx1-core.c index b4400cb19b61..a4e9f430d452 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1-core.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1-core.c @@ -19,7 +19,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/machine.h> @@ -157,7 +156,7 @@ static int imx1_read_bit(struct imx1_pinctrl *ipctl, unsigned int pin_id, return !!(readl(reg) & BIT(offset)); } -static const inline struct imx1_pin_group *imx1_pinctrl_find_group_by_name( +static inline const struct imx1_pin_group *imx1_pinctrl_find_group_by_name( const struct imx1_pinctrl_soc_info *info, const char *name) { diff --git a/drivers/pinctrl/freescale/pinctrl-imx1.c b/drivers/pinctrl/freescale/pinctrl-imx1.c index 04723455db58..fc8efc748734 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1.c @@ -9,7 +9,7 @@ * (at your option) any later version. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pinctrl/pinctrl.h> @@ -262,7 +262,6 @@ static const struct of_device_id imx1_pinctrl_of_match[] = { { .compatible = "fsl,imx1-iomuxc", }, { } }; -MODULE_DEVICE_TABLE(of, imx1_pinctrl_of_match); static struct platform_driver imx1_pinctrl_driver = { .driver = { @@ -270,8 +269,4 @@ static struct platform_driver imx1_pinctrl_driver = { .of_match_table = imx1_pinctrl_of_match, }, }; -module_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe); - -MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); -MODULE_DESCRIPTION("Freescale i.MX1 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver_probe(imx1_pinctrl_driver, imx1_pinctrl_probe); diff --git a/drivers/pinctrl/freescale/pinctrl-imx21.c b/drivers/pinctrl/freescale/pinctrl-imx21.c index aa1221f4dbb7..73e26bc12f09 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx21.c +++ b/drivers/pinctrl/freescale/pinctrl-imx21.c @@ -9,7 +9,7 @@ * (at your option) any later version. */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pinctrl/pinctrl.h> @@ -325,7 +325,6 @@ static const struct of_device_id imx21_pinctrl_of_match[] = { { .compatible = "fsl,imx21-iomuxc", }, { } }; -MODULE_DEVICE_TABLE(of, imx21_pinctrl_of_match); static struct platform_driver imx21_pinctrl_driver = { .driver = { @@ -333,8 +332,4 @@ static struct platform_driver imx21_pinctrl_driver = { .of_match_table = imx21_pinctrl_of_match, }, }; -module_platform_driver_probe(imx21_pinctrl_driver, imx21_pinctrl_probe); - -MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); -MODULE_DESCRIPTION("Freescale i.MX21 pinctrl driver"); -MODULE_LICENSE("GPL"); +builtin_platform_driver_probe(imx21_pinctrl_driver, imx21_pinctrl_probe); diff --git a/drivers/pinctrl/freescale/pinctrl-imx23.c b/drivers/pinctrl/freescale/pinctrl-imx23.c index 955cbf4f094f..89b4f160138f 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx23.c +++ b/drivers/pinctrl/freescale/pinctrl-imx23.c @@ -1,4 +1,7 @@ /* + * Freescale i.MX23 pinctrl driver + * + * Author: Shawn Guo <shawn.guo@linaro.org> * Copyright 2012 Freescale Semiconductor, Inc. * * The code contained herein is licensed under the GNU General Public @@ -10,7 +13,6 @@ */ #include <linux/init.h> -#include <linux/module.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> #include "pinctrl-mxs.h" @@ -276,15 +278,14 @@ static const struct of_device_id imx23_pinctrl_of_match[] = { { .compatible = "fsl,imx23-pinctrl", }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, imx23_pinctrl_of_match); static struct platform_driver imx23_pinctrl_driver = { .driver = { .name = "imx23-pinctrl", + .suppress_bind_attrs = true, .of_match_table = imx23_pinctrl_of_match, }, .probe = imx23_pinctrl_probe, - .remove = mxs_pinctrl_remove, }; static int __init imx23_pinctrl_init(void) @@ -292,13 +293,3 @@ static int __init imx23_pinctrl_init(void) return platform_driver_register(&imx23_pinctrl_driver); } postcore_initcall(imx23_pinctrl_init); - -static void __exit imx23_pinctrl_exit(void) -{ - platform_driver_unregister(&imx23_pinctrl_driver); -} -module_exit(imx23_pinctrl_exit); - -MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>"); -MODULE_DESCRIPTION("Freescale i.MX23 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx25.c b/drivers/pinctrl/freescale/pinctrl-imx25.c index 81ad546d74bb..d7367fabe712 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx25.c +++ b/drivers/pinctrl/freescale/pinctrl-imx25.c @@ -18,7 +18,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -338,12 +337,3 @@ static int __init imx25_pinctrl_init(void) return platform_driver_register(&imx25_pinctrl_driver); } arch_initcall(imx25_pinctrl_init); - -static void __exit imx25_pinctrl_exit(void) -{ - platform_driver_unregister(&imx25_pinctrl_driver); -} -module_exit(imx25_pinctrl_exit); -MODULE_AUTHOR("Denis Carikli <denis@eukrea.com>"); -MODULE_DESCRIPTION("Freescale IMX25 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx27.c b/drivers/pinctrl/freescale/pinctrl-imx27.c index f828fbbba4b9..e5992036fc6c 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx27.c +++ b/drivers/pinctrl/freescale/pinctrl-imx27.c @@ -14,7 +14,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -412,12 +411,3 @@ static int __init imx27_pinctrl_init(void) return platform_driver_register(&imx27_pinctrl_driver); } arch_initcall(imx27_pinctrl_init); - -static void __exit imx27_pinctrl_exit(void) -{ - platform_driver_unregister(&imx27_pinctrl_driver); -} -module_exit(imx27_pinctrl_exit); -MODULE_AUTHOR("Markus Pargmann <mpa@pengutronix.de>"); -MODULE_DESCRIPTION("Freescale IMX27 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx28.c b/drivers/pinctrl/freescale/pinctrl-imx28.c index 5082efec4f72..295236dfb0bc 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx28.c +++ b/drivers/pinctrl/freescale/pinctrl-imx28.c @@ -1,4 +1,7 @@ /* + * Freescale i.MX28 pinctrl driver + * + * Author: Shawn Guo <shawn.guo@linaro.org> * Copyright 2012 Freescale Semiconductor, Inc. * * The code contained herein is licensed under the GNU General Public @@ -10,7 +13,6 @@ */ #include <linux/init.h> -#include <linux/module.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> #include "pinctrl-mxs.h" @@ -392,15 +394,14 @@ static const struct of_device_id imx28_pinctrl_of_match[] = { { .compatible = "fsl,imx28-pinctrl", }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, imx28_pinctrl_of_match); static struct platform_driver imx28_pinctrl_driver = { .driver = { .name = "imx28-pinctrl", + .suppress_bind_attrs = true, .of_match_table = imx28_pinctrl_of_match, }, .probe = imx28_pinctrl_probe, - .remove = mxs_pinctrl_remove, }; static int __init imx28_pinctrl_init(void) @@ -408,13 +409,3 @@ static int __init imx28_pinctrl_init(void) return platform_driver_register(&imx28_pinctrl_driver); } postcore_initcall(imx28_pinctrl_init); - -static void __exit imx28_pinctrl_exit(void) -{ - platform_driver_unregister(&imx28_pinctrl_driver); -} -module_exit(imx28_pinctrl_exit); - -MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>"); -MODULE_DESCRIPTION("Freescale i.MX28 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx35.c b/drivers/pinctrl/freescale/pinctrl-imx35.c index 13eb224a29a9..6315ba6af431 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx35.c +++ b/drivers/pinctrl/freescale/pinctrl-imx35.c @@ -16,7 +16,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -1028,12 +1027,3 @@ static int __init imx35_pinctrl_init(void) return platform_driver_register(&imx35_pinctrl_driver); } arch_initcall(imx35_pinctrl_init); - -static void __exit imx35_pinctrl_exit(void) -{ - platform_driver_unregister(&imx35_pinctrl_driver); -} -module_exit(imx35_pinctrl_exit); -MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>"); -MODULE_DESCRIPTION("Freescale IMX35 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx50.c b/drivers/pinctrl/freescale/pinctrl-imx50.c index 95a36c88b66a..8e3a17df5c5d 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx50.c +++ b/drivers/pinctrl/freescale/pinctrl-imx50.c @@ -14,7 +14,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -415,11 +414,3 @@ static int __init imx50_pinctrl_init(void) return platform_driver_register(&imx50_pinctrl_driver); } arch_initcall(imx50_pinctrl_init); - -static void __exit imx50_pinctrl_exit(void) -{ - platform_driver_unregister(&imx50_pinctrl_driver); -} -module_exit(imx50_pinctrl_exit); -MODULE_DESCRIPTION("Freescale IMX50 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx51.c b/drivers/pinctrl/freescale/pinctrl-imx51.c index 0863e5279896..eeac64ba2709 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx51.c +++ b/drivers/pinctrl/freescale/pinctrl-imx51.c @@ -15,7 +15,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -791,12 +790,3 @@ static int __init imx51_pinctrl_init(void) return platform_driver_register(&imx51_pinctrl_driver); } arch_initcall(imx51_pinctrl_init); - -static void __exit imx51_pinctrl_exit(void) -{ - platform_driver_unregister(&imx51_pinctrl_driver); -} -module_exit(imx51_pinctrl_exit); -MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>"); -MODULE_DESCRIPTION("Freescale IMX51 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx53.c b/drivers/pinctrl/freescale/pinctrl-imx53.c index 64c9cbe2a5df..46a9572f3473 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx53.c +++ b/drivers/pinctrl/freescale/pinctrl-imx53.c @@ -15,7 +15,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -478,12 +477,3 @@ static int __init imx53_pinctrl_init(void) return platform_driver_register(&imx53_pinctrl_driver); } arch_initcall(imx53_pinctrl_init); - -static void __exit imx53_pinctrl_exit(void) -{ - platform_driver_unregister(&imx53_pinctrl_driver); -} -module_exit(imx53_pinctrl_exit); -MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>"); -MODULE_DESCRIPTION("Freescale IMX53 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx6dl.c b/drivers/pinctrl/freescale/pinctrl-imx6dl.c index de17bac8ad89..3f25ca5867cc 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6dl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6dl.c @@ -1,4 +1,7 @@ /* + * Freescale imx6dl pinctrl driver + * + * Author: Shawn Guo <shawn.guo@linaro.org> * Copyright (C) 2013 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify @@ -9,7 +12,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -484,13 +486,3 @@ static int __init imx6dl_pinctrl_init(void) return platform_driver_register(&imx6dl_pinctrl_driver); } arch_initcall(imx6dl_pinctrl_init); - -static void __exit imx6dl_pinctrl_exit(void) -{ - platform_driver_unregister(&imx6dl_pinctrl_driver); -} -module_exit(imx6dl_pinctrl_exit); - -MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>"); -MODULE_DESCRIPTION("Freescale imx6dl pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx6q.c b/drivers/pinctrl/freescale/pinctrl-imx6q.c index 55cd8a0e367d..d61651c40458 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6q.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6q.c @@ -15,7 +15,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -490,12 +489,3 @@ static int __init imx6q_pinctrl_init(void) return platform_driver_register(&imx6q_pinctrl_driver); } arch_initcall(imx6q_pinctrl_init); - -static void __exit imx6q_pinctrl_exit(void) -{ - platform_driver_unregister(&imx6q_pinctrl_driver); -} -module_exit(imx6q_pinctrl_exit); -MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>"); -MODULE_DESCRIPTION("Freescale IMX6Q pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sl.c b/drivers/pinctrl/freescale/pinctrl-imx6sl.c index bf455b8e73fc..d023f6b00623 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6sl.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6sl.c @@ -1,4 +1,7 @@ /* + * Freescale imx6sl pinctrl driver + * + * Author: Shawn Guo <shawn.guo@linaro.org> * Copyright (C) 2013 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify @@ -9,7 +12,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -371,7 +373,6 @@ static const struct of_device_id imx6sl_pinctrl_of_match[] = { { .compatible = "fsl,imx6sl-iomuxc", }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, imx6sl_pinctrl_of_match); static int imx6sl_pinctrl_probe(struct platform_device *pdev) { @@ -391,13 +392,3 @@ static int __init imx6sl_pinctrl_init(void) return platform_driver_register(&imx6sl_pinctrl_driver); } arch_initcall(imx6sl_pinctrl_init); - -static void __exit imx6sl_pinctrl_exit(void) -{ - platform_driver_unregister(&imx6sl_pinctrl_driver); -} -module_exit(imx6sl_pinctrl_exit); - -MODULE_AUTHOR("Shawn Guo <shawn.guo@linaro.org>"); -MODULE_DESCRIPTION("Freescale imx6sl pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx6sx.c b/drivers/pinctrl/freescale/pinctrl-imx6sx.c index 84118c388cc5..898b781701e6 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6sx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6sx.c @@ -1,4 +1,7 @@ /* + * Freescale imx6sx pinctrl driver + * + * Author: Anson Huang <Anson.Huang@freescale.com> * Copyright (C) 2014 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify @@ -9,7 +12,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -394,13 +396,3 @@ static int __init imx6sx_pinctrl_init(void) return platform_driver_register(&imx6sx_pinctrl_driver); } arch_initcall(imx6sx_pinctrl_init); - -static void __exit imx6sx_pinctrl_exit(void) -{ - platform_driver_unregister(&imx6sx_pinctrl_driver); -} -module_exit(imx6sx_pinctrl_exit); - -MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>"); -MODULE_DESCRIPTION("Freescale imx6sx pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx6ul.c b/drivers/pinctrl/freescale/pinctrl-imx6ul.c index c707fdd933ec..1aeb840aae1d 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx6ul.c +++ b/drivers/pinctrl/freescale/pinctrl-imx6ul.c @@ -1,4 +1,7 @@ /* + * Freescale imx6ul pinctrl driver + * + * Author: Anson Huang <Anson.Huang@freescale.com> * Copyright (C) 2015 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify @@ -9,7 +12,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -310,13 +312,3 @@ static int __init imx6ul_pinctrl_init(void) return platform_driver_register(&imx6ul_pinctrl_driver); } arch_initcall(imx6ul_pinctrl_init); - -static void __exit imx6ul_pinctrl_exit(void) -{ - platform_driver_unregister(&imx6ul_pinctrl_driver); -} -module_exit(imx6ul_pinctrl_exit); - -MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>"); -MODULE_DESCRIPTION("Freescale imx6ul pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-imx7d.c b/drivers/pinctrl/freescale/pinctrl-imx7d.c index d30d91f80dfd..a465a66c3ef4 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx7d.c +++ b/drivers/pinctrl/freescale/pinctrl-imx7d.c @@ -1,4 +1,7 @@ /* + * Freescale imx7d pinctrl driver + * + * Author: Anson Huang <Anson.Huang@freescale.com> * Copyright (C) 2014-2015 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify @@ -9,7 +12,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -402,13 +404,3 @@ static int __init imx7d_pinctrl_init(void) return platform_driver_register(&imx7d_pinctrl_driver); } arch_initcall(imx7d_pinctrl_init); - -static void __exit imx7d_pinctrl_exit(void) -{ - platform_driver_unregister(&imx7d_pinctrl_driver); -} -module_exit(imx7d_pinctrl_exit); - -MODULE_AUTHOR("Anson Huang <Anson.Huang@freescale.com>"); -MODULE_DESCRIPTION("Freescale imx7d pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c index 6bbda6b4ab50..41b5b07d5a2b 100644 --- a/drivers/pinctrl/freescale/pinctrl-mxs.c +++ b/drivers/pinctrl/freescale/pinctrl-mxs.c @@ -12,7 +12,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> #include <linux/pinctrl/machine.h> @@ -553,14 +552,3 @@ err: return ret; } EXPORT_SYMBOL_GPL(mxs_pinctrl_probe); - -int mxs_pinctrl_remove(struct platform_device *pdev) -{ - struct mxs_pinctrl_data *d = platform_get_drvdata(pdev); - - pinctrl_unregister(d->pctl); - iounmap(d->base); - - return 0; -} -EXPORT_SYMBOL_GPL(mxs_pinctrl_remove); diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.h b/drivers/pinctrl/freescale/pinctrl-mxs.h index fdd88d0bae22..34dbf75208dc 100644 --- a/drivers/pinctrl/freescale/pinctrl-mxs.h +++ b/drivers/pinctrl/freescale/pinctrl-mxs.h @@ -86,6 +86,5 @@ struct mxs_pinctrl_soc_data { int mxs_pinctrl_probe(struct platform_device *pdev, struct mxs_pinctrl_soc_data *soc); -int mxs_pinctrl_remove(struct platform_device *pdev); #endif /* __PINCTRL_MXS_H */ diff --git a/drivers/pinctrl/freescale/pinctrl-vf610.c b/drivers/pinctrl/freescale/pinctrl-vf610.c index 6d81be096bc0..2b1e198e3092 100644 --- a/drivers/pinctrl/freescale/pinctrl-vf610.c +++ b/drivers/pinctrl/freescale/pinctrl-vf610.c @@ -12,7 +12,6 @@ #include <linux/err.h> #include <linux/init.h> #include <linux/io.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -325,12 +324,3 @@ static int __init vf610_pinctrl_init(void) return platform_driver_register(&vf610_pinctrl_driver); } arch_initcall(vf610_pinctrl_init); - -static void __exit vf610_pinctrl_exit(void) -{ - platform_driver_unregister(&vf610_pinctrl_driver); -} -module_exit(vf610_pinctrl_exit); - -MODULE_DESCRIPTION("Freescale VF610 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 1c74e038b7b0..00fb055a4897 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -29,6 +29,17 @@ config PINCTRL_CHERRYVIEW Cherryview/Braswell pinctrl driver provides an interface that allows configuring of SoC pins and using them as GPIOs. +config PINCTRL_MERRIFIELD + tristate "Intel Merrifield pinctrl driver" + depends on X86_INTEL_MID + select PINMUX + select PINCONF + select GENERIC_PINCONF + help + Merrifield Family-Level Interface Shim (FLIS) driver provides an + interface that allows configuring of SoC pins and using them as + GPIOs. + config PINCTRL_INTEL tristate select PINMUX diff --git a/drivers/pinctrl/intel/Makefile b/drivers/pinctrl/intel/Makefile index 03bc68e3546c..30803078f09e 100644 --- a/drivers/pinctrl/intel/Makefile +++ b/drivers/pinctrl/intel/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o obj-$(CONFIG_PINCTRL_CHERRYVIEW) += pinctrl-cherryview.o +obj-$(CONFIG_PINCTRL_MERRIFIELD) += pinctrl-merrifield.o obj-$(CONFIG_PINCTRL_INTEL) += pinctrl-intel.o obj-$(CONFIG_PINCTRL_BROXTON) += pinctrl-broxton.o obj-$(CONFIG_PINCTRL_SUNRISEPOINT) += pinctrl-sunrisepoint.o diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 7abfd42e8ffd..d22a9fe2e6df 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -15,7 +15,6 @@ */ #include <linux/kernel.h> -#include <linux/module.h> #include <linux/init.h> #include <linux/types.h> #include <linux/bitops.h> @@ -1822,17 +1821,6 @@ static int byt_pinctrl_probe(struct platform_device *pdev) return 0; } -static int byt_pinctrl_remove(struct platform_device *pdev) -{ - struct byt_gpio *vg = platform_get_drvdata(pdev); - - pm_runtime_disable(&pdev->dev); - gpiochip_remove(&vg->chip); - pinctrl_unregister(vg->pctl_dev); - - return 0; -} - #ifdef CONFIG_PM_SLEEP static int byt_gpio_suspend(struct device *dev) { @@ -1930,10 +1918,11 @@ static const struct dev_pm_ops byt_gpio_pm_ops = { static struct platform_driver byt_gpio_driver = { .probe = byt_pinctrl_probe, - .remove = byt_pinctrl_remove, .driver = { - .name = "byt_gpio", - .pm = &byt_gpio_pm_ops, + .name = "byt_gpio", + .pm = &byt_gpio_pm_ops, + .suppress_bind_attrs = true, + .acpi_match_table = ACPI_PTR(byt_gpio_acpi_match), }, }; @@ -1943,9 +1932,3 @@ static int __init byt_gpio_init(void) return platform_driver_register(&byt_gpio_driver); } subsys_initcall(byt_gpio_init); - -static void __exit byt_gpio_exit(void) -{ - platform_driver_unregister(&byt_gpio_driver); -} -module_exit(byt_gpio_exit); diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c index 5979d38c46b2..59cb7a6fc5be 100644 --- a/drivers/pinctrl/intel/pinctrl-broxton.c +++ b/drivers/pinctrl/intel/pinctrl-broxton.c @@ -1,7 +1,7 @@ /* * Intel Broxton SoC pinctrl/GPIO driver * - * Copyright (C) 2015, Intel Corporation + * Copyright (C) 2015, 2016 Intel Corporation * Author: Mika Westerberg <mika.westerberg@linux.intel.com> * * This program is free software; you can redistribute it and/or modify @@ -1003,29 +1003,46 @@ static const struct acpi_device_id bxt_pinctrl_acpi_match[] = { }; MODULE_DEVICE_TABLE(acpi, bxt_pinctrl_acpi_match); +static const struct platform_device_id bxt_pinctrl_platform_ids[] = { + { "apl-pinctrl", (kernel_ulong_t)&apl_pinctrl_soc_data }, + { "broxton-pinctrl", (kernel_ulong_t)&bxt_pinctrl_soc_data }, + { }, +}; + static int bxt_pinctrl_probe(struct platform_device *pdev) { const struct intel_pinctrl_soc_data *soc_data = NULL; const struct intel_pinctrl_soc_data **soc_table; - const struct acpi_device_id *id; struct acpi_device *adev; int i; adev = ACPI_COMPANION(&pdev->dev); - if (!adev) - return -ENODEV; + if (adev) { + const struct acpi_device_id *id; - id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev); - if (!id) - return -ENODEV; + id = acpi_match_device(bxt_pinctrl_acpi_match, &pdev->dev); + if (!id) + return -ENODEV; - soc_table = (const struct intel_pinctrl_soc_data **)id->driver_data; + soc_table = (const struct intel_pinctrl_soc_data **) + id->driver_data; - for (i = 0; soc_table[i]; i++) { - if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) { - soc_data = soc_table[i]; - break; + for (i = 0; soc_table[i]; i++) { + if (!strcmp(adev->pnp.unique_id, soc_table[i]->uid)) { + soc_data = soc_table[i]; + break; + } } + } else { + const struct platform_device_id *pid; + + pid = platform_get_device_id(pdev); + if (!pid) + return -ENODEV; + + soc_table = (const struct intel_pinctrl_soc_data **) + pid->driver_data; + soc_data = soc_table[pdev->id]; } if (!soc_data) @@ -1047,6 +1064,7 @@ static struct platform_driver bxt_pinctrl_driver = { .acpi_match_table = bxt_pinctrl_acpi_match, .pm = &bxt_pinctrl_pm_ops, }, + .id_table = bxt_pinctrl_platform_ids, }; static int __init bxt_pinctrl_init(void) @@ -1064,3 +1082,4 @@ module_exit(bxt_pinctrl_exit); MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); MODULE_DESCRIPTION("Intel Broxton SoC pinctrl/GPIO driver"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:broxton-pinctrl"); diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index ac4f564f1c3e..5749a4eee746 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -160,7 +160,6 @@ struct chv_pin_context { * @pctldev: Pointer to the pin controller device * @chip: GPIO chip in this pin controller * @regs: MMIO registers - * @lock: Lock to serialize register accesses * @intr_lines: Stores mapping between 16 HW interrupt wires and GPIO * offset (in GPIO number space) * @community: Community this pinctrl instance represents @@ -174,7 +173,6 @@ struct chv_pinctrl { struct pinctrl_dev *pctldev; struct gpio_chip chip; void __iomem *regs; - raw_spinlock_t lock; unsigned intr_lines[16]; const struct chv_community *community; u32 saved_intmask; @@ -657,6 +655,17 @@ static const struct chv_community *chv_communities[] = { &southeast_community, }; +/* + * Lock to serialize register accesses + * + * Due to a silicon issue, a shared lock must be used to prevent + * concurrent accesses across the 4 GPIO controllers. + * + * See Intel Atom Z8000 Processor Series Specification Update (Rev. 005), + * errata #CHT34, for further information. + */ +static DEFINE_RAW_SPINLOCK(chv_lock); + static void __iomem *chv_padreg(struct chv_pinctrl *pctrl, unsigned offset, unsigned reg) { @@ -718,13 +727,13 @@ static void chv_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, u32 ctrl0, ctrl1; bool locked; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); ctrl0 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); ctrl1 = readl(chv_padreg(pctrl, offset, CHV_PADCTRL1)); locked = chv_pad_locked(pctrl, offset); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); if (ctrl0 & CHV_PADCTRL0_GPIOEN) { seq_puts(s, "GPIO "); @@ -787,14 +796,14 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function, grp = &pctrl->community->groups[group]; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); /* Check first that the pad is not locked */ for (i = 0; i < grp->npins; i++) { if (chv_pad_locked(pctrl, grp->pins[i])) { dev_warn(pctrl->dev, "unable to set mode for locked pin %u\n", grp->pins[i]); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return -EBUSY; } } @@ -837,7 +846,7 @@ static int chv_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function, pin, altfunc->mode, altfunc->invert_oe ? "" : "not "); } - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; } @@ -851,13 +860,13 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, void __iomem *reg; u32 value; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); if (chv_pad_locked(pctrl, offset)) { value = readl(chv_padreg(pctrl, offset, CHV_PADCTRL0)); if (!(value & CHV_PADCTRL0_GPIOEN)) { /* Locked so cannot enable */ - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return -EBUSY; } } else { @@ -897,7 +906,7 @@ static int chv_gpio_request_enable(struct pinctrl_dev *pctldev, chv_writel(value, reg); } - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; } @@ -911,13 +920,13 @@ static void chv_gpio_disable_free(struct pinctrl_dev *pctldev, void __iomem *reg; u32 value; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); reg = chv_padreg(pctrl, offset, CHV_PADCTRL0); value = readl(reg) & ~CHV_PADCTRL0_GPIOEN; chv_writel(value, reg); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); } static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, @@ -929,7 +938,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, unsigned long flags; u32 ctrl0; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); ctrl0 = readl(reg) & ~CHV_PADCTRL0_GPIOCFG_MASK; if (input) @@ -938,7 +947,7 @@ static int chv_gpio_set_direction(struct pinctrl_dev *pctldev, ctrl0 |= CHV_PADCTRL0_GPIOCFG_GPO << CHV_PADCTRL0_GPIOCFG_SHIFT; chv_writel(ctrl0, reg); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; } @@ -963,10 +972,10 @@ static int chv_config_get(struct pinctrl_dev *pctldev, unsigned pin, u16 arg = 0; u32 term; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); ctrl1 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL1)); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); term = (ctrl0 & CHV_PADCTRL0_TERM_MASK) >> CHV_PADCTRL0_TERM_SHIFT; @@ -1040,7 +1049,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin, unsigned long flags; u32 ctrl0, pull; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); ctrl0 = readl(reg); switch (param) { @@ -1063,7 +1072,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin, pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; break; default: - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return -EINVAL; } @@ -1081,7 +1090,7 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin, pull = CHV_PADCTRL0_TERM_20K << CHV_PADCTRL0_TERM_SHIFT; break; default: - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return -EINVAL; } @@ -1089,12 +1098,33 @@ static int chv_config_set_pull(struct chv_pinctrl *pctrl, unsigned pin, break; default: - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return -EINVAL; } chv_writel(ctrl0, reg); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); + + return 0; +} + +static int chv_config_set_oden(struct chv_pinctrl *pctrl, unsigned int pin, + bool enable) +{ + void __iomem *reg = chv_padreg(pctrl, pin, CHV_PADCTRL1); + unsigned long flags; + u32 ctrl1; + + raw_spin_lock_irqsave(&chv_lock, flags); + ctrl1 = readl(reg); + + if (enable) + ctrl1 |= CHV_PADCTRL1_ODEN; + else + ctrl1 &= ~CHV_PADCTRL1_ODEN; + + chv_writel(ctrl1, reg); + raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; } @@ -1123,6 +1153,18 @@ static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin, return ret; break; + case PIN_CONFIG_DRIVE_PUSH_PULL: + ret = chv_config_set_oden(pctrl, pin, false); + if (ret) + return ret; + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + ret = chv_config_set_oden(pctrl, pin, true); + if (ret) + return ret; + break; + default: return -ENOTSUPP; } @@ -1134,10 +1176,52 @@ static int chv_config_set(struct pinctrl_dev *pctldev, unsigned pin, return 0; } +static int chv_config_group_get(struct pinctrl_dev *pctldev, + unsigned int group, + unsigned long *config) +{ + const unsigned int *pins; + unsigned int npins; + int ret; + + ret = chv_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + + ret = chv_config_get(pctldev, pins[0], config); + if (ret) + return ret; + + return 0; +} + +static int chv_config_group_set(struct pinctrl_dev *pctldev, + unsigned int group, unsigned long *configs, + unsigned int num_configs) +{ + const unsigned int *pins; + unsigned int npins; + int i, ret; + + ret = chv_get_group_pins(pctldev, group, &pins, &npins); + if (ret) + return ret; + + for (i = 0; i < npins; i++) { + ret = chv_config_set(pctldev, pins[i], configs, num_configs); + if (ret) + return ret; + } + + return 0; +} + static const struct pinconf_ops chv_pinconf_ops = { .is_generic = true, .pin_config_set = chv_config_set, .pin_config_get = chv_config_get, + .pin_config_group_get = chv_config_group_get, + .pin_config_group_set = chv_config_group_set, }; static struct pinctrl_desc chv_pinctrl_desc = { @@ -1160,9 +1244,9 @@ static int chv_gpio_get(struct gpio_chip *chip, unsigned offset) unsigned long flags; u32 ctrl0, cfg; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); cfg = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; cfg >>= CHV_PADCTRL0_GPIOCFG_SHIFT; @@ -1180,7 +1264,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value) void __iomem *reg; u32 ctrl0; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); reg = chv_padreg(pctrl, pin, CHV_PADCTRL0); ctrl0 = readl(reg); @@ -1192,7 +1276,7 @@ static void chv_gpio_set(struct gpio_chip *chip, unsigned offset, int value) chv_writel(ctrl0, reg); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); } static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset) @@ -1202,9 +1286,9 @@ static int chv_gpio_get_direction(struct gpio_chip *chip, unsigned offset) u32 ctrl0, direction; unsigned long flags; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); ctrl0 = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); direction = ctrl0 & CHV_PADCTRL0_GPIOCFG_MASK; direction >>= CHV_PADCTRL0_GPIOCFG_SHIFT; @@ -1242,14 +1326,14 @@ static void chv_gpio_irq_ack(struct irq_data *d) int pin = chv_gpio_offset_to_pin(pctrl, irqd_to_hwirq(d)); u32 intr_line; - raw_spin_lock(&pctrl->lock); + raw_spin_lock(&chv_lock); intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); intr_line &= CHV_PADCTRL0_INTSEL_MASK; intr_line >>= CHV_PADCTRL0_INTSEL_SHIFT; chv_writel(BIT(intr_line), pctrl->regs + CHV_INTSTAT); - raw_spin_unlock(&pctrl->lock); + raw_spin_unlock(&chv_lock); } static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) @@ -1260,7 +1344,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) u32 value, intr_line; unsigned long flags; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); intr_line = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); intr_line &= CHV_PADCTRL0_INTSEL_MASK; @@ -1273,7 +1357,7 @@ static void chv_gpio_irq_mask_unmask(struct irq_data *d, bool mask) value |= BIT(intr_line); chv_writel(value, pctrl->regs + CHV_INTMASK); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); } static void chv_gpio_irq_mask(struct irq_data *d) @@ -1307,7 +1391,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) unsigned long flags; u32 intsel, value; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); intsel = readl(chv_padreg(pctrl, pin, CHV_PADCTRL0)); intsel &= CHV_PADCTRL0_INTSEL_MASK; intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; @@ -1322,7 +1406,7 @@ static unsigned chv_gpio_irq_startup(struct irq_data *d) irq_set_handler_locked(d, handler); pctrl->intr_lines[intsel] = offset; } - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); } chv_gpio_irq_unmask(d); @@ -1338,7 +1422,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type) unsigned long flags; u32 value; - raw_spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&chv_lock, flags); /* * Pins which can be used as shared interrupt are configured in @@ -1387,7 +1471,7 @@ static int chv_gpio_irq_type(struct irq_data *d, unsigned type) else if (type & IRQ_TYPE_LEVEL_MASK) irq_set_handler_locked(d, handle_level_irq); - raw_spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&chv_lock, flags); return 0; } @@ -1499,7 +1583,6 @@ static int chv_pinctrl_probe(struct platform_device *pdev) if (i == ARRAY_SIZE(chv_communities)) return -ENODEV; - raw_spin_lock_init(&pctrl->lock); pctrl->dev = &pdev->dev; #ifdef CONFIG_PM_SLEEP diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 3584e50fa2c6..257cab129692 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -89,7 +89,7 @@ struct intel_pinctrl_context { */ struct intel_pinctrl { struct device *dev; - spinlock_t lock; + raw_spinlock_t lock; struct pinctrl_desc pctldesc; struct pinctrl_dev *pctldev; struct gpio_chip chip; @@ -318,7 +318,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function, unsigned long flags; int i; - spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&pctrl->lock, flags); /* * All pins in the groups needs to be accessible and writable @@ -326,7 +326,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function, */ for (i = 0; i < grp->npins; i++) { if (!intel_pad_usable(pctrl, grp->pins[i])) { - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); return -EBUSY; } } @@ -345,7 +345,7 @@ static int intel_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned function, writel(value, padcfg0); } - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); return 0; } @@ -359,10 +359,10 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, unsigned long flags; u32 value; - spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&pctrl->lock, flags); if (!intel_pad_usable(pctrl, pin)) { - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); return -EBUSY; } @@ -377,7 +377,7 @@ static int intel_gpio_request_enable(struct pinctrl_dev *pctldev, value |= PADCFG0_GPIOTXDIS; writel(value, padcfg0); - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); return 0; } @@ -391,7 +391,7 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev, unsigned long flags; u32 value; - spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&pctrl->lock, flags); padcfg0 = intel_get_padcfg(pctrl, pin, PADCFG0); @@ -402,7 +402,7 @@ static int intel_gpio_set_direction(struct pinctrl_dev *pctldev, value &= ~PADCFG0_GPIOTXDIS; writel(value, padcfg0); - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); return 0; } @@ -490,7 +490,7 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin, int ret = 0; u32 value; - spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&pctrl->lock, flags); padcfg1 = intel_get_padcfg(pctrl, pin, PADCFG1); value = readl(padcfg1); @@ -544,7 +544,7 @@ static int intel_config_set_pull(struct intel_pinctrl *pctrl, unsigned pin, if (!ret) writel(value, padcfg1); - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); return ret; } @@ -611,14 +611,14 @@ static void intel_gpio_set(struct gpio_chip *chip, unsigned offset, int value) unsigned long flags; u32 padcfg0; - spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&pctrl->lock, flags); padcfg0 = readl(reg); if (value) padcfg0 |= PADCFG0_GPIOTXSTATE; else padcfg0 &= ~PADCFG0_GPIOTXSTATE; writel(padcfg0, reg); - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); } } @@ -651,7 +651,7 @@ static void intel_gpio_irq_ack(struct irq_data *d) const struct intel_community *community; unsigned pin = irqd_to_hwirq(d); - spin_lock(&pctrl->lock); + raw_spin_lock(&pctrl->lock); community = intel_get_community(pctrl, pin); if (community) { @@ -662,7 +662,7 @@ static void intel_gpio_irq_ack(struct irq_data *d) writel(BIT(gpp_offset), community->regs + GPI_IS + gpp * 4); } - spin_unlock(&pctrl->lock); + raw_spin_unlock(&pctrl->lock); } static void intel_gpio_irq_enable(struct irq_data *d) @@ -673,7 +673,7 @@ static void intel_gpio_irq_enable(struct irq_data *d) unsigned pin = irqd_to_hwirq(d); unsigned long flags; - spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&pctrl->lock, flags); community = intel_get_community(pctrl, pin); if (community) { @@ -691,7 +691,7 @@ static void intel_gpio_irq_enable(struct irq_data *d) writel(value, community->regs + community->ie_offset + gpp * 4); } - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); } static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) @@ -702,7 +702,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) unsigned pin = irqd_to_hwirq(d); unsigned long flags; - spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&pctrl->lock, flags); community = intel_get_community(pctrl, pin); if (community) { @@ -721,7 +721,7 @@ static void intel_gpio_irq_mask_unmask(struct irq_data *d, bool mask) writel(value, reg); } - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); } static void intel_gpio_irq_mask(struct irq_data *d) @@ -757,7 +757,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) return -EPERM; } - spin_lock_irqsave(&pctrl->lock, flags); + raw_spin_lock_irqsave(&pctrl->lock, flags); value = readl(reg); @@ -784,7 +784,7 @@ static int intel_gpio_irq_type(struct irq_data *d, unsigned type) else if (type & IRQ_TYPE_LEVEL_MASK) irq_set_handler_locked(d, handle_level_irq); - spin_unlock_irqrestore(&pctrl->lock, flags); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); return 0; } @@ -796,12 +796,15 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) const struct intel_community *community; unsigned pin = irqd_to_hwirq(d); unsigned padno, gpp, gpp_offset; + unsigned long flags; u32 gpe_en; community = intel_get_community(pctrl, pin); if (!community) return -EINVAL; + raw_spin_lock_irqsave(&pctrl->lock, flags); + padno = pin_to_padno(community, pin); gpp = padno / community->gpp_size; gpp_offset = padno % community->gpp_size; @@ -821,6 +824,8 @@ static int intel_gpio_irq_wake(struct irq_data *d, unsigned int on) gpe_en &= ~BIT(gpp_offset); writel(gpe_en, community->regs + GPI_GPE_EN + gpp * 4); + raw_spin_unlock_irqrestore(&pctrl->lock, flags); + dev_dbg(pctrl->dev, "%sable wake for pin %u\n", on ? "en" : "dis", pin); return 0; } @@ -919,7 +924,8 @@ static int intel_gpio_probe(struct intel_pinctrl *pctrl, int irq) * to the irq directly) because on some platforms several GPIO * controllers share the same interrupt line. */ - ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq, IRQF_SHARED, + ret = devm_request_irq(pctrl->dev, irq, intel_gpio_irq, + IRQF_SHARED | IRQF_NO_THREAD, dev_name(pctrl->dev), pctrl); if (ret) { dev_err(pctrl->dev, "failed to request interrupt\n"); @@ -995,7 +1001,7 @@ int intel_pinctrl_probe(struct platform_device *pdev, pctrl->dev = &pdev->dev; pctrl->soc = soc_data; - spin_lock_init(&pctrl->lock); + raw_spin_lock_init(&pctrl->lock); /* * Make a copy of the communities which we can use to hold pointers diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c new file mode 100644 index 000000000000..eb4990ff26ca --- /dev/null +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -0,0 +1,911 @@ +/* + * Intel Merrifield SoC pinctrl driver + * + * Copyright (C) 2016, Intel Corporation + * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/bitops.h> +#include <linux/err.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> + +#include "pinctrl-intel.h" + +#define MRFLD_FAMILY_NR 64 +#define MRFLD_FAMILY_LEN 0x400 + +#define SLEW_OFFSET 0x000 +#define BUFCFG_OFFSET 0x100 +#define MISC_OFFSET 0x300 + +#define BUFCFG_PINMODE_SHIFT 0 +#define BUFCFG_PINMODE_MASK GENMASK(2, 0) +#define BUFCFG_PINMODE_GPIO 0 +#define BUFCFG_PUPD_VAL_SHIFT 4 +#define BUFCFG_PUPD_VAL_MASK GENMASK(5, 4) +#define BUFCFG_PUPD_VAL_2K 0 +#define BUFCFG_PUPD_VAL_20K 1 +#define BUFCFG_PUPD_VAL_50K 2 +#define BUFCFG_PUPD_VAL_910 3 +#define BUFCFG_PU_EN BIT(8) +#define BUFCFG_PD_EN BIT(9) +#define BUFCFG_Px_EN_MASK GENMASK(9, 8) +#define BUFCFG_SLEWSEL BIT(10) +#define BUFCFG_OVINEN BIT(12) +#define BUFCFG_OVINEN_EN BIT(13) +#define BUFCFG_OVINEN_MASK GENMASK(13, 12) +#define BUFCFG_OVOUTEN BIT(14) +#define BUFCFG_OVOUTEN_EN BIT(15) +#define BUFCFG_OVOUTEN_MASK GENMASK(15, 14) +#define BUFCFG_INDATAOV_VAL BIT(16) +#define BUFCFG_INDATAOV_EN BIT(17) +#define BUFCFG_INDATAOV_MASK GENMASK(17, 16) +#define BUFCFG_OUTDATAOV_VAL BIT(18) +#define BUFCFG_OUTDATAOV_EN BIT(19) +#define BUFCFG_OUTDATAOV_MASK GENMASK(19, 18) +#define BUFCFG_OD_EN BIT(21) + +/** + * struct mrfld_family - Intel pin family description + * @barno: MMIO BAR number where registers for this family reside + * @pin_base: Starting pin of pins in this family + * @npins: Number of pins in this family + * @protected: True if family is protected by access + * @regs: family specific common registers + */ +struct mrfld_family { + unsigned int barno; + unsigned int pin_base; + size_t npins; + bool protected; + void __iomem *regs; +}; + +#define MRFLD_FAMILY(b, s, e) \ + { \ + .barno = (b), \ + .pin_base = (s), \ + .npins = (e) - (s) + 1, \ + } + +#define MRFLD_FAMILY_PROTECTED(b, s, e) \ + { \ + .barno = (b), \ + .pin_base = (s), \ + .npins = (e) - (s) + 1, \ + .protected = true, \ + } + +static const struct pinctrl_pin_desc mrfld_pins[] = { + /* Family 0: OCP2SSC (0 pins) */ + /* Family 1: ULPI (13 pins) */ + PINCTRL_PIN(0, "ULPI_CLK"), + PINCTRL_PIN(1, "ULPI_D0"), + PINCTRL_PIN(2, "ULPI_D1"), + PINCTRL_PIN(3, "ULPI_D2"), + PINCTRL_PIN(4, "ULPI_D3"), + PINCTRL_PIN(5, "ULPI_D4"), + PINCTRL_PIN(6, "ULPI_D5"), + PINCTRL_PIN(7, "ULPI_D6"), + PINCTRL_PIN(8, "ULPI_D7"), + PINCTRL_PIN(9, "ULPI_DIR"), + PINCTRL_PIN(10, "ULPI_NXT"), + PINCTRL_PIN(11, "ULPI_REFCLK"), + PINCTRL_PIN(12, "ULPI_STP"), + /* Family 2: eMMC (24 pins) */ + PINCTRL_PIN(13, "EMMC_CLK"), + PINCTRL_PIN(14, "EMMC_CMD"), + PINCTRL_PIN(15, "EMMC_D0"), + PINCTRL_PIN(16, "EMMC_D1"), + PINCTRL_PIN(17, "EMMC_D2"), + PINCTRL_PIN(18, "EMMC_D3"), + PINCTRL_PIN(19, "EMMC_D4"), + PINCTRL_PIN(20, "EMMC_D5"), + PINCTRL_PIN(21, "EMMC_D6"), + PINCTRL_PIN(22, "EMMC_D7"), + PINCTRL_PIN(23, "EMMC_RST_N"), + PINCTRL_PIN(24, "GP154"), + PINCTRL_PIN(25, "GP155"), + PINCTRL_PIN(26, "GP156"), + PINCTRL_PIN(27, "GP157"), + PINCTRL_PIN(28, "GP158"), + PINCTRL_PIN(29, "GP159"), + PINCTRL_PIN(30, "GP160"), + PINCTRL_PIN(31, "GP161"), + PINCTRL_PIN(32, "GP162"), + PINCTRL_PIN(33, "GP163"), + PINCTRL_PIN(34, "GP97"), + PINCTRL_PIN(35, "GP14"), + PINCTRL_PIN(36, "GP15"), + /* Family 3: SDIO (20 pins) */ + PINCTRL_PIN(37, "GP77_SD_CD"), + PINCTRL_PIN(38, "GP78_SD_CLK"), + PINCTRL_PIN(39, "GP79_SD_CMD"), + PINCTRL_PIN(40, "GP80_SD_D0"), + PINCTRL_PIN(41, "GP81_SD_D1"), + PINCTRL_PIN(42, "GP82_SD_D2"), + PINCTRL_PIN(43, "GP83_SD_D3"), + PINCTRL_PIN(44, "GP84_SD_LS_CLK_FB"), + PINCTRL_PIN(45, "GP85_SD_LS_CMD_DIR"), + PINCTRL_PIN(46, "GP86_SD_LVL_D_DIR"), + PINCTRL_PIN(47, "GP88_SD_LS_SEL"), + PINCTRL_PIN(48, "GP87_SD_PD"), + PINCTRL_PIN(49, "GP89_SD_WP"), + PINCTRL_PIN(50, "GP90_SDIO_CLK"), + PINCTRL_PIN(51, "GP91_SDIO_CMD"), + PINCTRL_PIN(52, "GP92_SDIO_D0"), + PINCTRL_PIN(53, "GP93_SDIO_D1"), + PINCTRL_PIN(54, "GP94_SDIO_D2"), + PINCTRL_PIN(55, "GP95_SDIO_D3"), + PINCTRL_PIN(56, "GP96_SDIO_PD"), + /* Family 4: HSI (8 pins) */ + PINCTRL_PIN(57, "HSI_ACDATA"), + PINCTRL_PIN(58, "HSI_ACFLAG"), + PINCTRL_PIN(59, "HSI_ACREADY"), + PINCTRL_PIN(60, "HSI_ACWAKE"), + PINCTRL_PIN(61, "HSI_CADATA"), + PINCTRL_PIN(62, "HSI_CAFLAG"), + PINCTRL_PIN(63, "HSI_CAREADY"), + PINCTRL_PIN(64, "HSI_CAWAKE"), + /* Family 5: SSP Audio (14 pins) */ + PINCTRL_PIN(65, "GP70"), + PINCTRL_PIN(66, "GP71"), + PINCTRL_PIN(67, "GP32_I2S_0_CLK"), + PINCTRL_PIN(68, "GP33_I2S_0_FS"), + PINCTRL_PIN(69, "GP34_I2S_0_RXD"), + PINCTRL_PIN(70, "GP35_I2S_0_TXD"), + PINCTRL_PIN(71, "GP36_I2S_1_CLK"), + PINCTRL_PIN(72, "GP37_I2S_1_FS"), + PINCTRL_PIN(73, "GP38_I2S_1_RXD"), + PINCTRL_PIN(74, "GP39_I2S_1_TXD"), + PINCTRL_PIN(75, "GP40_I2S_2_CLK"), + PINCTRL_PIN(76, "GP41_I2S_2_FS"), + PINCTRL_PIN(77, "GP42_I2S_2_RXD"), + PINCTRL_PIN(78, "GP43_I2S_2_TXD"), + /* Family 6: GP SSP (22 pins) */ + PINCTRL_PIN(79, "GP120_SPI_3_CLK"), + PINCTRL_PIN(80, "GP121_SPI_3_SS"), + PINCTRL_PIN(81, "GP122_SPI_3_RXD"), + PINCTRL_PIN(82, "GP123_SPI_3_TXD"), + PINCTRL_PIN(83, "GP102_SPI_4_CLK"), + PINCTRL_PIN(84, "GP103_SPI_4_SS_0"), + PINCTRL_PIN(85, "GP104_SPI_4_SS_1"), + PINCTRL_PIN(86, "GP105_SPI_4_SS_2"), + PINCTRL_PIN(87, "GP106_SPI_4_SS_3"), + PINCTRL_PIN(88, "GP107_SPI_4_RXD"), + PINCTRL_PIN(89, "GP108_SPI_4_TXD"), + PINCTRL_PIN(90, "GP109_SPI_5_CLK"), + PINCTRL_PIN(91, "GP110_SPI_5_SS_0"), + PINCTRL_PIN(92, "GP111_SPI_5_SS_1"), + PINCTRL_PIN(93, "GP112_SPI_5_SS_2"), + PINCTRL_PIN(94, "GP113_SPI_5_SS_3"), + PINCTRL_PIN(95, "GP114_SPI_5_RXD"), + PINCTRL_PIN(96, "GP115_SPI_5_TXD"), + PINCTRL_PIN(97, "GP116_SPI_6_CLK"), + PINCTRL_PIN(98, "GP117_SPI_6_SS"), + PINCTRL_PIN(99, "GP118_SPI_6_RXD"), + PINCTRL_PIN(100, "GP119_SPI_6_TXD"), + /* Family 7: I2C (14 pins) */ + PINCTRL_PIN(101, "GP19_I2C_1_SCL"), + PINCTRL_PIN(102, "GP20_I2C_1_SDA"), + PINCTRL_PIN(103, "GP21_I2C_2_SCL"), + PINCTRL_PIN(104, "GP22_I2C_2_SDA"), + PINCTRL_PIN(105, "GP17_I2C_3_SCL_HDMI"), + PINCTRL_PIN(106, "GP18_I2C_3_SDA_HDMI"), + PINCTRL_PIN(107, "GP23_I2C_4_SCL"), + PINCTRL_PIN(108, "GP24_I2C_4_SDA"), + PINCTRL_PIN(109, "GP25_I2C_5_SCL"), + PINCTRL_PIN(110, "GP26_I2C_5_SDA"), + PINCTRL_PIN(111, "GP27_I2C_6_SCL"), + PINCTRL_PIN(112, "GP28_I2C_6_SDA"), + PINCTRL_PIN(113, "GP29_I2C_7_SCL"), + PINCTRL_PIN(114, "GP30_I2C_7_SDA"), + /* Family 8: UART (12 pins) */ + PINCTRL_PIN(115, "GP124_UART_0_CTS"), + PINCTRL_PIN(116, "GP125_UART_0_RTS"), + PINCTRL_PIN(117, "GP126_UART_0_RX"), + PINCTRL_PIN(118, "GP127_UART_0_TX"), + PINCTRL_PIN(119, "GP128_UART_1_CTS"), + PINCTRL_PIN(120, "GP129_UART_1_RTS"), + PINCTRL_PIN(121, "GP130_UART_1_RX"), + PINCTRL_PIN(122, "GP131_UART_1_TX"), + PINCTRL_PIN(123, "GP132_UART_2_CTS"), + PINCTRL_PIN(124, "GP133_UART_2_RTS"), + PINCTRL_PIN(125, "GP134_UART_2_RX"), + PINCTRL_PIN(126, "GP135_UART_2_TX"), + /* Family 9: GPIO South (19 pins) */ + PINCTRL_PIN(127, "GP177"), + PINCTRL_PIN(128, "GP178"), + PINCTRL_PIN(129, "GP179"), + PINCTRL_PIN(130, "GP180"), + PINCTRL_PIN(131, "GP181"), + PINCTRL_PIN(132, "GP182_PWM2"), + PINCTRL_PIN(133, "GP183_PWM3"), + PINCTRL_PIN(134, "GP184"), + PINCTRL_PIN(135, "GP185"), + PINCTRL_PIN(136, "GP186"), + PINCTRL_PIN(137, "GP187"), + PINCTRL_PIN(138, "GP188"), + PINCTRL_PIN(139, "GP189"), + PINCTRL_PIN(140, "GP64_FAST_INT0"), + PINCTRL_PIN(141, "GP65_FAST_INT1"), + PINCTRL_PIN(142, "GP66_FAST_INT2"), + PINCTRL_PIN(143, "GP67_FAST_INT3"), + PINCTRL_PIN(144, "GP12_PWM0"), + PINCTRL_PIN(145, "GP13_PWM1"), + /* Family 10: Camera Sideband (12 pins) */ + PINCTRL_PIN(146, "GP0"), + PINCTRL_PIN(147, "GP1"), + PINCTRL_PIN(148, "GP2"), + PINCTRL_PIN(149, "GP3"), + PINCTRL_PIN(150, "GP4"), + PINCTRL_PIN(151, "GP5"), + PINCTRL_PIN(152, "GP6"), + PINCTRL_PIN(153, "GP7"), + PINCTRL_PIN(154, "GP8"), + PINCTRL_PIN(155, "GP9"), + PINCTRL_PIN(156, "GP10"), + PINCTRL_PIN(157, "GP11"), + /* Family 11: Clock (22 pins) */ + PINCTRL_PIN(158, "GP137"), + PINCTRL_PIN(159, "GP138"), + PINCTRL_PIN(160, "GP139"), + PINCTRL_PIN(161, "GP140"), + PINCTRL_PIN(162, "GP141"), + PINCTRL_PIN(163, "GP142"), + PINCTRL_PIN(164, "GP16_HDMI_HPD"), + PINCTRL_PIN(165, "GP68_DSI_A_TE"), + PINCTRL_PIN(166, "GP69_DSI_C_TE"), + PINCTRL_PIN(167, "OSC_CLK_CTRL0"), + PINCTRL_PIN(168, "OSC_CLK_CTRL1"), + PINCTRL_PIN(169, "OSC_CLK0"), + PINCTRL_PIN(170, "OSC_CLK1"), + PINCTRL_PIN(171, "OSC_CLK2"), + PINCTRL_PIN(172, "OSC_CLK3"), + PINCTRL_PIN(173, "OSC_CLK4"), + PINCTRL_PIN(174, "RESETOUT"), + PINCTRL_PIN(175, "PMODE"), + PINCTRL_PIN(176, "PRDY"), + PINCTRL_PIN(177, "PREQ"), + PINCTRL_PIN(178, "GP190"), + PINCTRL_PIN(179, "GP191"), + /* Family 12: MSIC (15 pins) */ + PINCTRL_PIN(180, "I2C_0_SCL"), + PINCTRL_PIN(181, "I2C_0_SDA"), + PINCTRL_PIN(182, "IERR"), + PINCTRL_PIN(183, "JTAG_TCK"), + PINCTRL_PIN(184, "JTAG_TDI"), + PINCTRL_PIN(185, "JTAG_TDO"), + PINCTRL_PIN(186, "JTAG_TMS"), + PINCTRL_PIN(187, "JTAG_TRST"), + PINCTRL_PIN(188, "PROCHOT"), + PINCTRL_PIN(189, "RTC_CLK"), + PINCTRL_PIN(190, "SVID_ALERT"), + PINCTRL_PIN(191, "SVID_CLK"), + PINCTRL_PIN(192, "SVID_D"), + PINCTRL_PIN(193, "THERMTRIP"), + PINCTRL_PIN(194, "STANDBY"), + /* Family 13: Keyboard (20 pins) */ + PINCTRL_PIN(195, "GP44"), + PINCTRL_PIN(196, "GP45"), + PINCTRL_PIN(197, "GP46"), + PINCTRL_PIN(198, "GP47"), + PINCTRL_PIN(199, "GP48"), + PINCTRL_PIN(200, "GP49"), + PINCTRL_PIN(201, "GP50"), + PINCTRL_PIN(202, "GP51"), + PINCTRL_PIN(203, "GP52"), + PINCTRL_PIN(204, "GP53"), + PINCTRL_PIN(205, "GP54"), + PINCTRL_PIN(206, "GP55"), + PINCTRL_PIN(207, "GP56"), + PINCTRL_PIN(208, "GP57"), + PINCTRL_PIN(209, "GP58"), + PINCTRL_PIN(210, "GP59"), + PINCTRL_PIN(211, "GP60"), + PINCTRL_PIN(212, "GP61"), + PINCTRL_PIN(213, "GP62"), + PINCTRL_PIN(214, "GP63"), + /* Family 14: GPIO North (13 pins) */ + PINCTRL_PIN(215, "GP164"), + PINCTRL_PIN(216, "GP165"), + PINCTRL_PIN(217, "GP166"), + PINCTRL_PIN(218, "GP167"), + PINCTRL_PIN(219, "GP168_MJTAG_TCK"), + PINCTRL_PIN(220, "GP169_MJTAG_TDI"), + PINCTRL_PIN(221, "GP170_MJTAG_TDO"), + PINCTRL_PIN(222, "GP171_MJTAG_TMS"), + PINCTRL_PIN(223, "GP172_MJTAG_TRST"), + PINCTRL_PIN(224, "GP173"), + PINCTRL_PIN(225, "GP174"), + PINCTRL_PIN(226, "GP175"), + PINCTRL_PIN(227, "GP176"), + /* Family 15: PTI (5 pins) */ + PINCTRL_PIN(228, "GP72_PTI_CLK"), + PINCTRL_PIN(229, "GP73_PTI_D0"), + PINCTRL_PIN(230, "GP74_PTI_D1"), + PINCTRL_PIN(231, "GP75_PTI_D2"), + PINCTRL_PIN(232, "GP76_PTI_D3"), + /* Family 16: USB3 (0 pins) */ + /* Family 17: HSIC (0 pins) */ + /* Family 18: Broadcast (0 pins) */ +}; + +static const unsigned int mrfld_sdio_pins[] = { 50, 51, 52, 53, 54, 55, 56 }; +static const unsigned int mrfld_spi5_pins[] = { 90, 91, 92, 93, 94, 95, 96 }; +static const unsigned int mrfld_uart0_pins[] = { 124, 125, 126, 127 }; +static const unsigned int mrfld_uart1_pins[] = { 128, 129, 130, 131 }; +static const unsigned int mrfld_uart2_pins[] = { 132, 133, 134, 135 }; +static const unsigned int mrfld_pwm0_pins[] = { 144 }; +static const unsigned int mrfld_pwm1_pins[] = { 145 }; +static const unsigned int mrfld_pwm2_pins[] = { 132 }; +static const unsigned int mrfld_pwm3_pins[] = { 133 }; + +static const struct intel_pingroup mrfld_groups[] = { + PIN_GROUP("sdio_grp", mrfld_sdio_pins, 1), + PIN_GROUP("spi5_grp", mrfld_spi5_pins, 1), + PIN_GROUP("uart0_grp", mrfld_uart0_pins, 1), + PIN_GROUP("uart1_grp", mrfld_uart1_pins, 1), + PIN_GROUP("uart2_grp", mrfld_uart2_pins, 1), + PIN_GROUP("pwm0_grp", mrfld_pwm0_pins, 1), + PIN_GROUP("pwm1_grp", mrfld_pwm1_pins, 1), + PIN_GROUP("pwm2_grp", mrfld_pwm2_pins, 1), + PIN_GROUP("pwm3_grp", mrfld_pwm3_pins, 1), +}; + +static const char * const mrfld_sdio_groups[] = { "sdio_grp" }; +static const char * const mrfld_spi5_groups[] = { "spi5_grp" }; +static const char * const mrfld_uart0_groups[] = { "uart0_grp" }; +static const char * const mrfld_uart1_groups[] = { "uart1_grp" }; +static const char * const mrfld_uart2_groups[] = { "uart2_grp" }; +static const char * const mrfld_pwm0_groups[] = { "pwm0_grp" }; +static const char * const mrfld_pwm1_groups[] = { "pwm1_grp" }; +static const char * const mrfld_pwm2_groups[] = { "pwm2_grp" }; +static const char * const mrfld_pwm3_groups[] = { "pwm3_grp" }; + +static const struct intel_function mrfld_functions[] = { + FUNCTION("sdio", mrfld_sdio_groups), + FUNCTION("spi5", mrfld_spi5_groups), + FUNCTION("uart0", mrfld_uart0_groups), + FUNCTION("uart1", mrfld_uart1_groups), + FUNCTION("uart2", mrfld_uart2_groups), + FUNCTION("pwm0", mrfld_pwm0_groups), + FUNCTION("pwm1", mrfld_pwm1_groups), + FUNCTION("pwm2", mrfld_pwm2_groups), + FUNCTION("pwm3", mrfld_pwm3_groups), +}; + +static const struct mrfld_family mrfld_families[] = { + MRFLD_FAMILY(1, 0, 12), + MRFLD_FAMILY(2, 13, 36), + MRFLD_FAMILY(3, 37, 56), + MRFLD_FAMILY(4, 57, 64), + MRFLD_FAMILY(5, 65, 78), + MRFLD_FAMILY(6, 79, 100), + MRFLD_FAMILY_PROTECTED(7, 101, 114), + MRFLD_FAMILY(8, 115, 126), + MRFLD_FAMILY(9, 127, 145), + MRFLD_FAMILY(10, 146, 157), + MRFLD_FAMILY(11, 158, 179), + MRFLD_FAMILY_PROTECTED(12, 180, 194), + MRFLD_FAMILY(13, 195, 214), + MRFLD_FAMILY(14, 215, 227), + MRFLD_FAMILY(15, 228, 232), +}; + +/** + * struct mrfld_pinctrl - Intel Merrifield pinctrl private structure + * @dev: Pointer to the device structure + * @lock: Lock to serialize register access + * @pctldesc: Pin controller description + * @pctldev: Pointer to the pin controller device + * @families: Array of families this pinctrl handles + * @nfamilies: Number of families in the array + * @functions: Array of functions + * @nfunctions: Number of functions in the array + * @groups: Array of pin groups + * @ngroups: Number of groups in the array + * @pins: Array of pins this pinctrl controls + * @npins: Number of pins in the array + */ +struct mrfld_pinctrl { + struct device *dev; + raw_spinlock_t lock; + struct pinctrl_desc pctldesc; + struct pinctrl_dev *pctldev; + + /* Pin controller configuration */ + const struct mrfld_family *families; + size_t nfamilies; + const struct intel_function *functions; + size_t nfunctions; + const struct intel_pingroup *groups; + size_t ngroups; + const struct pinctrl_pin_desc *pins; + size_t npins; +}; + +#define pin_to_bufno(f, p) ((p) - (f)->pin_base) + +static const struct mrfld_family *mrfld_get_family(struct mrfld_pinctrl *mp, + unsigned int pin) +{ + const struct mrfld_family *family; + unsigned int i; + + for (i = 0; i < mp->nfamilies; i++) { + family = &mp->families[i]; + if (pin >= family->pin_base && + pin < family->pin_base + family->npins) + return family; + } + + dev_warn(mp->dev, "failed to find family for pin %u\n", pin); + return NULL; +} + +static bool mrfld_buf_available(struct mrfld_pinctrl *mp, unsigned int pin) +{ + const struct mrfld_family *family; + + family = mrfld_get_family(mp, pin); + if (!family) + return false; + + return !family->protected; +} + +static void __iomem *mrfld_get_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin) +{ + const struct mrfld_family *family; + unsigned int bufno; + + family = mrfld_get_family(mp, pin); + if (!family) + return NULL; + + bufno = pin_to_bufno(family, pin); + return family->regs + BUFCFG_OFFSET + bufno * 4; +} + +static int mrfld_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + return mp->ngroups; +} + +static const char *mrfld_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + return mp->groups[group].name; +} + +static int mrfld_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group, + const unsigned int **pins, unsigned int *npins) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + *pins = mp->groups[group].pins; + *npins = mp->groups[group].npins; + return 0; +} + +static void mrfld_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned int pin) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + void __iomem *bufcfg; + u32 value, mode; + + if (!mrfld_buf_available(mp, pin)) { + seq_puts(s, "not available"); + return; + } + + bufcfg = mrfld_get_bufcfg(mp, pin); + value = readl(bufcfg); + + mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT; + if (!mode) + seq_puts(s, "GPIO "); + else + seq_printf(s, "mode %d ", mode); + + seq_printf(s, "0x%08x", value); +} + +static const struct pinctrl_ops mrfld_pinctrl_ops = { + .get_groups_count = mrfld_get_groups_count, + .get_group_name = mrfld_get_group_name, + .get_group_pins = mrfld_get_group_pins, + .pin_dbg_show = mrfld_pin_dbg_show, +}; + +static int mrfld_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + return mp->nfunctions; +} + +static const char *mrfld_get_function_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + return mp->functions[function].name; +} + +static int mrfld_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char * const **groups, + unsigned int * const ngroups) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + + *groups = mp->functions[function].groups; + *ngroups = mp->functions[function].ngroups; + return 0; +} + +static void mrfld_update_bufcfg(struct mrfld_pinctrl *mp, unsigned int pin, + u32 bits, u32 mask) +{ + void __iomem *bufcfg; + u32 value; + + bufcfg = mrfld_get_bufcfg(mp, pin); + value = readl(bufcfg); + + value &= ~mask; + value |= bits & mask; + + writel(value, bufcfg); +} + +static int mrfld_pinmux_set_mux(struct pinctrl_dev *pctldev, + unsigned int function, + unsigned int group) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + const struct intel_pingroup *grp = &mp->groups[group]; + u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT; + u32 mask = BUFCFG_PINMODE_MASK; + unsigned long flags; + unsigned int i; + + /* + * All pins in the groups needs to be accessible and writable + * before we can enable the mux for this group. + */ + for (i = 0; i < grp->npins; i++) { + if (!mrfld_buf_available(mp, grp->pins[i])) + return -EBUSY; + } + + /* Now enable the mux setting for each pin in the group */ + raw_spin_lock_irqsave(&mp->lock, flags); + for (i = 0; i < grp->npins; i++) + mrfld_update_bufcfg(mp, grp->pins[i], bits, mask); + raw_spin_unlock_irqrestore(&mp->lock, flags); + + return 0; +} + +static int mrfld_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int pin) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT; + u32 mask = BUFCFG_PINMODE_MASK; + unsigned long flags; + + if (!mrfld_buf_available(mp, pin)) + return -EBUSY; + + raw_spin_lock_irqsave(&mp->lock, flags); + mrfld_update_bufcfg(mp, pin, bits, mask); + raw_spin_unlock_irqrestore(&mp->lock, flags); + + return 0; +} + +static const struct pinmux_ops mrfld_pinmux_ops = { + .get_functions_count = mrfld_get_functions_count, + .get_function_name = mrfld_get_function_name, + .get_function_groups = mrfld_get_function_groups, + .set_mux = mrfld_pinmux_set_mux, + .gpio_request_enable = mrfld_gpio_request_enable, +}; + +static int mrfld_config_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + enum pin_config_param param = pinconf_to_config_param(*config); + u32 value, term; + u16 arg = 0; + + if (!mrfld_buf_available(mp, pin)) + return -ENOTSUPP; + + value = readl(mrfld_get_bufcfg(mp, pin)); + term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + if (value & BUFCFG_Px_EN_MASK) + return -EINVAL; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN) + return -EINVAL; + + switch (term) { + case BUFCFG_PUPD_VAL_910: + arg = 910; + break; + case BUFCFG_PUPD_VAL_2K: + arg = 2000; + break; + case BUFCFG_PUPD_VAL_20K: + arg = 20000; + break; + case BUFCFG_PUPD_VAL_50K: + arg = 50000; + break; + } + + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN) + return -EINVAL; + + switch (term) { + case BUFCFG_PUPD_VAL_910: + arg = 910; + break; + case BUFCFG_PUPD_VAL_2K: + arg = 2000; + break; + case BUFCFG_PUPD_VAL_20K: + arg = 20000; + break; + case BUFCFG_PUPD_VAL_50K: + arg = 50000; + break; + } + + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (!(value & BUFCFG_OD_EN)) + return -EINVAL; + break; + + case PIN_CONFIG_SLEW_RATE: + if (!(value & BUFCFG_SLEWSEL)) + arg = 0; + else + arg = 1; + break; + + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + return 0; +} + +static int mrfld_config_set_pin(struct mrfld_pinctrl *mp, unsigned int pin, + unsigned long config) +{ + unsigned int param = pinconf_to_config_param(config); + unsigned int arg = pinconf_to_config_argument(config); + u32 bits = 0, mask = 0; + unsigned long flags; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; + bits |= BUFCFG_PU_EN; + + switch (arg) { + case 50000: + bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT; + break; + case 20000: + bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT; + break; + case 2000: + bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT; + break; + default: + return -EINVAL; + } + + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + mask |= BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK; + bits |= BUFCFG_PD_EN; + + switch (arg) { + case 50000: + bits |= BUFCFG_PUPD_VAL_50K << BUFCFG_PUPD_VAL_SHIFT; + break; + case 20000: + bits |= BUFCFG_PUPD_VAL_20K << BUFCFG_PUPD_VAL_SHIFT; + break; + case 2000: + bits |= BUFCFG_PUPD_VAL_2K << BUFCFG_PUPD_VAL_SHIFT; + break; + default: + return -EINVAL; + } + + break; + + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + mask |= BUFCFG_OD_EN; + if (arg) + bits |= BUFCFG_OD_EN; + break; + + case PIN_CONFIG_SLEW_RATE: + mask |= BUFCFG_SLEWSEL; + if (arg) + bits |= BUFCFG_SLEWSEL; + break; + } + + raw_spin_lock_irqsave(&mp->lock, flags); + mrfld_update_bufcfg(mp, pin, bits, mask); + raw_spin_unlock_irqrestore(&mp->lock, flags); + + return 0; +} + +static int mrfld_config_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int nconfigs) +{ + struct mrfld_pinctrl *mp = pinctrl_dev_get_drvdata(pctldev); + unsigned int i; + int ret; + + for (i = 0; i < nconfigs; i++) { + switch (pinconf_to_config_param(configs[i])) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + case PIN_CONFIG_SLEW_RATE: + ret = mrfld_config_set_pin(mp, pin, configs[i]); + if (ret) + return ret; + break; + + default: + return -ENOTSUPP; + } + } + + return 0; +} + +static const struct pinconf_ops mrfld_pinconf_ops = { + .is_generic = true, + .pin_config_get = mrfld_config_get, + .pin_config_set = mrfld_config_set, +}; + +static const struct pinctrl_desc mrfld_pinctrl_desc = { + .pctlops = &mrfld_pinctrl_ops, + .pmxops = &mrfld_pinmux_ops, + .confops = &mrfld_pinconf_ops, + .owner = THIS_MODULE, +}; + +static int mrfld_pinctrl_probe(struct platform_device *pdev) +{ + struct mrfld_family *families; + struct mrfld_pinctrl *mp; + struct resource *mem; + void __iomem *regs; + size_t nfamilies; + unsigned int i; + + mp = devm_kzalloc(&pdev->dev, sizeof(*mp), GFP_KERNEL); + if (!mp) + return -ENOMEM; + + mp->dev = &pdev->dev; + raw_spin_lock_init(&mp->lock); + + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + regs = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + /* + * Make a copy of the families which we can use to hold pointers + * to the registers. + */ + nfamilies = ARRAY_SIZE(mrfld_families), + families = devm_kmemdup(&pdev->dev, mrfld_families, + nfamilies * sizeof(mrfld_families), + GFP_KERNEL); + if (!families) + return -ENOMEM; + + /* Splice memory resource by chunk per family */ + for (i = 0; i < nfamilies; i++) { + struct mrfld_family *family = &families[i]; + + family->regs = regs + family->barno * MRFLD_FAMILY_LEN; + } + + mp->families = families; + mp->nfamilies = nfamilies; + mp->functions = mrfld_functions; + mp->nfunctions = ARRAY_SIZE(mrfld_functions); + mp->groups = mrfld_groups; + mp->ngroups = ARRAY_SIZE(mrfld_groups); + mp->pctldesc = mrfld_pinctrl_desc; + mp->pctldesc.name = dev_name(&pdev->dev); + mp->pctldesc.pins = mrfld_pins; + mp->pctldesc.npins = ARRAY_SIZE(mrfld_pins); + + mp->pctldev = devm_pinctrl_register(&pdev->dev, &mp->pctldesc, mp); + if (IS_ERR(mp->pctldev)) { + dev_err(&pdev->dev, "failed to register pinctrl driver\n"); + return PTR_ERR(mp->pctldev); + } + + platform_set_drvdata(pdev, mp); + return 0; +} + +static struct platform_driver mrfld_pinctrl_driver = { + .probe = mrfld_pinctrl_probe, + .driver = { + .name = "pinctrl-merrifield", + }, +}; + +static int __init mrfld_pinctrl_init(void) +{ + return platform_driver_register(&mrfld_pinctrl_driver); +} +subsys_initcall(mrfld_pinctrl_init); + +static void __exit mrfld_pinctrl_exit(void) +{ + platform_driver_unregister(&mrfld_pinctrl_driver); +} +module_exit(mrfld_pinctrl_exit); + +MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>"); +MODULE_DESCRIPTION("Intel Merrifield SoC pinctrl driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:pinctrl-merrifield"); diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index a607655d7830..ce554e0d6979 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -1183,8 +1183,8 @@ static int mtk_eint_resume(struct device *device) } const struct dev_pm_ops mtk_eint_pm_ops = { - .suspend = mtk_eint_suspend, - .resume = mtk_eint_resume, + .suspend_noirq = mtk_eint_suspend, + .resume_noirq = mtk_eint_resume, }; static void mtk_eint_ack(struct irq_data *d) diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c index eeabafbbf598..cb4d6ad30530 100644 --- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c +++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c @@ -147,6 +147,52 @@ static const struct pinctrl_pin_desc meson_gxbb_periphs_pins[] = { MESON_PIN(GPIO_TEST_N, EE_OFF), }; +static const unsigned int emmc_nand_d07_pins[] = { + PIN(BOOT_0, EE_OFF), PIN(BOOT_1, EE_OFF), PIN(BOOT_2, EE_OFF), + PIN(BOOT_3, EE_OFF), PIN(BOOT_4, EE_OFF), PIN(BOOT_5, EE_OFF), + PIN(BOOT_6, EE_OFF), PIN(BOOT_7, EE_OFF), +}; +static const unsigned int emmc_clk_pins[] = { PIN(BOOT_8, EE_OFF) }; +static const unsigned int emmc_cmd_pins[] = { PIN(BOOT_10, EE_OFF) }; +static const unsigned int emmc_ds_pins[] = { PIN(BOOT_15, EE_OFF) }; + +static const unsigned int sdcard_d0_pins[] = { PIN(CARD_1, EE_OFF) }; +static const unsigned int sdcard_d1_pins[] = { PIN(CARD_0, EE_OFF) }; +static const unsigned int sdcard_d2_pins[] = { PIN(CARD_5, EE_OFF) }; +static const unsigned int sdcard_d3_pins[] = { PIN(CARD_4, EE_OFF) }; +static const unsigned int sdcard_cmd_pins[] = { PIN(CARD_3, EE_OFF) }; +static const unsigned int sdcard_clk_pins[] = { PIN(CARD_2, EE_OFF) }; + +static const unsigned int uart_tx_a_pins[] = { PIN(GPIOX_12, EE_OFF) }; +static const unsigned int uart_rx_a_pins[] = { PIN(GPIOX_13, EE_OFF) }; +static const unsigned int uart_cts_a_pins[] = { PIN(GPIOX_14, EE_OFF) }; +static const unsigned int uart_rts_a_pins[] = { PIN(GPIOX_15, EE_OFF) }; + +static const unsigned int uart_tx_b_pins[] = { PIN(GPIODV_24, EE_OFF) }; +static const unsigned int uart_rx_b_pins[] = { PIN(GPIODV_25, EE_OFF) }; +static const unsigned int uart_cts_b_pins[] = { PIN(GPIODV_26, EE_OFF) }; +static const unsigned int uart_rts_b_pins[] = { PIN(GPIODV_27, EE_OFF) }; + +static const unsigned int uart_tx_c_pins[] = { PIN(GPIOY_13, EE_OFF) }; +static const unsigned int uart_rx_c_pins[] = { PIN(GPIOY_14, EE_OFF) }; +static const unsigned int uart_cts_c_pins[] = { PIN(GPIOX_11, EE_OFF) }; +static const unsigned int uart_rts_c_pins[] = { PIN(GPIOX_12, EE_OFF) }; + +static const unsigned int eth_mdio_pins[] = { PIN(GPIOZ_0, EE_OFF) }; +static const unsigned int eth_mdc_pins[] = { PIN(GPIOZ_1, EE_OFF) }; +static const unsigned int eth_clk_rx_clk_pins[] = { PIN(GPIOZ_2, EE_OFF) }; +static const unsigned int eth_rx_dv_pins[] = { PIN(GPIOZ_3, EE_OFF) }; +static const unsigned int eth_rxd0_pins[] = { PIN(GPIOZ_4, EE_OFF) }; +static const unsigned int eth_rxd1_pins[] = { PIN(GPIOZ_5, EE_OFF) }; +static const unsigned int eth_rxd2_pins[] = { PIN(GPIOZ_6, EE_OFF) }; +static const unsigned int eth_rxd3_pins[] = { PIN(GPIOZ_7, EE_OFF) }; +static const unsigned int eth_rgmii_tx_clk_pins[] = { PIN(GPIOZ_8, EE_OFF) }; +static const unsigned int eth_tx_en_pins[] = { PIN(GPIOZ_9, EE_OFF) }; +static const unsigned int eth_txd0_pins[] = { PIN(GPIOZ_10, EE_OFF) }; +static const unsigned int eth_txd1_pins[] = { PIN(GPIOZ_11, EE_OFF) }; +static const unsigned int eth_txd2_pins[] = { PIN(GPIOZ_12, EE_OFF) }; +static const unsigned int eth_txd3_pins[] = { PIN(GPIOZ_13, EE_OFF) }; + static const struct pinctrl_pin_desc meson_gxbb_aobus_pins[] = { MESON_PIN(GPIOAO_0, 0), MESON_PIN(GPIOAO_1, 0), @@ -168,6 +214,16 @@ static const unsigned int uart_tx_ao_a_pins[] = { PIN(GPIOAO_0, 0) }; static const unsigned int uart_rx_ao_a_pins[] = { PIN(GPIOAO_1, 0) }; static const unsigned int uart_cts_ao_a_pins[] = { PIN(GPIOAO_2, 0) }; static const unsigned int uart_rts_ao_a_pins[] = { PIN(GPIOAO_3, 0) }; +static const unsigned int uart_tx_ao_b_pins[] = { PIN(GPIOAO_0, 0) }; +static const unsigned int uart_rx_ao_b_pins[] = { PIN(GPIOAO_1, 0), + PIN(GPIOAO_5, 0) }; +static const unsigned int uart_cts_ao_b_pins[] = { PIN(GPIOAO_2, 0) }; +static const unsigned int uart_rts_ao_b_pins[] = { PIN(GPIOAO_3, 0) }; + +static const unsigned int i2c_sck_ao_pins[] = {PIN(GPIOAO_4, 0) }; +static const unsigned int i2c_sda_ao_pins[] = {PIN(GPIOAO_5, 0) }; +static const unsigned int i2c_slave_sck_ao_pins[] = {PIN(GPIOAO_4, 0) }; +static const unsigned int i2c_slave_sda_ao_pins[] = {PIN(GPIOAO_5, 0) }; static struct meson_pmx_group meson_gxbb_periphs_groups[] = { GPIO_GROUP(GPIOZ_0, EE_OFF), @@ -297,6 +353,54 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = { GPIO_GROUP(GPIOCLK_3, EE_OFF), GPIO_GROUP(GPIO_TEST_N, EE_OFF), + + /* Bank X */ + GROUP(uart_tx_a, 4, 13), + GROUP(uart_rx_a, 4, 12), + GROUP(uart_cts_a, 4, 11), + GROUP(uart_rts_a, 4, 10), + + /* Bank Y */ + GROUP(uart_cts_c, 1, 19), + GROUP(uart_rts_c, 1, 18), + GROUP(uart_tx_c, 1, 17), + GROUP(uart_rx_c, 1, 16), + + /* Bank Z */ + GROUP(eth_mdio, 6, 1), + GROUP(eth_mdc, 6, 0), + GROUP(eth_clk_rx_clk, 6, 13), + GROUP(eth_rx_dv, 6, 12), + GROUP(eth_rxd0, 6, 11), + GROUP(eth_rxd1, 6, 10), + GROUP(eth_rxd2, 6, 9), + GROUP(eth_rxd3, 6, 8), + GROUP(eth_rgmii_tx_clk, 6, 7), + GROUP(eth_tx_en, 6, 6), + GROUP(eth_txd0, 6, 5), + GROUP(eth_txd1, 6, 4), + GROUP(eth_txd2, 6, 3), + GROUP(eth_txd3, 6, 2), + + /* Bank DV */ + GROUP(uart_tx_b, 2, 29), + GROUP(uart_rx_b, 2, 28), + GROUP(uart_cts_b, 2, 27), + GROUP(uart_rts_b, 2, 26), + + /* Bank BOOT */ + GROUP(emmc_nand_d07, 4, 30), + GROUP(emmc_clk, 4, 18), + GROUP(emmc_cmd, 4, 19), + GROUP(emmc_ds, 4, 31), + + /* Bank CARD */ + GROUP(sdcard_d1, 2, 14), + GROUP(sdcard_d0, 2, 15), + GROUP(sdcard_d3, 2, 12), + GROUP(sdcard_d2, 2, 13), + GROUP(sdcard_cmd, 2, 10), + GROUP(sdcard_clk, 2, 11), }; static struct meson_pmx_group meson_gxbb_aobus_groups[] = { @@ -316,10 +420,18 @@ static struct meson_pmx_group meson_gxbb_aobus_groups[] = { GPIO_GROUP(GPIOAO_13, 0), /* bank AO */ + GROUP(uart_tx_ao_b, 0, 26), + GROUP(uart_rx_ao_b, 0, 25), GROUP(uart_tx_ao_a, 0, 12), GROUP(uart_rx_ao_a, 0, 11), GROUP(uart_cts_ao_a, 0, 10), GROUP(uart_rts_ao_a, 0, 9), + GROUP(uart_cts_ao_b, 0, 8), + GROUP(uart_rts_ao_b, 0, 7), + GROUP(i2c_sck_ao, 0, 6), + GROUP(i2c_sda_ao, 0, 5), + GROUP(i2c_slave_sck_ao, 0, 2), + GROUP(i2c_slave_sda_ao, 0, 1), }; static const char * const gpio_periphs_groups[] = { @@ -359,6 +471,34 @@ static const char * const gpio_periphs_groups[] = { "GPIO_TEST_N", }; +static const char * const emmc_groups[] = { + "emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds", +}; + +static const char * const sdcard_groups[] = { + "sdcard_d0", "sdcard_d1", "sdcard_d2", "sdcard_d3", + "sdcard_cmd", "sdcard_clk", +}; + +static const char * const uart_a_groups[] = { + "uart_tx_a", "uart_rx_a", "uart_cts_a", "uart_rts_a", +}; + +static const char * const uart_b_groups[] = { + "uart_tx_b", "uart_rx_b", "uart_cts_b", "uart_rts_b", +}; + +static const char * const uart_c_groups[] = { + "uart_tx_c", "uart_rx_c", "uart_cts_c", "uart_rts_c", +}; + +static const char * const eth_groups[] = { + "eth_mdio", "eth_mdc", "eth_clk_rx_clk", "eth_rx_dv", + "eth_rxd0", "eth_rxd1", "eth_rxd2", "eth_rxd3", + "eth_rgmii_tx_clk", "eth_tx_en", + "eth_txd0", "eth_txd1", "eth_txd2", "eth_txd3", +}; + static const char * const gpio_aobus_groups[] = { "GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4", "GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9", @@ -366,16 +506,37 @@ static const char * const gpio_aobus_groups[] = { }; static const char * const uart_ao_groups[] = { - "uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a" + "uart_tx_ao_a", "uart_rx_ao_a", "uart_cts_ao_a", "uart_rts_ao_a", +}; + +static const char * const uart_ao_b_groups[] = { + "uart_tx_ao_b", "uart_rx_ao_b", "uart_cts_ao_b", "uart_rts_ao_b", +}; + +static const char * const i2c_ao_groups[] = { + "i2c_sdk_ao", "i2c_sda_ao", +}; + +static const char * const i2c_slave_ao_groups[] = { + "i2c_slave_sdk_ao", "i2c_slave_sda_ao", }; static struct meson_pmx_func meson_gxbb_periphs_functions[] = { FUNCTION(gpio_periphs), + FUNCTION(emmc), + FUNCTION(sdcard), + FUNCTION(uart_a), + FUNCTION(uart_b), + FUNCTION(uart_c), + FUNCTION(eth), }; static struct meson_pmx_func meson_gxbb_aobus_functions[] = { FUNCTION(gpio_aobus), FUNCTION(uart_ao), + FUNCTION(uart_ao_b), + FUNCTION(i2c_ao), + FUNCTION(i2c_slave_ao), }; static struct meson_bank meson_gxbb_periphs_banks[] = { diff --git a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c index a78e9a4997ba..5f89c26f3292 100644 --- a/drivers/pinctrl/mvebu/pinctrl-kirkwood.c +++ b/drivers/pinctrl/mvebu/pinctrl-kirkwood.c @@ -168,87 +168,87 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = { MPP_VAR_FUNCTION(0x0, "gpo", NULL, V(1, 1, 1, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "nand", "io1", V(1, 1, 1, 1, 1, 1))), MPP_MODE(20, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "txd0", V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d0", V(0, 0, 0, 0, 1, 0)), - MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 0, 0, 0, 0, 0))), + MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 0, 0, 0, 0, 0))), MPP_MODE(21, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "rx0ql", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "txd1", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d1", V(0, 0, 0, 0, 1, 0))), MPP_MODE(22, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "txd2", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x5, "sata1", "prsnt", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d2", V(0, 0, 0, 0, 1, 0))), MPP_MODE(23, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "txd3", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x5, "sata0", "prsnt", V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d3", V(0, 0, 0, 0, 1, 0))), MPP_MODE(24, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "rxd0", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d4", V(0, 0, 0, 0, 1, 0))), MPP_MODE(25, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "rxd1", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d5", V(0, 0, 0, 0, 1, 0))), MPP_MODE(26, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "rxd2", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d6", V(0, 0, 0, 0, 1, 0))), MPP_MODE(27, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "rxd3", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d7", V(0, 0, 0, 0, 1, 0))), MPP_MODE(28, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "col", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d8", V(0, 0, 0, 0, 1, 0))), MPP_MODE(29, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 0)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x1, "ts", "mp9", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "txclk", V(0, 1, 1, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 0, 0, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 0, 0, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d9", V(0, 0, 0, 0, 1, 0))), MPP_MODE(30, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 0)), @@ -280,65 +280,65 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = { MPP_VAR_FUNCTION(0x5, "sata1", "act", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d14", V(0, 0, 0, 0, 1, 0))), MPP_MODE(35, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 1, 1, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 1, 1, 1, 1, 1)), MPP_VAR_FUNCTION(0x2, "tdm", "tx0ql", V(0, 0, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x3, "ge1", "rxerr", V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0x5, "sata0", "act", V(0, 1, 1, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d15", V(0, 0, 0, 0, 1, 0)), - MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(0, 1, 1, 1, 1, 0))), + MPP_VAR_FUNCTION(0xc, "mii", "rxerr", V(1, 1, 1, 1, 1, 0))), MPP_MODE(36, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp0", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs1", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifi", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "twsi1", "sda", V(0, 0, 0, 0, 1, 0))), MPP_MODE(37, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp1", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "tx2ql", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "spdifo", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "twsi1", "sck", V(0, 0, 0, 0, 1, 0))), MPP_MODE(38, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp2", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "rx2ql", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "rmclk", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d18", V(0, 0, 0, 0, 1, 0))), MPP_MODE(39, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp3", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-cs0", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "bclk", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d19", V(0, 0, 0, 0, 1, 0))), MPP_MODE(40, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp4", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-sck", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "sdo", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d20", V(0, 0, 0, 0, 1, 0))), MPP_MODE(41, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp5", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-miso", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "lrclk", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d21", V(0, 0, 0, 0, 1, 0))), MPP_MODE(42, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp6", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "spi-mosi", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "mclk", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d22", V(0, 0, 0, 0, 1, 0))), MPP_MODE(43, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp7", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "int", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "sdi", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "d23", V(0, 0, 0, 0, 1, 0))), MPP_MODE(44, - MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), + MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(1, 0, 0, 1, 1, 1)), MPP_VAR_FUNCTION(0x1, "ts", "mp8", V(0, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0x2, "tdm", "rst", V(0, 0, 0, 1, 1, 0)), - MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(0, 0, 0, 1, 1, 0)), + MPP_VAR_FUNCTION(0x4, "audio", "extclk", V(1, 0, 0, 1, 1, 0)), MPP_VAR_FUNCTION(0xb, "lcd", "clk", V(0, 0, 0, 0, 1, 0))), MPP_MODE(45, MPP_VAR_FUNCTION(0x0, "gpio", NULL, V(0, 0, 0, 1, 1, 1)), @@ -371,11 +371,12 @@ static struct mvebu_mpp_mode mv88f6xxx_mpp_modes[] = { }; static struct mvebu_mpp_ctrl mv88f6180_mpp_controls[] = { - MPP_FUNC_CTRL(0, 29, NULL, kirkwood_mpp_ctrl), + MPP_FUNC_CTRL(0, 44, NULL, kirkwood_mpp_ctrl), }; static struct pinctrl_gpio_range mv88f6180_gpio_ranges[] = { - MPP_GPIO_RANGE(0, 0, 0, 30), + MPP_GPIO_RANGE(0, 0, 0, 20), + MPP_GPIO_RANGE(1, 35, 35, 10), }; static struct mvebu_mpp_ctrl mv88f619x_mpp_controls[] = { diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index 38faceff2f08..35f62180db4e 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -1033,102 +1033,6 @@ static inline void nmk_gpio_dbg_show_one(struct seq_file *s, #define nmk_gpio_dbg_show NULL #endif -void nmk_gpio_clocks_enable(void) -{ - int i; - - for (i = 0; i < NUM_BANKS; i++) { - struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; - - if (!chip) - continue; - - clk_enable(chip->clk); - } -} - -void nmk_gpio_clocks_disable(void) -{ - int i; - - for (i = 0; i < NUM_BANKS; i++) { - struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; - - if (!chip) - continue; - - clk_disable(chip->clk); - } -} - -/* - * Called from the suspend/resume path to only keep the real wakeup interrupts - * (those that have had set_irq_wake() called on them) as wakeup interrupts, - * and not the rest of the interrupts which we needed to have as wakeups for - * cpuidle. - * - * PM ops are not used since this needs to be done at the end, after all the - * other drivers are done with their suspend callbacks. - */ -void nmk_gpio_wakeups_suspend(void) -{ - int i; - - for (i = 0; i < NUM_BANKS; i++) { - struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; - - if (!chip) - break; - - clk_enable(chip->clk); - - writel(chip->rwimsc & chip->real_wake, - chip->addr + NMK_GPIO_RWIMSC); - writel(chip->fwimsc & chip->real_wake, - chip->addr + NMK_GPIO_FWIMSC); - - clk_disable(chip->clk); - } -} - -void nmk_gpio_wakeups_resume(void) -{ - int i; - - for (i = 0; i < NUM_BANKS; i++) { - struct nmk_gpio_chip *chip = nmk_gpio_chips[i]; - - if (!chip) - break; - - clk_enable(chip->clk); - - writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC); - writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC); - - clk_disable(chip->clk); - } -} - -/* - * Read the pull up/pull down status. - * A bit set in 'pull_up' means that pull up - * is selected if pull is enabled in PDIS register. - * Note: only pull up/down set via this driver can - * be detected due to HW limitations. - */ -void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up) -{ - if (gpio_bank < NUM_BANKS) { - struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank]; - - if (!chip) - return; - - *pull_up = chip->pull_up; - } -} - /* * We will allocate memory for the state container using devm* allocators * binding to the first device reaching this point, it doesn't matter if diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index d5bf9fae2ddd..5020ae534479 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -53,7 +53,7 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev, struct seq_file *s, const char *gname, unsigned pin, const struct pin_config_item *items, - int nitems) + int nitems, int *print_sep) { int i; @@ -75,8 +75,10 @@ static void pinconf_generic_dump_one(struct pinctrl_dev *pctldev, seq_printf(s, "ERROR READING CONFIG SETTING %d ", i); continue; } - /* Space between multiple configs */ - seq_puts(s, " "); + /* comma between multiple configs */ + if (*print_sep) + seq_puts(s, ", "); + *print_sep = 1; seq_puts(s, items[i].display); /* Print unit if available */ if (items[i].has_arg) { @@ -105,19 +107,21 @@ void pinconf_generic_dump_pins(struct pinctrl_dev *pctldev, struct seq_file *s, const char *gname, unsigned pin) { const struct pinconf_ops *ops = pctldev->desc->confops; + int print_sep = 0; if (!ops->is_generic) return; /* generic parameters */ pinconf_generic_dump_one(pctldev, s, gname, pin, conf_items, - ARRAY_SIZE(conf_items)); + ARRAY_SIZE(conf_items), &print_sep); /* driver-specific parameters */ if (pctldev->desc->num_custom_params && pctldev->desc->custom_conf_items) pinconf_generic_dump_one(pctldev, s, gname, pin, pctldev->desc->custom_conf_items, - pctldev->desc->num_custom_params); + pctldev->desc->num_custom_params, + &print_sep); } void pinconf_generic_dump_config(struct pinctrl_dev *pctldev, @@ -391,4 +395,12 @@ exit: } EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map); +void pinconf_generic_dt_free_map(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, + unsigned num_maps) +{ + pinctrl_utils_free_map(pctldev, map, num_maps); +} +EXPORT_SYMBOL_GPL(pinconf_generic_dt_free_map); + #endif diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 4dd7722f9935..799048f3c8d4 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -258,8 +258,7 @@ void pinconf_show_setting(struct seq_file *s, case PIN_MAP_TYPE_CONFIGS_PIN: desc = pin_desc_get(setting->pctldev, setting->data.configs.group_or_pin); - seq_printf(s, "pin %s (%d)", - desc->name ? desc->name : "unnamed", + seq_printf(s, "pin %s (%d)", desc->name, setting->data.configs.group_or_pin); break; case PIN_MAP_TYPE_CONFIGS_GROUP: @@ -311,8 +310,7 @@ static int pinconf_pins_show(struct seq_file *s, void *what) if (desc == NULL) continue; - seq_printf(s, "pin %d (%s):", pin, - desc->name ? desc->name : "unnamed"); + seq_printf(s, "pin %d (%s): ", pin, desc->name); pinconf_dump_pin(pctldev, s, pin); @@ -349,7 +347,7 @@ static int pinconf_groups_show(struct seq_file *s, void *what) while (selector < ngroups) { const char *gname = pctlops->get_group_name(pctldev, selector); - seq_printf(s, "%u (%s):", selector, gname); + seq_printf(s, "%u (%s): ", selector, gname); pinconf_dump_group(pctldev, s, selector, gname); seq_printf(s, "\n"); diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index a025b40d246b..28bbc1bb9e6c 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -20,7 +20,7 @@ #include <linux/gpio.h> #include <linux/interrupt.h> #include <linux/io.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pinctrl/pinconf.h> @@ -421,8 +421,8 @@ static int atmel_pctl_get_group_pins(struct pinctrl_dev *pctldev, return 0; } -struct atmel_group *atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, - unsigned pin) +static struct atmel_group * +atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, unsigned pin) { struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); int i; @@ -879,7 +879,6 @@ static const struct of_device_id atmel_pctrl_of_match[] = { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, atmel_pctrl_of_match); static int atmel_pinctrl_probe(struct platform_device *pdev) { @@ -1074,28 +1073,13 @@ clk_prepare_enable_error: return ret; } -int atmel_pinctrl_remove(struct platform_device *pdev) -{ - struct atmel_pioctrl *atmel_pioctrl = platform_get_drvdata(pdev); - - irq_domain_remove(atmel_pioctrl->irq_domain); - clk_disable_unprepare(atmel_pioctrl->clk); - gpiochip_remove(atmel_pioctrl->gpio_chip); - - return 0; -} - static struct platform_driver atmel_pinctrl_driver = { .driver = { .name = "pinctrl-at91-pio4", .of_match_table = atmel_pctrl_of_match, .pm = &atmel_pctrl_pm_ops, + .suppress_bind_attrs = true, }, .probe = atmel_pinctrl_probe, - .remove = atmel_pinctrl_remove, }; -module_platform_driver(atmel_pinctrl_driver); - -MODULE_AUTHOR(Ludovic Desroches <ludovic.desroches@atmel.com>); -MODULE_DESCRIPTION("Atmel PIO4 pinctrl driver"); -MODULE_LICENSE("GPL v2"); +builtin_platform_driver(atmel_pinctrl_driver); diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index b7c0d6f7c046..80daead3a5a1 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -9,7 +9,6 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/init.h> -#include <linux/module.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/of_address.h> @@ -189,7 +188,7 @@ struct at91_pinctrl { struct at91_pinctrl_mux_ops *ops; }; -static const inline struct at91_pin_group *at91_pinctrl_find_group_by_name( +static inline const struct at91_pin_group *at91_pinctrl_find_group_by_name( const struct at91_pinctrl *info, const char *name) { @@ -1818,13 +1817,3 @@ static int __init at91_pinctrl_init(void) return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); } arch_initcall(at91_pinctrl_init); - -static void __exit at91_pinctrl_exit(void) -{ - platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); -} - -module_exit(at91_pinctrl_exit); -MODULE_AUTHOR("Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>"); -MODULE_DESCRIPTION("Atmel AT91 pinctrl driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-digicolor.c b/drivers/pinctrl/pinctrl-digicolor.c index 30ee56427f56..639a57ecc7c2 100644 --- a/drivers/pinctrl/pinctrl-digicolor.c +++ b/drivers/pinctrl/pinctrl-digicolor.c @@ -15,7 +15,7 @@ * - Pin pad configuration (pull up/down, strength) */ -#include <linux/module.h> +#include <linux/init.h> #include <linux/platform_device.h> #include <linux/of.h> #include <linux/of_device.h> @@ -335,27 +335,17 @@ static int dc_pinctrl_probe(struct platform_device *pdev) return dc_gpiochip_add(pmap, pdev->dev.of_node); } -static int dc_pinctrl_remove(struct platform_device *pdev) -{ - struct dc_pinmap *pmap = platform_get_drvdata(pdev); - - gpiochip_remove(&pmap->chip); - - return 0; -} - static const struct of_device_id dc_pinctrl_ids[] = { { .compatible = "cnxt,cx92755-pinctrl" }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, dc_pinctrl_ids); static struct platform_driver dc_pinctrl_driver = { .driver = { .name = DRIVER_NAME, .of_match_table = dc_pinctrl_ids, + .suppress_bind_attrs = true, }, .probe = dc_pinctrl_probe, - .remove = dc_pinctrl_remove, }; -module_platform_driver(dc_pinctrl_driver); +builtin_platform_driver(dc_pinctrl_driver); diff --git a/drivers/pinctrl/pinctrl-lpc18xx.c b/drivers/pinctrl/pinctrl-lpc18xx.c index 8a931c7ba2ff..e053f1fa5512 100644 --- a/drivers/pinctrl/pinctrl-lpc18xx.c +++ b/drivers/pinctrl/pinctrl-lpc18xx.c @@ -11,7 +11,7 @@ #include <linux/bitops.h> #include <linux/clk.h> #include <linux/io.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of.h> #include <linux/of_device.h> #include <linux/pinctrl/pinctrl.h> @@ -1365,31 +1365,17 @@ static int lpc18xx_scu_probe(struct platform_device *pdev) return 0; } -static int lpc18xx_scu_remove(struct platform_device *pdev) -{ - struct lpc18xx_scu_data *scu = platform_get_drvdata(pdev); - - clk_disable_unprepare(scu->clk); - - return 0; -} - static const struct of_device_id lpc18xx_scu_match[] = { { .compatible = "nxp,lpc1850-scu" }, {}, }; -MODULE_DEVICE_TABLE(of, lpc18xx_scu_match); static struct platform_driver lpc18xx_scu_driver = { .probe = lpc18xx_scu_probe, - .remove = lpc18xx_scu_remove, .driver = { .name = "lpc18xx-scu", .of_match_table = lpc18xx_scu_match, + .suppress_bind_attrs = true, }, }; -module_platform_driver(lpc18xx_scu_driver); - -MODULE_AUTHOR("Joachim Eastwood <manabian@gmail.com>"); -MODULE_DESCRIPTION("Pinctrl driver for NXP LPC18xx/43xx SCU"); -MODULE_LICENSE("GPL v2"); +builtin_platform_driver(lpc18xx_scu_driver); diff --git a/drivers/pinctrl/pinctrl-max77620.c b/drivers/pinctrl/pinctrl-max77620.c new file mode 100644 index 000000000000..d9ff53e8f715 --- /dev/null +++ b/drivers/pinctrl/pinctrl-max77620.c @@ -0,0 +1,673 @@ +/* + * MAX77620 pin control driver. + * + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. + * + * Author: + * Chaitanya Bandi <bandik@nvidia.com> + * Laxman Dewangan <ldewangan@nvidia.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + */ + +#include <linux/mfd/max77620.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include "core.h" +#include "pinconf.h" +#include "pinctrl-utils.h" + +#define MAX77620_PIN_NUM 8 + +enum max77620_pin_ppdrv { + MAX77620_PIN_UNCONFIG_DRV, + MAX77620_PIN_OD_DRV, + MAX77620_PIN_PP_DRV, +}; + +enum max77620_pinconf_param { + MAX77620_ACTIVE_FPS_SOURCE = PIN_CONFIG_END + 1, + MAX77620_ACTIVE_FPS_POWER_ON_SLOTS, + MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS, + MAX77620_SUSPEND_FPS_SOURCE, + MAX77620_SUSPEND_FPS_POWER_ON_SLOTS, + MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS, +}; + +struct max77620_pin_function { + const char *name; + const char * const *groups; + unsigned int ngroups; + int mux_option; +}; + +static const struct pinconf_generic_params max77620_cfg_params[] = { + { + .property = "maxim,active-fps-source", + .param = MAX77620_ACTIVE_FPS_SOURCE, + }, { + .property = "maxim,active-fps-power-up-slot", + .param = MAX77620_ACTIVE_FPS_POWER_ON_SLOTS, + }, { + .property = "maxim,active-fps-power-down-slot", + .param = MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS, + }, { + .property = "maxim,suspend-fps-source", + .param = MAX77620_SUSPEND_FPS_SOURCE, + }, { + .property = "maxim,suspend-fps-power-up-slot", + .param = MAX77620_SUSPEND_FPS_POWER_ON_SLOTS, + }, { + .property = "maxim,suspend-fps-power-down-slot", + .param = MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS, + }, +}; + +enum max77620_alternate_pinmux_option { + MAX77620_PINMUX_GPIO = 0, + MAX77620_PINMUX_LOW_POWER_MODE_CONTROL_IN = 1, + MAX77620_PINMUX_FLEXIBLE_POWER_SEQUENCER_OUT = 2, + MAX77620_PINMUX_32K_OUT1 = 3, + MAX77620_PINMUX_SD0_DYNAMIC_VOLTAGE_SCALING_IN = 4, + MAX77620_PINMUX_SD1_DYNAMIC_VOLTAGE_SCALING_IN = 5, + MAX77620_PINMUX_REFERENCE_OUT = 6, +}; + +struct max77620_pingroup { + const char *name; + const unsigned int pins[1]; + unsigned int npins; + enum max77620_alternate_pinmux_option alt_option; +}; + +struct max77620_pin_info { + enum max77620_pin_ppdrv drv_type; + int pull_config; +}; + +struct max77620_fps_config { + int active_fps_src; + int active_power_up_slots; + int active_power_down_slots; + int suspend_fps_src; + int suspend_power_up_slots; + int suspend_power_down_slots; +}; + +struct max77620_pctrl_info { + struct device *dev; + struct pinctrl_dev *pctl; + struct regmap *rmap; + int pins_current_opt[MAX77620_GPIO_NR]; + const struct max77620_pin_function *functions; + unsigned int num_functions; + const struct max77620_pingroup *pin_groups; + int num_pin_groups; + const struct pinctrl_pin_desc *pins; + unsigned int num_pins; + struct max77620_pin_info pin_info[MAX77620_PIN_NUM]; + struct max77620_fps_config fps_config[MAX77620_PIN_NUM]; +}; + +static const struct pinctrl_pin_desc max77620_pins_desc[] = { + PINCTRL_PIN(MAX77620_GPIO0, "gpio0"), + PINCTRL_PIN(MAX77620_GPIO1, "gpio1"), + PINCTRL_PIN(MAX77620_GPIO2, "gpio2"), + PINCTRL_PIN(MAX77620_GPIO3, "gpio3"), + PINCTRL_PIN(MAX77620_GPIO4, "gpio4"), + PINCTRL_PIN(MAX77620_GPIO5, "gpio5"), + PINCTRL_PIN(MAX77620_GPIO6, "gpio6"), + PINCTRL_PIN(MAX77620_GPIO7, "gpio7"), +}; + +static const char * const gpio_groups[] = { + "gpio0", + "gpio1", + "gpio2", + "gpio3", + "gpio4", + "gpio5", + "gpio6", + "gpio7", +}; + +#define FUNCTION_GROUP(fname, mux) \ + { \ + .name = fname, \ + .groups = gpio_groups, \ + .ngroups = ARRAY_SIZE(gpio_groups), \ + .mux_option = MAX77620_PINMUX_##mux, \ + } + +static const struct max77620_pin_function max77620_pin_function[] = { + FUNCTION_GROUP("gpio", GPIO), + FUNCTION_GROUP("lpm-control-in", LOW_POWER_MODE_CONTROL_IN), + FUNCTION_GROUP("fps-out", FLEXIBLE_POWER_SEQUENCER_OUT), + FUNCTION_GROUP("32k-out1", 32K_OUT1), + FUNCTION_GROUP("sd0-dvs-in", SD0_DYNAMIC_VOLTAGE_SCALING_IN), + FUNCTION_GROUP("sd1-dvs-in", SD1_DYNAMIC_VOLTAGE_SCALING_IN), + FUNCTION_GROUP("reference-out", REFERENCE_OUT), +}; + +#define MAX77620_PINGROUP(pg_name, pin_id, option) \ + { \ + .name = #pg_name, \ + .pins = {MAX77620_##pin_id}, \ + .npins = 1, \ + .alt_option = MAX77620_PINMUX_##option, \ + } + +static const struct max77620_pingroup max77620_pingroups[] = { + MAX77620_PINGROUP(gpio0, GPIO0, LOW_POWER_MODE_CONTROL_IN), + MAX77620_PINGROUP(gpio1, GPIO1, FLEXIBLE_POWER_SEQUENCER_OUT), + MAX77620_PINGROUP(gpio2, GPIO2, FLEXIBLE_POWER_SEQUENCER_OUT), + MAX77620_PINGROUP(gpio3, GPIO3, FLEXIBLE_POWER_SEQUENCER_OUT), + MAX77620_PINGROUP(gpio4, GPIO4, 32K_OUT1), + MAX77620_PINGROUP(gpio5, GPIO5, SD0_DYNAMIC_VOLTAGE_SCALING_IN), + MAX77620_PINGROUP(gpio6, GPIO6, SD1_DYNAMIC_VOLTAGE_SCALING_IN), + MAX77620_PINGROUP(gpio7, GPIO7, REFERENCE_OUT), +}; + +static int max77620_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + + return mpci->num_pin_groups; +} + +static const char *max77620_pinctrl_get_group_name( + struct pinctrl_dev *pctldev, unsigned int group) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + + return mpci->pin_groups[group].name; +} + +static int max77620_pinctrl_get_group_pins( + struct pinctrl_dev *pctldev, unsigned int group, + const unsigned int **pins, unsigned int *num_pins) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + + *pins = mpci->pin_groups[group].pins; + *num_pins = mpci->pin_groups[group].npins; + + return 0; +} + +static const struct pinctrl_ops max77620_pinctrl_ops = { + .get_groups_count = max77620_pinctrl_get_groups_count, + .get_group_name = max77620_pinctrl_get_group_name, + .get_group_pins = max77620_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int max77620_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + + return mpci->num_functions; +} + +static const char *max77620_pinctrl_get_func_name(struct pinctrl_dev *pctldev, + unsigned int function) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + + return mpci->functions[function].name; +} + +static int max77620_pinctrl_get_func_groups(struct pinctrl_dev *pctldev, + unsigned int function, + const char * const **groups, + unsigned int * const num_groups) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + + *groups = mpci->functions[function].groups; + *num_groups = mpci->functions[function].ngroups; + + return 0; +} + +static int max77620_pinctrl_enable(struct pinctrl_dev *pctldev, + unsigned int function, unsigned int group) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + u8 val; + int ret; + + if (function == MAX77620_PINMUX_GPIO) { + val = 0; + } else if (function == mpci->pin_groups[group].alt_option) { + val = 1 << group; + } else { + dev_err(mpci->dev, "GPIO %u doesn't have function %u\n", + group, function); + return -EINVAL; + } + ret = regmap_update_bits(mpci->rmap, MAX77620_REG_AME_GPIO, + BIT(group), val); + if (ret < 0) + dev_err(mpci->dev, "REG AME GPIO update failed: %d\n", ret); + + return ret; +} + +static const struct pinmux_ops max77620_pinmux_ops = { + .get_functions_count = max77620_pinctrl_get_funcs_count, + .get_function_name = max77620_pinctrl_get_func_name, + .get_function_groups = max77620_pinctrl_get_func_groups, + .set_mux = max77620_pinctrl_enable, +}; + +static int max77620_pinconf_get(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *config) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + struct device *dev = mpci->dev; + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned int val; + int arg = 0; + int ret; + + switch (param) { + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + if (mpci->pin_info[pin].drv_type == MAX77620_PIN_OD_DRV) + arg = 1; + break; + + case PIN_CONFIG_DRIVE_PUSH_PULL: + if (mpci->pin_info[pin].drv_type == MAX77620_PIN_PP_DRV) + arg = 1; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + ret = regmap_read(mpci->rmap, MAX77620_REG_PUE_GPIO, &val); + if (ret < 0) { + dev_err(dev, "Reg PUE_GPIO read failed: %d\n", ret); + return ret; + } + if (val & BIT(pin)) + arg = 1; + break; + + case PIN_CONFIG_BIAS_PULL_DOWN: + ret = regmap_read(mpci->rmap, MAX77620_REG_PDE_GPIO, &val); + if (ret < 0) { + dev_err(dev, "Reg PDE_GPIO read failed: %d\n", ret); + return ret; + } + if (val & BIT(pin)) + arg = 1; + break; + + default: + dev_err(dev, "Properties not supported\n"); + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, (u16)arg); + + return 0; +} + +static int max77620_get_default_fps(struct max77620_pctrl_info *mpci, + int addr, int *fps) +{ + unsigned int val; + int ret; + + ret = regmap_read(mpci->rmap, addr, &val); + if (ret < 0) { + dev_err(mpci->dev, "Reg PUE_GPIO read failed: %d\n", ret); + return ret; + } + *fps = (val & MAX77620_FPS_SRC_MASK) >> MAX77620_FPS_SRC_SHIFT; + + return 0; +} + +static int max77620_set_fps_param(struct max77620_pctrl_info *mpci, + int pin, int param) +{ + struct max77620_fps_config *fps_config = &mpci->fps_config[pin]; + int addr, ret; + int param_val; + int mask, shift; + + if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3)) + return 0; + + addr = MAX77620_REG_FPS_GPIO1 + pin - 1; + switch (param) { + case MAX77620_ACTIVE_FPS_SOURCE: + case MAX77620_SUSPEND_FPS_SOURCE: + mask = MAX77620_FPS_SRC_MASK; + shift = MAX77620_FPS_SRC_SHIFT; + param_val = fps_config->active_fps_src; + if (param == MAX77620_SUSPEND_FPS_SOURCE) + param_val = fps_config->suspend_fps_src; + break; + + case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS: + case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS: + mask = MAX77620_FPS_PU_PERIOD_MASK; + shift = MAX77620_FPS_PU_PERIOD_SHIFT; + param_val = fps_config->active_power_up_slots; + if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS) + param_val = fps_config->suspend_power_up_slots; + break; + + case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS: + case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS: + mask = MAX77620_FPS_PD_PERIOD_MASK; + shift = MAX77620_FPS_PD_PERIOD_SHIFT; + param_val = fps_config->active_power_down_slots; + if (param == MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS) + param_val = fps_config->suspend_power_down_slots; + break; + + default: + dev_err(mpci->dev, "Invalid parameter %d for pin %d\n", + param, pin); + return -EINVAL; + } + + if (param_val < 0) + return 0; + + ret = regmap_update_bits(mpci->rmap, addr, mask, param_val << shift); + if (ret < 0) + dev_err(mpci->dev, "Reg 0x%02x update failed %d\n", addr, ret); + + return ret; +} + +static int max77620_pinconf_set(struct pinctrl_dev *pctldev, + unsigned int pin, unsigned long *configs, + unsigned int num_configs) +{ + struct max77620_pctrl_info *mpci = pinctrl_dev_get_drvdata(pctldev); + struct device *dev = mpci->dev; + struct max77620_fps_config *fps_config; + int param; + u16 param_val; + unsigned int val; + unsigned int pu_val; + unsigned int pd_val; + int addr, ret; + int i; + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + param_val = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + val = param_val ? 0 : 1; + ret = regmap_update_bits(mpci->rmap, + MAX77620_REG_GPIO0 + pin, + MAX77620_CNFG_GPIO_DRV_MASK, + val); + if (ret < 0) { + dev_err(dev, "Reg 0x%02x update failed %d\n", + MAX77620_REG_GPIO0 + pin, ret); + return ret; + } + mpci->pin_info[pin].drv_type = val ? + MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV; + break; + + case PIN_CONFIG_DRIVE_PUSH_PULL: + val = param_val ? 1 : 0; + ret = regmap_update_bits(mpci->rmap, + MAX77620_REG_GPIO0 + pin, + MAX77620_CNFG_GPIO_DRV_MASK, + val); + if (ret < 0) { + dev_err(dev, "Reg 0x%02x update failed %d\n", + MAX77620_REG_GPIO0 + pin, ret); + return ret; + } + mpci->pin_info[pin].drv_type = val ? + MAX77620_PIN_PP_DRV : MAX77620_PIN_OD_DRV; + break; + + case MAX77620_ACTIVE_FPS_SOURCE: + case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS: + case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS: + if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3)) + return -EINVAL; + + fps_config = &mpci->fps_config[pin]; + + if ((param == MAX77620_ACTIVE_FPS_SOURCE) && + (param_val == MAX77620_FPS_SRC_DEF)) { + addr = MAX77620_REG_FPS_GPIO1 + pin - 1; + ret = max77620_get_default_fps( + mpci, addr, + &fps_config->active_fps_src); + if (ret < 0) + return ret; + break; + } + + if (param == MAX77620_ACTIVE_FPS_SOURCE) + fps_config->active_fps_src = param_val; + else if (param == MAX77620_ACTIVE_FPS_POWER_ON_SLOTS) + fps_config->active_power_up_slots = param_val; + else + fps_config->active_power_down_slots = param_val; + + ret = max77620_set_fps_param(mpci, pin, param); + if (ret < 0) + return ret; + break; + + case MAX77620_SUSPEND_FPS_SOURCE: + case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS: + case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS: + if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3)) + return -EINVAL; + + fps_config = &mpci->fps_config[pin]; + + if ((param == MAX77620_SUSPEND_FPS_SOURCE) && + (param_val == MAX77620_FPS_SRC_DEF)) { + addr = MAX77620_REG_FPS_GPIO1 + pin - 1; + ret = max77620_get_default_fps( + mpci, addr, + &fps_config->suspend_fps_src); + if (ret < 0) + return ret; + break; + } + + if (param == MAX77620_SUSPEND_FPS_SOURCE) + fps_config->suspend_fps_src = param_val; + else if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS) + fps_config->suspend_power_up_slots = param_val; + else + fps_config->suspend_power_down_slots = + param_val; + break; + + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + pu_val = (param == PIN_CONFIG_BIAS_PULL_UP) ? + BIT(pin) : 0; + pd_val = (param == PIN_CONFIG_BIAS_PULL_DOWN) ? + BIT(pin) : 0; + + ret = regmap_update_bits(mpci->rmap, + MAX77620_REG_PUE_GPIO, + BIT(pin), pu_val); + if (ret < 0) { + dev_err(dev, "PUE_GPIO update failed: %d\n", + ret); + return ret; + } + + ret = regmap_update_bits(mpci->rmap, + MAX77620_REG_PDE_GPIO, + BIT(pin), pd_val); + if (ret < 0) { + dev_err(dev, "PDE_GPIO update failed: %d\n", + ret); + return ret; + } + break; + + default: + dev_err(dev, "Properties not supported\n"); + return -ENOTSUPP; + } + } + + return 0; +} + +static const struct pinconf_ops max77620_pinconf_ops = { + .pin_config_get = max77620_pinconf_get, + .pin_config_set = max77620_pinconf_set, +}; + +static struct pinctrl_desc max77620_pinctrl_desc = { + .pctlops = &max77620_pinctrl_ops, + .pmxops = &max77620_pinmux_ops, + .confops = &max77620_pinconf_ops, +}; + +static int max77620_pinctrl_probe(struct platform_device *pdev) +{ + struct max77620_chip *max77620 = dev_get_drvdata(pdev->dev.parent); + struct max77620_pctrl_info *mpci; + int i; + + mpci = devm_kzalloc(&pdev->dev, sizeof(*mpci), GFP_KERNEL); + if (!mpci) + return -ENOMEM; + + mpci->dev = &pdev->dev; + mpci->dev->of_node = pdev->dev.parent->of_node; + mpci->rmap = max77620->rmap; + + mpci->pins = max77620_pins_desc; + mpci->num_pins = ARRAY_SIZE(max77620_pins_desc); + mpci->functions = max77620_pin_function; + mpci->num_functions = ARRAY_SIZE(max77620_pin_function); + mpci->pin_groups = max77620_pingroups; + mpci->num_pin_groups = ARRAY_SIZE(max77620_pingroups); + platform_set_drvdata(pdev, mpci); + + max77620_pinctrl_desc.name = dev_name(&pdev->dev); + max77620_pinctrl_desc.pins = max77620_pins_desc; + max77620_pinctrl_desc.npins = ARRAY_SIZE(max77620_pins_desc); + max77620_pinctrl_desc.num_custom_params = + ARRAY_SIZE(max77620_cfg_params); + max77620_pinctrl_desc.custom_params = max77620_cfg_params; + + for (i = 0; i < MAX77620_PIN_NUM; ++i) { + mpci->fps_config[i].active_fps_src = -1; + mpci->fps_config[i].active_power_up_slots = -1; + mpci->fps_config[i].active_power_down_slots = -1; + mpci->fps_config[i].suspend_fps_src = -1; + mpci->fps_config[i].suspend_power_up_slots = -1; + mpci->fps_config[i].suspend_power_down_slots = -1; + } + + mpci->pctl = devm_pinctrl_register(&pdev->dev, &max77620_pinctrl_desc, + mpci); + if (IS_ERR(mpci->pctl)) { + dev_err(&pdev->dev, "Couldn't register pinctrl driver\n"); + return PTR_ERR(mpci->pctl); + } + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int max77620_suspend_fps_param[] = { + MAX77620_SUSPEND_FPS_SOURCE, + MAX77620_SUSPEND_FPS_POWER_ON_SLOTS, + MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS, +}; + +static int max77620_active_fps_param[] = { + MAX77620_ACTIVE_FPS_SOURCE, + MAX77620_ACTIVE_FPS_POWER_ON_SLOTS, + MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS, +}; + +static int max77620_pinctrl_suspend(struct device *dev) +{ + struct max77620_pctrl_info *mpci = dev_get_drvdata(dev); + int pin, p; + + for (pin = 0; pin < MAX77620_PIN_NUM; ++pin) { + if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3)) + continue; + for (p = 0; p < 3; ++p) + max77620_set_fps_param( + mpci, pin, max77620_suspend_fps_param[p]); + } + + return 0; +}; + +static int max77620_pinctrl_resume(struct device *dev) +{ + struct max77620_pctrl_info *mpci = dev_get_drvdata(dev); + int pin, p; + + for (pin = 0; pin < MAX77620_PIN_NUM; ++pin) { + if ((pin < MAX77620_GPIO1) || (pin > MAX77620_GPIO3)) + continue; + for (p = 0; p < 3; ++p) + max77620_set_fps_param( + mpci, pin, max77620_active_fps_param[p]); + } + + return 0; +} +#endif + +static const struct dev_pm_ops max77620_pinctrl_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS( + max77620_pinctrl_suspend, max77620_pinctrl_resume) +}; + +static const struct platform_device_id max77620_pinctrl_devtype[] = { + { .name = "max77620-pinctrl", }, + { .name = "max20024-pinctrl", }, + {}, +}; +MODULE_DEVICE_TABLE(platform, max77620_pinctrl_devtype); + +static struct platform_driver max77620_pinctrl_driver = { + .driver = { + .name = "max77620-pinctrl", + .pm = &max77620_pinctrl_pm_ops, + }, + .probe = max77620_pinctrl_probe, + .id_table = max77620_pinctrl_devtype, +}; + +module_platform_driver(max77620_pinctrl_driver); + +MODULE_DESCRIPTION("MAX77620/MAX20024 pin control driver"); +MODULE_AUTHOR("Chaitanya Bandi<bandik@nvidia.com>"); +MODULE_AUTHOR("Laxman Dewangan<ldewangan@nvidia.com>"); +MODULE_ALIAS("platform:max77620-pinctrl"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-oxnas.c b/drivers/pinctrl/pinctrl-oxnas.c new file mode 100644 index 000000000000..917a7d2535d7 --- /dev/null +++ b/drivers/pinctrl/pinctrl-oxnas.c @@ -0,0 +1,846 @@ +/* + * Oxford Semiconductor OXNAS SoC Family pinctrl driver + * + * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> + * + * Based on pinctrl-pic32.c + * Joshua Henderson, <joshua.henderson@microchip.com> + * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. + * + * This program is free software; you can distribute it and/or modify it + * under the terms of the GNU General Public License (Version 2) as + * published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include <linux/gpio/driver.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/regmap.h> +#include <linux/mfd/syscon.h> + +#include "pinctrl-utils.h" + +#define PINS_PER_BANK 32 + +#define GPIO_BANK_START(bank) ((bank) * PINS_PER_BANK) + +/* Regmap Offsets */ +#define PINMUX_PRIMARY_SEL0 0x0c +#define PINMUX_SECONDARY_SEL0 0x14 +#define PINMUX_TERTIARY_SEL0 0x8c +#define PINMUX_PRIMARY_SEL1 0x10 +#define PINMUX_SECONDARY_SEL1 0x18 +#define PINMUX_TERTIARY_SEL1 0x90 +#define PINMUX_PULLUP_CTRL0 0xac +#define PINMUX_PULLUP_CTRL1 0xb0 + +/* GPIO Registers */ +#define INPUT_VALUE 0x00 +#define OUTPUT_EN 0x04 +#define IRQ_PENDING 0x0c +#define OUTPUT_SET 0x14 +#define OUTPUT_CLEAR 0x18 +#define OUTPUT_EN_SET 0x1c +#define OUTPUT_EN_CLEAR 0x20 +#define RE_IRQ_ENABLE 0x28 +#define FE_IRQ_ENABLE 0x2c + +struct oxnas_function { + const char *name; + const char * const *groups; + unsigned int ngroups; +}; + +struct oxnas_pin_group { + const char *name; + unsigned int pin; + unsigned int bank; + struct oxnas_desc_function *functions; +}; + +struct oxnas_desc_function { + const char *name; + unsigned int fct; +}; + +struct oxnas_gpio_bank { + void __iomem *reg_base; + struct gpio_chip gpio_chip; + struct irq_chip irq_chip; + unsigned int id; +}; + +struct oxnas_pinctrl { + struct regmap *regmap; + struct device *dev; + struct pinctrl_dev *pctldev; + const struct pinctrl_pin_desc *pins; + unsigned int npins; + const struct oxnas_function *functions; + unsigned int nfunctions; + const struct oxnas_pin_group *groups; + unsigned int ngroups; + struct oxnas_gpio_bank *gpio_banks; + unsigned int nbanks; +}; + +static const struct pinctrl_pin_desc oxnas_pins[] = { + PINCTRL_PIN(0, "gpio0"), + PINCTRL_PIN(1, "gpio1"), + PINCTRL_PIN(2, "gpio2"), + PINCTRL_PIN(3, "gpio3"), + PINCTRL_PIN(4, "gpio4"), + PINCTRL_PIN(5, "gpio5"), + PINCTRL_PIN(6, "gpio6"), + PINCTRL_PIN(7, "gpio7"), + PINCTRL_PIN(8, "gpio8"), + PINCTRL_PIN(9, "gpio9"), + PINCTRL_PIN(10, "gpio10"), + PINCTRL_PIN(11, "gpio11"), + PINCTRL_PIN(12, "gpio12"), + PINCTRL_PIN(13, "gpio13"), + PINCTRL_PIN(14, "gpio14"), + PINCTRL_PIN(15, "gpio15"), + PINCTRL_PIN(16, "gpio16"), + PINCTRL_PIN(17, "gpio17"), + PINCTRL_PIN(18, "gpio18"), + PINCTRL_PIN(19, "gpio19"), + PINCTRL_PIN(20, "gpio20"), + PINCTRL_PIN(21, "gpio21"), + PINCTRL_PIN(22, "gpio22"), + PINCTRL_PIN(23, "gpio23"), + PINCTRL_PIN(24, "gpio24"), + PINCTRL_PIN(25, "gpio25"), + PINCTRL_PIN(26, "gpio26"), + PINCTRL_PIN(27, "gpio27"), + PINCTRL_PIN(28, "gpio28"), + PINCTRL_PIN(29, "gpio29"), + PINCTRL_PIN(30, "gpio30"), + PINCTRL_PIN(31, "gpio31"), + PINCTRL_PIN(32, "gpio32"), + PINCTRL_PIN(33, "gpio33"), + PINCTRL_PIN(34, "gpio34"), +}; + +static const char * const oxnas_fct0_group[] = { + "gpio0", "gpio1", "gpio2", "gpio3", + "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", + "gpio12", "gpio13", "gpio14", "gpio15", + "gpio16", "gpio17", "gpio18", "gpio19", + "gpio20", "gpio21", "gpio22", "gpio23", + "gpio24", "gpio25", "gpio26", "gpio27", + "gpio28", "gpio29", "gpio30", "gpio31", + "gpio32", "gpio33", "gpio34" +}; + +static const char * const oxnas_fct3_group[] = { + "gpio0", "gpio1", "gpio2", "gpio3", + "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", + "gpio20", + "gpio22", "gpio23", "gpio24", "gpio25", + "gpio26", "gpio27", "gpio28", "gpio29", + "gpio30", "gpio31", "gpio32", "gpio33", + "gpio34" +}; + +#define FUNCTION(_name, _gr) \ + { \ + .name = #_name, \ + .groups = oxnas_##_gr##_group, \ + .ngroups = ARRAY_SIZE(oxnas_##_gr##_group), \ + } + +static const struct oxnas_function oxnas_functions[] = { + FUNCTION(gpio, fct0), + FUNCTION(fct3, fct3), +}; + +#define OXNAS_PINCTRL_GROUP(_pin, _name, ...) \ + { \ + .name = #_name, \ + .pin = _pin, \ + .bank = _pin / PINS_PER_BANK, \ + .functions = (struct oxnas_desc_function[]){ \ + __VA_ARGS__, { } }, \ + } + +#define OXNAS_PINCTRL_FUNCTION(_name, _fct) \ + { \ + .name = #_name, \ + .fct = _fct, \ + } + +static const struct oxnas_pin_group oxnas_groups[] = { + OXNAS_PINCTRL_GROUP(0, gpio0, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(1, gpio1, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(2, gpio2, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(3, gpio3, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(4, gpio4, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(5, gpio5, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(6, gpio6, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(7, gpio7, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(8, gpio8, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(9, gpio9, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(10, gpio10, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(11, gpio11, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(12, gpio12, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(13, gpio13, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(14, gpio14, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(15, gpio15, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(16, gpio16, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(17, gpio17, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(18, gpio18, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(19, gpio19, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(20, gpio20, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(21, gpio21, + OXNAS_PINCTRL_FUNCTION(gpio, 0)), + OXNAS_PINCTRL_GROUP(22, gpio22, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(23, gpio23, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(24, gpio24, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(25, gpio25, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(26, gpio26, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(27, gpio27, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(28, gpio28, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(29, gpio29, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(30, gpio30, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(31, gpio31, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(32, gpio32, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(33, gpio33, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), + OXNAS_PINCTRL_GROUP(34, gpio34, + OXNAS_PINCTRL_FUNCTION(gpio, 0), + OXNAS_PINCTRL_FUNCTION(fct3, 3)), +}; + +static inline struct oxnas_gpio_bank *pctl_to_bank(struct oxnas_pinctrl *pctl, + unsigned int pin) +{ + return &pctl->gpio_banks[pin / PINS_PER_BANK]; +} + +static int oxnas_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + return pctl->ngroups; +} + +static const char *oxnas_pinctrl_get_group_name(struct pinctrl_dev *pctldev, + unsigned int group) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + return pctl->groups[group].name; +} + +static int oxnas_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, + unsigned int group, + const unsigned int **pins, + unsigned int *num_pins) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + *pins = &pctl->groups[group].pin; + *num_pins = 1; + + return 0; +} + +static const struct pinctrl_ops oxnas_pinctrl_ops = { + .get_groups_count = oxnas_pinctrl_get_groups_count, + .get_group_name = oxnas_pinctrl_get_group_name, + .get_group_pins = oxnas_pinctrl_get_group_pins, + .dt_node_to_map = pinconf_generic_dt_node_to_map_pin, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int oxnas_pinmux_get_functions_count(struct pinctrl_dev *pctldev) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + return pctl->nfunctions; +} + +static const char * +oxnas_pinmux_get_function_name(struct pinctrl_dev *pctldev, unsigned int func) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + return pctl->functions[func].name; +} + +static int oxnas_pinmux_get_function_groups(struct pinctrl_dev *pctldev, + unsigned int func, + const char * const **groups, + unsigned int * const num_groups) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + *groups = pctl->functions[func].groups; + *num_groups = pctl->functions[func].ngroups; + + return 0; +} + +static int oxnas_pinmux_enable(struct pinctrl_dev *pctldev, + unsigned int func, unsigned int group) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + const struct oxnas_pin_group *pg = &pctl->groups[group]; + const struct oxnas_function *pf = &pctl->functions[func]; + const char *fname = pf->name; + struct oxnas_desc_function *functions = pg->functions; + u32 mask = BIT(pg->pin); + + while (functions->name) { + if (!strcmp(functions->name, fname)) { + dev_dbg(pctl->dev, + "setting function %s bank %d pin %d fct %d mask %x\n", + fname, pg->bank, pg->pin, + functions->fct, mask); + + regmap_write_bits(pctl->regmap, + (pg->bank ? + PINMUX_PRIMARY_SEL1 : + PINMUX_PRIMARY_SEL0), + mask, + (functions->fct == 1 ? + mask : 0)); + regmap_write_bits(pctl->regmap, + (pg->bank ? + PINMUX_SECONDARY_SEL1 : + PINMUX_SECONDARY_SEL0), + mask, + (functions->fct == 2 ? + mask : 0)); + regmap_write_bits(pctl->regmap, + (pg->bank ? + PINMUX_TERTIARY_SEL1 : + PINMUX_TERTIARY_SEL0), + mask, + (functions->fct == 3 ? + mask : 0)); + + return 0; + } + + functions++; + } + + dev_err(pctl->dev, "cannot mux pin %u to function %u\n", group, func); + + return -EINVAL; +} + +static int oxnas_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct oxnas_gpio_bank *bank = gpiochip_get_data(range->gc); + u32 mask = BIT(offset - bank->gpio_chip.base); + + dev_dbg(pctl->dev, "requesting gpio %d in bank %d (id %d) with mask 0x%x\n", + offset, bank->gpio_chip.base, bank->id, mask); + + regmap_write_bits(pctl->regmap, + (bank->id ? + PINMUX_PRIMARY_SEL1 : + PINMUX_PRIMARY_SEL0), + mask, 0); + regmap_write_bits(pctl->regmap, + (bank->id ? + PINMUX_SECONDARY_SEL1 : + PINMUX_SECONDARY_SEL0), + mask, 0); + regmap_write_bits(pctl->regmap, + (bank->id ? + PINMUX_TERTIARY_SEL1 : + PINMUX_TERTIARY_SEL0), + mask, 0); + + return 0; +} + +static int oxnas_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct oxnas_gpio_bank *bank = gpiochip_get_data(chip); + u32 mask = BIT(offset); + + return !(readl_relaxed(bank->reg_base + OUTPUT_EN) & mask); +} + +static int oxnas_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct oxnas_gpio_bank *bank = gpiochip_get_data(chip); + u32 mask = BIT(offset); + + writel_relaxed(mask, bank->reg_base + OUTPUT_EN_CLEAR); + + return 0; +} + +static int oxnas_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct oxnas_gpio_bank *bank = gpiochip_get_data(chip); + u32 mask = BIT(offset); + + return (readl_relaxed(bank->reg_base + INPUT_VALUE) & mask) != 0; +} + +static void oxnas_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + struct oxnas_gpio_bank *bank = gpiochip_get_data(chip); + u32 mask = BIT(offset); + + if (value) + writel_relaxed(mask, bank->reg_base + OUTPUT_SET); + else + writel_relaxed(mask, bank->reg_base + OUTPUT_CLEAR); +} + +static int oxnas_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int value) +{ + struct oxnas_gpio_bank *bank = gpiochip_get_data(chip); + u32 mask = BIT(offset); + + oxnas_gpio_set(chip, offset, value); + writel_relaxed(mask, bank->reg_base + OUTPUT_EN_SET); + + return 0; +} + +static int oxnas_gpio_set_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset, bool input) +{ + struct gpio_chip *chip = range->gc; + + if (input) + oxnas_gpio_direction_input(chip, offset); + else + oxnas_gpio_direction_output(chip, offset, 0); + + return 0; +} + +static const struct pinmux_ops oxnas_pinmux_ops = { + .get_functions_count = oxnas_pinmux_get_functions_count, + .get_function_name = oxnas_pinmux_get_function_name, + .get_function_groups = oxnas_pinmux_get_function_groups, + .set_mux = oxnas_pinmux_enable, + .gpio_request_enable = oxnas_gpio_request_enable, + .gpio_set_direction = oxnas_gpio_set_direction, +}; + +static int oxnas_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *config) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin); + unsigned int param = pinconf_to_config_param(*config); + u32 mask = BIT(pin - bank->gpio_chip.base); + int ret; + u32 arg; + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + ret = regmap_read(pctl->regmap, + (bank->id ? + PINMUX_PULLUP_CTRL1 : + PINMUX_PULLUP_CTRL0), + &arg); + if (ret) + return ret; + + arg = !!(arg & mask); + break; + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int oxnas_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct oxnas_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct oxnas_gpio_bank *bank = pctl_to_bank(pctl, pin); + unsigned int param; + u32 arg; + unsigned int i; + u32 offset = pin - bank->gpio_chip.base; + u32 mask = BIT(offset); + + dev_dbg(pctl->dev, "setting pin %d bank %d mask 0x%x\n", + pin, bank->gpio_chip.base, mask); + + for (i = 0; i < num_configs; i++) { + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_PULL_UP: + dev_dbg(pctl->dev, " pullup\n"); + regmap_write_bits(pctl->regmap, + (bank->id ? + PINMUX_PULLUP_CTRL1 : + PINMUX_PULLUP_CTRL0), + mask, mask); + break; + default: + dev_err(pctl->dev, "Property %u not supported\n", + param); + return -ENOTSUPP; + } + } + + return 0; +} + +static const struct pinconf_ops oxnas_pinconf_ops = { + .pin_config_get = oxnas_pinconf_get, + .pin_config_set = oxnas_pinconf_set, + .is_generic = true, +}; + +static struct pinctrl_desc oxnas_pinctrl_desc = { + .name = "oxnas-pinctrl", + .pctlops = &oxnas_pinctrl_ops, + .pmxops = &oxnas_pinmux_ops, + .confops = &oxnas_pinconf_ops, + .owner = THIS_MODULE, +}; + +static void oxnas_gpio_irq_ack(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct oxnas_gpio_bank *bank = gpiochip_get_data(chip); + u32 mask = BIT(data->hwirq); + + writel(mask, bank->reg_base + IRQ_PENDING); +} + +static void oxnas_gpio_irq_mask(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct oxnas_gpio_bank *bank = gpiochip_get_data(chip); + unsigned int type = irqd_get_trigger_type(data); + u32 mask = BIT(data->hwirq); + + if (type & IRQ_TYPE_EDGE_RISING) + writel(readl(bank->reg_base + RE_IRQ_ENABLE) & ~mask, + bank->reg_base + RE_IRQ_ENABLE); + + if (type & IRQ_TYPE_EDGE_FALLING) + writel(readl(bank->reg_base + FE_IRQ_ENABLE) & ~mask, + bank->reg_base + FE_IRQ_ENABLE); +} + +static void oxnas_gpio_irq_unmask(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct oxnas_gpio_bank *bank = gpiochip_get_data(chip); + unsigned int type = irqd_get_trigger_type(data); + u32 mask = BIT(data->hwirq); + + if (type & IRQ_TYPE_EDGE_RISING) + writel(readl(bank->reg_base + RE_IRQ_ENABLE) | mask, + bank->reg_base + RE_IRQ_ENABLE); + + if (type & IRQ_TYPE_EDGE_FALLING) + writel(readl(bank->reg_base + FE_IRQ_ENABLE) | mask, + bank->reg_base + FE_IRQ_ENABLE); +} + +static unsigned int oxnas_gpio_irq_startup(struct irq_data *data) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + + oxnas_gpio_direction_input(chip, data->hwirq); + oxnas_gpio_irq_unmask(data); + + return 0; +} + +static int oxnas_gpio_irq_set_type(struct irq_data *data, unsigned int type) +{ + if ((type & (IRQ_TYPE_EDGE_RISING|IRQ_TYPE_EDGE_FALLING)) == 0) + return -EINVAL; + + irq_set_handler_locked(data, handle_edge_irq); + + return 0; +} + +static void oxnas_gpio_irq_handler(struct irq_desc *desc) +{ + struct gpio_chip *gc = irq_desc_get_handler_data(desc); + struct oxnas_gpio_bank *bank = gpiochip_get_data(gc); + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned long stat; + unsigned int pin; + + chained_irq_enter(chip, desc); + + stat = readl(bank->reg_base + IRQ_PENDING); + + for_each_set_bit(pin, &stat, BITS_PER_LONG) + generic_handle_irq(irq_linear_revmap(gc->irqdomain, pin)); + + chained_irq_exit(chip, desc); +} + +#define GPIO_BANK(_bank) \ + { \ + .gpio_chip = { \ + .label = "GPIO" #_bank, \ + .request = gpiochip_generic_request, \ + .free = gpiochip_generic_free, \ + .get_direction = oxnas_gpio_get_direction, \ + .direction_input = oxnas_gpio_direction_input, \ + .direction_output = oxnas_gpio_direction_output, \ + .get = oxnas_gpio_get, \ + .set = oxnas_gpio_set, \ + .ngpio = PINS_PER_BANK, \ + .base = GPIO_BANK_START(_bank), \ + .owner = THIS_MODULE, \ + .can_sleep = 0, \ + }, \ + .irq_chip = { \ + .name = "GPIO" #_bank, \ + .irq_startup = oxnas_gpio_irq_startup, \ + .irq_ack = oxnas_gpio_irq_ack, \ + .irq_mask = oxnas_gpio_irq_mask, \ + .irq_unmask = oxnas_gpio_irq_unmask, \ + .irq_set_type = oxnas_gpio_irq_set_type, \ + }, \ + } + +static struct oxnas_gpio_bank oxnas_gpio_banks[] = { + GPIO_BANK(0), + GPIO_BANK(1), +}; + +static int oxnas_pinctrl_probe(struct platform_device *pdev) +{ + struct oxnas_pinctrl *pctl; + + pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL); + if (!pctl) + return -ENOMEM; + pctl->dev = &pdev->dev; + dev_set_drvdata(&pdev->dev, pctl); + + pctl->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "oxsemi,sys-ctrl"); + if (IS_ERR(pctl->regmap)) { + dev_err(&pdev->dev, "failed to get sys ctrl regmap\n"); + return -ENODEV; + } + + pctl->pins = oxnas_pins; + pctl->npins = ARRAY_SIZE(oxnas_pins); + pctl->functions = oxnas_functions; + pctl->nfunctions = ARRAY_SIZE(oxnas_functions); + pctl->groups = oxnas_groups; + pctl->ngroups = ARRAY_SIZE(oxnas_groups); + pctl->gpio_banks = oxnas_gpio_banks; + pctl->nbanks = ARRAY_SIZE(oxnas_gpio_banks); + + oxnas_pinctrl_desc.pins = pctl->pins; + oxnas_pinctrl_desc.npins = pctl->npins; + + pctl->pctldev = pinctrl_register(&oxnas_pinctrl_desc, + &pdev->dev, pctl); + if (IS_ERR(pctl->pctldev)) { + dev_err(&pdev->dev, "Failed to register pinctrl device\n"); + return PTR_ERR(pctl->pctldev); + } + + return 0; +} + +static int oxnas_gpio_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct of_phandle_args pinspec; + struct oxnas_gpio_bank *bank; + unsigned int id, ngpios; + int irq, ret; + struct resource *res; + + if (of_parse_phandle_with_fixed_args(np, "gpio-ranges", + 3, 0, &pinspec)) { + dev_err(&pdev->dev, "gpio-ranges property not found\n"); + return -EINVAL; + } + + id = pinspec.args[1] / PINS_PER_BANK; + ngpios = pinspec.args[2]; + + if (id >= ARRAY_SIZE(oxnas_gpio_banks)) { + dev_err(&pdev->dev, "invalid gpio-ranges base arg\n"); + return -EINVAL; + } + + if (ngpios > PINS_PER_BANK) { + dev_err(&pdev->dev, "invalid gpio-ranges count arg\n"); + return -EINVAL; + } + + bank = &oxnas_gpio_banks[id]; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + bank->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(bank->reg_base)) + return PTR_ERR(bank->reg_base); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "irq get failed\n"); + return irq; + } + + bank->id = id; + bank->gpio_chip.parent = &pdev->dev; + bank->gpio_chip.of_node = np; + bank->gpio_chip.ngpio = ngpios; + ret = gpiochip_add_data(&bank->gpio_chip, bank); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to add GPIO chip %u: %d\n", + id, ret); + return ret; + } + + ret = gpiochip_irqchip_add(&bank->gpio_chip, &bank->irq_chip, + 0, handle_level_irq, IRQ_TYPE_NONE); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to add IRQ chip %u: %d\n", + id, ret); + gpiochip_remove(&bank->gpio_chip); + return ret; + } + + gpiochip_set_chained_irqchip(&bank->gpio_chip, &bank->irq_chip, + irq, oxnas_gpio_irq_handler); + + return 0; +} + +static const struct of_device_id oxnas_pinctrl_of_match[] = { + { .compatible = "oxsemi,ox810se-pinctrl", }, + { }, +}; + +static struct platform_driver oxnas_pinctrl_driver = { + .driver = { + .name = "oxnas-pinctrl", + .of_match_table = oxnas_pinctrl_of_match, + .suppress_bind_attrs = true, + }, + .probe = oxnas_pinctrl_probe, +}; + +static const struct of_device_id oxnas_gpio_of_match[] = { + { .compatible = "oxsemi,ox810se-gpio", }, + { }, +}; + +static struct platform_driver oxnas_gpio_driver = { + .driver = { + .name = "oxnas-gpio", + .of_match_table = oxnas_gpio_of_match, + .suppress_bind_attrs = true, + }, + .probe = oxnas_gpio_probe, +}; + +static int __init oxnas_gpio_register(void) +{ + return platform_driver_register(&oxnas_gpio_driver); +} +arch_initcall(oxnas_gpio_register); + +static int __init oxnas_pinctrl_register(void) +{ + return platform_driver_register(&oxnas_pinctrl_driver); +} +arch_initcall(oxnas_pinctrl_register); diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index a91026e8cd7c..44902c63f507 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -360,7 +360,7 @@ static struct regmap_config rockchip_regmap_config = { .reg_stride = 4, }; -static const inline struct rockchip_pin_group *pinctrl_name_to_group( +static inline const struct rockchip_pin_group *pinctrl_name_to_group( const struct rockchip_pinctrl *info, const char *name) { @@ -2007,7 +2007,7 @@ static void rockchip_irq_gc_mask_clr_bit(struct irq_data *d) irq_gc_mask_clr_bit(d); } -void rockchip_irq_gc_mask_set_bit(struct irq_data *d) +static void rockchip_irq_gc_mask_set_bit(struct irq_data *d) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct rockchip_pin_bank *bank = gc->private; diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index d0ba968af5bb..0de1c67dfb94 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -844,7 +844,7 @@ static int st_pctl_get_group_pins(struct pinctrl_dev *pctldev, return 0; } -static const inline struct st_pctl_group *st_pctl_find_group_by_name( +static inline const struct st_pctl_group *st_pctl_find_group_by_name( const struct st_pinctrl *info, const char *name) { int i; diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index d1af908a7060..9cc80a500880 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -670,7 +670,7 @@ struct u300_pmx { * u300_pmx_registers - the array of registers read/written for each pinmux * shunt setting */ -const u32 u300_pmx_registers[] = { +static const u32 u300_pmx_registers[] = { U300_SYSCON_PMC1LR, U300_SYSCON_PMC1HR, U300_SYSCON_PMC2R, diff --git a/drivers/pinctrl/pinctrl-xway.c b/drivers/pinctrl/pinctrl-xway.c index b9375544dff0..dd85ad1807f5 100644 --- a/drivers/pinctrl/pinctrl-xway.c +++ b/drivers/pinctrl/pinctrl-xway.c @@ -1616,50 +1616,74 @@ struct pinctrl_xway_soc { /* xway xr9 series (DEPRECATED: Use XWAY xRX100/xRX200 Family) */ static struct pinctrl_xway_soc xr9_pinctrl = { - XR9_MAX_PIN, xway_mfp, - xway_grps, ARRAY_SIZE(xway_grps), - xrx_funcs, ARRAY_SIZE(xrx_funcs), - xway_exin_pin_map, 6 + .pin_count = XR9_MAX_PIN, + .mfp = xway_mfp, + .grps = xway_grps, + .num_grps = ARRAY_SIZE(xway_grps), + .funcs = xrx_funcs, + .num_funcs = ARRAY_SIZE(xrx_funcs), + .exin = xway_exin_pin_map, + .num_exin = 6 }; /* XWAY AMAZON Family */ static struct pinctrl_xway_soc ase_pinctrl = { - ASE_MAX_PIN, ase_mfp, - ase_grps, ARRAY_SIZE(ase_grps), - ase_funcs, ARRAY_SIZE(ase_funcs), - ase_exin_pin_map, 3 + .pin_count = ASE_MAX_PIN, + .mfp = ase_mfp, + .grps = ase_grps, + .num_grps = ARRAY_SIZE(ase_grps), + .funcs = ase_funcs, + .num_funcs = ARRAY_SIZE(ase_funcs), + .exin = ase_exin_pin_map, + .num_exin = 3 }; /* XWAY DANUBE Family */ static struct pinctrl_xway_soc danube_pinctrl = { - DANUBE_MAX_PIN, danube_mfp, - danube_grps, ARRAY_SIZE(danube_grps), - danube_funcs, ARRAY_SIZE(danube_funcs), - danube_exin_pin_map, 3 + .pin_count = DANUBE_MAX_PIN, + .mfp = danube_mfp, + .grps = danube_grps, + .num_grps = ARRAY_SIZE(danube_grps), + .funcs = danube_funcs, + .num_funcs = ARRAY_SIZE(danube_funcs), + .exin = danube_exin_pin_map, + .num_exin = 3 }; /* XWAY xRX100 Family */ static struct pinctrl_xway_soc xrx100_pinctrl = { - XRX100_MAX_PIN, xrx100_mfp, - xrx100_grps, ARRAY_SIZE(xrx100_grps), - xrx100_funcs, ARRAY_SIZE(xrx100_funcs), - xrx100_exin_pin_map, 6 + .pin_count = XRX100_MAX_PIN, + .mfp = xrx100_mfp, + .grps = xrx100_grps, + .num_grps = ARRAY_SIZE(xrx100_grps), + .funcs = xrx100_funcs, + .num_funcs = ARRAY_SIZE(xrx100_funcs), + .exin = xrx100_exin_pin_map, + .num_exin = 6 }; /* XWAY xRX200 Family */ static struct pinctrl_xway_soc xrx200_pinctrl = { - XRX200_MAX_PIN, xrx200_mfp, - xrx200_grps, ARRAY_SIZE(xrx200_grps), - xrx200_funcs, ARRAY_SIZE(xrx200_funcs), - xrx200_exin_pin_map, 6 + .pin_count = XRX200_MAX_PIN, + .mfp = xrx200_mfp, + .grps = xrx200_grps, + .num_grps = ARRAY_SIZE(xrx200_grps), + .funcs = xrx200_funcs, + .num_funcs = ARRAY_SIZE(xrx200_funcs), + .exin = xrx200_exin_pin_map, + .num_exin = 6 }; /* XWAY xRX300 Family */ static struct pinctrl_xway_soc xrx300_pinctrl = { - XRX300_MAX_PIN, xrx300_mfp, - xrx300_grps, ARRAY_SIZE(xrx300_grps), - xrx300_funcs, ARRAY_SIZE(xrx300_funcs), - xrx300_exin_pin_map, 5 + .pin_count = XRX300_MAX_PIN, + .mfp = xrx300_mfp, + .grps = xrx300_grps, + .num_grps = ARRAY_SIZE(xrx300_grps), + .funcs = xrx300_funcs, + .num_funcs = ARRAY_SIZE(xrx300_funcs), + .exin = xrx300_exin_pin_map, + .num_exin = 5 }; static struct pinctrl_gpio_range xway_gpio_range = { diff --git a/drivers/pinctrl/pinctrl-zynq.c b/drivers/pinctrl/pinctrl-zynq.c index 8fdc60c5aeaf..7afdbede6823 100644 --- a/drivers/pinctrl/pinctrl-zynq.c +++ b/drivers/pinctrl/pinctrl-zynq.c @@ -20,7 +20,7 @@ */ #include <linux/io.h> #include <linux/mfd/syscon.h> -#include <linux/module.h> +#include <linux/init.h> #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pinctrl/pinctrl.h> @@ -1210,7 +1210,6 @@ static const struct of_device_id zynq_pinctrl_of_match[] = { { .compatible = "xlnx,pinctrl-zynq" }, { } }; -MODULE_DEVICE_TABLE(of, zynq_pinctrl_of_match); static struct platform_driver zynq_pinctrl_driver = { .driver = { @@ -1225,13 +1224,3 @@ static int __init zynq_pinctrl_init(void) return platform_driver_register(&zynq_pinctrl_driver); } arch_initcall(zynq_pinctrl_init); - -static void __exit zynq_pinctrl_exit(void) -{ - platform_driver_unregister(&zynq_pinctrl_driver); -} -module_exit(zynq_pinctrl_exit); - -MODULE_AUTHOR("Sören Brinkmann <soren.brinkmann@xilinx.com>"); -MODULE_DESCRIPTION("Xilinx Zynq pinctrl driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index c223a9ef1fe1..ece702881946 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -256,7 +256,7 @@ int pinmux_request_gpio(struct pinctrl_dev *pctldev, /* Conjure some name stating what chip and pin this is taken by */ owner = kasprintf(GFP_KERNEL, "%s:%d", range->name, gpio); if (!owner) - return -EINVAL; + return -ENOMEM; ret = pin_request(pctldev, pin, owner, range); if (ret < 0) @@ -606,23 +606,17 @@ static int pinmux_pins_show(struct seq_file *s, void *what) if (pmxops->strict) { if (desc->mux_owner) seq_printf(s, "pin %d (%s): device %s%s", - pin, - desc->name ? desc->name : "unnamed", - desc->mux_owner, + pin, desc->name, desc->mux_owner, is_hog ? " (HOG)" : ""); else if (desc->gpio_owner) seq_printf(s, "pin %d (%s): GPIO %s", - pin, - desc->name ? desc->name : "unnamed", - desc->gpio_owner); + pin, desc->name, desc->gpio_owner); else seq_printf(s, "pin %d (%s): UNCLAIMED", - pin, - desc->name ? desc->name : "unnamed"); + pin, desc->name); } else { /* For non-strict controllers */ - seq_printf(s, "pin %d (%s): %s %s%s", pin, - desc->name ? desc->name : "unnamed", + seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name, desc->mux_owner ? desc->mux_owner : "(MUX UNCLAIMED)", desc->gpio_owner ? desc->gpio_owner diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig index 67bc70dcda64..93ef268d5ccd 100644 --- a/drivers/pinctrl/qcom/Kconfig +++ b/drivers/pinctrl/qcom/Kconfig @@ -55,6 +55,14 @@ config PINCTRL_MSM8960 This is the pinctrl, pinmux, pinconf and gpiolib driver for the Qualcomm TLMM block found in the Qualcomm 8960 platform. +config PINCTRL_MDM9615 + tristate "Qualcomm 9615 pin controller driver" + depends on GPIOLIB && OF + select PINCTRL_MSM + help + This is the pinctrl, pinmux, pinconf and gpiolib driver for the + Qualcomm TLMM block found in the Qualcomm 9615 platform. + config PINCTRL_MSM8X74 tristate "Qualcomm 8x74 pin controller driver" depends on GPIOLIB && OF diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile index c964a2c4b90a..8319e11cecb5 100644 --- a/drivers/pinctrl/qcom/Makefile +++ b/drivers/pinctrl/qcom/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_PINCTRL_MSM8X74) += pinctrl-msm8x74.o obj-$(CONFIG_PINCTRL_MSM8916) += pinctrl-msm8916.o obj-$(CONFIG_PINCTRL_MSM8996) += pinctrl-msm8996.o obj-$(CONFIG_PINCTRL_QDF2XXX) += pinctrl-qdf2xxx.o +obj-$(CONFIG_PINCTRL_MDM9615) += pinctrl-mdm9615.o obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-gpio.o obj-$(CONFIG_PINCTRL_QCOM_SPMI_PMIC) += pinctrl-spmi-mpp.o obj-$(CONFIG_PINCTRL_QCOM_SSBI_PMIC) += pinctrl-ssbi-gpio.o diff --git a/drivers/pinctrl/qcom/pinctrl-mdm9615.c b/drivers/pinctrl/qcom/pinctrl-mdm9615.c new file mode 100644 index 000000000000..2b8f4521692c --- /dev/null +++ b/drivers/pinctrl/qcom/pinctrl-mdm9615.c @@ -0,0 +1,483 @@ +/* + * Copyright (c) 2014, Sony Mobile Communications AB. + * Copyright (c) 2016 BayLibre, SAS. + * Author : Neil Armstrong <narmstrong@baylibre.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/pinctrl/pinmux.h> + +#include "pinctrl-msm.h" + +static const struct pinctrl_pin_desc mdm9615_pins[] = { + PINCTRL_PIN(0, "GPIO_0"), + PINCTRL_PIN(1, "GPIO_1"), + PINCTRL_PIN(2, "GPIO_2"), + PINCTRL_PIN(3, "GPIO_3"), + PINCTRL_PIN(4, "GPIO_4"), + PINCTRL_PIN(5, "GPIO_5"), + PINCTRL_PIN(6, "GPIO_6"), + PINCTRL_PIN(7, "GPIO_7"), + PINCTRL_PIN(8, "GPIO_8"), + PINCTRL_PIN(9, "GPIO_9"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "GPIO_80"), + PINCTRL_PIN(81, "GPIO_81"), + PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), + PINCTRL_PIN(86, "GPIO_86"), + PINCTRL_PIN(87, "GPIO_87"), +}; + +#define DECLARE_MSM_GPIO_PINS(pin) \ + static const unsigned int gpio##pin##_pins[] = { pin } +DECLARE_MSM_GPIO_PINS(0); +DECLARE_MSM_GPIO_PINS(1); +DECLARE_MSM_GPIO_PINS(2); +DECLARE_MSM_GPIO_PINS(3); +DECLARE_MSM_GPIO_PINS(4); +DECLARE_MSM_GPIO_PINS(5); +DECLARE_MSM_GPIO_PINS(6); +DECLARE_MSM_GPIO_PINS(7); +DECLARE_MSM_GPIO_PINS(8); +DECLARE_MSM_GPIO_PINS(9); +DECLARE_MSM_GPIO_PINS(10); +DECLARE_MSM_GPIO_PINS(11); +DECLARE_MSM_GPIO_PINS(12); +DECLARE_MSM_GPIO_PINS(13); +DECLARE_MSM_GPIO_PINS(14); +DECLARE_MSM_GPIO_PINS(15); +DECLARE_MSM_GPIO_PINS(16); +DECLARE_MSM_GPIO_PINS(17); +DECLARE_MSM_GPIO_PINS(18); +DECLARE_MSM_GPIO_PINS(19); +DECLARE_MSM_GPIO_PINS(20); +DECLARE_MSM_GPIO_PINS(21); +DECLARE_MSM_GPIO_PINS(22); +DECLARE_MSM_GPIO_PINS(23); +DECLARE_MSM_GPIO_PINS(24); +DECLARE_MSM_GPIO_PINS(25); +DECLARE_MSM_GPIO_PINS(26); +DECLARE_MSM_GPIO_PINS(27); +DECLARE_MSM_GPIO_PINS(28); +DECLARE_MSM_GPIO_PINS(29); +DECLARE_MSM_GPIO_PINS(30); +DECLARE_MSM_GPIO_PINS(31); +DECLARE_MSM_GPIO_PINS(32); +DECLARE_MSM_GPIO_PINS(33); +DECLARE_MSM_GPIO_PINS(34); +DECLARE_MSM_GPIO_PINS(35); +DECLARE_MSM_GPIO_PINS(36); +DECLARE_MSM_GPIO_PINS(37); +DECLARE_MSM_GPIO_PINS(38); +DECLARE_MSM_GPIO_PINS(39); +DECLARE_MSM_GPIO_PINS(40); +DECLARE_MSM_GPIO_PINS(41); +DECLARE_MSM_GPIO_PINS(42); +DECLARE_MSM_GPIO_PINS(43); +DECLARE_MSM_GPIO_PINS(44); +DECLARE_MSM_GPIO_PINS(45); +DECLARE_MSM_GPIO_PINS(46); +DECLARE_MSM_GPIO_PINS(47); +DECLARE_MSM_GPIO_PINS(48); +DECLARE_MSM_GPIO_PINS(49); +DECLARE_MSM_GPIO_PINS(50); +DECLARE_MSM_GPIO_PINS(51); +DECLARE_MSM_GPIO_PINS(52); +DECLARE_MSM_GPIO_PINS(53); +DECLARE_MSM_GPIO_PINS(54); +DECLARE_MSM_GPIO_PINS(55); +DECLARE_MSM_GPIO_PINS(56); +DECLARE_MSM_GPIO_PINS(57); +DECLARE_MSM_GPIO_PINS(58); +DECLARE_MSM_GPIO_PINS(59); +DECLARE_MSM_GPIO_PINS(60); +DECLARE_MSM_GPIO_PINS(61); +DECLARE_MSM_GPIO_PINS(62); +DECLARE_MSM_GPIO_PINS(63); +DECLARE_MSM_GPIO_PINS(64); +DECLARE_MSM_GPIO_PINS(65); +DECLARE_MSM_GPIO_PINS(66); +DECLARE_MSM_GPIO_PINS(67); +DECLARE_MSM_GPIO_PINS(68); +DECLARE_MSM_GPIO_PINS(69); +DECLARE_MSM_GPIO_PINS(70); +DECLARE_MSM_GPIO_PINS(71); +DECLARE_MSM_GPIO_PINS(72); +DECLARE_MSM_GPIO_PINS(73); +DECLARE_MSM_GPIO_PINS(74); +DECLARE_MSM_GPIO_PINS(75); +DECLARE_MSM_GPIO_PINS(76); +DECLARE_MSM_GPIO_PINS(77); +DECLARE_MSM_GPIO_PINS(78); +DECLARE_MSM_GPIO_PINS(79); +DECLARE_MSM_GPIO_PINS(80); +DECLARE_MSM_GPIO_PINS(81); +DECLARE_MSM_GPIO_PINS(82); +DECLARE_MSM_GPIO_PINS(83); +DECLARE_MSM_GPIO_PINS(84); +DECLARE_MSM_GPIO_PINS(85); +DECLARE_MSM_GPIO_PINS(86); +DECLARE_MSM_GPIO_PINS(87); + +#define FUNCTION(fname) \ + [MSM_MUX_##fname] = { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +#define PINGROUP(id, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11) \ + { \ + .name = "gpio" #id, \ + .pins = gpio##id##_pins, \ + .npins = ARRAY_SIZE(gpio##id##_pins), \ + .funcs = (int[]){ \ + MSM_MUX_gpio, \ + MSM_MUX_##f1, \ + MSM_MUX_##f2, \ + MSM_MUX_##f3, \ + MSM_MUX_##f4, \ + MSM_MUX_##f5, \ + MSM_MUX_##f6, \ + MSM_MUX_##f7, \ + MSM_MUX_##f8, \ + MSM_MUX_##f9, \ + MSM_MUX_##f10, \ + MSM_MUX_##f11 \ + }, \ + .nfuncs = 12, \ + .ctl_reg = 0x1000 + 0x10 * id, \ + .io_reg = 0x1004 + 0x10 * id, \ + .intr_cfg_reg = 0x1008 + 0x10 * id, \ + .intr_status_reg = 0x100c + 0x10 * id, \ + .intr_target_reg = 0x400 + 0x4 * id, \ + .mux_bit = 2, \ + .pull_bit = 0, \ + .drv_bit = 6, \ + .oe_bit = 9, \ + .in_bit = 0, \ + .out_bit = 1, \ + .intr_enable_bit = 0, \ + .intr_status_bit = 0, \ + .intr_ack_high = 1, \ + .intr_target_bit = 0, \ + .intr_target_kpss_val = 4, \ + .intr_raw_status_bit = 3, \ + .intr_polarity_bit = 1, \ + .intr_detection_bit = 2, \ + .intr_detection_width = 1, \ + } + +enum mdm9615_functions { + MSM_MUX_gpio, + MSM_MUX_gsbi2_i2c, + MSM_MUX_gsbi3, + MSM_MUX_gsbi4, + MSM_MUX_gsbi5_i2c, + MSM_MUX_gsbi5_uart, + MSM_MUX_sdc2, + MSM_MUX_ebi2_lcdc, + MSM_MUX_ps_hold, + MSM_MUX_prim_audio, + MSM_MUX_sec_audio, + MSM_MUX_cdc_mclk, + MSM_MUX_NA, +}; + +static const char * const gpio_groups[] = { + "gpio0", "gpio1", "gpio2", "gpio3", "gpio4", "gpio5", "gpio6", "gpio7", + "gpio8", "gpio9", "gpio10", "gpio11", "gpio12", "gpio13", "gpio14", + "gpio15", "gpio16", "gpio17", "gpio18", "gpio19", "gpio20", "gpio21", + "gpio22", "gpio23", "gpio24", "gpio25", "gpio26", "gpio27", "gpio28", + "gpio29", "gpio30", "gpio31", "gpio32", "gpio33", "gpio34", "gpio35", + "gpio36", "gpio37", "gpio38", "gpio39", "gpio40", "gpio41", "gpio42", + "gpio43", "gpio44", "gpio45", "gpio46", "gpio47", "gpio48", "gpio49", + "gpio50", "gpio51", "gpio52", "gpio53", "gpio54", "gpio55", "gpio56", + "gpio57", "gpio58", "gpio59", "gpio60", "gpio61", "gpio62", "gpio63", + "gpio64", "gpio65", "gpio66", "gpio67", "gpio68", "gpio69", "gpio70", + "gpio71", "gpio72", "gpio73", "gpio74", "gpio75", "gpio76", "gpio77", + "gpio78", "gpio79", "gpio80", "gpio81", "gpio82", "gpio83", "gpio84", + "gpio85", "gpio86", "gpio87" +}; + +static const char * const gsbi2_i2c_groups[] = { + "gpio4", "gpio5" +}; + +static const char * const gsbi3_groups[] = { + "gpio8", "gpio9", "gpio10", "gpio11" +}; + +static const char * const gsbi4_groups[] = { + "gpio12", "gpio13", "gpio14", "gpio15" +}; + +static const char * const gsbi5_i2c_groups[] = { + "gpio16", "gpio17" +}; + +static const char * const gsbi5_uart_groups[] = { + "gpio18", "gpio19" +}; + +static const char * const sdc2_groups[] = { + "gpio25", "gpio26", "gpio27", "gpio28", "gpio29", "gpio30", +}; + +static const char * const ebi2_lcdc_groups[] = { + "gpio21", "gpio22", "gpio24", +}; + +static const char * const ps_hold_groups[] = { + "gpio83", +}; + +static const char * const prim_audio_groups[] = { + "gpio20", "gpio21", "gpio22", "gpio23", +}; + +static const char * const sec_audio_groups[] = { + "gpio25", "gpio26", "gpio27", "gpio28", +}; + +static const char * const cdc_mclk_groups[] = { + "gpio24", +}; + +static const struct msm_function mdm9615_functions[] = { + FUNCTION(gpio), + FUNCTION(gsbi2_i2c), + FUNCTION(gsbi3), + FUNCTION(gsbi4), + FUNCTION(gsbi5_i2c), + FUNCTION(gsbi5_uart), + FUNCTION(sdc2), + FUNCTION(ebi2_lcdc), + FUNCTION(ps_hold), + FUNCTION(prim_audio), + FUNCTION(sec_audio), + FUNCTION(cdc_mclk), +}; + +static const struct msm_pingroup mdm9615_groups[] = { + PINGROUP(0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(1, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(2, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(4, gsbi2_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(5, gsbi2_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(6, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(8, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(9, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(10, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(11, gsbi3, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(12, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(13, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(14, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(15, gsbi4, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(16, gsbi5_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(17, gsbi5_i2c, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(18, gsbi5_uart, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(19, gsbi5_uart, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(20, prim_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(21, prim_audio, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(22, prim_audio, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(23, prim_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(24, cdc_mclk, NA, ebi2_lcdc, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(25, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(26, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(27, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(28, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(29, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(30, sdc2, sec_audio, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(31, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(32, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(33, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(34, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(35, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(36, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(37, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(38, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(39, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(40, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(41, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(42, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(43, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(44, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(45, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(46, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(47, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(48, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(49, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(50, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(51, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(52, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(53, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(54, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(55, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(56, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(57, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(58, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(59, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(60, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(61, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(62, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(63, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(64, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(65, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(66, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(67, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(68, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(69, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(70, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(71, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(72, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(73, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(74, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(75, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(76, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(77, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(78, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(79, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(80, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(81, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(82, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(83, ps_hold, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(84, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(85, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(86, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), + PINGROUP(87, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), +}; + +#define NUM_GPIO_PINGROUPS 88 + +static const struct msm_pinctrl_soc_data mdm9615_pinctrl = { + .pins = mdm9615_pins, + .npins = ARRAY_SIZE(mdm9615_pins), + .functions = mdm9615_functions, + .nfunctions = ARRAY_SIZE(mdm9615_functions), + .groups = mdm9615_groups, + .ngroups = ARRAY_SIZE(mdm9615_groups), + .ngpios = NUM_GPIO_PINGROUPS, +}; + +static int mdm9615_pinctrl_probe(struct platform_device *pdev) +{ + return msm_pinctrl_probe(pdev, &mdm9615_pinctrl); +} + +static const struct of_device_id mdm9615_pinctrl_of_match[] = { + { .compatible = "qcom,mdm9615-pinctrl", }, + { }, +}; + +static struct platform_driver mdm9615_pinctrl_driver = { + .driver = { + .name = "mdm9615-pinctrl", + .of_match_table = mdm9615_pinctrl_of_match, + }, + .probe = mdm9615_pinctrl_probe, + .remove = msm_pinctrl_remove, +}; + +static int __init mdm9615_pinctrl_init(void) +{ + return platform_driver_register(&mdm9615_pinctrl_driver); +} +arch_initcall(mdm9615_pinctrl_init); + +static void __exit mdm9615_pinctrl_exit(void) +{ + platform_driver_unregister(&mdm9615_pinctrl_driver); +} +module_exit(mdm9615_pinctrl_exit); + +MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); +MODULE_DESCRIPTION("Qualcomm MDM9615 pinctrl driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, mdm9615_pinctrl_of_match); diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index 1a44e1d03390..51c42d746883 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -29,6 +29,7 @@ #include <linux/spinlock.h> #include <linux/reboot.h> #include <linux/pm.h> +#include <linux/log2.h> #include "../core.h" #include "../pinconf.h" @@ -138,10 +139,11 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, struct msm_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); const struct msm_pingroup *g; unsigned long flags; - u32 val; + u32 val, mask; int i; g = &pctrl->soc->groups[group]; + mask = GENMASK(g->mux_bit + order_base_2(g->nfuncs) - 1, g->mux_bit); for (i = 0; i < g->nfuncs; i++) { if (g->funcs[i] == function) @@ -154,7 +156,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev, spin_lock_irqsave(&pctrl->lock, flags); val = readl(pctrl->regs + g->ctl_reg); - val &= ~(0x7 << g->mux_bit); + val &= mask; val |= i << g->mux_bit; writel(val, pctrl->regs + g->ctl_reg); diff --git a/drivers/pinctrl/qcom/pinctrl-msm8660.c b/drivers/pinctrl/qcom/pinctrl-msm8660.c index 3e8f7ac2ac8a..5591d093bf78 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8660.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8660.c @@ -506,6 +506,8 @@ enum msm8660_functions { MSM_MUX_usb_fs2_oe_n, MSM_MUX_vfe, MSM_MUX_vsens_alarm, + MSM_MUX_ebi2cs, + MSM_MUX_ebi2, MSM_MUX__, }; @@ -696,6 +698,36 @@ static const char * const vfe_groups[] = { static const char * const vsens_alarm_groups[] = { "gpio127" }; +static const char * const ebi2cs_groups[] = { + "gpio39", /* CS1A */ + "gpio40", /* CS2A */ + "gpio123", /* CS1B */ + "gpio124", /* CS2B */ + "gpio131", /* CS5 */ + "gpio132", /* CS4 */ + "gpio133", /* CS3 */ + "gpio134", /* CS0 */ +}; +static const char * const ebi2_groups[] = { + /* ADDR9 & ADDR8 */ + "gpio37", "gpio38", + /* ADDR7 - ADDR 0 */ + "gpio123", "gpio124", "gpio125", "gpio126", + "gpio127", "gpio128", "gpio129", "gpio130", + /* (muxed address+data) AD15 - AD0 */ + "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", + "gpio140", "gpio141", "gpio142", "gpio143", "gpio144", + "gpio145", "gpio146", "gpio147", "gpio148", "gpio149", + "gpio150", + "gpio151", /* OE output enable */ + "gpio152", /* clock */ + "gpio153", /* ADV */ + "gpio154", /* WAIT (input) */ + "gpio155", /* UB Upper Byte Enable */ + "gpio156", /* LB Lower Byte Enable */ + "gpio157", /* WE Write Enable */ + "gpio158", /* busy */ +}; static const struct msm_function msm8660_functions[] = { FUNCTION(gpio), @@ -749,6 +781,8 @@ static const struct msm_function msm8660_functions[] = { FUNCTION(usb_fs2_oe_n), FUNCTION(vfe), FUNCTION(vsens_alarm), + FUNCTION(ebi2cs), /* for EBI2 chip selects */ + FUNCTION(ebi2), /* for general EBI2 pins */ }; static const struct msm_pingroup msm8660_groups[] = { @@ -789,10 +823,10 @@ static const struct msm_pingroup msm8660_groups[] = { PINGROUP(34, gsbi1, _, _, _, _, _, _), PINGROUP(35, gsbi1, _, _, _, _, _, _), PINGROUP(36, gsbi1, _, _, _, _, _, _), - PINGROUP(37, gsbi2, _, _, _, _, _, _), - PINGROUP(38, gsbi2, _, _, _, _, _, _), - PINGROUP(39, gsbi2, _, mdp_vsync, _, _, _, _), - PINGROUP(40, gsbi2, _, _, _, _, _, _), + PINGROUP(37, gsbi2, ebi2, _, _, _, _, _), + PINGROUP(38, gsbi2, ebi2, _, _, _, _, _), + PINGROUP(39, gsbi2, ebi2cs, mdp_vsync, _, _, _, _), + PINGROUP(40, gsbi2, ebi2cs, _, _, _, _, _), PINGROUP(41, gsbi3, mdp_vsync, _, _, _, _, _), PINGROUP(42, gsbi3, vfe, _, _, _, _, _), PINGROUP(43, gsbi3, _, _, _, _, _, _), @@ -875,42 +909,42 @@ static const struct msm_pingroup msm8660_groups[] = { PINGROUP(120, i2s, _, _, _, _, _, _), PINGROUP(121, i2s, _, _, _, _, _, _), PINGROUP(122, i2s, gp_clk_1b, _, _, _, _, _), - PINGROUP(123, _, gsbi2_spi_cs1_n, _, _, _, _, _), - PINGROUP(124, _, gsbi2_spi_cs2_n, _, _, _, _, _), - PINGROUP(125, _, gsbi2_spi_cs3_n, _, _, _, _, _), - PINGROUP(126, _, _, _, _, _, _, _), - PINGROUP(127, _, vsens_alarm, _, _, _, _, _), - PINGROUP(128, _, _, _, _, _, _, _), - PINGROUP(129, _, _, _, _, _, _, _), - PINGROUP(130, _, _, _, _, _, _, _), - PINGROUP(131, _, _, _, _, _, _, _), - PINGROUP(132, _, _, _, _, _, _, _), - PINGROUP(133, _, _, _, _, _, _, _), - PINGROUP(134, _, _, _, _, _, _, _), - PINGROUP(135, _, _, _, _, _, _, _), - PINGROUP(136, _, _, _, _, _, _, _), - PINGROUP(137, _, _, _, _, _, _, _), - PINGROUP(138, _, _, _, _, _, _, _), - PINGROUP(139, _, _, _, _, _, _, _), - PINGROUP(140, _, _, _, _, _, _, _), - PINGROUP(141, _, _, _, _, _, _, _), - PINGROUP(142, _, _, _, _, _, _, _), - PINGROUP(143, _, sdc2, _, _, _, _, _), - PINGROUP(144, _, sdc2, _, _, _, _, _), - PINGROUP(145, _, sdc2, _, _, _, _, _), - PINGROUP(146, _, sdc2, _, _, _, _, _), - PINGROUP(147, _, sdc2, _, _, _, _, _), - PINGROUP(148, _, sdc2, _, _, _, _, _), - PINGROUP(149, _, sdc2, _, _, _, _, _), - PINGROUP(150, _, sdc2, _, _, _, _, _), - PINGROUP(151, _, sdc2, _, _, _, _, _), - PINGROUP(152, _, sdc2, _, _, _, _, _), - PINGROUP(153, _, _, _, _, _, _, _), - PINGROUP(154, _, _, _, _, _, _, _), - PINGROUP(155, _, _, _, _, _, _, _), - PINGROUP(156, _, _, _, _, _, _, _), - PINGROUP(157, _, _, _, _, _, _, _), - PINGROUP(158, _, _, _, _, _, _, _), + PINGROUP(123, ebi2, gsbi2_spi_cs1_n, ebi2cs, _, _, _, _), + PINGROUP(124, ebi2, gsbi2_spi_cs2_n, ebi2cs, _, _, _, _), + PINGROUP(125, ebi2, gsbi2_spi_cs3_n, _, _, _, _, _), + PINGROUP(126, ebi2, _, _, _, _, _, _), + PINGROUP(127, ebi2, vsens_alarm, _, _, _, _, _), + PINGROUP(128, ebi2, _, _, _, _, _, _), + PINGROUP(129, ebi2, _, _, _, _, _, _), + PINGROUP(130, ebi2, _, _, _, _, _, _), + PINGROUP(131, ebi2cs, _, _, _, _, _, _), + PINGROUP(132, ebi2cs, _, _, _, _, _, _), + PINGROUP(133, ebi2cs, _, _, _, _, _, _), + PINGROUP(134, ebi2cs, _, _, _, _, _, _), + PINGROUP(135, ebi2, _, _, _, _, _, _), + PINGROUP(136, ebi2, _, _, _, _, _, _), + PINGROUP(137, ebi2, _, _, _, _, _, _), + PINGROUP(138, ebi2, _, _, _, _, _, _), + PINGROUP(139, ebi2, _, _, _, _, _, _), + PINGROUP(140, ebi2, _, _, _, _, _, _), + PINGROUP(141, ebi2, _, _, _, _, _, _), + PINGROUP(142, ebi2, _, _, _, _, _, _), + PINGROUP(143, ebi2, sdc2, _, _, _, _, _), + PINGROUP(144, ebi2, sdc2, _, _, _, _, _), + PINGROUP(145, ebi2, sdc2, _, _, _, _, _), + PINGROUP(146, ebi2, sdc2, _, _, _, _, _), + PINGROUP(147, ebi2, sdc2, _, _, _, _, _), + PINGROUP(148, ebi2, sdc2, _, _, _, _, _), + PINGROUP(149, ebi2, sdc2, _, _, _, _, _), + PINGROUP(150, ebi2, sdc2, _, _, _, _, _), + PINGROUP(151, ebi2, sdc2, _, _, _, _, _), + PINGROUP(152, ebi2, sdc2, _, _, _, _, _), + PINGROUP(153, ebi2, _, _, _, _, _, _), + PINGROUP(154, ebi2, _, _, _, _, _, _), + PINGROUP(155, ebi2, _, _, _, _, _, _), + PINGROUP(156, ebi2, _, _, _, _, _, _), + PINGROUP(157, ebi2, _, _, _, _, _, _), + PINGROUP(158, ebi2, _, _, _, _, _, _), PINGROUP(159, sdc1, _, _, _, _, _, _), PINGROUP(160, sdc1, _, _, _, _, _, _), PINGROUP(161, sdc1, _, _, _, _, _, _), diff --git a/drivers/pinctrl/qcom/pinctrl-msm8x74.c b/drivers/pinctrl/qcom/pinctrl-msm8x74.c index 46fe6ad5f97e..9eb63d3403d4 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm8x74.c +++ b/drivers/pinctrl/qcom/pinctrl-msm8x74.c @@ -172,6 +172,8 @@ static const struct pinctrl_pin_desc msm8x74_pins[] = { PINCTRL_PIN(149, "SDC2_CLK"), PINCTRL_PIN(150, "SDC2_CMD"), PINCTRL_PIN(151, "SDC2_DATA"), + PINCTRL_PIN(152, "HSIC_STROBE"), + PINCTRL_PIN(153, "HSIC_DATA"), }; #define DECLARE_MSM_GPIO_PINS(pin) static const unsigned int gpio##pin##_pins[] = { pin } @@ -328,6 +330,8 @@ static const unsigned int sdc1_data_pins[] = { 148 }; static const unsigned int sdc2_clk_pins[] = { 149 }; static const unsigned int sdc2_cmd_pins[] = { 150 }; static const unsigned int sdc2_data_pins[] = { 151 }; +static const unsigned int hsic_strobe_pins[] = { 152 }; +static const unsigned int hsic_data_pins[] = { 153 }; #define FUNCTION(fname) \ [MSM_MUX_##fname] = { \ @@ -399,6 +403,37 @@ static const unsigned int sdc2_data_pins[] = { 151 }; .intr_detection_width = -1, \ } +#define HSIC_PINGROUP(pg_name, ctl) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .funcs = (int[]){ \ + MSM_MUX_gpio, \ + MSM_MUX_hsic_ctl, \ + }, \ + .nfuncs = 2, \ + .ctl_reg = ctl, \ + .io_reg = 0, \ + .intr_cfg_reg = 0, \ + .intr_status_reg = 0, \ + .intr_target_reg = 0, \ + .mux_bit = 25, \ + .pull_bit = -1, \ + .drv_bit = -1, \ + .oe_bit = -1, \ + .in_bit = -1, \ + .out_bit = -1, \ + .intr_enable_bit = -1, \ + .intr_status_bit = -1, \ + .intr_target_bit = -1, \ + .intr_target_kpss_val = -1, \ + .intr_raw_status_bit = -1, \ + .intr_polarity_bit = -1, \ + .intr_detection_bit = -1, \ + .intr_detection_width = -1, \ + } + /* * TODO: Add the rest of the possible functions and fill out * the pingroup table below. @@ -509,6 +544,7 @@ enum msm8x74_functions { MSM_MUX_fm, MSM_MUX_wlan, MSM_MUX_slimbus, + MSM_MUX_hsic_ctl, MSM_MUX_NA, }; @@ -534,7 +570,8 @@ static const char * const gpio_groups[] = { "gpio123", "gpio124", "gpio125", "gpio126", "gpio127", "gpio128", "gpio129", "gpio130", "gpio131", "gpio132", "gpio133", "gpio134", "gpio135", "gpio136", "gpio137", "gpio138", "gpio139", "gpio140", - "gpio141", "gpio142", "gpio143", "gpio144", "gpio145" + "gpio141", "gpio142", "gpio143", "gpio144", "gpio145", "hsic_data", + "hsic_strobe", }; static const char * const blsp_uart1_groups[] = { @@ -754,6 +791,7 @@ static const char * const wlan_groups[] = { }; static const char * const slimbus_groups[] = { "gpio70", "gpio71" }; +static const char * const hsic_ctl_groups[] = { "hsic_strobe", "hsic_data" }; static const struct msm_function msm8x74_functions[] = { FUNCTION(gpio), @@ -861,6 +899,7 @@ static const struct msm_function msm8x74_functions[] = { FUNCTION(fm), FUNCTION(wlan), FUNCTION(slimbus), + FUNCTION(hsic_ctl), }; static const struct msm_pingroup msm8x74_groups[] = { @@ -1016,6 +1055,8 @@ static const struct msm_pingroup msm8x74_groups[] = { SDC_PINGROUP(sdc2_clk, 0x2048, 14, 6), SDC_PINGROUP(sdc2_cmd, 0x2048, 11, 3), SDC_PINGROUP(sdc2_data, 0x2048, 9, 0), + HSIC_PINGROUP(hsic_strobe, 0x2050), + HSIC_PINGROUP(hsic_data, 0x2054), }; #define NUM_GPIO_PINGROUPS 146 diff --git a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c index 9191727aff5e..0d1392fc32dd 100644 --- a/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c +++ b/drivers/pinctrl/qcom/pinctrl-ssbi-mpp.c @@ -744,6 +744,7 @@ static int pm8xxx_pin_populate(struct pm8xxx_mpp *pctrl, static const struct of_device_id pm8xxx_mpp_of_match[] = { { .compatible = "qcom,pm8018-mpp" }, { .compatible = "qcom,pm8038-mpp" }, + { .compatible = "qcom,pm8058-mpp" }, { .compatible = "qcom,pm8917-mpp" }, { .compatible = "qcom,pm8821-mpp" }, { .compatible = "qcom,pm8921-mpp" }, diff --git a/drivers/pinctrl/samsung/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c index fb71fc3e5aa0..3000df80709f 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos5440.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos5440.c @@ -998,6 +998,7 @@ static struct platform_driver exynos5440_pinctrl_driver = { .driver = { .name = "exynos5440-pinctrl", .of_match_table = exynos5440_pinctrl_dt_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index ed0b70881e19..513fe6b23248 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1274,6 +1274,7 @@ static struct platform_driver samsung_pinctrl_driver = { .driver = { .name = "samsung-pinctrl", .of_match_table = samsung_pinctrl_dt_match, + .suppress_bind_attrs = true, }, }; diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c index 9b9cee06ec59..a3b82041b6a2 100644 --- a/drivers/pinctrl/sh-pfc/core.c +++ b/drivers/pinctrl/sh-pfc/core.c @@ -598,15 +598,6 @@ static int sh_pfc_probe(struct platform_device *pdev) return 0; } -static int sh_pfc_remove(struct platform_device *pdev) -{ -#ifdef CONFIG_PINCTRL_SH_PFC_GPIO - sh_pfc_unregister_gpiochip(platform_get_drvdata(pdev)); -#endif - - return 0; -} - static const struct platform_device_id sh_pfc_id_table[] = { #ifdef CONFIG_PINCTRL_PFC_SH7203 { "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info }, @@ -650,7 +641,6 @@ static const struct platform_device_id sh_pfc_id_table[] = { static struct platform_driver sh_pfc_driver = { .probe = sh_pfc_probe, - .remove = sh_pfc_remove, .id_table = sh_pfc_id_table, .driver = { .name = DRV_NAME, diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h index dc1b2adb24c5..0bbdea5849f4 100644 --- a/drivers/pinctrl/sh-pfc/core.h +++ b/drivers/pinctrl/sh-pfc/core.h @@ -10,50 +10,16 @@ #ifndef __SH_PFC_CORE_H__ #define __SH_PFC_CORE_H__ -#include <linux/compiler.h> -#include <linux/spinlock.h> #include <linux/types.h> #include "sh_pfc.h" -struct sh_pfc_window { - phys_addr_t phys; - void __iomem *virt; - unsigned long size; -}; - -struct sh_pfc_chip; -struct sh_pfc_pinctrl; - struct sh_pfc_pin_range { u16 start; u16 end; }; -struct sh_pfc { - struct device *dev; - const struct sh_pfc_soc_info *info; - spinlock_t lock; - - unsigned int num_windows; - struct sh_pfc_window *windows; - unsigned int num_irqs; - unsigned int *irqs; - - struct sh_pfc_pin_range *ranges; - unsigned int nr_ranges; - - unsigned int nr_gpio_pins; - - struct sh_pfc_chip *gpio; -#ifdef CONFIG_SUPERH - struct sh_pfc_chip *func; -#endif - -}; - int sh_pfc_register_gpiochip(struct sh_pfc *pfc); -int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc); int sh_pfc_register_pinctrl(struct sh_pfc *pfc); @@ -67,28 +33,4 @@ void sh_pfc_write_reg(struct sh_pfc *pfc, u32 reg, unsigned int width, int sh_pfc_get_pin_index(struct sh_pfc *pfc, unsigned int pin); int sh_pfc_config_mux(struct sh_pfc *pfc, unsigned mark, int pinmux_type); -extern const struct sh_pfc_soc_info emev2_pinmux_info; -extern const struct sh_pfc_soc_info r8a73a4_pinmux_info; -extern const struct sh_pfc_soc_info r8a7740_pinmux_info; -extern const struct sh_pfc_soc_info r8a7778_pinmux_info; -extern const struct sh_pfc_soc_info r8a7779_pinmux_info; -extern const struct sh_pfc_soc_info r8a7790_pinmux_info; -extern const struct sh_pfc_soc_info r8a7791_pinmux_info; -extern const struct sh_pfc_soc_info r8a7793_pinmux_info; -extern const struct sh_pfc_soc_info r8a7794_pinmux_info; -extern const struct sh_pfc_soc_info r8a7795_pinmux_info; -extern const struct sh_pfc_soc_info sh7203_pinmux_info; -extern const struct sh_pfc_soc_info sh7264_pinmux_info; -extern const struct sh_pfc_soc_info sh7269_pinmux_info; -extern const struct sh_pfc_soc_info sh73a0_pinmux_info; -extern const struct sh_pfc_soc_info sh7720_pinmux_info; -extern const struct sh_pfc_soc_info sh7722_pinmux_info; -extern const struct sh_pfc_soc_info sh7723_pinmux_info; -extern const struct sh_pfc_soc_info sh7724_pinmux_info; -extern const struct sh_pfc_soc_info sh7734_pinmux_info; -extern const struct sh_pfc_soc_info sh7757_pinmux_info; -extern const struct sh_pfc_soc_info sh7785_pinmux_info; -extern const struct sh_pfc_soc_info sh7786_pinmux_info; -extern const struct sh_pfc_soc_info shx3_pinmux_info; - #endif /* __SH_PFC_CORE_H__ */ diff --git a/drivers/pinctrl/sh-pfc/gpio.c b/drivers/pinctrl/sh-pfc/gpio.c index 97dff6a09ff0..6b5422766f13 100644 --- a/drivers/pinctrl/sh-pfc/gpio.c +++ b/drivers/pinctrl/sh-pfc/gpio.c @@ -318,7 +318,7 @@ sh_pfc_add_gpiochip(struct sh_pfc *pfc, int(*setup)(struct sh_pfc_chip *), if (ret < 0) return ERR_PTR(ret); - ret = gpiochip_add_data(&chip->gpio_chip, chip); + ret = devm_gpiochip_add_data(pfc->dev, &chip->gpio_chip, chip); if (unlikely(ret < 0)) return ERR_PTR(ret); @@ -399,18 +399,7 @@ int sh_pfc_register_gpiochip(struct sh_pfc *pfc) chip = sh_pfc_add_gpiochip(pfc, gpio_function_setup, NULL); if (IS_ERR(chip)) return PTR_ERR(chip); - - pfc->func = chip; #endif /* CONFIG_SUPERH */ return 0; } - -int sh_pfc_unregister_gpiochip(struct sh_pfc *pfc) -{ - gpiochip_remove(&pfc->gpio->gpio_chip); -#ifdef CONFIG_SUPERH - gpiochip_remove(&pfc->func->gpio_chip); -#endif - return 0; -} diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c b/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c index d9d9228b15fa..ff5655dee67e 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a73a4.c @@ -21,7 +21,6 @@ #include <linux/kernel.h> #include <linux/pinctrl/pinconf-generic.h> -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_PORT(fn, pfx, sfx) \ diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c index 7f7c8a6e76e8..35f436bcb849 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c @@ -22,7 +22,6 @@ #include <linux/kernel.h> #include <linux/pinctrl/pinconf-generic.h> -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_PORT(fn, pfx, sfx) \ diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c index 411d0887ba19..18ef7042b3d1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c @@ -23,7 +23,7 @@ #include <linux/io.h> #include <linux/kernel.h> #include <linux/pinctrl/pinconf-generic.h> -#include "core.h" + #include "sh_pfc.h" #define PORT_GP_PUP_1(bank, pin, fn, sfx) \ diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c index eed8daa464cc..b769c05480da 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c @@ -24,7 +24,6 @@ #include <linux/io.h> #include <linux/kernel.h> -#include "core.h" #include "sh_pfc.h" /* @@ -4696,47 +4695,6 @@ static const char * const vin3_groups[] = { "vin3_clk", }; -#define IOCTRL6 0x8c - -static int r8a7790_get_io_voltage(struct sh_pfc *pfc, unsigned int pin) -{ - u32 data, mask; - - if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin)) - return -EINVAL; - - data = ioread32(pfc->windows->virt + IOCTRL6), - /* Bits in IOCTRL6 are numbered in opposite order to pins */ - mask = 0x80000000 >> (pin & 0x1f); - - return (data & mask) ? 3300 : 1800; -} - -static int r8a7790_set_io_voltage(struct sh_pfc *pfc, unsigned int pin, u16 mV) -{ - u32 data, mask; - - if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin)) - return -EINVAL; - - if (mV != 1800 && mV != 3300) - return -EINVAL; - - data = ioread32(pfc->windows->virt + IOCTRL6); - /* Bits in IOCTRL6 are numbered in opposite order to pins */ - mask = 0x80000000 >> (pin & 0x1f); - - if (mV == 3300) - data |= mask; - else - data &= ~mask; - - iowrite32(~data, pfc->windows->virt); /* unlock reg */ - iowrite32(data, pfc->windows->virt + IOCTRL6); - - return 0; -} - static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(audio_clk), SH_PFC_FUNCTION(avb), @@ -5736,14 +5694,23 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = { { }, }; -static const struct sh_pfc_soc_operations pinmux_ops = { - .get_io_voltage = r8a7790_get_io_voltage, - .set_io_voltage = r8a7790_set_io_voltage, +static int r8a7790_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl) +{ + if (pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31)) + return -EINVAL; + + *pocctrl = 0xe606008c; + + return 31 - (pin & 0x1f); +} + +static const struct sh_pfc_soc_operations r8a7790_pinmux_ops = { + .pin_to_pocctrl = r8a7790_pin_to_pocctrl, }; const struct sh_pfc_soc_info r8a7790_pinmux_info = { .name = "r8a77900_pfc", - .ops = &pinmux_ops, + .ops = &r8a7790_pinmux_ops, .unlock_reg = 0xe6060000, /* PMMR */ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c index 01abbd5b4e49..0c1a60c9a844 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c @@ -11,7 +11,6 @@ #include <linux/kernel.h> -#include "core.h" #include "sh_pfc.h" #define CPU_ALL_PORT(fn, sfx) \ diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c index 44632b1a5c97..b74cdd310d83 100644 --- a/drivers/pinctrl/sh-pfc/pfc-r8a7795.c +++ b/drivers/pinctrl/sh-pfc/pfc-r8a7795.c @@ -17,8 +17,12 @@ PORT_GP_CFG_16(0, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ PORT_GP_CFG_28(1, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ PORT_GP_CFG_15(2, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ - PORT_GP_CFG_16(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ - PORT_GP_CFG_18(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_12(3, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_IO_VOLTAGE), \ + PORT_GP_CFG_1(3, 12, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_1(3, 13, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_1(3, 14, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_1(3, 15, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ + PORT_GP_CFG_18(4, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH | SH_PFC_PIN_CFG_IO_VOLTAGE), \ PORT_GP_CFG_26(5, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ PORT_GP_CFG_32(6, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH), \ PORT_GP_CFG_4(7, fn, sfx, SH_PFC_PIN_CFG_DRIVE_STRENGTH) @@ -552,6 +556,9 @@ static const u16 pinmux_data[] = { PINMUX_SINGLE(AVS2), PINMUX_SINGLE(HDMI0_CEC), PINMUX_SINGLE(HDMI1_CEC), + PINMUX_SINGLE(I2C_SEL_0_1), + PINMUX_SINGLE(I2C_SEL_3_1), + PINMUX_SINGLE(I2C_SEL_5_1), PINMUX_SINGLE(MSIOF0_RXD), PINMUX_SINGLE(MSIOF0_SCK), PINMUX_SINGLE(MSIOF0_TXD), @@ -1401,11 +1408,6 @@ static const u16 pinmux_data[] = { PINMUX_IPSR_MSEL(IP17_7_4, STP_ISSYNC_0_E, SEL_SSP1_0_4), PINMUX_IPSR_MSEL(IP17_7_4, RIF2_D1_B, SEL_DRIF2_1), PINMUX_IPSR_GPSR(IP17_7_4, TPU0TO3), - - /* I2C */ - PINMUX_IPSR_NOGP(0, I2C_SEL_0_1), - PINMUX_IPSR_NOGP(0, I2C_SEL_3_1), - PINMUX_IPSR_NOGP(0, I2C_SEL_5_1), }; static const struct sh_pfc_pin pinmux_pins[] = { @@ -1654,6 +1656,221 @@ static const unsigned int canfd1_data_mux[] = { CANFD1_TX_MARK, CANFD1_RX_MARK, }; +/* - DRIF0 --------------------------------------------------------------- */ +static const unsigned int drif0_ctrl_a_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9), +}; +static const unsigned int drif0_ctrl_a_mux[] = { + RIF0_CLK_A_MARK, RIF0_SYNC_A_MARK, +}; +static const unsigned int drif0_data0_a_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 10), +}; +static const unsigned int drif0_data0_a_mux[] = { + RIF0_D0_A_MARK, +}; +static const unsigned int drif0_data1_a_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 7), +}; +static const unsigned int drif0_data1_a_mux[] = { + RIF0_D1_A_MARK, +}; +static const unsigned int drif0_ctrl_b_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(5, 0), RCAR_GP_PIN(5, 4), +}; +static const unsigned int drif0_ctrl_b_mux[] = { + RIF0_CLK_B_MARK, RIF0_SYNC_B_MARK, +}; +static const unsigned int drif0_data0_b_pins[] = { + /* D0 */ + RCAR_GP_PIN(5, 1), +}; +static const unsigned int drif0_data0_b_mux[] = { + RIF0_D0_B_MARK, +}; +static const unsigned int drif0_data1_b_pins[] = { + /* D1 */ + RCAR_GP_PIN(5, 2), +}; +static const unsigned int drif0_data1_b_mux[] = { + RIF0_D1_B_MARK, +}; +static const unsigned int drif0_ctrl_c_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(5, 12), RCAR_GP_PIN(5, 15), +}; +static const unsigned int drif0_ctrl_c_mux[] = { + RIF0_CLK_C_MARK, RIF0_SYNC_C_MARK, +}; +static const unsigned int drif0_data0_c_pins[] = { + /* D0 */ + RCAR_GP_PIN(5, 13), +}; +static const unsigned int drif0_data0_c_mux[] = { + RIF0_D0_C_MARK, +}; +static const unsigned int drif0_data1_c_pins[] = { + /* D1 */ + RCAR_GP_PIN(5, 14), +}; +static const unsigned int drif0_data1_c_mux[] = { + RIF0_D1_C_MARK, +}; +/* - DRIF1 --------------------------------------------------------------- */ +static const unsigned int drif1_ctrl_a_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18), +}; +static const unsigned int drif1_ctrl_a_mux[] = { + RIF1_CLK_A_MARK, RIF1_SYNC_A_MARK, +}; +static const unsigned int drif1_data0_a_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 19), +}; +static const unsigned int drif1_data0_a_mux[] = { + RIF1_D0_A_MARK, +}; +static const unsigned int drif1_data1_a_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 20), +}; +static const unsigned int drif1_data1_a_mux[] = { + RIF1_D1_A_MARK, +}; +static const unsigned int drif1_ctrl_b_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(5, 9), RCAR_GP_PIN(5, 3), +}; +static const unsigned int drif1_ctrl_b_mux[] = { + RIF1_CLK_B_MARK, RIF1_SYNC_B_MARK, +}; +static const unsigned int drif1_data0_b_pins[] = { + /* D0 */ + RCAR_GP_PIN(5, 7), +}; +static const unsigned int drif1_data0_b_mux[] = { + RIF1_D0_B_MARK, +}; +static const unsigned int drif1_data1_b_pins[] = { + /* D1 */ + RCAR_GP_PIN(5, 8), +}; +static const unsigned int drif1_data1_b_mux[] = { + RIF1_D1_B_MARK, +}; +static const unsigned int drif1_ctrl_c_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 11), +}; +static const unsigned int drif1_ctrl_c_mux[] = { + RIF1_CLK_C_MARK, RIF1_SYNC_C_MARK, +}; +static const unsigned int drif1_data0_c_pins[] = { + /* D0 */ + RCAR_GP_PIN(5, 6), +}; +static const unsigned int drif1_data0_c_mux[] = { + RIF1_D0_C_MARK, +}; +static const unsigned int drif1_data1_c_pins[] = { + /* D1 */ + RCAR_GP_PIN(5, 10), +}; +static const unsigned int drif1_data1_c_mux[] = { + RIF1_D1_C_MARK, +}; +/* - DRIF2 --------------------------------------------------------------- */ +static const unsigned int drif2_ctrl_a_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9), +}; +static const unsigned int drif2_ctrl_a_mux[] = { + RIF2_CLK_A_MARK, RIF2_SYNC_A_MARK, +}; +static const unsigned int drif2_data0_a_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 7), +}; +static const unsigned int drif2_data0_a_mux[] = { + RIF2_D0_A_MARK, +}; +static const unsigned int drif2_data1_a_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 10), +}; +static const unsigned int drif2_data1_a_mux[] = { + RIF2_D1_A_MARK, +}; +static const unsigned int drif2_ctrl_b_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 26), RCAR_GP_PIN(6, 27), +}; +static const unsigned int drif2_ctrl_b_mux[] = { + RIF2_CLK_B_MARK, RIF2_SYNC_B_MARK, +}; +static const unsigned int drif2_data0_b_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 30), +}; +static const unsigned int drif2_data0_b_mux[] = { + RIF2_D0_B_MARK, +}; +static const unsigned int drif2_data1_b_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 31), +}; +static const unsigned int drif2_data1_b_mux[] = { + RIF2_D1_B_MARK, +}; +/* - DRIF3 --------------------------------------------------------------- */ +static const unsigned int drif3_ctrl_a_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 17), RCAR_GP_PIN(6, 18), +}; +static const unsigned int drif3_ctrl_a_mux[] = { + RIF3_CLK_A_MARK, RIF3_SYNC_A_MARK, +}; +static const unsigned int drif3_data0_a_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 19), +}; +static const unsigned int drif3_data0_a_mux[] = { + RIF3_D0_A_MARK, +}; +static const unsigned int drif3_data1_a_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 20), +}; +static const unsigned int drif3_data1_a_mux[] = { + RIF3_D1_A_MARK, +}; +static const unsigned int drif3_ctrl_b_pins[] = { + /* CLK, SYNC */ + RCAR_GP_PIN(6, 24), RCAR_GP_PIN(6, 25), +}; +static const unsigned int drif3_ctrl_b_mux[] = { + RIF3_CLK_B_MARK, RIF3_SYNC_B_MARK, +}; +static const unsigned int drif3_data0_b_pins[] = { + /* D0 */ + RCAR_GP_PIN(6, 28), +}; +static const unsigned int drif3_data0_b_mux[] = { + RIF3_D0_B_MARK, +}; +static const unsigned int drif3_data1_b_pins[] = { + /* D1 */ + RCAR_GP_PIN(6, 29), +}; +static const unsigned int drif3_data1_b_mux[] = { + RIF3_D1_B_MARK, +}; + /* - HSCIF0 ----------------------------------------------------------------- */ static const unsigned int hscif0_data_pins[] = { /* RX, TX */ @@ -3346,6 +3563,36 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { SH_PFC_PIN_GROUP(canfd0_data_a), SH_PFC_PIN_GROUP(canfd0_data_b), SH_PFC_PIN_GROUP(canfd1_data), + SH_PFC_PIN_GROUP(drif0_ctrl_a), + SH_PFC_PIN_GROUP(drif0_data0_a), + SH_PFC_PIN_GROUP(drif0_data1_a), + SH_PFC_PIN_GROUP(drif0_ctrl_b), + SH_PFC_PIN_GROUP(drif0_data0_b), + SH_PFC_PIN_GROUP(drif0_data1_b), + SH_PFC_PIN_GROUP(drif0_ctrl_c), + SH_PFC_PIN_GROUP(drif0_data0_c), + SH_PFC_PIN_GROUP(drif0_data1_c), + SH_PFC_PIN_GROUP(drif1_ctrl_a), + SH_PFC_PIN_GROUP(drif1_data0_a), + SH_PFC_PIN_GROUP(drif1_data1_a), + SH_PFC_PIN_GROUP(drif1_ctrl_b), + SH_PFC_PIN_GROUP(drif1_data0_b), + SH_PFC_PIN_GROUP(drif1_data1_b), + SH_PFC_PIN_GROUP(drif1_ctrl_c), + SH_PFC_PIN_GROUP(drif1_data0_c), + SH_PFC_PIN_GROUP(drif1_data1_c), + SH_PFC_PIN_GROUP(drif2_ctrl_a), + SH_PFC_PIN_GROUP(drif2_data0_a), + SH_PFC_PIN_GROUP(drif2_data1_a), + SH_PFC_PIN_GROUP(drif2_ctrl_b), + SH_PFC_PIN_GROUP(drif2_data0_b), + SH_PFC_PIN_GROUP(drif2_data1_b), + SH_PFC_PIN_GROUP(drif3_ctrl_a), + SH_PFC_PIN_GROUP(drif3_data0_a), + SH_PFC_PIN_GROUP(drif3_data1_a), + SH_PFC_PIN_GROUP(drif3_ctrl_b), + SH_PFC_PIN_GROUP(drif3_data0_b), + SH_PFC_PIN_GROUP(drif3_data1_b), SH_PFC_PIN_GROUP(hscif0_data), SH_PFC_PIN_GROUP(hscif0_clk), SH_PFC_PIN_GROUP(hscif0_ctrl), @@ -3629,6 +3876,48 @@ static const char * const canfd1_groups[] = { "canfd1_data", }; +static const char * const drif0_groups[] = { + "drif0_ctrl_a", + "drif0_data0_a", + "drif0_data1_a", + "drif0_ctrl_b", + "drif0_data0_b", + "drif0_data1_b", + "drif0_ctrl_c", + "drif0_data0_c", + "drif0_data1_c", +}; + +static const char * const drif1_groups[] = { + "drif1_ctrl_a", + "drif1_data0_a", + "drif1_data1_a", + "drif1_ctrl_b", + "drif1_data0_b", + "drif1_data1_b", + "drif1_ctrl_c", + "drif1_data0_c", + "drif1_data1_c", +}; + +static const char * const drif2_groups[] = { + "drif2_ctrl_a", + "drif2_data0_a", + "drif2_data1_a", + "drif2_ctrl_b", + "drif2_data0_b", + "drif2_data1_b", +}; + +static const char * const drif3_groups[] = { + "drif3_ctrl_a", + "drif3_data0_a", + "drif3_data1_a", + "drif3_ctrl_b", + "drif3_data0_b", + "drif3_data1_b", +}; + static const char * const hscif0_groups[] = { "hscif0_data", "hscif0_clk", @@ -3972,6 +4261,10 @@ static const struct sh_pfc_function pinmux_functions[] = { SH_PFC_FUNCTION(can_clk), SH_PFC_FUNCTION(canfd0), SH_PFC_FUNCTION(canfd1), + SH_PFC_FUNCTION(drif0), + SH_PFC_FUNCTION(drif1), + SH_PFC_FUNCTION(drif2), + SH_PFC_FUNCTION(drif3), SH_PFC_FUNCTION(hscif0), SH_PFC_FUNCTION(hscif1), SH_PFC_FUNCTION(hscif2), @@ -4765,8 +5058,28 @@ static const struct pinmux_drive_reg pinmux_drive_regs[] = { { }, }; +static int r8a7795_pin_to_pocctrl(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl) +{ + int bit = -EINVAL; + + *pocctrl = 0xe6060380; + + if (pin >= RCAR_GP_PIN(3, 0) && pin <= RCAR_GP_PIN(3, 11)) + bit = pin & 0x1f; + + if (pin >= RCAR_GP_PIN(4, 0) && pin <= RCAR_GP_PIN(4, 17)) + bit = (pin & 0x1f) + 12; + + return bit; +} + +static const struct sh_pfc_soc_operations r8a7795_pinmux_ops = { + .pin_to_pocctrl = r8a7795_pin_to_pocctrl, +}; + const struct sh_pfc_soc_info r8a7795_pinmux_info = { .name = "r8a77950_pfc", + .ops = &r8a7795_pinmux_ops, .unlock_reg = 0xe6060000, /* PMMR */ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7757.c b/drivers/pinctrl/sh-pfc/pfc-sh7757.c index 0555a1fe076e..6d8c31caefc1 100644 --- a/drivers/pinctrl/sh-pfc/pfc-sh7757.c +++ b/drivers/pinctrl/sh-pfc/pfc-sh7757.c @@ -1625,7 +1625,6 @@ static const struct pinmux_func pinmux_func_gpios[] = { GPIO_FN(VBIOS_CS), /* PTW (mobule: LBSC, EVC, SCIF) */ - GPIO_FN(A16), GPIO_FN(A15), GPIO_FN(A14), GPIO_FN(A13), diff --git a/drivers/pinctrl/sh-pfc/pinctrl.c b/drivers/pinctrl/sh-pfc/pinctrl.c index fdb445d68b9a..e208ee04a9f4 100644 --- a/drivers/pinctrl/sh-pfc/pinctrl.c +++ b/drivers/pinctrl/sh-pfc/pinctrl.c @@ -632,19 +632,21 @@ static int sh_pfc_pinconf_get(struct pinctrl_dev *pctldev, unsigned _pin, } case PIN_CONFIG_POWER_SOURCE: { - int ret; + u32 pocctrl, val; + int bit; - if (!pfc->info->ops || !pfc->info->ops->get_io_voltage) + if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl) return -ENOTSUPP; + bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl); + if (WARN(bit < 0, "invalid pin %#x", _pin)) + return bit; + spin_lock_irqsave(&pfc->lock, flags); - ret = pfc->info->ops->get_io_voltage(pfc, _pin); + val = sh_pfc_read_reg(pfc, pocctrl, 32); spin_unlock_irqrestore(&pfc->lock, flags); - if (ret < 0) - return ret; - - *config = ret; + *config = (val & BIT(bit)) ? 3300 : 1800; break; } @@ -696,20 +698,29 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned _pin, } case PIN_CONFIG_POWER_SOURCE: { - unsigned int arg = - pinconf_to_config_argument(configs[i]); - int ret; + unsigned int mV = pinconf_to_config_argument(configs[i]); + u32 pocctrl, val; + int bit; - if (!pfc->info->ops || !pfc->info->ops->set_io_voltage) + if (!pfc->info->ops || !pfc->info->ops->pin_to_pocctrl) return -ENOTSUPP; + bit = pfc->info->ops->pin_to_pocctrl(pfc, _pin, &pocctrl); + if (WARN(bit < 0, "invalid pin %#x", _pin)) + return bit; + + if (mV != 1800 && mV != 3300) + return -EINVAL; + spin_lock_irqsave(&pfc->lock, flags); - ret = pfc->info->ops->set_io_voltage(pfc, _pin, arg); + val = sh_pfc_read_reg(pfc, pocctrl, 32); + if (mV == 3300) + val |= BIT(bit); + else + val &= ~BIT(bit); + sh_pfc_write_reg(pfc, pocctrl, 32, val); spin_unlock_irqrestore(&pfc->lock, flags); - if (ret) - return ret; - break; } @@ -803,8 +814,5 @@ int sh_pfc_register_pinctrl(struct sh_pfc *pfc) pmx->pctl_desc.npins = pfc->info->nr_pins; pmx->pctl = devm_pinctrl_register(pfc->dev, &pmx->pctl_desc, pmx); - if (IS_ERR(pmx->pctl)) - return PTR_ERR(pmx->pctl); - - return 0; + return PTR_ERR_OR_ZERO(pmx->pctl); } diff --git a/drivers/pinctrl/sh-pfc/sh_pfc.h b/drivers/pinctrl/sh-pfc/sh_pfc.h index 656ea32f776c..5e966c09434d 100644 --- a/drivers/pinctrl/sh-pfc/sh_pfc.h +++ b/drivers/pinctrl/sh-pfc/sh_pfc.h @@ -13,6 +13,7 @@ #include <linux/bug.h> #include <linux/pinctrl/pinconf-generic.h> +#include <linux/spinlock.h> #include <linux/stringify.h> enum { @@ -182,16 +183,38 @@ struct pinmux_range { u16 force; }; -struct sh_pfc; +struct sh_pfc_window { + phys_addr_t phys; + void __iomem *virt; + unsigned long size; +}; + +struct sh_pfc_pin_range; + +struct sh_pfc { + struct device *dev; + const struct sh_pfc_soc_info *info; + spinlock_t lock; + + unsigned int num_windows; + struct sh_pfc_window *windows; + unsigned int num_irqs; + unsigned int *irqs; + + struct sh_pfc_pin_range *ranges; + unsigned int nr_ranges; + + unsigned int nr_gpio_pins; + + struct sh_pfc_chip *gpio; +}; struct sh_pfc_soc_operations { int (*init)(struct sh_pfc *pfc); unsigned int (*get_bias)(struct sh_pfc *pfc, unsigned int pin); void (*set_bias)(struct sh_pfc *pfc, unsigned int pin, unsigned int bias); - int (*get_io_voltage)(struct sh_pfc *pfc, unsigned int pin); - int (*set_io_voltage)(struct sh_pfc *pfc, unsigned int pin, - u16 voltage_mV); + int (*pin_to_pocctrl)(struct sh_pfc *pfc, unsigned int pin, u32 *pocctrl); }; struct sh_pfc_soc_info { @@ -227,6 +250,30 @@ struct sh_pfc_soc_info { u32 unlock_reg; }; +extern const struct sh_pfc_soc_info emev2_pinmux_info; +extern const struct sh_pfc_soc_info r8a73a4_pinmux_info; +extern const struct sh_pfc_soc_info r8a7740_pinmux_info; +extern const struct sh_pfc_soc_info r8a7778_pinmux_info; +extern const struct sh_pfc_soc_info r8a7779_pinmux_info; +extern const struct sh_pfc_soc_info r8a7790_pinmux_info; +extern const struct sh_pfc_soc_info r8a7791_pinmux_info; +extern const struct sh_pfc_soc_info r8a7793_pinmux_info; +extern const struct sh_pfc_soc_info r8a7794_pinmux_info; +extern const struct sh_pfc_soc_info r8a7795_pinmux_info; +extern const struct sh_pfc_soc_info sh7203_pinmux_info; +extern const struct sh_pfc_soc_info sh7264_pinmux_info; +extern const struct sh_pfc_soc_info sh7269_pinmux_info; +extern const struct sh_pfc_soc_info sh73a0_pinmux_info; +extern const struct sh_pfc_soc_info sh7720_pinmux_info; +extern const struct sh_pfc_soc_info sh7722_pinmux_info; +extern const struct sh_pfc_soc_info sh7723_pinmux_info; +extern const struct sh_pfc_soc_info sh7724_pinmux_info; +extern const struct sh_pfc_soc_info sh7734_pinmux_info; +extern const struct sh_pfc_soc_info sh7757_pinmux_info; +extern const struct sh_pfc_soc_info sh7785_pinmux_info; +extern const struct sh_pfc_soc_info sh7786_pinmux_info; +extern const struct sh_pfc_soc_info shx3_pinmux_info; + /* ----------------------------------------------------------------------------- * Helper macros to create pin and port lists */ diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c index 168c0f5d4079..19952f73fa8c 100644 --- a/drivers/pinctrl/sirf/pinctrl-atlas7.c +++ b/drivers/pinctrl/sirf/pinctrl-atlas7.c @@ -5424,8 +5424,10 @@ static int atlas7_pinmux_probe(struct platform_device *pdev) if (ret) return ret; pmx->sys2pci_base = devm_ioremap_resource(&pdev->dev, &res); - if (IS_ERR(pmx->sys2pci_base)) + if (IS_ERR(pmx->sys2pci_base)) { + of_node_put(sys2pci_np); return -ENOMEM; + } pmx->dev = &pdev->dev; diff --git a/drivers/pinctrl/stm32/Kconfig b/drivers/pinctrl/stm32/Kconfig index 0f28841b2332..4c40dae384d1 100644 --- a/drivers/pinctrl/stm32/Kconfig +++ b/drivers/pinctrl/stm32/Kconfig @@ -13,4 +13,10 @@ config PINCTRL_STM32F429 default MACH_STM32F429 select PINCTRL_STM32 +config PINCTRL_STM32F746 + bool "STMicroelectronics STM32F746 pin control" if COMPILE_TEST && !MACH_STM32F746 + depends on OF + default MACH_STM32F746 + select PINCTRL_STM32 + endif diff --git a/drivers/pinctrl/stm32/Makefile b/drivers/pinctrl/stm32/Makefile index fc17d4238845..4a1ee748441f 100644 --- a/drivers/pinctrl/stm32/Makefile +++ b/drivers/pinctrl/stm32/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_PINCTRL_STM32) += pinctrl-stm32.o # SoC Drivers obj-$(CONFIG_PINCTRL_STM32F429) += pinctrl-stm32f429.o +obj-$(CONFIG_PINCTRL_STM32F746) += pinctrl-stm32f746.o diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index ae9fab82a1b9..4ae596bf19b5 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -638,8 +638,8 @@ static u32 stm32_pconf_get_bias(struct stm32_gpio_bank *bank, return (val >> (offset * 2)); } -static bool stm32_pconf_input_get(struct stm32_gpio_bank *bank, - unsigned int offset) +static bool stm32_pconf_get(struct stm32_gpio_bank *bank, + unsigned int offset, bool dir) { unsigned long flags; u32 val; @@ -647,23 +647,12 @@ static bool stm32_pconf_input_get(struct stm32_gpio_bank *bank, clk_enable(bank->clk); spin_lock_irqsave(&bank->lock, flags); - val = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & BIT(offset)); - - spin_unlock_irqrestore(&bank->lock, flags); - clk_disable(bank->clk); - - return val; -} - -static bool stm32_pconf_output_get(struct stm32_gpio_bank *bank, - unsigned int offset) -{ - unsigned long flags; - u32 val; - - clk_enable(bank->clk); - spin_lock_irqsave(&bank->lock, flags); - val = !!(readl_relaxed(bank->base + STM32_GPIO_ODR) & BIT(offset)); + if (dir) + val = !!(readl_relaxed(bank->base + STM32_GPIO_IDR) & + BIT(offset)); + else + val = !!(readl_relaxed(bank->base + STM32_GPIO_ODR) & + BIT(offset)); spin_unlock_irqrestore(&bank->lock, flags); clk_disable(bank->clk); @@ -772,7 +761,7 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev, switch (mode) { /* input */ case 0: - val = stm32_pconf_input_get(bank, offset); + val = stm32_pconf_get(bank, offset, true); seq_printf(s, "- %s - %s", val ? "high" : "low", biasing[bias]); @@ -782,7 +771,7 @@ static void stm32_pconf_dbg_show(struct pinctrl_dev *pctldev, case 1: drive = stm32_pconf_get_driving(bank, offset); speed = stm32_pconf_get_speed(bank, offset); - val = stm32_pconf_output_get(bank, offset); + val = stm32_pconf_get(bank, offset, false); seq_printf(s, "- %s - %s - %s - %s %s", val ? "high" : "low", drive ? "open drain" : "push pull", diff --git a/drivers/pinctrl/stm32/pinctrl-stm32f746.c b/drivers/pinctrl/stm32/pinctrl-stm32f746.c new file mode 100644 index 000000000000..c0b4462ce97e --- /dev/null +++ b/drivers/pinctrl/stm32/pinctrl-stm32f746.c @@ -0,0 +1,1681 @@ +/* + * Copyright (C) Maxime Coquelin 2015 + * Author: Maxime Coquelin <mcoquelin.stm32@gmail.com> + * License terms: GNU General Public License (GPL), version 2 + */ +#include <linux/init.h> +#include <linux/of.h> +#include <linux/platform_device.h> + +#include "pinctrl-stm32.h" + +static const struct stm32_desc_pin stm32f746_pins[] = { + STM32_PIN( + PINCTRL_PIN(0, "PA0"), + STM32_FUNCTION(0, "GPIOA0"), + STM32_FUNCTION(2, "TIM2_CH1 TIM2_ETR"), + STM32_FUNCTION(3, "TIM5_CH1"), + STM32_FUNCTION(4, "TIM8_ETR"), + STM32_FUNCTION(8, "USART2_CTS"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(11, "SAI2_SD_B"), + STM32_FUNCTION(12, "ETH_MII_CRS"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(1, "PA1"), + STM32_FUNCTION(0, "GPIOA1"), + STM32_FUNCTION(2, "TIM2_CH2"), + STM32_FUNCTION(3, "TIM5_CH2"), + STM32_FUNCTION(8, "USART2_RTS"), + STM32_FUNCTION(9, "UART4_RX"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO3"), + STM32_FUNCTION(11, "SAI2_MCLK_B"), + STM32_FUNCTION(12, "ETH_MII_RX_CLK ETH_RMII_REF_CLK"), + STM32_FUNCTION(15, "LCD_R2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(2, "PA2"), + STM32_FUNCTION(0, "GPIOA2"), + STM32_FUNCTION(2, "TIM2_CH3"), + STM32_FUNCTION(3, "TIM5_CH3"), + STM32_FUNCTION(4, "TIM9_CH1"), + STM32_FUNCTION(8, "USART2_TX"), + STM32_FUNCTION(9, "SAI2_SCK_B"), + STM32_FUNCTION(12, "ETH_MDIO"), + STM32_FUNCTION(15, "LCD_R1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(3, "PA3"), + STM32_FUNCTION(0, "GPIOA3"), + STM32_FUNCTION(2, "TIM2_CH4"), + STM32_FUNCTION(3, "TIM5_CH4"), + STM32_FUNCTION(4, "TIM9_CH2"), + STM32_FUNCTION(8, "USART2_RX"), + STM32_FUNCTION(11, "OTG_HS_ULPI_D0"), + STM32_FUNCTION(12, "ETH_MII_COL"), + STM32_FUNCTION(15, "LCD_B5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(4, "PA4"), + STM32_FUNCTION(0, "GPIOA4"), + STM32_FUNCTION(6, "SPI1_NSS I2S1_WS"), + STM32_FUNCTION(7, "SPI3_NSS I2S3_WS"), + STM32_FUNCTION(8, "USART2_CK"), + STM32_FUNCTION(13, "OTG_HS_SOF"), + STM32_FUNCTION(14, "DCMI_HSYNC"), + STM32_FUNCTION(15, "LCD_VSYNC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(5, "PA5"), + STM32_FUNCTION(0, "GPIOA5"), + STM32_FUNCTION(2, "TIM2_CH1 TIM2_ETR"), + STM32_FUNCTION(4, "TIM8_CH1N"), + STM32_FUNCTION(6, "SPI1_SCK I2S1_CK"), + STM32_FUNCTION(11, "OTG_HS_ULPI_CK"), + STM32_FUNCTION(15, "LCD_R4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(6, "PA6"), + STM32_FUNCTION(0, "GPIOA6"), + STM32_FUNCTION(2, "TIM1_BKIN"), + STM32_FUNCTION(3, "TIM3_CH1"), + STM32_FUNCTION(4, "TIM8_BKIN"), + STM32_FUNCTION(6, "SPI1_MISO"), + STM32_FUNCTION(10, "TIM13_CH1"), + STM32_FUNCTION(14, "DCMI_PIXCLK"), + STM32_FUNCTION(15, "LCD_G2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(7, "PA7"), + STM32_FUNCTION(0, "GPIOA7"), + STM32_FUNCTION(2, "TIM1_CH1N"), + STM32_FUNCTION(3, "TIM3_CH2"), + STM32_FUNCTION(4, "TIM8_CH1N"), + STM32_FUNCTION(6, "SPI1_MOSI I2S1_SD"), + STM32_FUNCTION(10, "TIM14_CH1"), + STM32_FUNCTION(12, "ETH_MII_RX_DV ETH_RMII_CRS_DV"), + STM32_FUNCTION(13, "FMC_SDNWE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(8, "PA8"), + STM32_FUNCTION(0, "GPIOA8"), + STM32_FUNCTION(1, "MCO1"), + STM32_FUNCTION(2, "TIM1_CH1"), + STM32_FUNCTION(4, "TIM8_BKIN2"), + STM32_FUNCTION(5, "I2C3_SCL"), + STM32_FUNCTION(8, "USART1_CK"), + STM32_FUNCTION(11, "OTG_FS_SOF"), + STM32_FUNCTION(15, "LCD_R6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(9, "PA9"), + STM32_FUNCTION(0, "GPIOA9"), + STM32_FUNCTION(2, "TIM1_CH2"), + STM32_FUNCTION(5, "I2C3_SMBA"), + STM32_FUNCTION(6, "SPI2_SCK I2S2_CK"), + STM32_FUNCTION(8, "USART1_TX"), + STM32_FUNCTION(14, "DCMI_D0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(10, "PA10"), + STM32_FUNCTION(0, "GPIOA10"), + STM32_FUNCTION(2, "TIM1_CH3"), + STM32_FUNCTION(8, "USART1_RX"), + STM32_FUNCTION(11, "OTG_FS_ID"), + STM32_FUNCTION(14, "DCMI_D1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(11, "PA11"), + STM32_FUNCTION(0, "GPIOA11"), + STM32_FUNCTION(2, "TIM1_CH4"), + STM32_FUNCTION(8, "USART1_CTS"), + STM32_FUNCTION(10, "CAN1_RX"), + STM32_FUNCTION(11, "OTG_FS_DM"), + STM32_FUNCTION(15, "LCD_R4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(12, "PA12"), + STM32_FUNCTION(0, "GPIOA12"), + STM32_FUNCTION(2, "TIM1_ETR"), + STM32_FUNCTION(8, "USART1_RTS"), + STM32_FUNCTION(9, "SAI2_FS_B"), + STM32_FUNCTION(10, "CAN1_TX"), + STM32_FUNCTION(11, "OTG_FS_DP"), + STM32_FUNCTION(15, "LCD_R5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(13, "PA13"), + STM32_FUNCTION(0, "GPIOA13"), + STM32_FUNCTION(1, "JTMS SWDIO"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(14, "PA14"), + STM32_FUNCTION(0, "GPIOA14"), + STM32_FUNCTION(1, "JTCK SWCLK"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(15, "PA15"), + STM32_FUNCTION(0, "GPIOA15"), + STM32_FUNCTION(1, "JTDI"), + STM32_FUNCTION(2, "TIM2_CH1 TIM2_ETR"), + STM32_FUNCTION(5, "HDMI_CEC"), + STM32_FUNCTION(6, "SPI1_NSS I2S1_WS"), + STM32_FUNCTION(7, "SPI3_NSS I2S3_WS"), + STM32_FUNCTION(9, "UART4_RTS"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(16, "PB0"), + STM32_FUNCTION(0, "GPIOB0"), + STM32_FUNCTION(2, "TIM1_CH2N"), + STM32_FUNCTION(3, "TIM3_CH3"), + STM32_FUNCTION(4, "TIM8_CH2N"), + STM32_FUNCTION(9, "UART4_CTS"), + STM32_FUNCTION(10, "LCD_R3"), + STM32_FUNCTION(11, "OTG_HS_ULPI_D1"), + STM32_FUNCTION(12, "ETH_MII_RXD2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(17, "PB1"), + STM32_FUNCTION(0, "GPIOB1"), + STM32_FUNCTION(2, "TIM1_CH3N"), + STM32_FUNCTION(3, "TIM3_CH4"), + STM32_FUNCTION(4, "TIM8_CH3N"), + STM32_FUNCTION(10, "LCD_R6"), + STM32_FUNCTION(11, "OTG_HS_ULPI_D2"), + STM32_FUNCTION(12, "ETH_MII_RXD3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(18, "PB2"), + STM32_FUNCTION(0, "GPIOB2"), + STM32_FUNCTION(7, "SAI1_SD_A"), + STM32_FUNCTION(8, "SPI3_MOSI I2S3_SD"), + STM32_FUNCTION(10, "QUADSPI_CLK"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(19, "PB3"), + STM32_FUNCTION(0, "GPIOB3"), + STM32_FUNCTION(1, "JTDO TRACESWO"), + STM32_FUNCTION(2, "TIM2_CH2"), + STM32_FUNCTION(6, "SPI1_SCK I2S1_CK"), + STM32_FUNCTION(7, "SPI3_SCK I2S3_CK"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(20, "PB4"), + STM32_FUNCTION(0, "GPIOB4"), + STM32_FUNCTION(1, "NJTRST"), + STM32_FUNCTION(3, "TIM3_CH1"), + STM32_FUNCTION(6, "SPI1_MISO"), + STM32_FUNCTION(7, "SPI3_MISO"), + STM32_FUNCTION(8, "SPI2_NSS I2S2_WS"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(21, "PB5"), + STM32_FUNCTION(0, "GPIOB5"), + STM32_FUNCTION(3, "TIM3_CH2"), + STM32_FUNCTION(5, "I2C1_SMBA"), + STM32_FUNCTION(6, "SPI1_MOSI I2S1_SD"), + STM32_FUNCTION(7, "SPI3_MOSI I2S3_SD"), + STM32_FUNCTION(10, "CAN2_RX"), + STM32_FUNCTION(11, "OTG_HS_ULPI_D7"), + STM32_FUNCTION(12, "ETH_PPS_OUT"), + STM32_FUNCTION(13, "FMC_SDCKE1"), + STM32_FUNCTION(14, "DCMI_D10"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(22, "PB6"), + STM32_FUNCTION(0, "GPIOB6"), + STM32_FUNCTION(3, "TIM4_CH1"), + STM32_FUNCTION(4, "HDMI_CEC"), + STM32_FUNCTION(5, "I2C1_SCL"), + STM32_FUNCTION(8, "USART1_TX"), + STM32_FUNCTION(10, "CAN2_TX"), + STM32_FUNCTION(11, "QUADSPI_BK1_NCS"), + STM32_FUNCTION(13, "FMC_SDNE1"), + STM32_FUNCTION(14, "DCMI_D5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(23, "PB7"), + STM32_FUNCTION(0, "GPIOB7"), + STM32_FUNCTION(3, "TIM4_CH2"), + STM32_FUNCTION(5, "I2C1_SDA"), + STM32_FUNCTION(8, "USART1_RX"), + STM32_FUNCTION(13, "FMC_NL"), + STM32_FUNCTION(14, "DCMI_VSYNC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(24, "PB8"), + STM32_FUNCTION(0, "GPIOB8"), + STM32_FUNCTION(3, "TIM4_CH3"), + STM32_FUNCTION(4, "TIM10_CH1"), + STM32_FUNCTION(5, "I2C1_SCL"), + STM32_FUNCTION(10, "CAN1_RX"), + STM32_FUNCTION(12, "ETH_MII_TXD3"), + STM32_FUNCTION(13, "SDMMC1_D4"), + STM32_FUNCTION(14, "DCMI_D6"), + STM32_FUNCTION(15, "LCD_B6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(25, "PB9"), + STM32_FUNCTION(0, "GPIOB9"), + STM32_FUNCTION(3, "TIM4_CH4"), + STM32_FUNCTION(4, "TIM11_CH1"), + STM32_FUNCTION(5, "I2C1_SDA"), + STM32_FUNCTION(6, "SPI2_NSS I2S2_WS"), + STM32_FUNCTION(10, "CAN1_TX"), + STM32_FUNCTION(13, "SDMMC1_D5"), + STM32_FUNCTION(14, "DCMI_D7"), + STM32_FUNCTION(15, "LCD_B7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(26, "PB10"), + STM32_FUNCTION(0, "GPIOB10"), + STM32_FUNCTION(2, "TIM2_CH3"), + STM32_FUNCTION(5, "I2C2_SCL"), + STM32_FUNCTION(6, "SPI2_SCK I2S2_CK"), + STM32_FUNCTION(8, "USART3_TX"), + STM32_FUNCTION(11, "OTG_HS_ULPI_D3"), + STM32_FUNCTION(12, "ETH_MII_RX_ER"), + STM32_FUNCTION(15, "LCD_G4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(27, "PB11"), + STM32_FUNCTION(0, "GPIOB11"), + STM32_FUNCTION(2, "TIM2_CH4"), + STM32_FUNCTION(5, "I2C2_SDA"), + STM32_FUNCTION(8, "USART3_RX"), + STM32_FUNCTION(11, "OTG_HS_ULPI_D4"), + STM32_FUNCTION(12, "ETH_MII_TX_EN ETH_RMII_TX_EN"), + STM32_FUNCTION(15, "LCD_G5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(28, "PB12"), + STM32_FUNCTION(0, "GPIOB12"), + STM32_FUNCTION(2, "TIM1_BKIN"), + STM32_FUNCTION(5, "I2C2_SMBA"), + STM32_FUNCTION(6, "SPI2_NSS I2S2_WS"), + STM32_FUNCTION(8, "USART3_CK"), + STM32_FUNCTION(10, "CAN2_RX"), + STM32_FUNCTION(11, "OTG_HS_ULPI_D5"), + STM32_FUNCTION(12, "ETH_MII_TXD0 ETH_RMII_TXD0"), + STM32_FUNCTION(13, "OTG_HS_ID"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(29, "PB13"), + STM32_FUNCTION(0, "GPIOB13"), + STM32_FUNCTION(2, "TIM1_CH1N"), + STM32_FUNCTION(6, "SPI2_SCK I2S2_CK"), + STM32_FUNCTION(8, "USART3_CTS"), + STM32_FUNCTION(10, "CAN2_TX"), + STM32_FUNCTION(11, "OTG_HS_ULPI_D6"), + STM32_FUNCTION(12, "ETH_MII_TXD1 ETH_RMII_TXD1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(30, "PB14"), + STM32_FUNCTION(0, "GPIOB14"), + STM32_FUNCTION(2, "TIM1_CH2N"), + STM32_FUNCTION(4, "TIM8_CH2N"), + STM32_FUNCTION(6, "SPI2_MISO"), + STM32_FUNCTION(8, "USART3_RTS"), + STM32_FUNCTION(10, "TIM12_CH1"), + STM32_FUNCTION(13, "OTG_HS_DM"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(31, "PB15"), + STM32_FUNCTION(0, "GPIOB15"), + STM32_FUNCTION(1, "RTC_REFIN"), + STM32_FUNCTION(2, "TIM1_CH3N"), + STM32_FUNCTION(4, "TIM8_CH3N"), + STM32_FUNCTION(6, "SPI2_MOSI I2S2_SD"), + STM32_FUNCTION(10, "TIM12_CH2"), + STM32_FUNCTION(13, "OTG_HS_DP"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(32, "PC0"), + STM32_FUNCTION(0, "GPIOC0"), + STM32_FUNCTION(9, "SAI2_FS_B"), + STM32_FUNCTION(11, "OTG_HS_ULPI_STP"), + STM32_FUNCTION(13, "FMC_SDNWE"), + STM32_FUNCTION(15, "LCD_R5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(33, "PC1"), + STM32_FUNCTION(0, "GPIOC1"), + STM32_FUNCTION(1, "TRACED0"), + STM32_FUNCTION(6, "SPI2_MOSI I2S2_SD"), + STM32_FUNCTION(7, "SAI1_SD_A"), + STM32_FUNCTION(12, "ETH_MDC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(34, "PC2"), + STM32_FUNCTION(0, "GPIOC2"), + STM32_FUNCTION(6, "SPI2_MISO"), + STM32_FUNCTION(11, "OTG_HS_ULPI_DIR"), + STM32_FUNCTION(12, "ETH_MII_TXD2"), + STM32_FUNCTION(13, "FMC_SDNE0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(35, "PC3"), + STM32_FUNCTION(0, "GPIOC3"), + STM32_FUNCTION(6, "SPI2_MOSI I2S2_SD"), + STM32_FUNCTION(11, "OTG_HS_ULPI_NXT"), + STM32_FUNCTION(12, "ETH_MII_TX_CLK"), + STM32_FUNCTION(13, "FMC_SDCKE0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(36, "PC4"), + STM32_FUNCTION(0, "GPIOC4"), + STM32_FUNCTION(6, "I2S1_MCK"), + STM32_FUNCTION(9, "SPDIFRX_IN2"), + STM32_FUNCTION(12, "ETH_MII_RXD0 ETH_RMII_RXD0"), + STM32_FUNCTION(13, "FMC_SDNE0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(37, "PC5"), + STM32_FUNCTION(0, "GPIOC5"), + STM32_FUNCTION(9, "SPDIFRX_IN3"), + STM32_FUNCTION(12, "ETH_MII_RXD1 ETH_RMII_RXD1"), + STM32_FUNCTION(13, "FMC_SDCKE0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(38, "PC6"), + STM32_FUNCTION(0, "GPIOC6"), + STM32_FUNCTION(3, "TIM3_CH1"), + STM32_FUNCTION(4, "TIM8_CH1"), + STM32_FUNCTION(6, "I2S2_MCK"), + STM32_FUNCTION(9, "USART6_TX"), + STM32_FUNCTION(13, "SDMMC1_D6"), + STM32_FUNCTION(14, "DCMI_D0"), + STM32_FUNCTION(15, "LCD_HSYNC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(39, "PC7"), + STM32_FUNCTION(0, "GPIOC7"), + STM32_FUNCTION(3, "TIM3_CH2"), + STM32_FUNCTION(4, "TIM8_CH2"), + STM32_FUNCTION(7, "I2S3_MCK"), + STM32_FUNCTION(9, "USART6_RX"), + STM32_FUNCTION(13, "SDMMC1_D7"), + STM32_FUNCTION(14, "DCMI_D1"), + STM32_FUNCTION(15, "LCD_G6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(40, "PC8"), + STM32_FUNCTION(0, "GPIOC8"), + STM32_FUNCTION(1, "TRACED1"), + STM32_FUNCTION(3, "TIM3_CH3"), + STM32_FUNCTION(4, "TIM8_CH3"), + STM32_FUNCTION(8, "UART5_RTS"), + STM32_FUNCTION(9, "USART6_CK"), + STM32_FUNCTION(13, "SDMMC1_D0"), + STM32_FUNCTION(14, "DCMI_D2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(41, "PC9"), + STM32_FUNCTION(0, "GPIOC9"), + STM32_FUNCTION(1, "MCO2"), + STM32_FUNCTION(3, "TIM3_CH4"), + STM32_FUNCTION(4, "TIM8_CH4"), + STM32_FUNCTION(5, "I2C3_SDA"), + STM32_FUNCTION(6, "I2S_CKIN"), + STM32_FUNCTION(8, "UART5_CTS"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO0"), + STM32_FUNCTION(13, "SDMMC1_D1"), + STM32_FUNCTION(14, "DCMI_D3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(42, "PC10"), + STM32_FUNCTION(0, "GPIOC10"), + STM32_FUNCTION(7, "SPI3_SCK I2S3_CK"), + STM32_FUNCTION(8, "USART3_TX"), + STM32_FUNCTION(9, "UART4_TX"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO1"), + STM32_FUNCTION(13, "SDMMC1_D2"), + STM32_FUNCTION(14, "DCMI_D8"), + STM32_FUNCTION(15, "LCD_R2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(43, "PC11"), + STM32_FUNCTION(0, "GPIOC11"), + STM32_FUNCTION(7, "SPI3_MISO"), + STM32_FUNCTION(8, "USART3_RX"), + STM32_FUNCTION(9, "UART4_RX"), + STM32_FUNCTION(10, "QUADSPI_BK2_NCS"), + STM32_FUNCTION(13, "SDMMC1_D3"), + STM32_FUNCTION(14, "DCMI_D4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(44, "PC12"), + STM32_FUNCTION(0, "GPIOC12"), + STM32_FUNCTION(1, "TRACED3"), + STM32_FUNCTION(7, "SPI3_MOSI I2S3_SD"), + STM32_FUNCTION(8, "USART3_CK"), + STM32_FUNCTION(9, "UART5_TX"), + STM32_FUNCTION(13, "SDMMC1_CK"), + STM32_FUNCTION(14, "DCMI_D9"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(45, "PC13"), + STM32_FUNCTION(0, "GPIOC13"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(46, "PC14"), + STM32_FUNCTION(0, "GPIOC14"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(47, "PC15"), + STM32_FUNCTION(0, "GPIOC15"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(48, "PD0"), + STM32_FUNCTION(0, "GPIOD0"), + STM32_FUNCTION(10, "CAN1_RX"), + STM32_FUNCTION(13, "FMC_D2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(49, "PD1"), + STM32_FUNCTION(0, "GPIOD1"), + STM32_FUNCTION(10, "CAN1_TX"), + STM32_FUNCTION(13, "FMC_D3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(50, "PD2"), + STM32_FUNCTION(0, "GPIOD2"), + STM32_FUNCTION(1, "TRACED2"), + STM32_FUNCTION(3, "TIM3_ETR"), + STM32_FUNCTION(9, "UART5_RX"), + STM32_FUNCTION(13, "SDMMC1_CMD"), + STM32_FUNCTION(14, "DCMI_D11"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(51, "PD3"), + STM32_FUNCTION(0, "GPIOD3"), + STM32_FUNCTION(6, "SPI2_SCK I2S2_CK"), + STM32_FUNCTION(8, "USART2_CTS"), + STM32_FUNCTION(13, "FMC_CLK"), + STM32_FUNCTION(14, "DCMI_D5"), + STM32_FUNCTION(15, "LCD_G7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(52, "PD4"), + STM32_FUNCTION(0, "GPIOD4"), + STM32_FUNCTION(8, "USART2_RTS"), + STM32_FUNCTION(13, "FMC_NOE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(53, "PD5"), + STM32_FUNCTION(0, "GPIOD5"), + STM32_FUNCTION(8, "USART2_TX"), + STM32_FUNCTION(13, "FMC_NWE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(54, "PD6"), + STM32_FUNCTION(0, "GPIOD6"), + STM32_FUNCTION(6, "SPI3_MOSI I2S3_SD"), + STM32_FUNCTION(7, "SAI1_SD_A"), + STM32_FUNCTION(8, "USART2_RX"), + STM32_FUNCTION(13, "FMC_NWAIT"), + STM32_FUNCTION(14, "DCMI_D10"), + STM32_FUNCTION(15, "LCD_B2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(55, "PD7"), + STM32_FUNCTION(0, "GPIOD7"), + STM32_FUNCTION(8, "USART2_CK"), + STM32_FUNCTION(9, "SPDIFRX_IN0"), + STM32_FUNCTION(13, "FMC_NE1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(56, "PD8"), + STM32_FUNCTION(0, "GPIOD8"), + STM32_FUNCTION(8, "USART3_TX"), + STM32_FUNCTION(9, "SPDIFRX_IN1"), + STM32_FUNCTION(13, "FMC_D13"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(57, "PD9"), + STM32_FUNCTION(0, "GPIOD9"), + STM32_FUNCTION(8, "USART3_RX"), + STM32_FUNCTION(13, "FMC_D14"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(58, "PD10"), + STM32_FUNCTION(0, "GPIOD10"), + STM32_FUNCTION(8, "USART3_CK"), + STM32_FUNCTION(13, "FMC_D15"), + STM32_FUNCTION(15, "LCD_B3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(59, "PD11"), + STM32_FUNCTION(0, "GPIOD11"), + STM32_FUNCTION(5, "I2C4_SMBA"), + STM32_FUNCTION(8, "USART3_CTS"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO0"), + STM32_FUNCTION(11, "SAI2_SD_A"), + STM32_FUNCTION(13, "FMC_A16 FMC_CLE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(60, "PD12"), + STM32_FUNCTION(0, "GPIOD12"), + STM32_FUNCTION(3, "TIM4_CH1"), + STM32_FUNCTION(4, "LPTIM1_IN1"), + STM32_FUNCTION(5, "I2C4_SCL"), + STM32_FUNCTION(8, "USART3_RTS"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO1"), + STM32_FUNCTION(11, "SAI2_FS_A"), + STM32_FUNCTION(13, "FMC_A17 FMC_ALE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(61, "PD13"), + STM32_FUNCTION(0, "GPIOD13"), + STM32_FUNCTION(3, "TIM4_CH2"), + STM32_FUNCTION(4, "LPTIM1_OUT"), + STM32_FUNCTION(5, "I2C4_SDA"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO3"), + STM32_FUNCTION(11, "SAI2_SCK_A"), + STM32_FUNCTION(13, "FMC_A18"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(62, "PD14"), + STM32_FUNCTION(0, "GPIOD14"), + STM32_FUNCTION(3, "TIM4_CH3"), + STM32_FUNCTION(9, "UART8_CTS"), + STM32_FUNCTION(13, "FMC_D0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(63, "PD15"), + STM32_FUNCTION(0, "GPIOD15"), + STM32_FUNCTION(3, "TIM4_CH4"), + STM32_FUNCTION(9, "UART8_RTS"), + STM32_FUNCTION(13, "FMC_D1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(64, "PE0"), + STM32_FUNCTION(0, "GPIOE0"), + STM32_FUNCTION(3, "TIM4_ETR"), + STM32_FUNCTION(4, "LPTIM1_ETR"), + STM32_FUNCTION(9, "UART8_RX"), + STM32_FUNCTION(11, "SAI2_MCLK_A"), + STM32_FUNCTION(13, "FMC_NBL0"), + STM32_FUNCTION(14, "DCMI_D2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(65, "PE1"), + STM32_FUNCTION(0, "GPIOE1"), + STM32_FUNCTION(4, "LPTIM1_IN2"), + STM32_FUNCTION(9, "UART8_TX"), + STM32_FUNCTION(13, "FMC_NBL1"), + STM32_FUNCTION(14, "DCMI_D3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(66, "PE2"), + STM32_FUNCTION(0, "GPIOE2"), + STM32_FUNCTION(1, "TRACECLK"), + STM32_FUNCTION(6, "SPI4_SCK"), + STM32_FUNCTION(7, "SAI1_MCLK_A"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO2"), + STM32_FUNCTION(12, "ETH_MII_TXD3"), + STM32_FUNCTION(13, "FMC_A23"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(67, "PE3"), + STM32_FUNCTION(0, "GPIOE3"), + STM32_FUNCTION(1, "TRACED0"), + STM32_FUNCTION(7, "SAI1_SD_B"), + STM32_FUNCTION(13, "FMC_A19"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(68, "PE4"), + STM32_FUNCTION(0, "GPIOE4"), + STM32_FUNCTION(1, "TRACED1"), + STM32_FUNCTION(6, "SPI4_NSS"), + STM32_FUNCTION(7, "SAI1_FS_A"), + STM32_FUNCTION(13, "FMC_A20"), + STM32_FUNCTION(14, "DCMI_D4"), + STM32_FUNCTION(15, "LCD_B0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(69, "PE5"), + STM32_FUNCTION(0, "GPIOE5"), + STM32_FUNCTION(1, "TRACED2"), + STM32_FUNCTION(4, "TIM9_CH1"), + STM32_FUNCTION(6, "SPI4_MISO"), + STM32_FUNCTION(7, "SAI1_SCK_A"), + STM32_FUNCTION(13, "FMC_A21"), + STM32_FUNCTION(14, "DCMI_D6"), + STM32_FUNCTION(15, "LCD_G0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(70, "PE6"), + STM32_FUNCTION(0, "GPIOE6"), + STM32_FUNCTION(1, "TRACED3"), + STM32_FUNCTION(2, "TIM1_BKIN2"), + STM32_FUNCTION(4, "TIM9_CH2"), + STM32_FUNCTION(6, "SPI4_MOSI"), + STM32_FUNCTION(7, "SAI1_SD_A"), + STM32_FUNCTION(11, "SAI2_MCLK_B"), + STM32_FUNCTION(13, "FMC_A22"), + STM32_FUNCTION(14, "DCMI_D7"), + STM32_FUNCTION(15, "LCD_G1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(71, "PE7"), + STM32_FUNCTION(0, "GPIOE7"), + STM32_FUNCTION(2, "TIM1_ETR"), + STM32_FUNCTION(9, "UART7_RX"), + STM32_FUNCTION(11, "QUADSPI_BK2_IO0"), + STM32_FUNCTION(13, "FMC_D4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(72, "PE8"), + STM32_FUNCTION(0, "GPIOE8"), + STM32_FUNCTION(2, "TIM1_CH1N"), + STM32_FUNCTION(9, "UART7_TX"), + STM32_FUNCTION(11, "QUADSPI_BK2_IO1"), + STM32_FUNCTION(13, "FMC_D5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(73, "PE9"), + STM32_FUNCTION(0, "GPIOE9"), + STM32_FUNCTION(2, "TIM1_CH1"), + STM32_FUNCTION(9, "UART7_RTS"), + STM32_FUNCTION(11, "QUADSPI_BK2_IO2"), + STM32_FUNCTION(13, "FMC_D6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(74, "PE10"), + STM32_FUNCTION(0, "GPIOE10"), + STM32_FUNCTION(2, "TIM1_CH2N"), + STM32_FUNCTION(9, "UART7_CTS"), + STM32_FUNCTION(11, "QUADSPI_BK2_IO3"), + STM32_FUNCTION(13, "FMC_D7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(75, "PE11"), + STM32_FUNCTION(0, "GPIOE11"), + STM32_FUNCTION(2, "TIM1_CH2"), + STM32_FUNCTION(6, "SPI4_NSS"), + STM32_FUNCTION(11, "SAI2_SD_B"), + STM32_FUNCTION(13, "FMC_D8"), + STM32_FUNCTION(15, "LCD_G3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(76, "PE12"), + STM32_FUNCTION(0, "GPIOE12"), + STM32_FUNCTION(2, "TIM1_CH3N"), + STM32_FUNCTION(6, "SPI4_SCK"), + STM32_FUNCTION(11, "SAI2_SCK_B"), + STM32_FUNCTION(13, "FMC_D9"), + STM32_FUNCTION(15, "LCD_B4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(77, "PE13"), + STM32_FUNCTION(0, "GPIOE13"), + STM32_FUNCTION(2, "TIM1_CH3"), + STM32_FUNCTION(6, "SPI4_MISO"), + STM32_FUNCTION(11, "SAI2_FS_B"), + STM32_FUNCTION(13, "FMC_D10"), + STM32_FUNCTION(15, "LCD_DE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(78, "PE14"), + STM32_FUNCTION(0, "GPIOE14"), + STM32_FUNCTION(2, "TIM1_CH4"), + STM32_FUNCTION(6, "SPI4_MOSI"), + STM32_FUNCTION(11, "SAI2_MCLK_B"), + STM32_FUNCTION(13, "FMC_D11"), + STM32_FUNCTION(15, "LCD_CLK"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(79, "PE15"), + STM32_FUNCTION(0, "GPIOE15"), + STM32_FUNCTION(2, "TIM1_BKIN"), + STM32_FUNCTION(13, "FMC_D12"), + STM32_FUNCTION(15, "LCD_R7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(80, "PF0"), + STM32_FUNCTION(0, "GPIOF0"), + STM32_FUNCTION(5, "I2C2_SDA"), + STM32_FUNCTION(13, "FMC_A0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(81, "PF1"), + STM32_FUNCTION(0, "GPIOF1"), + STM32_FUNCTION(5, "I2C2_SCL"), + STM32_FUNCTION(13, "FMC_A1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(82, "PF2"), + STM32_FUNCTION(0, "GPIOF2"), + STM32_FUNCTION(5, "I2C2_SMBA"), + STM32_FUNCTION(13, "FMC_A2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(83, "PF3"), + STM32_FUNCTION(0, "GPIOF3"), + STM32_FUNCTION(13, "FMC_A3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(84, "PF4"), + STM32_FUNCTION(0, "GPIOF4"), + STM32_FUNCTION(13, "FMC_A4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(85, "PF5"), + STM32_FUNCTION(0, "GPIOF5"), + STM32_FUNCTION(13, "FMC_A5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(86, "PF6"), + STM32_FUNCTION(0, "GPIOF6"), + STM32_FUNCTION(4, "TIM10_CH1"), + STM32_FUNCTION(6, "SPI5_NSS"), + STM32_FUNCTION(7, "SAI1_SD_B"), + STM32_FUNCTION(9, "UART7_RX"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(87, "PF7"), + STM32_FUNCTION(0, "GPIOF7"), + STM32_FUNCTION(4, "TIM11_CH1"), + STM32_FUNCTION(6, "SPI5_SCK"), + STM32_FUNCTION(7, "SAI1_MCLK_B"), + STM32_FUNCTION(9, "UART7_TX"), + STM32_FUNCTION(10, "QUADSPI_BK1_IO2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(88, "PF8"), + STM32_FUNCTION(0, "GPIOF8"), + STM32_FUNCTION(6, "SPI5_MISO"), + STM32_FUNCTION(7, "SAI1_SCK_B"), + STM32_FUNCTION(9, "UART7_RTS"), + STM32_FUNCTION(10, "TIM13_CH1"), + STM32_FUNCTION(11, "QUADSPI_BK1_IO0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(89, "PF9"), + STM32_FUNCTION(0, "GPIOF9"), + STM32_FUNCTION(6, "SPI5_MOSI"), + STM32_FUNCTION(7, "SAI1_FS_B"), + STM32_FUNCTION(9, "UART7_CTS"), + STM32_FUNCTION(10, "TIM14_CH1"), + STM32_FUNCTION(11, "QUADSPI_BK1_IO1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(90, "PF10"), + STM32_FUNCTION(0, "GPIOF10"), + STM32_FUNCTION(14, "DCMI_D11"), + STM32_FUNCTION(15, "LCD_DE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(91, "PF11"), + STM32_FUNCTION(0, "GPIOF11"), + STM32_FUNCTION(6, "SPI5_MOSI"), + STM32_FUNCTION(11, "SAI2_SD_B"), + STM32_FUNCTION(13, "FMC_SDNRAS"), + STM32_FUNCTION(14, "DCMI_D12"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(92, "PF12"), + STM32_FUNCTION(0, "GPIOF12"), + STM32_FUNCTION(13, "FMC_A6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(93, "PF13"), + STM32_FUNCTION(0, "GPIOF13"), + STM32_FUNCTION(5, "I2C4_SMBA"), + STM32_FUNCTION(13, "FMC_A7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(94, "PF14"), + STM32_FUNCTION(0, "GPIOF14"), + STM32_FUNCTION(5, "I2C4_SCL"), + STM32_FUNCTION(13, "FMC_A8"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(95, "PF15"), + STM32_FUNCTION(0, "GPIOF15"), + STM32_FUNCTION(5, "I2C4_SDA"), + STM32_FUNCTION(13, "FMC_A9"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(96, "PG0"), + STM32_FUNCTION(0, "GPIOG0"), + STM32_FUNCTION(13, "FMC_A10"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(97, "PG1"), + STM32_FUNCTION(0, "GPIOG1"), + STM32_FUNCTION(13, "FMC_A11"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(98, "PG2"), + STM32_FUNCTION(0, "GPIOG2"), + STM32_FUNCTION(13, "FMC_A12"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(99, "PG3"), + STM32_FUNCTION(0, "GPIOG3"), + STM32_FUNCTION(13, "FMC_A13"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(100, "PG4"), + STM32_FUNCTION(0, "GPIOG4"), + STM32_FUNCTION(13, "FMC_A14 FMC_BA0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(101, "PG5"), + STM32_FUNCTION(0, "GPIOG5"), + STM32_FUNCTION(13, "FMC_A15 FMC_BA1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(102, "PG6"), + STM32_FUNCTION(0, "GPIOG6"), + STM32_FUNCTION(14, "DCMI_D12"), + STM32_FUNCTION(15, "LCD_R7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(103, "PG7"), + STM32_FUNCTION(0, "GPIOG7"), + STM32_FUNCTION(9, "USART6_CK"), + STM32_FUNCTION(13, "FMC_INT"), + STM32_FUNCTION(14, "DCMI_D13"), + STM32_FUNCTION(15, "LCD_CLK"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(104, "PG8"), + STM32_FUNCTION(0, "GPIOG8"), + STM32_FUNCTION(6, "SPI6_NSS"), + STM32_FUNCTION(8, "SPDIFRX_IN2"), + STM32_FUNCTION(9, "USART6_RTS"), + STM32_FUNCTION(12, "ETH_PPS_OUT"), + STM32_FUNCTION(13, "FMC_SDCLK"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(105, "PG9"), + STM32_FUNCTION(0, "GPIOG9"), + STM32_FUNCTION(8, "SPDIFRX_IN3"), + STM32_FUNCTION(9, "USART6_RX"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO2"), + STM32_FUNCTION(11, "SAI2_FS_B"), + STM32_FUNCTION(13, "FMC_NE2 FMC_NCE"), + STM32_FUNCTION(14, "DCMI_VSYNC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(106, "PG10"), + STM32_FUNCTION(0, "GPIOG10"), + STM32_FUNCTION(10, "LCD_G3"), + STM32_FUNCTION(11, "SAI2_SD_B"), + STM32_FUNCTION(13, "FMC_NE3"), + STM32_FUNCTION(14, "DCMI_D2"), + STM32_FUNCTION(15, "LCD_B2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(107, "PG11"), + STM32_FUNCTION(0, "GPIOG11"), + STM32_FUNCTION(8, "SPDIFRX_IN0"), + STM32_FUNCTION(12, "ETH_MII_TX_EN ETH_RMII_TX_EN"), + STM32_FUNCTION(14, "DCMI_D3"), + STM32_FUNCTION(15, "LCD_B3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(108, "PG12"), + STM32_FUNCTION(0, "GPIOG12"), + STM32_FUNCTION(4, "LPTIM1_IN1"), + STM32_FUNCTION(6, "SPI6_MISO"), + STM32_FUNCTION(8, "SPDIFRX_IN1"), + STM32_FUNCTION(9, "USART6_RTS"), + STM32_FUNCTION(10, "LCD_B4"), + STM32_FUNCTION(13, "FMC_NE4"), + STM32_FUNCTION(15, "LCD_B1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(109, "PG13"), + STM32_FUNCTION(0, "GPIOG13"), + STM32_FUNCTION(1, "TRACED0"), + STM32_FUNCTION(4, "LPTIM1_OUT"), + STM32_FUNCTION(6, "SPI6_SCK"), + STM32_FUNCTION(9, "USART6_CTS"), + STM32_FUNCTION(12, "ETH_MII_TXD0 ETH_RMII_TXD0"), + STM32_FUNCTION(13, "FMC_A24"), + STM32_FUNCTION(15, "LCD_R0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(110, "PG14"), + STM32_FUNCTION(0, "GPIOG14"), + STM32_FUNCTION(1, "TRACED1"), + STM32_FUNCTION(4, "LPTIM1_ETR"), + STM32_FUNCTION(6, "SPI6_MOSI"), + STM32_FUNCTION(9, "USART6_TX"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO3"), + STM32_FUNCTION(12, "ETH_MII_TXD1 ETH_RMII_TXD1"), + STM32_FUNCTION(13, "FMC_A25"), + STM32_FUNCTION(15, "LCD_B0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(111, "PG15"), + STM32_FUNCTION(0, "GPIOG15"), + STM32_FUNCTION(9, "USART6_CTS"), + STM32_FUNCTION(13, "FMC_SDNCAS"), + STM32_FUNCTION(14, "DCMI_D13"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(112, "PH0"), + STM32_FUNCTION(0, "GPIOH0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(113, "PH1"), + STM32_FUNCTION(0, "GPIOH1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(114, "PH2"), + STM32_FUNCTION(0, "GPIOH2"), + STM32_FUNCTION(4, "LPTIM1_IN2"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO0"), + STM32_FUNCTION(11, "SAI2_SCK_B"), + STM32_FUNCTION(12, "ETH_MII_CRS"), + STM32_FUNCTION(13, "FMC_SDCKE0"), + STM32_FUNCTION(15, "LCD_R0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(115, "PH3"), + STM32_FUNCTION(0, "GPIOH3"), + STM32_FUNCTION(10, "QUADSPI_BK2_IO1"), + STM32_FUNCTION(11, "SAI2_MCLK_B"), + STM32_FUNCTION(12, "ETH_MII_COL"), + STM32_FUNCTION(13, "FMC_SDNE0"), + STM32_FUNCTION(15, "LCD_R1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(116, "PH4"), + STM32_FUNCTION(0, "GPIOH4"), + STM32_FUNCTION(5, "I2C2_SCL"), + STM32_FUNCTION(11, "OTG_HS_ULPI_NXT"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(117, "PH5"), + STM32_FUNCTION(0, "GPIOH5"), + STM32_FUNCTION(5, "I2C2_SDA"), + STM32_FUNCTION(6, "SPI5_NSS"), + STM32_FUNCTION(13, "FMC_SDNWE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(118, "PH6"), + STM32_FUNCTION(0, "GPIOH6"), + STM32_FUNCTION(5, "I2C2_SMBA"), + STM32_FUNCTION(6, "SPI5_SCK"), + STM32_FUNCTION(10, "TIM12_CH1"), + STM32_FUNCTION(12, "ETH_MII_RXD2"), + STM32_FUNCTION(13, "FMC_SDNE1"), + STM32_FUNCTION(14, "DCMI_D8"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(119, "PH7"), + STM32_FUNCTION(0, "GPIOH7"), + STM32_FUNCTION(5, "I2C3_SCL"), + STM32_FUNCTION(6, "SPI5_MISO"), + STM32_FUNCTION(12, "ETH_MII_RXD3"), + STM32_FUNCTION(13, "FMC_SDCKE1"), + STM32_FUNCTION(14, "DCMI_D9"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(120, "PH8"), + STM32_FUNCTION(0, "GPIOH8"), + STM32_FUNCTION(5, "I2C3_SDA"), + STM32_FUNCTION(13, "FMC_D16"), + STM32_FUNCTION(14, "DCMI_HSYNC"), + STM32_FUNCTION(15, "LCD_R2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(121, "PH9"), + STM32_FUNCTION(0, "GPIOH9"), + STM32_FUNCTION(5, "I2C3_SMBA"), + STM32_FUNCTION(10, "TIM12_CH2"), + STM32_FUNCTION(13, "FMC_D17"), + STM32_FUNCTION(14, "DCMI_D0"), + STM32_FUNCTION(15, "LCD_R3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(122, "PH10"), + STM32_FUNCTION(0, "GPIOH10"), + STM32_FUNCTION(3, "TIM5_CH1"), + STM32_FUNCTION(5, "I2C4_SMBA"), + STM32_FUNCTION(13, "FMC_D18"), + STM32_FUNCTION(14, "DCMI_D1"), + STM32_FUNCTION(15, "LCD_R4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(123, "PH11"), + STM32_FUNCTION(0, "GPIOH11"), + STM32_FUNCTION(3, "TIM5_CH2"), + STM32_FUNCTION(5, "I2C4_SCL"), + STM32_FUNCTION(13, "FMC_D19"), + STM32_FUNCTION(14, "DCMI_D2"), + STM32_FUNCTION(15, "LCD_R5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(124, "PH12"), + STM32_FUNCTION(0, "GPIOH12"), + STM32_FUNCTION(3, "TIM5_CH3"), + STM32_FUNCTION(5, "I2C4_SDA"), + STM32_FUNCTION(13, "FMC_D20"), + STM32_FUNCTION(14, "DCMI_D3"), + STM32_FUNCTION(15, "LCD_R6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(125, "PH13"), + STM32_FUNCTION(0, "GPIOH13"), + STM32_FUNCTION(4, "TIM8_CH1N"), + STM32_FUNCTION(10, "CAN1_TX"), + STM32_FUNCTION(13, "FMC_D21"), + STM32_FUNCTION(15, "LCD_G2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(126, "PH14"), + STM32_FUNCTION(0, "GPIOH14"), + STM32_FUNCTION(4, "TIM8_CH2N"), + STM32_FUNCTION(13, "FMC_D22"), + STM32_FUNCTION(14, "DCMI_D4"), + STM32_FUNCTION(15, "LCD_G3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(127, "PH15"), + STM32_FUNCTION(0, "GPIOH15"), + STM32_FUNCTION(4, "TIM8_CH3N"), + STM32_FUNCTION(13, "FMC_D23"), + STM32_FUNCTION(14, "DCMI_D11"), + STM32_FUNCTION(15, "LCD_G4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(128, "PI0"), + STM32_FUNCTION(0, "GPIOI0"), + STM32_FUNCTION(3, "TIM5_CH4"), + STM32_FUNCTION(6, "SPI2_NSS I2S2_WS"), + STM32_FUNCTION(13, "FMC_D24"), + STM32_FUNCTION(14, "DCMI_D13"), + STM32_FUNCTION(15, "LCD_G5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(129, "PI1"), + STM32_FUNCTION(0, "GPIOI1"), + STM32_FUNCTION(4, "TIM8_BKIN2"), + STM32_FUNCTION(6, "SPI2_SCK I2S2_CK"), + STM32_FUNCTION(13, "FMC_D25"), + STM32_FUNCTION(14, "DCMI_D8"), + STM32_FUNCTION(15, "LCD_G6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(130, "PI2"), + STM32_FUNCTION(0, "GPIOI2"), + STM32_FUNCTION(4, "TIM8_CH4"), + STM32_FUNCTION(6, "SPI2_MISO"), + STM32_FUNCTION(13, "FMC_D26"), + STM32_FUNCTION(14, "DCMI_D9"), + STM32_FUNCTION(15, "LCD_G7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(131, "PI3"), + STM32_FUNCTION(0, "GPIOI3"), + STM32_FUNCTION(4, "TIM8_ETR"), + STM32_FUNCTION(6, "SPI2_MOSI I2S2_SD"), + STM32_FUNCTION(13, "FMC_D27"), + STM32_FUNCTION(14, "DCMI_D10"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(132, "PI4"), + STM32_FUNCTION(0, "GPIOI4"), + STM32_FUNCTION(4, "TIM8_BKIN"), + STM32_FUNCTION(11, "SAI2_MCLK_A"), + STM32_FUNCTION(13, "FMC_NBL2"), + STM32_FUNCTION(14, "DCMI_D5"), + STM32_FUNCTION(15, "LCD_B4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(133, "PI5"), + STM32_FUNCTION(0, "GPIOI5"), + STM32_FUNCTION(4, "TIM8_CH1"), + STM32_FUNCTION(11, "SAI2_SCK_A"), + STM32_FUNCTION(13, "FMC_NBL3"), + STM32_FUNCTION(14, "DCMI_VSYNC"), + STM32_FUNCTION(15, "LCD_B5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(134, "PI6"), + STM32_FUNCTION(0, "GPIOI6"), + STM32_FUNCTION(4, "TIM8_CH2"), + STM32_FUNCTION(11, "SAI2_SD_A"), + STM32_FUNCTION(13, "FMC_D28"), + STM32_FUNCTION(14, "DCMI_D6"), + STM32_FUNCTION(15, "LCD_B6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(135, "PI7"), + STM32_FUNCTION(0, "GPIOI7"), + STM32_FUNCTION(4, "TIM8_CH3"), + STM32_FUNCTION(11, "SAI2_FS_A"), + STM32_FUNCTION(13, "FMC_D29"), + STM32_FUNCTION(14, "DCMI_D7"), + STM32_FUNCTION(15, "LCD_B7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(136, "PI8"), + STM32_FUNCTION(0, "GPIOI8"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(137, "PI9"), + STM32_FUNCTION(0, "GPIOI9"), + STM32_FUNCTION(10, "CAN1_RX"), + STM32_FUNCTION(13, "FMC_D30"), + STM32_FUNCTION(15, "LCD_VSYNC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(138, "PI10"), + STM32_FUNCTION(0, "GPIOI10"), + STM32_FUNCTION(12, "ETH_MII_RX_ER"), + STM32_FUNCTION(13, "FMC_D31"), + STM32_FUNCTION(15, "LCD_HSYNC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(139, "PI11"), + STM32_FUNCTION(0, "GPIOI11"), + STM32_FUNCTION(11, "OTG_HS_ULPI_DIR"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(140, "PI12"), + STM32_FUNCTION(0, "GPIOI12"), + STM32_FUNCTION(15, "LCD_HSYNC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(141, "PI13"), + STM32_FUNCTION(0, "GPIOI13"), + STM32_FUNCTION(15, "LCD_VSYNC"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(142, "PI14"), + STM32_FUNCTION(0, "GPIOI14"), + STM32_FUNCTION(15, "LCD_CLK"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(143, "PI15"), + STM32_FUNCTION(0, "GPIOI15"), + STM32_FUNCTION(15, "LCD_R0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(144, "PJ0"), + STM32_FUNCTION(0, "GPIOJ0"), + STM32_FUNCTION(15, "LCD_R1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(145, "PJ1"), + STM32_FUNCTION(0, "GPIOJ1"), + STM32_FUNCTION(15, "LCD_R2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(146, "PJ2"), + STM32_FUNCTION(0, "GPIOJ2"), + STM32_FUNCTION(15, "LCD_R3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(147, "PJ3"), + STM32_FUNCTION(0, "GPIOJ3"), + STM32_FUNCTION(15, "LCD_R4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(148, "PJ4"), + STM32_FUNCTION(0, "GPIOJ4"), + STM32_FUNCTION(15, "LCD_R5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(149, "PJ5"), + STM32_FUNCTION(0, "GPIOJ5"), + STM32_FUNCTION(15, "LCD_R6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(150, "PJ6"), + STM32_FUNCTION(0, "GPIOJ6"), + STM32_FUNCTION(15, "LCD_R7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(151, "PJ7"), + STM32_FUNCTION(0, "GPIOJ7"), + STM32_FUNCTION(15, "LCD_G0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(152, "PJ8"), + STM32_FUNCTION(0, "GPIOJ8"), + STM32_FUNCTION(15, "LCD_G1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(153, "PJ9"), + STM32_FUNCTION(0, "GPIOJ9"), + STM32_FUNCTION(15, "LCD_G2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(154, "PJ10"), + STM32_FUNCTION(0, "GPIOJ10"), + STM32_FUNCTION(15, "LCD_G3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(155, "PJ11"), + STM32_FUNCTION(0, "GPIOJ11"), + STM32_FUNCTION(15, "LCD_G4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(156, "PJ12"), + STM32_FUNCTION(0, "GPIOJ12"), + STM32_FUNCTION(15, "LCD_B0"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(157, "PJ13"), + STM32_FUNCTION(0, "GPIOJ13"), + STM32_FUNCTION(15, "LCD_B1"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(158, "PJ14"), + STM32_FUNCTION(0, "GPIOJ14"), + STM32_FUNCTION(15, "LCD_B2"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(159, "PJ15"), + STM32_FUNCTION(0, "GPIOJ15"), + STM32_FUNCTION(15, "LCD_B3"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(160, "PK0"), + STM32_FUNCTION(0, "GPIOK0"), + STM32_FUNCTION(15, "LCD_G5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(161, "PK1"), + STM32_FUNCTION(0, "GPIOK1"), + STM32_FUNCTION(15, "LCD_G6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(162, "PK2"), + STM32_FUNCTION(0, "GPIOK2"), + STM32_FUNCTION(15, "LCD_G7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(163, "PK3"), + STM32_FUNCTION(0, "GPIOK3"), + STM32_FUNCTION(15, "LCD_B4"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(164, "PK4"), + STM32_FUNCTION(0, "GPIOK4"), + STM32_FUNCTION(15, "LCD_B5"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(165, "PK5"), + STM32_FUNCTION(0, "GPIOK5"), + STM32_FUNCTION(15, "LCD_B6"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(166, "PK6"), + STM32_FUNCTION(0, "GPIOK6"), + STM32_FUNCTION(15, "LCD_B7"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), + STM32_PIN( + PINCTRL_PIN(167, "PK7"), + STM32_FUNCTION(0, "GPIOK7"), + STM32_FUNCTION(15, "LCD_DE"), + STM32_FUNCTION(16, "EVENTOUT"), + STM32_FUNCTION(17, "ANALOG") + ), +}; + +static struct stm32_pinctrl_match_data stm32f746_match_data = { + .pins = stm32f746_pins, + .npins = ARRAY_SIZE(stm32f746_pins), +}; + +static const struct of_device_id stm32f746_pctrl_match[] = { + { + .compatible = "st,stm32f746-pinctrl", + .data = &stm32f746_match_data, + }, + { } +}; + +static struct platform_driver stm32f746_pinctrl_driver = { + .probe = stm32_pctl_probe, + .driver = { + .name = "stm32f746-pinctrl", + .of_match_table = stm32f746_pctrl_match, + }, +}; +builtin_platform_driver(stm32f746_pinctrl_driver); diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c index 55083d278bb1..ce483b03a263 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a23.c @@ -180,17 +180,17 @@ static const struct sunxi_desc_pin sun8i_a23_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQS */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQS */ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17), SUNXI_FUNCTION(0x0, "gpio_in"), diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c index 8b381d69df86..3040abe6f73a 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a33.c @@ -140,17 +140,17 @@ static const struct sunxi_desc_pin sun8i_a33_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQS */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQS */ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2), diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c index 11760bbe9d51..26a2ad3b651f 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-h3.c @@ -219,17 +219,17 @@ static const struct sunxi_desc_pin sun8i_h3_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQS */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQS */ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 0), diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c index 6e82b290cb4f..277622b4b6fb 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra.c @@ -632,11 +632,11 @@ static void tegra_pinctrl_clear_parked_bits(struct tegra_pmx *pmx) u32 val; for (i = 0; i < pmx->soc->ngroups; ++i) { - if (pmx->soc->groups[i].parked_reg >= 0) { - g = &pmx->soc->groups[i]; - val = pmx_readl(pmx, g->parked_bank, g->parked_reg); + g = &pmx->soc->groups[i]; + if (g->parked_bit >= 0) { + val = pmx_readl(pmx, g->mux_bank, g->mux_reg); val &= ~(1 << g->parked_bit); - pmx_writel(pmx, val, g->parked_bank, g->parked_reg); + pmx_writel(pmx, val, g->mux_bank, g->mux_reg); } } } diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.h b/drivers/pinctrl/tegra/pinctrl-tegra.h index d2ced17382b5..33b17cb1471e 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra.h +++ b/drivers/pinctrl/tegra/pinctrl-tegra.h @@ -93,9 +93,7 @@ struct tegra_function { * @tri_reg: Tri-state register offset. * @tri_bank: Tri-state register bank. * @tri_bit: Tri-state register bit. - * @parked_reg: Parked register offset. -1 if unsupported. - * @parked_bank: Parked register bank. 0 if unsupported. - * @parked_bit: Parked register bit. 0 if unsupported. + * @parked_bit: Parked register bit. -1 if unsupported. * @einput_bit: Enable-input register bit. * @odrain_bit: Open-drain register bit. * @lock_bit: Lock register bit. @@ -138,12 +136,10 @@ struct tegra_pingroup { s16 pupd_reg; s16 tri_reg; s16 drv_reg; - s16 parked_reg; u32 mux_bank:2; u32 pupd_bank:2; u32 tri_bank:2; u32 drv_bank:2; - u32 parked_bank:2; s32 mux_bit:6; s32 pupd_bit:6; s32 tri_bit:6; diff --git a/drivers/pinctrl/tegra/pinctrl-tegra114.c b/drivers/pinctrl/tegra/pinctrl-tegra114.c index 4851d169f4c7..952132ce5ea0 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra114.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra114.c @@ -1578,7 +1578,7 @@ static struct tegra_function tegra114_functions[] = { .lock_bit = 7, \ .ioreset_bit = PINGROUP_BIT_##ior(8), \ .rcv_sel_bit = PINGROUP_BIT_##rcv_sel(9), \ - .parked_reg = -1, \ + .parked_bit = -1, \ .drv_reg = -1, \ } @@ -1599,7 +1599,7 @@ static struct tegra_function tegra114_functions[] = { .rcv_sel_bit = -1, \ .drv_reg = DRV_PINGROUP_REG(r), \ .drv_bank = 0, \ - .parked_reg = -1, \ + .parked_bit = -1, \ .hsm_bit = hsm_b, \ .schmitt_bit = schmitt_b, \ .lpmd_bit = lpmd_b, \ diff --git a/drivers/pinctrl/tegra/pinctrl-tegra124.c b/drivers/pinctrl/tegra/pinctrl-tegra124.c index a0ce723a9482..bca239e3ae50 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra124.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra124.c @@ -1747,7 +1747,7 @@ static struct tegra_function tegra124_functions[] = { .lock_bit = 7, \ .ioreset_bit = PINGROUP_BIT_##ior(8), \ .rcv_sel_bit = PINGROUP_BIT_##rcv_sel(9), \ - .parked_reg = -1, \ + .parked_bit = -1, \ .drv_reg = -1, \ } @@ -1768,7 +1768,7 @@ static struct tegra_function tegra124_functions[] = { .rcv_sel_bit = -1, \ .drv_reg = DRV_PINGROUP_REG(r), \ .drv_bank = 0, \ - .parked_reg = -1, \ + .parked_bit = -1, \ .hsm_bit = hsm_b, \ .schmitt_bit = schmitt_b, \ .lpmd_bit = lpmd_b, \ diff --git a/drivers/pinctrl/tegra/pinctrl-tegra20.c b/drivers/pinctrl/tegra/pinctrl-tegra20.c index 09bad6980ad1..ad62451a5a9b 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra20.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra20.c @@ -1994,7 +1994,7 @@ static struct tegra_function tegra20_functions[] = { .tri_reg = ((tri_r) - TRISTATE_REG_A), \ .tri_bank = 0, \ .tri_bit = tri_b, \ - .parked_reg = -1, \ + .parked_bit = -1, \ .einput_bit = -1, \ .odrain_bit = -1, \ .lock_bit = -1, \ @@ -2014,7 +2014,7 @@ static struct tegra_function tegra20_functions[] = { .pupd_bank = 2, \ .pupd_bit = pupd_b, \ .drv_reg = -1, \ - .parked_reg = -1, \ + .parked_bit = -1, \ } /* Pin groups for drive strength registers (configurable version) */ @@ -2030,7 +2030,7 @@ static struct tegra_function tegra20_functions[] = { .tri_reg = -1, \ .drv_reg = ((r) - PINGROUP_REG_A), \ .drv_bank = 3, \ - .parked_reg = -1, \ + .parked_bit = -1, \ .hsm_bit = hsm_b, \ .schmitt_bit = schmitt_b, \ .lpmd_bit = lpmd_b, \ diff --git a/drivers/pinctrl/tegra/pinctrl-tegra210.c b/drivers/pinctrl/tegra/pinctrl-tegra210.c index 2d856af389ef..2b70e93da9db 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra210.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra210.c @@ -1310,8 +1310,6 @@ static struct tegra_function tegra210_functions[] = { .lock_bit = 7, \ .ioreset_bit = -1, \ .rcv_sel_bit = PINGROUP_BIT_##e_io_hv(10), \ - .parked_reg = PINGROUP_REG(r), \ - .parked_bank = 1, \ .parked_bit = 5, \ .hsm_bit = PINGROUP_BIT_##hsm(9), \ .schmitt_bit = 12, \ @@ -1345,7 +1343,7 @@ static struct tegra_function tegra210_functions[] = { .rcv_sel_bit = -1, \ .drv_reg = DRV_PINGROUP_REG(r), \ .drv_bank = 0, \ - .parked_reg = -1, \ + .parked_bit = -1, \ .hsm_bit = -1, \ .schmitt_bit = -1, \ .lpmd_bit = -1, \ diff --git a/drivers/pinctrl/tegra/pinctrl-tegra30.c b/drivers/pinctrl/tegra/pinctrl-tegra30.c index fb7817fea2d9..474ac6daf513 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra30.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra30.c @@ -2139,7 +2139,7 @@ static struct tegra_function tegra30_functions[] = { .lock_bit = 7, \ .ioreset_bit = PINGROUP_BIT_##ior(8), \ .rcv_sel_bit = -1, \ - .parked_reg = -1, \ + .parked_bit = -1, \ .drv_reg = -1, \ } @@ -2160,7 +2160,7 @@ static struct tegra_function tegra30_functions[] = { .rcv_sel_bit = -1, \ .drv_reg = DRV_PINGROUP_REG(r), \ .drv_bank = 0, \ - .parked_reg = -1, \ + .parked_bit = -1, \ .hsm_bit = hsm_b, \ .schmitt_bit = schmitt_b, \ .lpmd_bit = lpmd_b, \ diff --git a/drivers/pinctrl/uniphier/Kconfig b/drivers/pinctrl/uniphier/Kconfig index 0b40ded5738f..e077a9ec23d9 100644 --- a/drivers/pinctrl/uniphier/Kconfig +++ b/drivers/pinctrl/uniphier/Kconfig @@ -10,26 +10,34 @@ if PINCTRL_UNIPHIER config PINCTRL_UNIPHIER_LD4 tristate "UniPhier PH1-LD4 SoC pinctrl driver" - default y + default ARM config PINCTRL_UNIPHIER_PRO4 tristate "UniPhier PH1-Pro4 SoC pinctrl driver" - default y + default ARM config PINCTRL_UNIPHIER_SLD8 tristate "UniPhier PH1-sLD8 SoC pinctrl driver" - default y + default ARM config PINCTRL_UNIPHIER_PRO5 tristate "UniPhier PH1-Pro5 SoC pinctrl driver" - default y + default ARM config PINCTRL_UNIPHIER_PXS2 tristate "UniPhier ProXstream2 SoC pinctrl driver" - default y + default ARM config PINCTRL_UNIPHIER_LD6B tristate "UniPhier PH1-LD6b SoC pinctrl driver" - default y + default ARM + +config PINCTRL_UNIPHIER_LD11 + tristate "UniPhier PH1-LD11 SoC pinctrl driver" + default ARM64 + +config PINCTRL_UNIPHIER_LD20 + tristate "UniPhier PH1-LD20 SoC pinctrl driver" + default ARM64 endif diff --git a/drivers/pinctrl/uniphier/Makefile b/drivers/pinctrl/uniphier/Makefile index 3b8f9ee0bb6f..9f4bc8aa6f68 100644 --- a/drivers/pinctrl/uniphier/Makefile +++ b/drivers/pinctrl/uniphier/Makefile @@ -6,3 +6,5 @@ obj-$(CONFIG_PINCTRL_UNIPHIER_SLD8) += pinctrl-uniphier-sld8.o obj-$(CONFIG_PINCTRL_UNIPHIER_PRO5) += pinctrl-uniphier-pro5.o obj-$(CONFIG_PINCTRL_UNIPHIER_PXS2) += pinctrl-uniphier-pxs2.o obj-$(CONFIG_PINCTRL_UNIPHIER_LD6B) += pinctrl-uniphier-ld6b.o +obj-$(CONFIG_PINCTRL_UNIPHIER_LD11) += pinctrl-uniphier-ld11.o +obj-$(CONFIG_PINCTRL_UNIPHIER_LD20) += pinctrl-uniphier-ld20.o diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c index 967400971d45..9b2ee717bccc 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c @@ -14,6 +14,7 @@ #include <linux/export.h> #include <linux/mfd/syscon.h> +#include <linux/of.h> #include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinctrl.h> @@ -26,8 +27,10 @@ #include "pinctrl-uniphier.h" struct uniphier_pinctrl_priv { + struct pinctrl_desc pctldesc; struct pinctrl_dev *pctldev; struct regmap *regmap; + unsigned int regbase; struct uniphier_pinctrl_socdata *socdata; }; @@ -63,16 +66,22 @@ static int uniphier_pctl_get_group_pins(struct pinctrl_dev *pctldev, static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned offset) { - const struct pinctrl_pin_desc *pin = &pctldev->desc->pins[offset]; - const char *pull_dir, *drv_str; + const struct pin_desc *desc = pin_desc_get(pctldev, offset); + const char *pull_dir, *drv_type; - switch (uniphier_pin_get_pull_dir(pin->drv_data)) { + switch (uniphier_pin_get_pull_dir(desc->drv_data)) { case UNIPHIER_PIN_PULL_UP: pull_dir = "UP"; break; case UNIPHIER_PIN_PULL_DOWN: pull_dir = "DOWN"; break; + case UNIPHIER_PIN_PULL_UP_FIXED: + pull_dir = "UP(FIXED)"; + break; + case UNIPHIER_PIN_PULL_DOWN_FIXED: + pull_dir = "DOWN(FIXED)"; + break; case UNIPHIER_PIN_PULL_NONE: pull_dir = "NONE"; break; @@ -80,30 +89,33 @@ static void uniphier_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, BUG(); } - switch (uniphier_pin_get_drv_str(pin->drv_data)) { - case UNIPHIER_PIN_DRV_4_8: - drv_str = "4/8(mA)"; + switch (uniphier_pin_get_drv_type(desc->drv_data)) { + case UNIPHIER_PIN_DRV_1BIT: + drv_type = "4/8(mA)"; + break; + case UNIPHIER_PIN_DRV_2BIT: + drv_type = "8/12/16/20(mA)"; break; - case UNIPHIER_PIN_DRV_8_12_16_20: - drv_str = "8/12/16/20(mA)"; + case UNIPHIER_PIN_DRV_3BIT: + drv_type = "4/5/7/9/11/12/14/16(mA)"; break; - case UNIPHIER_PIN_DRV_FIXED_4: - drv_str = "4(mA)"; + case UNIPHIER_PIN_DRV_FIXED4: + drv_type = "4(mA)"; break; - case UNIPHIER_PIN_DRV_FIXED_5: - drv_str = "5(mA)"; + case UNIPHIER_PIN_DRV_FIXED5: + drv_type = "5(mA)"; break; - case UNIPHIER_PIN_DRV_FIXED_8: - drv_str = "8(mA)"; + case UNIPHIER_PIN_DRV_FIXED8: + drv_type = "8(mA)"; break; case UNIPHIER_PIN_DRV_NONE: - drv_str = "NONE"; + drv_type = "NONE"; break; default: BUG(); } - seq_printf(s, " PULL_DIR=%s DRV_STR=%s", pull_dir, drv_str); + seq_printf(s, " PULL_DIR=%s DRV_TYPE=%s", pull_dir, drv_type); } #endif @@ -119,12 +131,12 @@ static const struct pinctrl_ops uniphier_pctlops = { }; static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev, - const struct pinctrl_pin_desc *pin, + const struct pin_desc *desc, enum pin_config_param param) { struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); enum uniphier_pin_pull_dir pull_dir = - uniphier_pin_get_pull_dir(pin->drv_data); + uniphier_pin_get_pull_dir(desc->drv_data); unsigned int pupdctrl, reg, shift, val; unsigned int expected = 1; int ret; @@ -154,12 +166,12 @@ static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev, BUG(); } - pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data); + pupdctrl = uniphier_pin_get_pupdctrl(desc->drv_data); reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4; shift = pupdctrl % 32; - ret = regmap_read(priv->regmap, reg, &val); + ret = regmap_read(priv->regmap, priv->regbase + reg, &val); if (ret) return ret; @@ -169,34 +181,42 @@ static int uniphier_conf_pin_bias_get(struct pinctrl_dev *pctldev, } static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, - const struct pinctrl_pin_desc *pin, + const struct pin_desc *desc, u16 *strength) { struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); - enum uniphier_pin_drv_str drv_str = - uniphier_pin_get_drv_str(pin->drv_data); - const unsigned int strength_4_8[] = {4, 8}; - const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20}; + enum uniphier_pin_drv_type type = + uniphier_pin_get_drv_type(desc->drv_data); + const unsigned int strength_1bit[] = {4, 8}; + const unsigned int strength_2bit[] = {8, 12, 16, 20}; + const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16}; const unsigned int *supported_strength; unsigned int drvctrl, reg, shift, mask, width, val; int ret; - switch (drv_str) { - case UNIPHIER_PIN_DRV_4_8: - supported_strength = strength_4_8; + switch (type) { + case UNIPHIER_PIN_DRV_1BIT: + supported_strength = strength_1bit; + reg = UNIPHIER_PINCTRL_DRVCTRL_BASE; width = 1; break; - case UNIPHIER_PIN_DRV_8_12_16_20: - supported_strength = strength_8_12_16_20; + case UNIPHIER_PIN_DRV_2BIT: + supported_strength = strength_2bit; + reg = UNIPHIER_PINCTRL_DRV2CTRL_BASE; width = 2; break; - case UNIPHIER_PIN_DRV_FIXED_4: + case UNIPHIER_PIN_DRV_3BIT: + supported_strength = strength_3bit; + reg = UNIPHIER_PINCTRL_DRV3CTRL_BASE; + width = 4; + break; + case UNIPHIER_PIN_DRV_FIXED4: *strength = 4; return 0; - case UNIPHIER_PIN_DRV_FIXED_5: + case UNIPHIER_PIN_DRV_FIXED5: *strength = 5; return 0; - case UNIPHIER_PIN_DRV_FIXED_8: + case UNIPHIER_PIN_DRV_FIXED8: *strength = 8; return 0; default: @@ -204,17 +224,14 @@ static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, return -EINVAL; } - drvctrl = uniphier_pin_get_drvctrl(pin->drv_data); + drvctrl = uniphier_pin_get_drvctrl(desc->drv_data); drvctrl *= width; - reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE : - UNIPHIER_PINCTRL_DRVCTRL_BASE; - reg += drvctrl / 32 * 4; shift = drvctrl % 32; mask = (1U << width) - 1; - ret = regmap_read(priv->regmap, reg, &val); + ret = regmap_read(priv->regmap, priv->regbase + reg, &val); if (ret) return ret; @@ -224,10 +241,10 @@ static int uniphier_conf_pin_drive_get(struct pinctrl_dev *pctldev, } static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev, - const struct pinctrl_pin_desc *pin) + const struct pin_desc *desc) { struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); - unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data); + unsigned int iectrl = uniphier_pin_get_iectrl(desc->drv_data); unsigned int val; int ret; @@ -235,7 +252,8 @@ static int uniphier_conf_pin_input_enable_get(struct pinctrl_dev *pctldev, /* This pin is always input-enabled. */ return 0; - ret = regmap_read(priv->regmap, UNIPHIER_PINCTRL_IECTRL, &val); + ret = regmap_read(priv->regmap, + priv->regbase + UNIPHIER_PINCTRL_IECTRL, &val); if (ret) return ret; @@ -246,7 +264,7 @@ static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *configs) { - const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin]; + const struct pin_desc *desc = pin_desc_get(pctldev, pin); enum pin_config_param param = pinconf_to_config_param(*configs); bool has_arg = false; u16 arg; @@ -256,14 +274,14 @@ static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev, case PIN_CONFIG_BIAS_DISABLE: case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_DOWN: - ret = uniphier_conf_pin_bias_get(pctldev, pin_desc, param); + ret = uniphier_conf_pin_bias_get(pctldev, desc, param); break; case PIN_CONFIG_DRIVE_STRENGTH: - ret = uniphier_conf_pin_drive_get(pctldev, pin_desc, &arg); + ret = uniphier_conf_pin_drive_get(pctldev, desc, &arg); has_arg = true; break; case PIN_CONFIG_INPUT_ENABLE: - ret = uniphier_conf_pin_input_enable_get(pctldev, pin_desc); + ret = uniphier_conf_pin_input_enable_get(pctldev, desc); break; default: /* unsupported parameter */ @@ -278,13 +296,12 @@ static int uniphier_conf_pin_config_get(struct pinctrl_dev *pctldev, } static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, - const struct pinctrl_pin_desc *pin, - enum pin_config_param param, - u16 arg) + const struct pin_desc *desc, + enum pin_config_param param, u16 arg) { struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); enum uniphier_pin_pull_dir pull_dir = - uniphier_pin_get_pull_dir(pin->drv_data); + uniphier_pin_get_pull_dir(desc->drv_data); unsigned int pupdctrl, reg, shift; unsigned int val = 1; @@ -295,8 +312,8 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, if (pull_dir == UNIPHIER_PIN_PULL_UP_FIXED || pull_dir == UNIPHIER_PIN_PULL_DOWN_FIXED) { dev_err(pctldev->dev, - "can not disable pull register for pin %u (%s)\n", - pin->number, pin->name); + "can not disable pull register for pin %s\n", + desc->name); return -EINVAL; } val = 0; @@ -306,8 +323,8 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, return 0; if (pull_dir != UNIPHIER_PIN_PULL_UP) { dev_err(pctldev->dev, - "pull-up is unsupported for pin %u (%s)\n", - pin->number, pin->name); + "pull-up is unsupported for pin %s\n", + desc->name); return -EINVAL; } if (arg == 0) { @@ -320,8 +337,8 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, return 0; if (pull_dir != UNIPHIER_PIN_PULL_DOWN) { dev_err(pctldev->dev, - "pull-down is unsupported for pin %u (%s)\n", - pin->number, pin->name); + "pull-down is unsupported for pin %s\n", + desc->name); return -EINVAL; } if (arg == 0) { @@ -332,8 +349,8 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: if (pull_dir == UNIPHIER_PIN_PULL_NONE) { dev_err(pctldev->dev, - "pull-up/down is unsupported for pin %u (%s)\n", - pin->number, pin->name); + "pull-up/down is unsupported for pin %s\n", + desc->name); return -EINVAL; } @@ -344,39 +361,48 @@ static int uniphier_conf_pin_bias_set(struct pinctrl_dev *pctldev, BUG(); } - pupdctrl = uniphier_pin_get_pupdctrl(pin->drv_data); + pupdctrl = uniphier_pin_get_pupdctrl(desc->drv_data); reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pupdctrl / 32 * 4; shift = pupdctrl % 32; - return regmap_update_bits(priv->regmap, reg, 1 << shift, val << shift); + return regmap_update_bits(priv->regmap, priv->regbase + reg, + 1 << shift, val << shift); } static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, - const struct pinctrl_pin_desc *pin, + const struct pin_desc *desc, u16 strength) { struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); - enum uniphier_pin_drv_str drv_str = - uniphier_pin_get_drv_str(pin->drv_data); - const unsigned int strength_4_8[] = {4, 8, -1}; - const unsigned int strength_8_12_16_20[] = {8, 12, 16, 20, -1}; + enum uniphier_pin_drv_type type = + uniphier_pin_get_drv_type(desc->drv_data); + const unsigned int strength_1bit[] = {4, 8, -1}; + const unsigned int strength_2bit[] = {8, 12, 16, 20, -1}; + const unsigned int strength_3bit[] = {4, 5, 7, 9, 11, 12, 14, 16, -1}; const unsigned int *supported_strength; unsigned int drvctrl, reg, shift, mask, width, val; - switch (drv_str) { - case UNIPHIER_PIN_DRV_4_8: - supported_strength = strength_4_8; + switch (type) { + case UNIPHIER_PIN_DRV_1BIT: + supported_strength = strength_1bit; + reg = UNIPHIER_PINCTRL_DRVCTRL_BASE; width = 1; break; - case UNIPHIER_PIN_DRV_8_12_16_20: - supported_strength = strength_8_12_16_20; + case UNIPHIER_PIN_DRV_2BIT: + supported_strength = strength_2bit; + reg = UNIPHIER_PINCTRL_DRV2CTRL_BASE; width = 2; break; + case UNIPHIER_PIN_DRV_3BIT: + supported_strength = strength_3bit; + reg = UNIPHIER_PINCTRL_DRV3CTRL_BASE; + width = 4; + break; default: dev_err(pctldev->dev, - "cannot change drive strength for pin %u (%s)\n", - pin->number, pin->name); + "cannot change drive strength for pin %s\n", + desc->name); return -EINVAL; } @@ -387,49 +413,48 @@ static int uniphier_conf_pin_drive_set(struct pinctrl_dev *pctldev, if (val == 0) { dev_err(pctldev->dev, - "unsupported drive strength %u mA for pin %u (%s)\n", - strength, pin->number, pin->name); + "unsupported drive strength %u mA for pin %s\n", + strength, desc->name); return -EINVAL; } val--; - drvctrl = uniphier_pin_get_drvctrl(pin->drv_data); + drvctrl = uniphier_pin_get_drvctrl(desc->drv_data); drvctrl *= width; - reg = (width == 2) ? UNIPHIER_PINCTRL_DRV2CTRL_BASE : - UNIPHIER_PINCTRL_DRVCTRL_BASE; - reg += drvctrl / 32 * 4; shift = drvctrl % 32; mask = (1U << width) - 1; - return regmap_update_bits(priv->regmap, reg, + return regmap_update_bits(priv->regmap, priv->regbase + reg, mask << shift, val << shift); } static int uniphier_conf_pin_input_enable(struct pinctrl_dev *pctldev, - const struct pinctrl_pin_desc *pin, + const struct pin_desc *desc, u16 enable) { struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); - unsigned int iectrl = uniphier_pin_get_iectrl(pin->drv_data); + unsigned int iectrl = uniphier_pin_get_iectrl(desc->drv_data); + unsigned int reg, mask; - if (enable == 0) { - /* - * Multiple pins share one input enable, so per-pin disabling - * is impossible. - */ - dev_err(pctldev->dev, "unable to disable input\n"); + /* + * Multiple pins share one input enable, per-pin disabling is + * impossible. + */ + if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL) && + !enable) return -EINVAL; - } + /* UNIPHIER_PIN_IECTRL_NONE means the pin is always input-enabled */ if (iectrl == UNIPHIER_PIN_IECTRL_NONE) - /* This pin is always input-enabled. nothing to do. */ - return 0; + return enable ? 0 : -EINVAL; + + reg = priv->regbase + UNIPHIER_PINCTRL_IECTRL + iectrl / 32 * 4; + mask = BIT(iectrl % 32); - return regmap_update_bits(priv->regmap, UNIPHIER_PINCTRL_IECTRL, - BIT(iectrl), BIT(iectrl)); + return regmap_update_bits(priv->regmap, reg, mask, enable ? mask : 0); } static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev, @@ -437,7 +462,7 @@ static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev, unsigned long *configs, unsigned num_configs) { - const struct pinctrl_pin_desc *pin_desc = &pctldev->desc->pins[pin]; + const struct pin_desc *desc = pin_desc_get(pctldev, pin); int i, ret; for (i = 0; i < num_configs; i++) { @@ -450,16 +475,15 @@ static int uniphier_conf_pin_config_set(struct pinctrl_dev *pctldev, case PIN_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_DOWN: case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: - ret = uniphier_conf_pin_bias_set(pctldev, pin_desc, + ret = uniphier_conf_pin_bias_set(pctldev, desc, param, arg); break; case PIN_CONFIG_DRIVE_STRENGTH: - ret = uniphier_conf_pin_drive_set(pctldev, pin_desc, - arg); + ret = uniphier_conf_pin_drive_set(pctldev, desc, arg); break; case PIN_CONFIG_INPUT_ENABLE: - ret = uniphier_conf_pin_input_enable(pctldev, - pin_desc, arg); + ret = uniphier_conf_pin_input_enable(pctldev, desc, + arg); break; default: dev_err(pctldev->dev, @@ -531,20 +555,42 @@ static int uniphier_pmx_get_function_groups(struct pinctrl_dev *pctldev, } static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin, - unsigned muxval) + int muxval) { struct uniphier_pinctrl_priv *priv = pinctrl_dev_get_drvdata(pctldev); - unsigned mux_bits = priv->socdata->mux_bits; - unsigned reg_stride = priv->socdata->reg_stride; - unsigned reg, reg_end, shift, mask; + unsigned int mux_bits, reg_stride, reg, reg_end, shift, mask; + bool load_pinctrl; int ret; /* some pins need input-enabling */ ret = uniphier_conf_pin_input_enable(pctldev, - &pctldev->desc->pins[pin], 1); + pin_desc_get(pctldev, pin), 1); if (ret) return ret; + if (muxval < 0) + return 0; /* dedicated pin; nothing to do for pin-mux */ + + if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) { + /* + * Mode reg_offset bit_position + * Normal 4 * n shift+3:shift + * Debug 4 * n shift+7:shift+4 + */ + mux_bits = 4; + reg_stride = 8; + load_pinctrl = true; + } else { + /* + * Mode reg_offset bit_position + * Normal 8 * n shift+3:shift + * Debug 8 * n + 4 shift+3:shift + */ + mux_bits = 8; + reg_stride = 4; + load_pinctrl = false; + } + reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride; reg_end = reg + reg_stride; shift = pin * mux_bits % 32; @@ -555,16 +601,17 @@ static int uniphier_pmx_set_one_mux(struct pinctrl_dev *pctldev, unsigned pin, * stored in the offset+4. */ for (; reg < reg_end; reg += 4) { - ret = regmap_update_bits(priv->regmap, reg, + ret = regmap_update_bits(priv->regmap, priv->regbase + reg, mask << shift, muxval << shift); if (ret) return ret; muxval >>= mux_bits; } - if (priv->socdata->load_pinctrl) { + if (load_pinctrl) { ret = regmap_write(priv->regmap, - UNIPHIER_PINCTRL_LOAD_PINMUX, 1); + priv->regbase + UNIPHIER_PINCTRL_LOAD_PINMUX, + 1); if (ret) return ret; } @@ -633,19 +680,16 @@ static const struct pinmux_ops uniphier_pmxops = { }; int uniphier_pinctrl_probe(struct platform_device *pdev, - struct pinctrl_desc *desc, struct uniphier_pinctrl_socdata *socdata) { struct device *dev = &pdev->dev; struct uniphier_pinctrl_priv *priv; + struct device_node *parent; if (!socdata || - !socdata->groups || - !socdata->groups_count || - !socdata->functions || - !socdata->functions_count || - !socdata->mux_bits || - !socdata->reg_stride) { + !socdata->pins || !socdata->npins || + !socdata->groups || !socdata->groups_count || + !socdata->functions || !socdata->functions_count) { dev_err(dev, "pinctrl socdata lacks necessary members\n"); return -EINVAL; } @@ -654,18 +698,36 @@ int uniphier_pinctrl_probe(struct platform_device *pdev, if (!priv) return -ENOMEM; - priv->regmap = syscon_node_to_regmap(dev->of_node); + if (of_device_is_compatible(dev->of_node, "socionext,ph1-ld4-pinctrl") || + of_device_is_compatible(dev->of_node, "socionext,ph1-pro4-pinctrl") || + of_device_is_compatible(dev->of_node, "socionext,ph1-sld8-pinctrl") || + of_device_is_compatible(dev->of_node, "socionext,ph1-pro5-pinctrl") || + of_device_is_compatible(dev->of_node, "socionext,proxstream2-pinctrl") || + of_device_is_compatible(dev->of_node, "socionext,ph1-ld6b-pinctrl")) { + /* old binding */ + priv->regmap = syscon_node_to_regmap(dev->of_node); + } else { + priv->regbase = 0x1000; + parent = of_get_parent(dev->of_node); + priv->regmap = syscon_node_to_regmap(parent); + of_node_put(parent); + } + if (IS_ERR(priv->regmap)) { dev_err(dev, "failed to get regmap\n"); return PTR_ERR(priv->regmap); } priv->socdata = socdata; - desc->pctlops = &uniphier_pctlops; - desc->pmxops = &uniphier_pmxops; - desc->confops = &uniphier_confops; - - priv->pctldev = devm_pinctrl_register(dev, desc, priv); + priv->pctldesc.name = dev->driver->name; + priv->pctldesc.pins = socdata->pins; + priv->pctldesc.npins = socdata->npins; + priv->pctldesc.pctlops = &uniphier_pctlops; + priv->pctldesc.pmxops = &uniphier_pmxops; + priv->pctldesc.confops = &uniphier_confops; + priv->pctldesc.owner = dev->driver->owner; + + priv->pctldev = devm_pinctrl_register(dev, &priv->pctldesc, priv); if (IS_ERR(priv->pctldev)) { dev_err(dev, "failed to register UniPhier pinctrl driver\n"); return PTR_ERR(priv->pctldev); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c new file mode 100644 index 000000000000..77a0236ee781 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c @@ -0,0 +1,952 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/platform_device.h> + +#include "pinctrl-uniphier.h" + +static const struct pinctrl_pin_desc uniphier_ld11_pins[] = { + UNIPHIER_PINCTRL_PIN(0, "XECS1", 0, + 0, UNIPHIER_PIN_DRV_1BIT, + 0, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(1, "ERXW", UNIPHIER_PIN_IECTRL_NONE, + 1, UNIPHIER_PIN_DRV_1BIT, + 1, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(2, "XERWE1", UNIPHIER_PIN_IECTRL_NONE, + 2, UNIPHIER_PIN_DRV_1BIT, + 2, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(3, "XNFWP", 3, + 3, UNIPHIER_PIN_DRV_1BIT, + 3, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(4, "XNFCE0", 4, + 4, UNIPHIER_PIN_DRV_1BIT, + 4, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(5, "NFRYBY0", 5, + 5, UNIPHIER_PIN_DRV_1BIT, + 5, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(6, "XNFRE", UNIPHIER_PIN_IECTRL_NONE, + 6, UNIPHIER_PIN_DRV_1BIT, + 6, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(7, "XNFWE", UNIPHIER_PIN_IECTRL_NONE, + 7, UNIPHIER_PIN_DRV_1BIT, + 7, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(8, "NFALE", UNIPHIER_PIN_IECTRL_NONE, + 8, UNIPHIER_PIN_DRV_1BIT, + 8, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(9, "NFCLE", UNIPHIER_PIN_IECTRL_NONE, + 9, UNIPHIER_PIN_DRV_1BIT, + 9, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(10, "NFD0", 10, + 10, UNIPHIER_PIN_DRV_1BIT, + 10, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(11, "NFD1", 11, + 11, UNIPHIER_PIN_DRV_1BIT, + 11, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(12, "NFD2", 12, + 12, UNIPHIER_PIN_DRV_1BIT, + 12, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(13, "NFD3", 13, + 13, UNIPHIER_PIN_DRV_1BIT, + 13, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(14, "NFD4", 14, + 14, UNIPHIER_PIN_DRV_1BIT, + 14, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(15, "NFD5", 15, + 15, UNIPHIER_PIN_DRV_1BIT, + 15, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(16, "NFD6", 16, + 16, UNIPHIER_PIN_DRV_1BIT, + 16, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(17, "NFD7", 17, + 17, UNIPHIER_PIN_DRV_1BIT, + 17, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(18, "XERST", 18, + 0, UNIPHIER_PIN_DRV_2BIT, + 18, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(19, "MMCCLK", 19, + 1, UNIPHIER_PIN_DRV_2BIT, + 19, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(20, "MMCCMD", 20, + 2, UNIPHIER_PIN_DRV_2BIT, + 20, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(21, "MMCDS", 21, + 3, UNIPHIER_PIN_DRV_2BIT, + 21, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(22, "MMCDAT0", 22, + 4, UNIPHIER_PIN_DRV_2BIT, + 22, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(23, "MMCDAT1", 23, + 5, UNIPHIER_PIN_DRV_2BIT, + 23, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(24, "MMCDAT2", 24, + 6, UNIPHIER_PIN_DRV_2BIT, + 24, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(25, "MMCDAT3", 25, + 7, UNIPHIER_PIN_DRV_2BIT, + 25, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(26, "MMCDAT4", 26, + 8, UNIPHIER_PIN_DRV_2BIT, + 26, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(27, "MMCDAT5", 27, + 9, UNIPHIER_PIN_DRV_2BIT, + 27, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(28, "MMCDAT6", 28, + 10, UNIPHIER_PIN_DRV_2BIT, + 28, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(29, "MMCDAT7", 29, + 11, UNIPHIER_PIN_DRV_2BIT, + 29, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(46, "USB0VBUS", 46, + 46, UNIPHIER_PIN_DRV_1BIT, + 46, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(47, "USB0OD", UNIPHIER_PIN_IECTRL_NONE, + 47, UNIPHIER_PIN_DRV_1BIT, + 47, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(48, "USB1VBUS", 48, + 48, UNIPHIER_PIN_DRV_1BIT, + 48, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(49, "USB1OD", 49, + 49, UNIPHIER_PIN_DRV_1BIT, + 49, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(50, "USB2VBUS", 50, + 50, UNIPHIER_PIN_DRV_1BIT, + 50, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(51, "USB2OD", 51, + 51, UNIPHIER_PIN_DRV_1BIT, + 51, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(54, "TXD0", 54, + 54, UNIPHIER_PIN_DRV_1BIT, + 54, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(55, "RXD0", 55, + 55, UNIPHIER_PIN_DRV_1BIT, + 55, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(56, "SPISYNC0", 56, + 56, UNIPHIER_PIN_DRV_1BIT, + 56, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(57, "SPISCLK0", 57, + 57, UNIPHIER_PIN_DRV_1BIT, + 57, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(58, "SPITXD0", 58, + 58, UNIPHIER_PIN_DRV_1BIT, + 58, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(59, "SPIRXD0", 59, + 59, UNIPHIER_PIN_DRV_1BIT, + 59, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(60, "AGCI", 60, + 60, UNIPHIER_PIN_DRV_1BIT, + 60, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(61, "DMDSDA0", 61, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(62, "DMDSCL0", 62, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(63, "SDA0", 63, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(64, "SCL0", 64, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(65, "SDA1", 65, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(66, "SCL1", 66, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(67, "HIN", 67, + -1, UNIPHIER_PIN_DRV_FIXED5, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(68, "VIN", 68, + -1, UNIPHIER_PIN_DRV_FIXED5, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(69, "PCA00", 69, + 69, UNIPHIER_PIN_DRV_1BIT, + 69, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(70, "PCA01", 70, + 70, UNIPHIER_PIN_DRV_1BIT, + 70, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(71, "PCA02", 71, + 71, UNIPHIER_PIN_DRV_1BIT, + 71, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(72, "PCA03", 72, + 72, UNIPHIER_PIN_DRV_1BIT, + 72, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(73, "PCA04", 73, + 73, UNIPHIER_PIN_DRV_1BIT, + 73, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(74, "PCA05", 74, + 74, UNIPHIER_PIN_DRV_1BIT, + 74, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(75, "PCA06", 75, + 75, UNIPHIER_PIN_DRV_1BIT, + 75, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(76, "PCA07", 76, + 76, UNIPHIER_PIN_DRV_1BIT, + 76, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(77, "PCA08", 77, + 77, UNIPHIER_PIN_DRV_1BIT, + 77, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(78, "PCA09", 78, + 78, UNIPHIER_PIN_DRV_1BIT, + 78, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(79, "PCA10", 79, + 79, UNIPHIER_PIN_DRV_1BIT, + 79, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(80, "PCA11", 80, + 80, UNIPHIER_PIN_DRV_1BIT, + 80, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(81, "PCA12", 81, + 81, UNIPHIER_PIN_DRV_1BIT, + 81, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(82, "PCA13", 82, + 82, UNIPHIER_PIN_DRV_1BIT, + 82, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(83, "PCA14", 83, + 83, UNIPHIER_PIN_DRV_1BIT, + 83, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(84, "PC0READY", 84, + 84, UNIPHIER_PIN_DRV_1BIT, + 84, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(85, "PC0CD1", 85, + 85, UNIPHIER_PIN_DRV_1BIT, + 85, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(86, "PC0CD2", 86, + 86, UNIPHIER_PIN_DRV_1BIT, + 86, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(87, "PC0WAIT", 87, + 87, UNIPHIER_PIN_DRV_1BIT, + 87, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(88, "PC0RESET", 88, + 88, UNIPHIER_PIN_DRV_1BIT, + 88, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(89, "PC0CE1", 89, + 89, UNIPHIER_PIN_DRV_1BIT, + 89, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(90, "PC0WE", 90, + 90, UNIPHIER_PIN_DRV_1BIT, + 90, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(91, "PC0OE", 91, + 91, UNIPHIER_PIN_DRV_1BIT, + 91, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(92, "PC0IOWR", 92, + 92, UNIPHIER_PIN_DRV_1BIT, + 92, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(93, "PC0IORD", 93, + 93, UNIPHIER_PIN_DRV_1BIT, + 93, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(94, "PCD00", 94, + 94, UNIPHIER_PIN_DRV_1BIT, + 94, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(95, "PCD01", 95, + 95, UNIPHIER_PIN_DRV_1BIT, + 95, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(96, "PCD02", 96, + 96, UNIPHIER_PIN_DRV_1BIT, + 96, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(97, "PCD03", 97, + 97, UNIPHIER_PIN_DRV_1BIT, + 97, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(98, "PCD04", 98, + 98, UNIPHIER_PIN_DRV_1BIT, + 98, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(99, "PCD05", 99, + 99, UNIPHIER_PIN_DRV_1BIT, + 99, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(100, "PCD06", 100, + 100, UNIPHIER_PIN_DRV_1BIT, + 100, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(101, "PCD07", 101, + 101, UNIPHIER_PIN_DRV_1BIT, + 101, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(102, "HS0BCLKIN", 102, + 102, UNIPHIER_PIN_DRV_1BIT, + 102, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(103, "HS0SYNCIN", 103, + 103, UNIPHIER_PIN_DRV_1BIT, + 103, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(104, "HS0VALIN", 104, + 104, UNIPHIER_PIN_DRV_1BIT, + 104, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(105, "HS0DIN0", 105, + 105, UNIPHIER_PIN_DRV_1BIT, + 105, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(106, "HS0DIN1", 106, + 106, UNIPHIER_PIN_DRV_1BIT, + 106, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(107, "HS0DIN2", 107, + 107, UNIPHIER_PIN_DRV_1BIT, + 107, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(108, "HS0DIN3", 108, + 108, UNIPHIER_PIN_DRV_1BIT, + 108, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(109, "HS0DIN4", 109, + 109, UNIPHIER_PIN_DRV_1BIT, + 109, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(110, "HS0DIN5", 110, + 110, UNIPHIER_PIN_DRV_1BIT, + 110, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(111, "HS0DIN6", 111, + 111, UNIPHIER_PIN_DRV_1BIT, + 111, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(112, "HS0DIN7", 112, + 112, UNIPHIER_PIN_DRV_1BIT, + 112, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(113, "HS0BCLKOUT", 113, + 113, UNIPHIER_PIN_DRV_1BIT, + 113, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(114, "HS0SYNCOUT", 114, + 114, UNIPHIER_PIN_DRV_1BIT, + 114, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(115, "HS0VALOUT", 115, + 115, UNIPHIER_PIN_DRV_1BIT, + 115, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(116, "HS0DOUT0", 116, + 116, UNIPHIER_PIN_DRV_1BIT, + 116, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(117, "HS0DOUT1", 117, + 117, UNIPHIER_PIN_DRV_1BIT, + 117, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(118, "HS0DOUT2", 118, + 118, UNIPHIER_PIN_DRV_1BIT, + 118, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(119, "HS0DOUT3", 119, + 119, UNIPHIER_PIN_DRV_1BIT, + 119, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(120, "HS0DOUT4", 120, + 120, UNIPHIER_PIN_DRV_1BIT, + 120, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(121, "HS0DOUT5", 121, + 121, UNIPHIER_PIN_DRV_1BIT, + 121, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(122, "HS0DOUT6", 122, + 122, UNIPHIER_PIN_DRV_1BIT, + 122, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(123, "HS0DOUT7", 123, + 123, UNIPHIER_PIN_DRV_1BIT, + 123, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(124, "HS1BCLKIN", 124, + 124, UNIPHIER_PIN_DRV_1BIT, + 124, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(125, "HS1SYNCIN", 125, + 125, UNIPHIER_PIN_DRV_1BIT, + 125, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(126, "HS1VALIN", 126, + 126, UNIPHIER_PIN_DRV_1BIT, + 126, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(127, "HS1DIN0", 127, + 127, UNIPHIER_PIN_DRV_1BIT, + 127, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(128, "HS1DIN1", 128, + 128, UNIPHIER_PIN_DRV_1BIT, + 128, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(129, "HS1DIN2", 129, + 129, UNIPHIER_PIN_DRV_1BIT, + 129, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(130, "HS1DIN3", 130, + 130, UNIPHIER_PIN_DRV_1BIT, + 130, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(131, "HS1DIN4", 131, + 131, UNIPHIER_PIN_DRV_1BIT, + 131, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(132, "HS1DIN5", 132, + 132, UNIPHIER_PIN_DRV_1BIT, + 132, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(133, "HS1DIN6", 133, + 133, UNIPHIER_PIN_DRV_1BIT, + 133, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(134, "HS1DIN7", 134, + 134, UNIPHIER_PIN_DRV_1BIT, + 134, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(135, "AO1IEC", 135, + 135, UNIPHIER_PIN_DRV_1BIT, + 135, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(136, "AO1ARC", 136, + 136, UNIPHIER_PIN_DRV_1BIT, + 136, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(137, "AO1DACCK", 137, + 137, UNIPHIER_PIN_DRV_1BIT, + 137, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(138, "AO1BCK", 138, + 138, UNIPHIER_PIN_DRV_1BIT, + 138, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(139, "AO1LRCK", 139, + 139, UNIPHIER_PIN_DRV_1BIT, + 139, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(140, "AO1D0", 140, + 140, UNIPHIER_PIN_DRV_1BIT, + 140, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(141, "TCON0", 141, + 141, UNIPHIER_PIN_DRV_1BIT, + 141, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(142, "TCON1", 142, + 142, UNIPHIER_PIN_DRV_1BIT, + 142, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(143, "TCON2", 143, + 143, UNIPHIER_PIN_DRV_1BIT, + 143, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(144, "TCON3", 144, + 144, UNIPHIER_PIN_DRV_1BIT, + 144, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(145, "TCON4", 145, + 145, UNIPHIER_PIN_DRV_1BIT, + 145, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(146, "TCON5", 146, + 146, UNIPHIER_PIN_DRV_1BIT, + 146, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(147, "PWMA", 147, + 147, UNIPHIER_PIN_DRV_1BIT, + 147, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(148, "LR_GOUT", 148, + 148, UNIPHIER_PIN_DRV_1BIT, + 148, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(149, "XIRQ0", 149, + 149, UNIPHIER_PIN_DRV_1BIT, + 149, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(150, "XIRQ1", 150, + 150, UNIPHIER_PIN_DRV_1BIT, + 150, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(151, "XIRQ2", 151, + 151, UNIPHIER_PIN_DRV_1BIT, + 151, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(152, "XIRQ3", 152, + 152, UNIPHIER_PIN_DRV_1BIT, + 152, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(153, "XIRQ4", 153, + 153, UNIPHIER_PIN_DRV_1BIT, + 153, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(154, "XIRQ5", 154, + 154, UNIPHIER_PIN_DRV_1BIT, + 154, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(155, "XIRQ6", 155, + 155, UNIPHIER_PIN_DRV_1BIT, + 155, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(156, "XIRQ7", 156, + 156, UNIPHIER_PIN_DRV_1BIT, + 156, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(157, "XIRQ8", 157, + 157, UNIPHIER_PIN_DRV_1BIT, + 157, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(158, "AGCBS", 158, + 158, UNIPHIER_PIN_DRV_1BIT, + 158, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(159, "XIRQ21", 159, + 159, UNIPHIER_PIN_DRV_1BIT, + 159, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(160, "XIRQ22", 160, + 160, UNIPHIER_PIN_DRV_1BIT, + 160, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(161, "XIRQ23", 161, + 161, UNIPHIER_PIN_DRV_1BIT, + 161, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(162, "CH2CLK", 162, + 162, UNIPHIER_PIN_DRV_1BIT, + 162, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(163, "CH2PSYNC", 163, + 163, UNIPHIER_PIN_DRV_1BIT, + 163, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(164, "CH2VAL", 164, + 164, UNIPHIER_PIN_DRV_1BIT, + 164, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(165, "CH2DATA", 165, + 165, UNIPHIER_PIN_DRV_1BIT, + 165, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(166, "CK25O", 166, + 166, UNIPHIER_PIN_DRV_1BIT, + 166, UNIPHIER_PIN_PULL_DOWN), +}; + +static const unsigned emmc_pins[] = {18, 19, 20, 21, 22, 23, 24, 25}; +static const int emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned emmc_dat8_pins[] = {26, 27, 28, 29}; +static const int emmc_dat8_muxvals[] = {0, 0, 0, 0}; +static const unsigned ether_rmii_pins[] = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17}; +static const int ether_rmii_muxvals[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; +static const unsigned i2c0_pins[] = {63, 64}; +static const int i2c0_muxvals[] = {0, 0}; +static const unsigned i2c1_pins[] = {65, 66}; +static const int i2c1_muxvals[] = {0, 0}; +static const unsigned i2c3_pins[] = {67, 68}; +static const int i2c3_muxvals[] = {1, 1}; +static const unsigned i2c4_pins[] = {61, 62}; +static const int i2c4_muxvals[] = {1, 1}; +static const unsigned nand_pins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17}; +static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned system_bus_pins[] = {1, 2, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17}; +static const int system_bus_muxvals[] = {0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2}; +static const unsigned system_bus_cs1_pins[] = {0}; +static const int system_bus_cs1_muxvals[] = {0}; +static const unsigned uart0_pins[] = {54, 55}; +static const int uart0_muxvals[] = {0, 0}; +static const unsigned uart1_pins[] = {58, 59}; +static const int uart1_muxvals[] = {1, 1}; +static const unsigned uart2_pins[] = {90, 91}; +static const int uart2_muxvals[] = {1, 1}; +static const unsigned uart3_pins[] = {94, 95}; +static const int uart3_muxvals[] = {1, 1}; +static const unsigned usb0_pins[] = {46, 47}; +static const int usb0_muxvals[] = {0, 0}; +static const unsigned usb1_pins[] = {48, 49}; +static const int usb1_muxvals[] = {0, 0}; +static const unsigned usb2_pins[] = {50, 51}; +static const int usb2_muxvals[] = {0, 0}; +static const unsigned port_range_pins[] = { + 159, 160, 161, 162, 163, 164, 165, 166, /* PORT0x */ + 0, 1, 2, 3, 4, 5, 6, 7, /* PORT1x */ + 8, 9, 10, 11, 12, 13, 14, 15, /* PORT2x */ + 16, 17, 18, -1, -1, -1, -1, -1, /* PORT3x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT4x */ + -1, -1, -1, 46, 47, 48, 49, 50, /* PORT5x */ + 51, -1, -1, 54, 55, 56, 57, 58, /* PORT6x */ + 59, 60, 69, 70, 71, 72, 73, 74, /* PORT7x */ + 75, 76, 77, 78, 79, 80, 81, 82, /* PORT8x */ + 83, 84, 85, 86, 87, 88, 89, 90, /* PORT9x */ + 91, 92, 93, 94, 95, 96, 97, 98, /* PORT10x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT11x */ + 99, 100, 101, 102, 103, 104, 105, 106, /* PORT12x */ + 107, 108, 109, 110, 111, 112, 113, 114, /* PORT13x */ + 115, 116, 117, 118, 119, 120, 121, 122, /* PORT14x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT15x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT16x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT17x */ + 61, 62, 63, 64, 65, 66, 67, 68, /* PORT18x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT19x */ + 123, 124, 125, 126, 127, 128, 129, 130, /* PORT20x */ + 131, 132, 133, 134, 135, 136, 137, 138, /* PORT21x */ + 139, 140, 141, 142, -1, -1, -1, -1, /* PORT22x */ + 147, 148, 149, 150, 151, 152, 153, 154, /* PORT23x */ + 155, 156, 157, 143, 144, 145, 146, 158, /* PORT24x */ +}; +static const int port_range_muxvals[] = { + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT0x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT1x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT2x */ + 15, 15, 15, -1, -1, -1, -1, -1, /* PORT3x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT4x */ + -1, -1, -1, 15, 15, 15, 15, 15, /* PORT5x */ + 15, -1, -1, 15, 15, 15, 15, 15, /* PORT6x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT7x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT8x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT9x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT10x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT11x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT12x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT13x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT14x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT15x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT16x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT17x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT18x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT19x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT20x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT21x */ + 15, 15, 15, 15, -1, -1, -1, -1, /* PORT22x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT23x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT24x */ +}; +static const unsigned xirq_pins[] = { + 149, 150, 151, 152, 153, 154, 155, 156, /* XIRQ0-7 */ + 157, 143, 144, 145, 85, 146, 158, 84, /* XIRQ8-15 */ + 141, 142, 148, 50, 51, 159, 160, 161, /* XIRQ16-23 */ +}; +static const int xirq_muxvals[] = { + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ0-7 */ + 14, 14, 14, 14, 13, 14, 14, 13, /* XIRQ8-15 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ16-23 */ +}; +static const unsigned xirq_alternatives_pins[] = { + 94, 95, 96, 97, 98, 99, 100, 101, /* XIRQ0-7 */ + 102, 103, 104, 105, 106, 107, /* XIRQ8-11,13,14 */ + 108, 109, 110, 111, 112, 113, 114, 115, /* XIRQ16-23 */ + 9, 10, 11, 12, 13, 14, 15, 16, /* XIRQ4-11 */ + 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, /* XIRQ13,14,16-23 */ + 139, 140, 135, 147, /* XIRQ17,18,21,22 */ +}; +static const int xirq_alternatives_muxvals[] = { + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ0-7 */ + 14, 14, 14, 14, 14, 14, /* XIRQ8-11,13,14 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ16-23 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ4-11 */ + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ13,14,16-23 */ + 14, 14, 14, 14, /* XIRQ17,18,21,22 */ +}; + +static const struct uniphier_pinctrl_group uniphier_ld11_groups[] = { + UNIPHIER_PINCTRL_GROUP(emmc), + UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(ether_rmii), + UNIPHIER_PINCTRL_GROUP(i2c0), + UNIPHIER_PINCTRL_GROUP(i2c1), + UNIPHIER_PINCTRL_GROUP(i2c3), + UNIPHIER_PINCTRL_GROUP(i2c4), + UNIPHIER_PINCTRL_GROUP(nand), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), + UNIPHIER_PINCTRL_GROUP(usb0), + UNIPHIER_PINCTRL_GROUP(usb1), + UNIPHIER_PINCTRL_GROUP(usb2), + UNIPHIER_PINCTRL_GROUP_GPIO_RANGE_PORT(port_range), + UNIPHIER_PINCTRL_GROUP_GPIO_RANGE_IRQ(xirq), + UNIPHIER_PINCTRL_GROUP_GPIO_RANGE_IRQ(xirq_alternatives), + UNIPHIER_PINCTRL_GROUP_SINGLE(port00, port_range, 0), + UNIPHIER_PINCTRL_GROUP_SINGLE(port01, port_range, 1), + UNIPHIER_PINCTRL_GROUP_SINGLE(port02, port_range, 2), + UNIPHIER_PINCTRL_GROUP_SINGLE(port03, port_range, 3), + UNIPHIER_PINCTRL_GROUP_SINGLE(port04, port_range, 4), + UNIPHIER_PINCTRL_GROUP_SINGLE(port05, port_range, 5), + UNIPHIER_PINCTRL_GROUP_SINGLE(port06, port_range, 6), + UNIPHIER_PINCTRL_GROUP_SINGLE(port07, port_range, 7), + UNIPHIER_PINCTRL_GROUP_SINGLE(port10, port_range, 8), + UNIPHIER_PINCTRL_GROUP_SINGLE(port11, port_range, 9), + UNIPHIER_PINCTRL_GROUP_SINGLE(port12, port_range, 10), + UNIPHIER_PINCTRL_GROUP_SINGLE(port13, port_range, 11), + UNIPHIER_PINCTRL_GROUP_SINGLE(port14, port_range, 12), + UNIPHIER_PINCTRL_GROUP_SINGLE(port15, port_range, 13), + UNIPHIER_PINCTRL_GROUP_SINGLE(port16, port_range, 14), + UNIPHIER_PINCTRL_GROUP_SINGLE(port17, port_range, 15), + UNIPHIER_PINCTRL_GROUP_SINGLE(port20, port_range, 16), + UNIPHIER_PINCTRL_GROUP_SINGLE(port21, port_range, 17), + UNIPHIER_PINCTRL_GROUP_SINGLE(port22, port_range, 18), + UNIPHIER_PINCTRL_GROUP_SINGLE(port23, port_range, 19), + UNIPHIER_PINCTRL_GROUP_SINGLE(port24, port_range, 20), + UNIPHIER_PINCTRL_GROUP_SINGLE(port25, port_range, 21), + UNIPHIER_PINCTRL_GROUP_SINGLE(port26, port_range, 22), + UNIPHIER_PINCTRL_GROUP_SINGLE(port27, port_range, 23), + UNIPHIER_PINCTRL_GROUP_SINGLE(port30, port_range, 24), + UNIPHIER_PINCTRL_GROUP_SINGLE(port31, port_range, 25), + UNIPHIER_PINCTRL_GROUP_SINGLE(port32, port_range, 26), + UNIPHIER_PINCTRL_GROUP_SINGLE(port53, port_range, 43), + UNIPHIER_PINCTRL_GROUP_SINGLE(port54, port_range, 44), + UNIPHIER_PINCTRL_GROUP_SINGLE(port55, port_range, 45), + UNIPHIER_PINCTRL_GROUP_SINGLE(port56, port_range, 46), + UNIPHIER_PINCTRL_GROUP_SINGLE(port57, port_range, 47), + UNIPHIER_PINCTRL_GROUP_SINGLE(port60, port_range, 48), + UNIPHIER_PINCTRL_GROUP_SINGLE(port63, port_range, 51), + UNIPHIER_PINCTRL_GROUP_SINGLE(port64, port_range, 52), + UNIPHIER_PINCTRL_GROUP_SINGLE(port65, port_range, 53), + UNIPHIER_PINCTRL_GROUP_SINGLE(port66, port_range, 54), + UNIPHIER_PINCTRL_GROUP_SINGLE(port67, port_range, 55), + UNIPHIER_PINCTRL_GROUP_SINGLE(port70, port_range, 56), + UNIPHIER_PINCTRL_GROUP_SINGLE(port71, port_range, 57), + UNIPHIER_PINCTRL_GROUP_SINGLE(port72, port_range, 58), + UNIPHIER_PINCTRL_GROUP_SINGLE(port73, port_range, 59), + UNIPHIER_PINCTRL_GROUP_SINGLE(port74, port_range, 60), + UNIPHIER_PINCTRL_GROUP_SINGLE(port75, port_range, 61), + UNIPHIER_PINCTRL_GROUP_SINGLE(port76, port_range, 62), + UNIPHIER_PINCTRL_GROUP_SINGLE(port77, port_range, 63), + UNIPHIER_PINCTRL_GROUP_SINGLE(port80, port_range, 64), + UNIPHIER_PINCTRL_GROUP_SINGLE(port81, port_range, 65), + UNIPHIER_PINCTRL_GROUP_SINGLE(port82, port_range, 66), + UNIPHIER_PINCTRL_GROUP_SINGLE(port83, port_range, 67), + UNIPHIER_PINCTRL_GROUP_SINGLE(port84, port_range, 68), + UNIPHIER_PINCTRL_GROUP_SINGLE(port85, port_range, 69), + UNIPHIER_PINCTRL_GROUP_SINGLE(port86, port_range, 70), + UNIPHIER_PINCTRL_GROUP_SINGLE(port87, port_range, 71), + UNIPHIER_PINCTRL_GROUP_SINGLE(port90, port_range, 72), + UNIPHIER_PINCTRL_GROUP_SINGLE(port91, port_range, 73), + UNIPHIER_PINCTRL_GROUP_SINGLE(port92, port_range, 74), + UNIPHIER_PINCTRL_GROUP_SINGLE(port93, port_range, 75), + UNIPHIER_PINCTRL_GROUP_SINGLE(port94, port_range, 76), + UNIPHIER_PINCTRL_GROUP_SINGLE(port95, port_range, 77), + UNIPHIER_PINCTRL_GROUP_SINGLE(port96, port_range, 78), + UNIPHIER_PINCTRL_GROUP_SINGLE(port97, port_range, 79), + UNIPHIER_PINCTRL_GROUP_SINGLE(port100, port_range, 80), + UNIPHIER_PINCTRL_GROUP_SINGLE(port101, port_range, 81), + UNIPHIER_PINCTRL_GROUP_SINGLE(port102, port_range, 82), + UNIPHIER_PINCTRL_GROUP_SINGLE(port103, port_range, 83), + UNIPHIER_PINCTRL_GROUP_SINGLE(port104, port_range, 84), + UNIPHIER_PINCTRL_GROUP_SINGLE(port105, port_range, 85), + UNIPHIER_PINCTRL_GROUP_SINGLE(port106, port_range, 86), + UNIPHIER_PINCTRL_GROUP_SINGLE(port107, port_range, 87), + UNIPHIER_PINCTRL_GROUP_SINGLE(port120, port_range, 96), + UNIPHIER_PINCTRL_GROUP_SINGLE(port121, port_range, 97), + UNIPHIER_PINCTRL_GROUP_SINGLE(port122, port_range, 98), + UNIPHIER_PINCTRL_GROUP_SINGLE(port123, port_range, 99), + UNIPHIER_PINCTRL_GROUP_SINGLE(port124, port_range, 100), + UNIPHIER_PINCTRL_GROUP_SINGLE(port125, port_range, 101), + UNIPHIER_PINCTRL_GROUP_SINGLE(port126, port_range, 102), + UNIPHIER_PINCTRL_GROUP_SINGLE(port127, port_range, 103), + UNIPHIER_PINCTRL_GROUP_SINGLE(port130, port_range, 104), + UNIPHIER_PINCTRL_GROUP_SINGLE(port131, port_range, 105), + UNIPHIER_PINCTRL_GROUP_SINGLE(port132, port_range, 106), + UNIPHIER_PINCTRL_GROUP_SINGLE(port133, port_range, 107), + UNIPHIER_PINCTRL_GROUP_SINGLE(port134, port_range, 108), + UNIPHIER_PINCTRL_GROUP_SINGLE(port135, port_range, 109), + UNIPHIER_PINCTRL_GROUP_SINGLE(port136, port_range, 110), + UNIPHIER_PINCTRL_GROUP_SINGLE(port137, port_range, 111), + UNIPHIER_PINCTRL_GROUP_SINGLE(port140, port_range, 112), + UNIPHIER_PINCTRL_GROUP_SINGLE(port141, port_range, 113), + UNIPHIER_PINCTRL_GROUP_SINGLE(port142, port_range, 114), + UNIPHIER_PINCTRL_GROUP_SINGLE(port143, port_range, 115), + UNIPHIER_PINCTRL_GROUP_SINGLE(port144, port_range, 116), + UNIPHIER_PINCTRL_GROUP_SINGLE(port145, port_range, 117), + UNIPHIER_PINCTRL_GROUP_SINGLE(port146, port_range, 118), + UNIPHIER_PINCTRL_GROUP_SINGLE(port147, port_range, 119), + UNIPHIER_PINCTRL_GROUP_SINGLE(port180, port_range, 144), + UNIPHIER_PINCTRL_GROUP_SINGLE(port181, port_range, 145), + UNIPHIER_PINCTRL_GROUP_SINGLE(port182, port_range, 146), + UNIPHIER_PINCTRL_GROUP_SINGLE(port183, port_range, 147), + UNIPHIER_PINCTRL_GROUP_SINGLE(port184, port_range, 148), + UNIPHIER_PINCTRL_GROUP_SINGLE(port185, port_range, 149), + UNIPHIER_PINCTRL_GROUP_SINGLE(port186, port_range, 150), + UNIPHIER_PINCTRL_GROUP_SINGLE(port187, port_range, 151), + UNIPHIER_PINCTRL_GROUP_SINGLE(port200, port_range, 160), + UNIPHIER_PINCTRL_GROUP_SINGLE(port201, port_range, 161), + UNIPHIER_PINCTRL_GROUP_SINGLE(port202, port_range, 162), + UNIPHIER_PINCTRL_GROUP_SINGLE(port203, port_range, 163), + UNIPHIER_PINCTRL_GROUP_SINGLE(port204, port_range, 164), + UNIPHIER_PINCTRL_GROUP_SINGLE(port205, port_range, 165), + UNIPHIER_PINCTRL_GROUP_SINGLE(port206, port_range, 166), + UNIPHIER_PINCTRL_GROUP_SINGLE(port207, port_range, 167), + UNIPHIER_PINCTRL_GROUP_SINGLE(port210, port_range, 168), + UNIPHIER_PINCTRL_GROUP_SINGLE(port211, port_range, 169), + UNIPHIER_PINCTRL_GROUP_SINGLE(port212, port_range, 170), + UNIPHIER_PINCTRL_GROUP_SINGLE(port213, port_range, 171), + UNIPHIER_PINCTRL_GROUP_SINGLE(port214, port_range, 172), + UNIPHIER_PINCTRL_GROUP_SINGLE(port215, port_range, 173), + UNIPHIER_PINCTRL_GROUP_SINGLE(port216, port_range, 174), + UNIPHIER_PINCTRL_GROUP_SINGLE(port217, port_range, 175), + UNIPHIER_PINCTRL_GROUP_SINGLE(port220, port_range, 176), + UNIPHIER_PINCTRL_GROUP_SINGLE(port221, port_range, 177), + UNIPHIER_PINCTRL_GROUP_SINGLE(port222, port_range, 178), + UNIPHIER_PINCTRL_GROUP_SINGLE(port223, port_range, 179), + UNIPHIER_PINCTRL_GROUP_SINGLE(port230, port_range, 184), + UNIPHIER_PINCTRL_GROUP_SINGLE(port231, port_range, 185), + UNIPHIER_PINCTRL_GROUP_SINGLE(port232, port_range, 186), + UNIPHIER_PINCTRL_GROUP_SINGLE(port233, port_range, 187), + UNIPHIER_PINCTRL_GROUP_SINGLE(port234, port_range, 188), + UNIPHIER_PINCTRL_GROUP_SINGLE(port235, port_range, 189), + UNIPHIER_PINCTRL_GROUP_SINGLE(port236, port_range, 190), + UNIPHIER_PINCTRL_GROUP_SINGLE(port237, port_range, 191), + UNIPHIER_PINCTRL_GROUP_SINGLE(port240, port_range, 192), + UNIPHIER_PINCTRL_GROUP_SINGLE(port241, port_range, 193), + UNIPHIER_PINCTRL_GROUP_SINGLE(port242, port_range, 194), + UNIPHIER_PINCTRL_GROUP_SINGLE(port243, port_range, 195), + UNIPHIER_PINCTRL_GROUP_SINGLE(port244, port_range, 196), + UNIPHIER_PINCTRL_GROUP_SINGLE(port245, port_range, 197), + UNIPHIER_PINCTRL_GROUP_SINGLE(port246, port_range, 198), + UNIPHIER_PINCTRL_GROUP_SINGLE(port247, port_range, 199), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq0, xirq, 0), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq1, xirq, 1), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq2, xirq, 2), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq3, xirq, 3), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq4, xirq, 4), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq5, xirq, 5), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq6, xirq, 6), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq7, xirq, 7), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq8, xirq, 8), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq9, xirq, 9), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq10, xirq, 10), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq11, xirq, 11), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq12, xirq, 12), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq13, xirq, 13), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq14, xirq, 14), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq15, xirq, 15), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq16, xirq, 16), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq17, xirq, 17), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq18, xirq, 18), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq19, xirq, 19), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq20, xirq, 20), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq21, xirq, 21), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq22, xirq, 22), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq23, xirq, 23), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq0b, xirq_alternatives, 0), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq1b, xirq_alternatives, 1), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq2b, xirq_alternatives, 2), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq3b, xirq_alternatives, 3), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq4b, xirq_alternatives, 4), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq5b, xirq_alternatives, 5), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq6b, xirq_alternatives, 6), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq7b, xirq_alternatives, 7), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq8b, xirq_alternatives, 8), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq9b, xirq_alternatives, 9), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq10b, xirq_alternatives, 10), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq11b, xirq_alternatives, 11), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq13b, xirq_alternatives, 12), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq14b, xirq_alternatives, 13), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq16b, xirq_alternatives, 14), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq17b, xirq_alternatives, 15), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq18b, xirq_alternatives, 16), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq19b, xirq_alternatives, 17), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq20b, xirq_alternatives, 18), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq21b, xirq_alternatives, 19), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq22b, xirq_alternatives, 20), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq23b, xirq_alternatives, 21), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq4c, xirq_alternatives, 22), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq5c, xirq_alternatives, 23), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq6c, xirq_alternatives, 24), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq7c, xirq_alternatives, 25), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq8c, xirq_alternatives, 26), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq9c, xirq_alternatives, 27), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq10c, xirq_alternatives, 28), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq11c, xirq_alternatives, 29), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq13c, xirq_alternatives, 30), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq14c, xirq_alternatives, 31), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq16c, xirq_alternatives, 32), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq17c, xirq_alternatives, 33), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq18c, xirq_alternatives, 34), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq19c, xirq_alternatives, 35), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq20c, xirq_alternatives, 36), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq21c, xirq_alternatives, 37), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq22c, xirq_alternatives, 38), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq23c, xirq_alternatives, 39), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq17d, xirq_alternatives, 40), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq18d, xirq_alternatives, 41), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq21d, xirq_alternatives, 42), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq22d, xirq_alternatives, 43), +}; + +static const char * const emmc_groups[] = {"emmc", "emmc_dat8"}; +static const char * const ether_rmii_groups[] = {"ether_rmii"}; +static const char * const i2c0_groups[] = {"i2c0"}; +static const char * const i2c1_groups[] = {"i2c1"}; +static const char * const i2c3_groups[] = {"i2c3"}; +static const char * const i2c4_groups[] = {"i2c4"}; +static const char * const nand_groups[] = {"nand"}; +static const char * const system_bus_groups[] = {"system_bus", + "system_bus_cs1"}; +static const char * const uart0_groups[] = {"uart0"}; +static const char * const uart1_groups[] = {"uart1"}; +static const char * const uart2_groups[] = {"uart2"}; +static const char * const uart3_groups[] = {"uart3"}; +static const char * const usb0_groups[] = {"usb0"}; +static const char * const usb1_groups[] = {"usb1"}; +static const char * const usb2_groups[] = {"usb2"}; +static const char * const port_groups[] = { + "port00", "port01", "port02", "port03", + "port04", "port05", "port06", "port07", + "port10", "port11", "port12", "port13", + "port14", "port15", "port16", "port17", + "port20", "port21", "port22", "port23", + "port24", "port25", "port26", "port27", + "port30", "port31", "port32", + /* port33-52 missing */ "port53", + "port54", "port55", "port56", "port57", + "port60", /* port61-62 missing*/ "port63", + "port64", "port65", "port66", "port67", + "port70", "port71", "port72", "port73", + "port74", "port75", "port76", "port77", + "port80", "port81", "port82", "port83", + "port84", "port85", "port86", "port87", + "port90", "port91", "port92", "port93", + "port94", "port95", "port96", "port97", + "port100", "port101", "port102", "port103", + "port104", "port105", "port106", "port107", + /* port110-117 missing */ + "port120", "port121", "port122", "port123", + "port124", "port125", "port126", "port127", + "port130", "port131", "port132", "port133", + "port134", "port135", "port136", "port137", + "port140", "port141", "port142", "port143", + "port144", "port145", "port146", "port147", + /* port150-177 missing */ + "port180", "port181", "port182", "port183", + "port184", "port185", "port186", "port187", + /* port190-197 missing */ + "port200", "port201", "port202", "port203", + "port204", "port205", "port206", "port207", + "port210", "port211", "port212", "port213", + "port214", "port215", "port216", "port217", + "port220", "port221", "port222", "port223", + /* port224-227 missing */ + "port230", "port231", "port232", "port233", + "port234", "port235", "port236", "port237", + "port240", "port241", "port242", "port243", + "port244", "port245", "port246", "port247", +}; +static const char * const xirq_groups[] = { + "xirq0", "xirq1", "xirq2", "xirq3", + "xirq4", "xirq5", "xirq6", "xirq7", + "xirq8", "xirq9", "xirq10", "xirq11", + "xirq12", "xirq13", "xirq14", "xirq15", + "xirq16", "xirq17", "xirq18", "xirq19", + "xirq20", "xirq21", "xirq22", "xirq23", + "xirq0b", "xirq1b", "xirq2b", "xirq3b", + "xirq4b", "xirq5b", "xirq6b", "xirq7b", + "xirq8b", "xirq9b", "xirq10b", "xirq11b", + /* none */ "xirq13b", "xirq14b", /* none */ + "xirq16b", "xirq17b", "xirq18b", "xirq19b", + "xirq20b", "xirq21b", "xirq22b", "xirq23b", + "xirq4c", "xirq5c", "xirq6c", "xirq7c", + "xirq8c", "xirq9c", "xirq10c", "xirq11c", + /* none */ "xirq13c", "xirq14c", /* none */ + "xirq16c", "xirq17c", "xirq18c", "xirq19c", + "xirq20c", "xirq21c", "xirq22c", "xirq23c", + "xirq17d", "xirq18d", "xirq21d", "xirq22d", +}; + +static const struct uniphier_pinmux_function uniphier_ld11_functions[] = { + UNIPHIER_PINMUX_FUNCTION(emmc), + UNIPHIER_PINMUX_FUNCTION(ether_rmii), + UNIPHIER_PINMUX_FUNCTION(i2c0), + UNIPHIER_PINMUX_FUNCTION(i2c1), + UNIPHIER_PINMUX_FUNCTION(i2c3), + UNIPHIER_PINMUX_FUNCTION(i2c4), + UNIPHIER_PINMUX_FUNCTION(nand), + UNIPHIER_PINMUX_FUNCTION(system_bus), + UNIPHIER_PINMUX_FUNCTION(uart0), + UNIPHIER_PINMUX_FUNCTION(uart1), + UNIPHIER_PINMUX_FUNCTION(uart2), + UNIPHIER_PINMUX_FUNCTION(uart3), + UNIPHIER_PINMUX_FUNCTION(usb0), + UNIPHIER_PINMUX_FUNCTION(usb1), + UNIPHIER_PINMUX_FUNCTION(usb2), + UNIPHIER_PINMUX_FUNCTION(port), + UNIPHIER_PINMUX_FUNCTION(xirq), +}; + +static struct uniphier_pinctrl_socdata uniphier_ld11_pindata = { + .pins = uniphier_ld11_pins, + .npins = ARRAY_SIZE(uniphier_ld11_pins), + .groups = uniphier_ld11_groups, + .groups_count = ARRAY_SIZE(uniphier_ld11_groups), + .functions = uniphier_ld11_functions, + .functions_count = ARRAY_SIZE(uniphier_ld11_functions), + .caps = UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL, +}; + +static int uniphier_ld11_pinctrl_probe(struct platform_device *pdev) +{ + return uniphier_pinctrl_probe(pdev, &uniphier_ld11_pindata); +} + +static const struct of_device_id uniphier_ld11_pinctrl_match[] = { + { .compatible = "socionext,uniphier-ld11-pinctrl" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, uniphier_ld11_pinctrl_match); + +static struct platform_driver uniphier_ld11_pinctrl_driver = { + .probe = uniphier_ld11_pinctrl_probe, + .driver = { + .name = "uniphier-ld11-pinctrl", + .of_match_table = uniphier_ld11_pinctrl_match, + }, +}; +module_platform_driver(uniphier_ld11_pinctrl_driver); + +MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); +MODULE_DESCRIPTION("UniPhier PH1-LD11 pinctrl driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c new file mode 100644 index 000000000000..aa8bd9794683 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c @@ -0,0 +1,1050 @@ +/* + * Copyright (C) 2016 Socionext Inc. + * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pinctrl/pinctrl.h> +#include <linux/platform_device.h> + +#include "pinctrl-uniphier.h" + +static const struct pinctrl_pin_desc uniphier_ld20_pins[] = { + UNIPHIER_PINCTRL_PIN(0, "XECS1", 0, + 0, UNIPHIER_PIN_DRV_3BIT, + 0, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(1, "ERXW", 1, + 1, UNIPHIER_PIN_DRV_3BIT, + 1, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(2, "XERWE1", 2, + 2, UNIPHIER_PIN_DRV_3BIT, + 2, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(3, "XNFWP", 3, + 3, UNIPHIER_PIN_DRV_3BIT, + 3, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(4, "XNFCE0", 4, + 4, UNIPHIER_PIN_DRV_3BIT, + 4, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(5, "NFRYBY0", 5, + 5, UNIPHIER_PIN_DRV_3BIT, + 5, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(6, "XNFRE", 6, + 6, UNIPHIER_PIN_DRV_3BIT, + 6, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(7, "XNFWE", 7, + 7, UNIPHIER_PIN_DRV_3BIT, + 7, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(8, "NFALE", 8, + 8, UNIPHIER_PIN_DRV_3BIT, + 8, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(9, "NFCLE", 9, + 9, UNIPHIER_PIN_DRV_3BIT, + 9, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(10, "NFD0", 10, + 10, UNIPHIER_PIN_DRV_3BIT, + 10, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(11, "NFD1", 11, + 11, UNIPHIER_PIN_DRV_3BIT, + 11, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(12, "NFD2", 12, + 12, UNIPHIER_PIN_DRV_3BIT, + 12, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(13, "NFD3", 13, + 13, UNIPHIER_PIN_DRV_3BIT, + 13, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(14, "NFD4", 14, + 14, UNIPHIER_PIN_DRV_3BIT, + 14, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(15, "NFD5", 15, + 15, UNIPHIER_PIN_DRV_3BIT, + 15, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(16, "NFD6", 16, + 16, UNIPHIER_PIN_DRV_3BIT, + 16, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(17, "NFD7", 17, + 17, UNIPHIER_PIN_DRV_3BIT, + 17, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(18, "XERST", 18, + 0, UNIPHIER_PIN_DRV_2BIT, + 18, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(19, "MMCCLK", 19, + 1, UNIPHIER_PIN_DRV_2BIT, + 19, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(20, "MMCCMD", 20, + 2, UNIPHIER_PIN_DRV_2BIT, + 20, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(21, "MMCDS", 21, + 3, UNIPHIER_PIN_DRV_2BIT, + 21, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(22, "MMCDAT0", 22, + 4, UNIPHIER_PIN_DRV_2BIT, + 22, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(23, "MMCDAT1", 23, + 5, UNIPHIER_PIN_DRV_2BIT, + 23, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(24, "MMCDAT2", 24, + 6, UNIPHIER_PIN_DRV_2BIT, + 24, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(25, "MMCDAT3", 25, + 7, UNIPHIER_PIN_DRV_2BIT, + 25, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(26, "MMCDAT4", 26, + 8, UNIPHIER_PIN_DRV_2BIT, + 26, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(27, "MMCDAT5", 27, + 9, UNIPHIER_PIN_DRV_2BIT, + 27, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(28, "MMCDAT6", 28, + 10, UNIPHIER_PIN_DRV_2BIT, + 28, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(29, "MMCDAT7", 29, + 11, UNIPHIER_PIN_DRV_2BIT, + 29, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(30, "MDC", 30, + 18, UNIPHIER_PIN_DRV_3BIT, + 30, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(31, "MDIO", 31, + 19, UNIPHIER_PIN_DRV_3BIT, + 31, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(32, "MDIO_INTL", 32, + 20, UNIPHIER_PIN_DRV_3BIT, + 32, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(33, "PHYRSTL", 33, + 21, UNIPHIER_PIN_DRV_3BIT, + 33, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(34, "RGMII_RXCLK", 34, + 22, UNIPHIER_PIN_DRV_3BIT, + 34, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(35, "RGMII_RXD0", 35, + 23, UNIPHIER_PIN_DRV_3BIT, + 35, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(36, "RGMII_RXD1", 36, + 24, UNIPHIER_PIN_DRV_3BIT, + 36, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(37, "RGMII_RXD2", 37, + 25, UNIPHIER_PIN_DRV_3BIT, + 37, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(38, "RGMII_RXD3", 38, + 26, UNIPHIER_PIN_DRV_3BIT, + 38, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(39, "RGMII_RXCTL", 39, + 27, UNIPHIER_PIN_DRV_3BIT, + 39, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(40, "RGMII_TXCLK", 40, + 28, UNIPHIER_PIN_DRV_3BIT, + 40, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(41, "RGMII_TXD0", 41, + 29, UNIPHIER_PIN_DRV_3BIT, + 41, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(42, "RGMII_TXD1", 42, + 30, UNIPHIER_PIN_DRV_3BIT, + 42, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(43, "RGMII_TXD2", 43, + 31, UNIPHIER_PIN_DRV_3BIT, + 43, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(44, "RGMII_TXD3", 44, + 32, UNIPHIER_PIN_DRV_3BIT, + 44, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(45, "RGMII_TXCTL", 45, + 33, UNIPHIER_PIN_DRV_3BIT, + 45, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(46, "USB0VBUS", 46, + 34, UNIPHIER_PIN_DRV_3BIT, + 46, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(47, "USB0OD", 47, + 35, UNIPHIER_PIN_DRV_3BIT, + 47, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(48, "USB1VBUS", 48, + 36, UNIPHIER_PIN_DRV_3BIT, + 48, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(49, "USB1OD", 49, + 37, UNIPHIER_PIN_DRV_3BIT, + 49, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(50, "USB2VBUS", 50, + 38, UNIPHIER_PIN_DRV_3BIT, + 50, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(51, "USB2OD", 51, + 39, UNIPHIER_PIN_DRV_3BIT, + 51, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(52, "USB3VBUS", 52, + 40, UNIPHIER_PIN_DRV_3BIT, + 52, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(53, "USB3OD", 53, + 41, UNIPHIER_PIN_DRV_3BIT, + 53, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(54, "TXD0", 54, + 42, UNIPHIER_PIN_DRV_3BIT, + 54, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(55, "RXD0", 55, + 43, UNIPHIER_PIN_DRV_3BIT, + 55, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(56, "SPISYNC0", 56, + 44, UNIPHIER_PIN_DRV_3BIT, + 56, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(57, "SPISCLK0", 57, + 45, UNIPHIER_PIN_DRV_3BIT, + 57, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(58, "SPITXD0", 58, + 46, UNIPHIER_PIN_DRV_3BIT, + 58, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(59, "SPIRXD0", 59, + 47, UNIPHIER_PIN_DRV_3BIT, + 59, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(60, "AGCI", 60, + 48, UNIPHIER_PIN_DRV_3BIT, + 60, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(61, "DMDSDA0", 61, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(62, "DMDSCL0", 62, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(63, "SDA0", 63, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(64, "SCL0", 64, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(65, "SDA1", 65, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(66, "SCL1", 66, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(67, "HIN", 67, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(68, "VIN", 68, + -1, UNIPHIER_PIN_DRV_FIXED4, + -1, UNIPHIER_PIN_PULL_NONE), + UNIPHIER_PINCTRL_PIN(69, "PCA00", 69, + 49, UNIPHIER_PIN_DRV_3BIT, + 69, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(70, "PCA01", 70, + 50, UNIPHIER_PIN_DRV_3BIT, + 70, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(71, "PCA02", 71, + 51, UNIPHIER_PIN_DRV_3BIT, + 71, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(72, "PCA03", 72, + 52, UNIPHIER_PIN_DRV_3BIT, + 72, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(73, "PCA04", 73, + 53, UNIPHIER_PIN_DRV_3BIT, + 73, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(74, "PCA05", 74, + 54, UNIPHIER_PIN_DRV_3BIT, + 74, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(75, "PCA06", 75, + 55, UNIPHIER_PIN_DRV_3BIT, + 75, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(76, "PCA07", 76, + 56, UNIPHIER_PIN_DRV_3BIT, + 76, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(77, "PCA08", 77, + 57, UNIPHIER_PIN_DRV_3BIT, + 77, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(78, "PCA09", 78, + 58, UNIPHIER_PIN_DRV_3BIT, + 78, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(79, "PCA10", 79, + 59, UNIPHIER_PIN_DRV_3BIT, + 79, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(80, "PCA11", 80, + 60, UNIPHIER_PIN_DRV_3BIT, + 80, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(81, "PCA12", 81, + 61, UNIPHIER_PIN_DRV_3BIT, + 81, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(82, "PCA13", 82, + 62, UNIPHIER_PIN_DRV_3BIT, + 82, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(83, "PCA14", 83, + 63, UNIPHIER_PIN_DRV_3BIT, + 83, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(84, "PC0READY", 84, + 0, UNIPHIER_PIN_DRV_1BIT, + 84, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(85, "PC0CD1", 85, + 1, UNIPHIER_PIN_DRV_1BIT, + 85, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(86, "PC0CD2", 86, + 2, UNIPHIER_PIN_DRV_1BIT, + 86, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(87, "PC0WAIT", 87, + 3, UNIPHIER_PIN_DRV_1BIT, + 87, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(88, "PC0RESET", 88, + 4, UNIPHIER_PIN_DRV_1BIT, + 88, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(89, "PC0CE1", 89, + 5, UNIPHIER_PIN_DRV_1BIT, + 89, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(90, "PC0WE", 90, + 6, UNIPHIER_PIN_DRV_1BIT, + 90, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(91, "PC0OE", 91, + 7, UNIPHIER_PIN_DRV_1BIT, + 91, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(92, "PC0IOWR", 92, + 8, UNIPHIER_PIN_DRV_1BIT, + 92, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(93, "PC0IORD", 93, + 9, UNIPHIER_PIN_DRV_1BIT, + 93, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(94, "PCD00", 94, + 10, UNIPHIER_PIN_DRV_1BIT, + 94, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(95, "PCD01", 95, + 11, UNIPHIER_PIN_DRV_1BIT, + 95, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(96, "PCD02", 96, + 12, UNIPHIER_PIN_DRV_1BIT, + 96, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(97, "PCD03", 97, + 13, UNIPHIER_PIN_DRV_1BIT, + 97, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(98, "PCD04", 98, + 14, UNIPHIER_PIN_DRV_1BIT, + 98, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(99, "PCD05", 99, + 15, UNIPHIER_PIN_DRV_1BIT, + 99, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(100, "PCD06", 100, + 16, UNIPHIER_PIN_DRV_1BIT, + 100, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(101, "PCD07", 101, + 17, UNIPHIER_PIN_DRV_1BIT, + 101, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(102, "HS0BCLKIN", 102, + 18, UNIPHIER_PIN_DRV_1BIT, + 102, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(103, "HS0SYNCIN", 103, + 19, UNIPHIER_PIN_DRV_1BIT, + 103, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(104, "HS0VALIN", 104, + 20, UNIPHIER_PIN_DRV_1BIT, + 104, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(105, "HS0DIN0", 105, + 21, UNIPHIER_PIN_DRV_1BIT, + 105, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(106, "HS0DIN1", 106, + 22, UNIPHIER_PIN_DRV_1BIT, + 106, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(107, "HS0DIN2", 107, + 23, UNIPHIER_PIN_DRV_1BIT, + 107, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(108, "HS0DIN3", 108, + 24, UNIPHIER_PIN_DRV_1BIT, + 108, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(109, "HS0DIN4", 109, + 25, UNIPHIER_PIN_DRV_1BIT, + 109, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(110, "HS0DIN5", 110, + 26, UNIPHIER_PIN_DRV_1BIT, + 110, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(111, "HS0DIN6", 111, + 27, UNIPHIER_PIN_DRV_1BIT, + 111, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(112, "HS0DIN7", 112, + 28, UNIPHIER_PIN_DRV_1BIT, + 112, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(113, "HS0BCLKOUT", 113, + 64, UNIPHIER_PIN_DRV_3BIT, + 113, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(114, "HS0SYNCOUT", 114, + 65, UNIPHIER_PIN_DRV_3BIT, + 114, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(115, "HS0VALOUT", 115, + 66, UNIPHIER_PIN_DRV_3BIT, + 115, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(116, "HS0DOUT0", 116, + 67, UNIPHIER_PIN_DRV_3BIT, + 116, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(117, "HS0DOUT1", 117, + 68, UNIPHIER_PIN_DRV_3BIT, + 117, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(118, "HS0DOUT2", 118, + 69, UNIPHIER_PIN_DRV_3BIT, + 118, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(119, "HS0DOUT3", 119, + 70, UNIPHIER_PIN_DRV_3BIT, + 119, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(120, "HS0DOUT4", 120, + 71, UNIPHIER_PIN_DRV_3BIT, + 120, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(121, "HS0DOUT5", 121, + 72, UNIPHIER_PIN_DRV_3BIT, + 121, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(122, "HS0DOUT6", 122, + 73, UNIPHIER_PIN_DRV_3BIT, + 122, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(123, "HS0DOUT7", 123, + 74, UNIPHIER_PIN_DRV_3BIT, + 123, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(124, "HS1BCLKIN", 124, + 75, UNIPHIER_PIN_DRV_3BIT, + 124, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(125, "HS1SYNCIN", 125, + 76, UNIPHIER_PIN_DRV_3BIT, + 125, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(126, "HS1VALIN", 126, + 77, UNIPHIER_PIN_DRV_3BIT, + 126, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(127, "HS1DIN0", 127, + 78, UNIPHIER_PIN_DRV_3BIT, + 127, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(128, "HS1DIN1", 128, + 79, UNIPHIER_PIN_DRV_3BIT, + 128, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(129, "HS1DIN2", 129, + 80, UNIPHIER_PIN_DRV_3BIT, + 129, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(130, "HS1DIN3", 130, + 81, UNIPHIER_PIN_DRV_3BIT, + 130, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(131, "HS1DIN4", 131, + 82, UNIPHIER_PIN_DRV_3BIT, + 131, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(132, "HS1DIN5", 132, + 83, UNIPHIER_PIN_DRV_3BIT, + 132, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(133, "HS1DIN6", 133, + 84, UNIPHIER_PIN_DRV_3BIT, + 133, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(134, "HS1DIN7", 134, + 85, UNIPHIER_PIN_DRV_3BIT, + 134, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(135, "AO1IEC", 135, + 86, UNIPHIER_PIN_DRV_3BIT, + 135, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(136, "AO1ARC", 136, + 87, UNIPHIER_PIN_DRV_3BIT, + 136, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(137, "AO1DACCK", 137, + 88, UNIPHIER_PIN_DRV_3BIT, + 137, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(138, "AO1BCK", 138, + 89, UNIPHIER_PIN_DRV_3BIT, + 138, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(139, "AO1LRCK", 139, + 90, UNIPHIER_PIN_DRV_3BIT, + 139, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(140, "AO1D0", 140, + 91, UNIPHIER_PIN_DRV_3BIT, + 140, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(141, "AO1D1", 141, + 92, UNIPHIER_PIN_DRV_3BIT, + 141, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(142, "AO1D2", 142, + 93, UNIPHIER_PIN_DRV_3BIT, + 142, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(143, "HTPDN0", 143, + 94, UNIPHIER_PIN_DRV_3BIT, + 143, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(144, "LOCKN0", 144, + 95, UNIPHIER_PIN_DRV_3BIT, + 144, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(145, "HTPDN1", 145, + 96, UNIPHIER_PIN_DRV_3BIT, + 145, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(146, "LOCKN1", 146, + 97, UNIPHIER_PIN_DRV_3BIT, + 146, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(147, "PWMA", 147, + 98, UNIPHIER_PIN_DRV_3BIT, + 147, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(148, "LR_GOUT", 148, + 99, UNIPHIER_PIN_DRV_3BIT, + 148, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(149, "XIRQ0", 149, + 100, UNIPHIER_PIN_DRV_3BIT, + 149, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(150, "XIRQ1", 150, + 101, UNIPHIER_PIN_DRV_3BIT, + 150, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(151, "XIRQ2", 151, + 102, UNIPHIER_PIN_DRV_3BIT, + 151, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(152, "XIRQ3", 152, + 103, UNIPHIER_PIN_DRV_3BIT, + 152, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(153, "XIRQ4", 153, + 104, UNIPHIER_PIN_DRV_3BIT, + 153, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(154, "XIRQ5", 154, + 105, UNIPHIER_PIN_DRV_3BIT, + 154, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(155, "XIRQ6", 155, + 106, UNIPHIER_PIN_DRV_3BIT, + 155, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(156, "XIRQ7", 156, + 107, UNIPHIER_PIN_DRV_3BIT, + 156, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(157, "XIRQ8", 157, + 108, UNIPHIER_PIN_DRV_3BIT, + 157, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(158, "XIRQ9", 158, + 109, UNIPHIER_PIN_DRV_3BIT, + 158, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(159, "XIRQ10", 159, + 110, UNIPHIER_PIN_DRV_3BIT, + 159, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(160, "XIRQ11", 160, + 111, UNIPHIER_PIN_DRV_3BIT, + 160, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(161, "XIRQ13", 161, + 112, UNIPHIER_PIN_DRV_3BIT, + 161, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(162, "XIRQ14", 162, + 113, UNIPHIER_PIN_DRV_3BIT, + 162, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(163, "XIRQ16", 163, + 114, UNIPHIER_PIN_DRV_3BIT, + 163, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(164, "XIRQ17", 164, + 115, UNIPHIER_PIN_DRV_3BIT, + 164, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(165, "XIRQ18", 165, + 116, UNIPHIER_PIN_DRV_3BIT, + 165, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(166, "XIRQ19", 166, + 117, UNIPHIER_PIN_DRV_3BIT, + 166, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(167, "XIRQ20", 167, + 118, UNIPHIER_PIN_DRV_3BIT, + 167, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(168, "PORT00", 168, + 119, UNIPHIER_PIN_DRV_3BIT, + 168, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(169, "PORT01", 169, + 120, UNIPHIER_PIN_DRV_3BIT, + 169, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(170, "PORT02", 170, + 121, UNIPHIER_PIN_DRV_3BIT, + 170, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(171, "PORT03", 171, + 122, UNIPHIER_PIN_DRV_3BIT, + 171, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(172, "PORT04", 172, + 123, UNIPHIER_PIN_DRV_3BIT, + 172, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(173, "CK27FO", 173, + 124, UNIPHIER_PIN_DRV_3BIT, + 173, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(174, "PHSYNCO", 174, + 125, UNIPHIER_PIN_DRV_3BIT, + 174, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(175, "PVSYNCO", 175, + 126, UNIPHIER_PIN_DRV_3BIT, + 175, UNIPHIER_PIN_PULL_DOWN), +}; + +static const unsigned emmc_pins[] = {18, 19, 20, 21, 22, 23, 24, 25}; +static const int emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned emmc_dat8_pins[] = {26, 27, 28, 29}; +static const int emmc_dat8_muxvals[] = {0, 0, 0, 0}; +static const unsigned ether_rgmii_pins[] = {30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45}; +static const int ether_rgmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; +static const unsigned ether_rmii_pins[] = {30, 31, 32, 33, 34, 35, 36, 37, 39, + 41, 42, 45}; +static const int ether_rmii_muxvals[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; +static const unsigned i2c0_pins[] = {63, 64}; +static const int i2c0_muxvals[] = {0, 0}; +static const unsigned i2c1_pins[] = {65, 66}; +static const int i2c1_muxvals[] = {0, 0}; +static const unsigned i2c3_pins[] = {67, 68}; +static const int i2c3_muxvals[] = {1, 1}; +static const unsigned i2c4_pins[] = {61, 62}; +static const int i2c4_muxvals[] = {1, 1}; +static const unsigned nand_pins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17}; +static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned sd_pins[] = {10, 11, 12, 13, 14, 15, 16, 17}; +static const int sd_muxvals[] = {3, 3, 3, 3, 3, 3, 3, 3}; /* No SDVOLC */ +static const unsigned system_bus_pins[] = {1, 2, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17}; +static const int system_bus_muxvals[] = {0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2}; +static const unsigned system_bus_cs1_pins[] = {0}; +static const int system_bus_cs1_muxvals[] = {0}; +static const unsigned uart0_pins[] = {54, 55}; +static const int uart0_muxvals[] = {0, 0}; +static const unsigned uart1_pins[] = {58, 59}; +static const int uart1_muxvals[] = {1, 1}; +static const unsigned uart2_pins[] = {90, 91}; +static const int uart2_muxvals[] = {1, 1}; +static const unsigned uart3_pins[] = {94, 95}; +static const int uart3_muxvals[] = {1, 1}; +static const unsigned usb0_pins[] = {46, 47}; +static const int usb0_muxvals[] = {0, 0}; +static const unsigned usb1_pins[] = {48, 49}; +static const int usb1_muxvals[] = {0, 0}; +static const unsigned usb2_pins[] = {50, 51}; +static const int usb2_muxvals[] = {0, 0}; +static const unsigned usb3_pins[] = {52, 53}; +static const int usb3_muxvals[] = {0, 0}; +static const unsigned port_range_pins[] = { + 168, 169, 170, 171, 172, 173, 174, 175, /* PORT0x */ + 0, 1, 2, 3, 4, 5, 6, 7, /* PORT1x */ + 8, 9, 10, 11, 12, 13, 14, 15, /* PORT2x */ + 16, 17, 18, 30, 31, 32, 33, 34, /* PORT3x */ + 35, 36, 37, 38, 39, 40, 41, 42, /* PORT4x */ + 43, 44, 45, 46, 47, 48, 49, 50, /* PORT5x */ + 51, 52, 53, 54, 55, 56, 57, 58, /* PORT6x */ + 59, 60, 69, 70, 71, 72, 73, 74, /* PORT7x */ + 75, 76, 77, 78, 79, 80, 81, 82, /* PORT8x */ + 83, 84, 85, 86, 87, 88, 89, 90, /* PORT9x */ + 91, 92, 93, 94, 95, 96, 97, 98, /* PORT10x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT11x */ + 99, 100, 101, 102, 103, 104, 105, 106, /* PORT12x */ + 107, 108, 109, 110, 111, 112, 113, 114, /* PORT13x */ + 115, 116, 117, 118, 119, 120, 121, 122, /* PORT14x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT15x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT16x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT17x */ + 61, 62, 63, 64, 65, 66, 67, 68, /* PORT18x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT19x */ + 123, 124, 125, 126, 127, 128, 129, 130, /* PORT20x */ + 131, 132, 133, 134, 135, 136, 137, 138, /* PORT21x */ + 139, 140, 141, 142, 143, 144, 145, 146, /* PORT22x */ + 147, 148, 149, 150, 151, 152, 153, 154, /* PORT23x */ + 155, 156, 157, 158, 159, 160, 161, 162, /* PORT24x */ + 163, 164, 165, 166, 167, /* PORT25x */ +}; +static const int port_range_muxvals[] = { + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT0x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT1x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT2x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT3x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT4x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT5x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT6x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT7x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT8x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT9x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT10x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT11x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT12x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT13x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT14x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT15x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT16x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT17x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT18x */ + -1, -1, -1, -1, -1, -1, -1, -1, /* PORT19x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT20x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT21x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT22x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT23x */ + 15, 15, 15, 15, 15, 15, 15, 15, /* PORT24x */ + 15, 15, 15, 15, 15, /* PORT25x */ +}; +static const unsigned xirq_pins[] = { + 149, 150, 151, 152, 153, 154, 155, 156, /* XIRQ0-7 */ + 157, 158, 159, 160, 85, 161, 162, 84, /* XIRQ8-15 */ + 163, 164, 165, 166, 167, 146, 52, 53, /* XIRQ16-23 */ +}; +static const int xirq_muxvals[] = { + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ0-7 */ + 14, 14, 14, 14, 13, 14, 14, 13, /* XIRQ8-15 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ16-23 */ +}; +static const unsigned xirq_alternatives_pins[] = { + 94, 95, 96, 97, 98, 99, 100, 101, /* XIRQ0-7 */ + 102, 103, 104, 105, 106, 107, /* XIRQ8-11,13,14 */ + 108, 109, 110, 111, 112, 147, 141, 142, /* XIRQ16-23 */ +}; +static const int xirq_alternatives_muxvals[] = { + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ0-7 */ + 14, 14, 14, 14, 14, 14, /* XIRQ8-11,13,14 */ + 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ16-23 */ +}; + +static const struct uniphier_pinctrl_group uniphier_ld20_groups[] = { + UNIPHIER_PINCTRL_GROUP(emmc), + UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(ether_rgmii), + UNIPHIER_PINCTRL_GROUP(ether_rmii), + UNIPHIER_PINCTRL_GROUP(i2c0), + UNIPHIER_PINCTRL_GROUP(i2c1), + UNIPHIER_PINCTRL_GROUP(i2c3), + UNIPHIER_PINCTRL_GROUP(i2c4), + UNIPHIER_PINCTRL_GROUP(nand), + UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(uart0), + UNIPHIER_PINCTRL_GROUP(uart1), + UNIPHIER_PINCTRL_GROUP(uart2), + UNIPHIER_PINCTRL_GROUP(uart3), + UNIPHIER_PINCTRL_GROUP(usb0), + UNIPHIER_PINCTRL_GROUP(usb1), + UNIPHIER_PINCTRL_GROUP(usb2), + UNIPHIER_PINCTRL_GROUP(usb3), + UNIPHIER_PINCTRL_GROUP_GPIO_RANGE_PORT(port_range), + UNIPHIER_PINCTRL_GROUP_GPIO_RANGE_IRQ(xirq), + UNIPHIER_PINCTRL_GROUP_GPIO_RANGE_IRQ(xirq_alternatives), + UNIPHIER_PINCTRL_GROUP_SINGLE(port00, port_range, 0), + UNIPHIER_PINCTRL_GROUP_SINGLE(port01, port_range, 1), + UNIPHIER_PINCTRL_GROUP_SINGLE(port02, port_range, 2), + UNIPHIER_PINCTRL_GROUP_SINGLE(port03, port_range, 3), + UNIPHIER_PINCTRL_GROUP_SINGLE(port04, port_range, 4), + UNIPHIER_PINCTRL_GROUP_SINGLE(port05, port_range, 5), + UNIPHIER_PINCTRL_GROUP_SINGLE(port06, port_range, 6), + UNIPHIER_PINCTRL_GROUP_SINGLE(port07, port_range, 7), + UNIPHIER_PINCTRL_GROUP_SINGLE(port10, port_range, 8), + UNIPHIER_PINCTRL_GROUP_SINGLE(port11, port_range, 9), + UNIPHIER_PINCTRL_GROUP_SINGLE(port12, port_range, 10), + UNIPHIER_PINCTRL_GROUP_SINGLE(port13, port_range, 11), + UNIPHIER_PINCTRL_GROUP_SINGLE(port14, port_range, 12), + UNIPHIER_PINCTRL_GROUP_SINGLE(port15, port_range, 13), + UNIPHIER_PINCTRL_GROUP_SINGLE(port16, port_range, 14), + UNIPHIER_PINCTRL_GROUP_SINGLE(port17, port_range, 15), + UNIPHIER_PINCTRL_GROUP_SINGLE(port20, port_range, 16), + UNIPHIER_PINCTRL_GROUP_SINGLE(port21, port_range, 17), + UNIPHIER_PINCTRL_GROUP_SINGLE(port22, port_range, 18), + UNIPHIER_PINCTRL_GROUP_SINGLE(port23, port_range, 19), + UNIPHIER_PINCTRL_GROUP_SINGLE(port24, port_range, 20), + UNIPHIER_PINCTRL_GROUP_SINGLE(port25, port_range, 21), + UNIPHIER_PINCTRL_GROUP_SINGLE(port26, port_range, 22), + UNIPHIER_PINCTRL_GROUP_SINGLE(port27, port_range, 23), + UNIPHIER_PINCTRL_GROUP_SINGLE(port30, port_range, 24), + UNIPHIER_PINCTRL_GROUP_SINGLE(port31, port_range, 25), + UNIPHIER_PINCTRL_GROUP_SINGLE(port32, port_range, 26), + UNIPHIER_PINCTRL_GROUP_SINGLE(port33, port_range, 27), + UNIPHIER_PINCTRL_GROUP_SINGLE(port34, port_range, 28), + UNIPHIER_PINCTRL_GROUP_SINGLE(port35, port_range, 29), + UNIPHIER_PINCTRL_GROUP_SINGLE(port36, port_range, 30), + UNIPHIER_PINCTRL_GROUP_SINGLE(port37, port_range, 31), + UNIPHIER_PINCTRL_GROUP_SINGLE(port40, port_range, 32), + UNIPHIER_PINCTRL_GROUP_SINGLE(port41, port_range, 33), + UNIPHIER_PINCTRL_GROUP_SINGLE(port42, port_range, 34), + UNIPHIER_PINCTRL_GROUP_SINGLE(port43, port_range, 35), + UNIPHIER_PINCTRL_GROUP_SINGLE(port44, port_range, 36), + UNIPHIER_PINCTRL_GROUP_SINGLE(port45, port_range, 37), + UNIPHIER_PINCTRL_GROUP_SINGLE(port46, port_range, 38), + UNIPHIER_PINCTRL_GROUP_SINGLE(port47, port_range, 39), + UNIPHIER_PINCTRL_GROUP_SINGLE(port50, port_range, 40), + UNIPHIER_PINCTRL_GROUP_SINGLE(port51, port_range, 41), + UNIPHIER_PINCTRL_GROUP_SINGLE(port52, port_range, 42), + UNIPHIER_PINCTRL_GROUP_SINGLE(port53, port_range, 43), + UNIPHIER_PINCTRL_GROUP_SINGLE(port54, port_range, 44), + UNIPHIER_PINCTRL_GROUP_SINGLE(port55, port_range, 45), + UNIPHIER_PINCTRL_GROUP_SINGLE(port56, port_range, 46), + UNIPHIER_PINCTRL_GROUP_SINGLE(port57, port_range, 47), + UNIPHIER_PINCTRL_GROUP_SINGLE(port60, port_range, 48), + UNIPHIER_PINCTRL_GROUP_SINGLE(port61, port_range, 49), + UNIPHIER_PINCTRL_GROUP_SINGLE(port62, port_range, 50), + UNIPHIER_PINCTRL_GROUP_SINGLE(port63, port_range, 51), + UNIPHIER_PINCTRL_GROUP_SINGLE(port64, port_range, 52), + UNIPHIER_PINCTRL_GROUP_SINGLE(port65, port_range, 53), + UNIPHIER_PINCTRL_GROUP_SINGLE(port66, port_range, 54), + UNIPHIER_PINCTRL_GROUP_SINGLE(port67, port_range, 55), + UNIPHIER_PINCTRL_GROUP_SINGLE(port70, port_range, 56), + UNIPHIER_PINCTRL_GROUP_SINGLE(port71, port_range, 57), + UNIPHIER_PINCTRL_GROUP_SINGLE(port72, port_range, 58), + UNIPHIER_PINCTRL_GROUP_SINGLE(port73, port_range, 59), + UNIPHIER_PINCTRL_GROUP_SINGLE(port74, port_range, 60), + UNIPHIER_PINCTRL_GROUP_SINGLE(port75, port_range, 61), + UNIPHIER_PINCTRL_GROUP_SINGLE(port76, port_range, 62), + UNIPHIER_PINCTRL_GROUP_SINGLE(port77, port_range, 63), + UNIPHIER_PINCTRL_GROUP_SINGLE(port80, port_range, 64), + UNIPHIER_PINCTRL_GROUP_SINGLE(port81, port_range, 65), + UNIPHIER_PINCTRL_GROUP_SINGLE(port82, port_range, 66), + UNIPHIER_PINCTRL_GROUP_SINGLE(port83, port_range, 67), + UNIPHIER_PINCTRL_GROUP_SINGLE(port84, port_range, 68), + UNIPHIER_PINCTRL_GROUP_SINGLE(port85, port_range, 69), + UNIPHIER_PINCTRL_GROUP_SINGLE(port86, port_range, 70), + UNIPHIER_PINCTRL_GROUP_SINGLE(port87, port_range, 71), + UNIPHIER_PINCTRL_GROUP_SINGLE(port90, port_range, 72), + UNIPHIER_PINCTRL_GROUP_SINGLE(port91, port_range, 73), + UNIPHIER_PINCTRL_GROUP_SINGLE(port92, port_range, 74), + UNIPHIER_PINCTRL_GROUP_SINGLE(port93, port_range, 75), + UNIPHIER_PINCTRL_GROUP_SINGLE(port94, port_range, 76), + UNIPHIER_PINCTRL_GROUP_SINGLE(port95, port_range, 77), + UNIPHIER_PINCTRL_GROUP_SINGLE(port96, port_range, 78), + UNIPHIER_PINCTRL_GROUP_SINGLE(port97, port_range, 79), + UNIPHIER_PINCTRL_GROUP_SINGLE(port100, port_range, 80), + UNIPHIER_PINCTRL_GROUP_SINGLE(port101, port_range, 81), + UNIPHIER_PINCTRL_GROUP_SINGLE(port102, port_range, 82), + UNIPHIER_PINCTRL_GROUP_SINGLE(port103, port_range, 83), + UNIPHIER_PINCTRL_GROUP_SINGLE(port104, port_range, 84), + UNIPHIER_PINCTRL_GROUP_SINGLE(port105, port_range, 85), + UNIPHIER_PINCTRL_GROUP_SINGLE(port106, port_range, 86), + UNIPHIER_PINCTRL_GROUP_SINGLE(port107, port_range, 87), + UNIPHIER_PINCTRL_GROUP_SINGLE(port120, port_range, 96), + UNIPHIER_PINCTRL_GROUP_SINGLE(port121, port_range, 97), + UNIPHIER_PINCTRL_GROUP_SINGLE(port122, port_range, 98), + UNIPHIER_PINCTRL_GROUP_SINGLE(port123, port_range, 99), + UNIPHIER_PINCTRL_GROUP_SINGLE(port124, port_range, 100), + UNIPHIER_PINCTRL_GROUP_SINGLE(port125, port_range, 101), + UNIPHIER_PINCTRL_GROUP_SINGLE(port126, port_range, 102), + UNIPHIER_PINCTRL_GROUP_SINGLE(port127, port_range, 103), + UNIPHIER_PINCTRL_GROUP_SINGLE(port130, port_range, 104), + UNIPHIER_PINCTRL_GROUP_SINGLE(port131, port_range, 105), + UNIPHIER_PINCTRL_GROUP_SINGLE(port132, port_range, 106), + UNIPHIER_PINCTRL_GROUP_SINGLE(port133, port_range, 107), + UNIPHIER_PINCTRL_GROUP_SINGLE(port134, port_range, 108), + UNIPHIER_PINCTRL_GROUP_SINGLE(port135, port_range, 109), + UNIPHIER_PINCTRL_GROUP_SINGLE(port136, port_range, 110), + UNIPHIER_PINCTRL_GROUP_SINGLE(port137, port_range, 111), + UNIPHIER_PINCTRL_GROUP_SINGLE(port140, port_range, 112), + UNIPHIER_PINCTRL_GROUP_SINGLE(port141, port_range, 113), + UNIPHIER_PINCTRL_GROUP_SINGLE(port142, port_range, 114), + UNIPHIER_PINCTRL_GROUP_SINGLE(port143, port_range, 115), + UNIPHIER_PINCTRL_GROUP_SINGLE(port144, port_range, 116), + UNIPHIER_PINCTRL_GROUP_SINGLE(port145, port_range, 117), + UNIPHIER_PINCTRL_GROUP_SINGLE(port146, port_range, 118), + UNIPHIER_PINCTRL_GROUP_SINGLE(port147, port_range, 119), + UNIPHIER_PINCTRL_GROUP_SINGLE(port180, port_range, 144), + UNIPHIER_PINCTRL_GROUP_SINGLE(port181, port_range, 145), + UNIPHIER_PINCTRL_GROUP_SINGLE(port182, port_range, 146), + UNIPHIER_PINCTRL_GROUP_SINGLE(port183, port_range, 147), + UNIPHIER_PINCTRL_GROUP_SINGLE(port184, port_range, 148), + UNIPHIER_PINCTRL_GROUP_SINGLE(port185, port_range, 149), + UNIPHIER_PINCTRL_GROUP_SINGLE(port186, port_range, 150), + UNIPHIER_PINCTRL_GROUP_SINGLE(port187, port_range, 151), + UNIPHIER_PINCTRL_GROUP_SINGLE(port200, port_range, 160), + UNIPHIER_PINCTRL_GROUP_SINGLE(port201, port_range, 161), + UNIPHIER_PINCTRL_GROUP_SINGLE(port202, port_range, 162), + UNIPHIER_PINCTRL_GROUP_SINGLE(port203, port_range, 163), + UNIPHIER_PINCTRL_GROUP_SINGLE(port204, port_range, 164), + UNIPHIER_PINCTRL_GROUP_SINGLE(port205, port_range, 165), + UNIPHIER_PINCTRL_GROUP_SINGLE(port206, port_range, 166), + UNIPHIER_PINCTRL_GROUP_SINGLE(port207, port_range, 167), + UNIPHIER_PINCTRL_GROUP_SINGLE(port210, port_range, 168), + UNIPHIER_PINCTRL_GROUP_SINGLE(port211, port_range, 169), + UNIPHIER_PINCTRL_GROUP_SINGLE(port212, port_range, 170), + UNIPHIER_PINCTRL_GROUP_SINGLE(port213, port_range, 171), + UNIPHIER_PINCTRL_GROUP_SINGLE(port214, port_range, 172), + UNIPHIER_PINCTRL_GROUP_SINGLE(port215, port_range, 173), + UNIPHIER_PINCTRL_GROUP_SINGLE(port216, port_range, 174), + UNIPHIER_PINCTRL_GROUP_SINGLE(port217, port_range, 175), + UNIPHIER_PINCTRL_GROUP_SINGLE(port220, port_range, 176), + UNIPHIER_PINCTRL_GROUP_SINGLE(port221, port_range, 177), + UNIPHIER_PINCTRL_GROUP_SINGLE(port222, port_range, 178), + UNIPHIER_PINCTRL_GROUP_SINGLE(port223, port_range, 179), + UNIPHIER_PINCTRL_GROUP_SINGLE(port224, port_range, 180), + UNIPHIER_PINCTRL_GROUP_SINGLE(port225, port_range, 181), + UNIPHIER_PINCTRL_GROUP_SINGLE(port226, port_range, 182), + UNIPHIER_PINCTRL_GROUP_SINGLE(port227, port_range, 183), + UNIPHIER_PINCTRL_GROUP_SINGLE(port230, port_range, 184), + UNIPHIER_PINCTRL_GROUP_SINGLE(port231, port_range, 185), + UNIPHIER_PINCTRL_GROUP_SINGLE(port232, port_range, 186), + UNIPHIER_PINCTRL_GROUP_SINGLE(port233, port_range, 187), + UNIPHIER_PINCTRL_GROUP_SINGLE(port234, port_range, 188), + UNIPHIER_PINCTRL_GROUP_SINGLE(port235, port_range, 189), + UNIPHIER_PINCTRL_GROUP_SINGLE(port236, port_range, 190), + UNIPHIER_PINCTRL_GROUP_SINGLE(port237, port_range, 191), + UNIPHIER_PINCTRL_GROUP_SINGLE(port240, port_range, 192), + UNIPHIER_PINCTRL_GROUP_SINGLE(port241, port_range, 193), + UNIPHIER_PINCTRL_GROUP_SINGLE(port242, port_range, 194), + UNIPHIER_PINCTRL_GROUP_SINGLE(port243, port_range, 195), + UNIPHIER_PINCTRL_GROUP_SINGLE(port244, port_range, 196), + UNIPHIER_PINCTRL_GROUP_SINGLE(port245, port_range, 197), + UNIPHIER_PINCTRL_GROUP_SINGLE(port246, port_range, 198), + UNIPHIER_PINCTRL_GROUP_SINGLE(port247, port_range, 199), + UNIPHIER_PINCTRL_GROUP_SINGLE(port250, port_range, 200), + UNIPHIER_PINCTRL_GROUP_SINGLE(port251, port_range, 201), + UNIPHIER_PINCTRL_GROUP_SINGLE(port252, port_range, 202), + UNIPHIER_PINCTRL_GROUP_SINGLE(port253, port_range, 203), + UNIPHIER_PINCTRL_GROUP_SINGLE(port254, port_range, 204), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq0, xirq, 0), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq1, xirq, 1), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq2, xirq, 2), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq3, xirq, 3), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq4, xirq, 4), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq5, xirq, 5), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq6, xirq, 6), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq7, xirq, 7), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq8, xirq, 8), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq9, xirq, 9), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq10, xirq, 10), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq11, xirq, 11), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq12, xirq, 12), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq13, xirq, 13), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq14, xirq, 14), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq15, xirq, 15), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq16, xirq, 16), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq17, xirq, 17), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq18, xirq, 18), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq19, xirq, 19), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq20, xirq, 20), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq21, xirq, 21), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq22, xirq, 22), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq23, xirq, 23), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq0b, xirq_alternatives, 0), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq1b, xirq_alternatives, 1), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq2b, xirq_alternatives, 2), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq3b, xirq_alternatives, 3), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq4b, xirq_alternatives, 4), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq5b, xirq_alternatives, 5), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq6b, xirq_alternatives, 6), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq7b, xirq_alternatives, 7), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq8b, xirq_alternatives, 8), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq9b, xirq_alternatives, 9), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq10b, xirq_alternatives, 10), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq11b, xirq_alternatives, 11), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq13b, xirq_alternatives, 12), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq14b, xirq_alternatives, 13), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq16b, xirq_alternatives, 14), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq17b, xirq_alternatives, 15), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq18b, xirq_alternatives, 16), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq19b, xirq_alternatives, 17), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq20b, xirq_alternatives, 18), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq21b, xirq_alternatives, 19), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq22b, xirq_alternatives, 20), + UNIPHIER_PINCTRL_GROUP_SINGLE(xirq23b, xirq_alternatives, 21), +}; + +static const char * const emmc_groups[] = {"emmc", "emmc_dat8"}; +static const char * const ether_rgmii_groups[] = {"ether_rgmii"}; +static const char * const ether_rmii_groups[] = {"ether_rmii"}; +static const char * const i2c0_groups[] = {"i2c0"}; +static const char * const i2c1_groups[] = {"i2c1"}; +static const char * const i2c3_groups[] = {"i2c3"}; +static const char * const i2c4_groups[] = {"i2c4"}; +static const char * const nand_groups[] = {"nand"}; +static const char * const sd_groups[] = {"sd"}; +static const char * const system_bus_groups[] = {"system_bus", + "system_bus_cs1"}; +static const char * const uart0_groups[] = {"uart0"}; +static const char * const uart1_groups[] = {"uart1"}; +static const char * const uart2_groups[] = {"uart2"}; +static const char * const uart3_groups[] = {"uart3"}; +static const char * const usb0_groups[] = {"usb0"}; +static const char * const usb1_groups[] = {"usb1"}; +static const char * const usb2_groups[] = {"usb2"}; +static const char * const usb3_groups[] = {"usb3"}; +static const char * const port_groups[] = { + "port00", "port01", "port02", "port03", + "port04", "port05", "port06", "port07", + "port10", "port11", "port12", "port13", + "port14", "port15", "port16", "port17", + "port20", "port21", "port22", "port23", + "port24", "port25", "port26", "port27", + "port30", "port31", "port32", "port33", + "port34", "port35", "port36", "port37", + "port40", "port41", "port42", "port43", + "port44", "port45", "port46", "port47", + "port50", "port51", "port52", "port53", + "port54", "port55", "port56", "port57", + "port60", "port61", "port62", "port63", + "port64", "port65", "port66", "port67", + "port70", "port71", "port72", "port73", + "port74", "port75", "port76", "port77", + "port80", "port81", "port82", "port83", + "port84", "port85", "port86", "port87", + "port90", "port91", "port92", "port93", + "port94", "port95", "port96", "port97", + "port100", "port101", "port102", "port103", + "port104", "port105", "port106", "port107", + /* port110-117 missing */ + "port120", "port121", "port122", "port123", + "port124", "port125", "port126", "port127", + "port130", "port131", "port132", "port133", + "port134", "port135", "port136", "port137", + "port140", "port141", "port142", "port143", + "port144", "port145", "port146", "port147", + /* port150-177 missing */ + "port180", "port181", "port182", "port183", + "port184", "port185", "port186", "port187", + /* port190-197 missing */ + "port200", "port201", "port202", "port203", + "port204", "port205", "port206", "port207", + "port210", "port211", "port212", "port213", + "port214", "port215", "port216", "port217", + "port220", "port221", "port222", "port223", + "port224", "port225", "port226", "port227", + "port230", "port231", "port232", "port233", + "port234", "port235", "port236", "port237", + "port240", "port241", "port242", "port243", + "port244", "port245", "port246", "port247", + "port250", "port251", "port252", "port253", + "port254", +}; +static const char * const xirq_groups[] = { + "xirq0", "xirq1", "xirq2", "xirq3", + "xirq4", "xirq5", "xirq6", "xirq7", + "xirq8", "xirq9", "xirq10", "xirq11", + "xirq12", "xirq13", "xirq14", "xirq15", + "xirq16", "xirq17", "xirq18", "xirq19", + "xirq20", "xirq21", "xirq22", "xirq23", + "xirq0b", "xirq1b", "xirq2b", "xirq3b", + "xirq4b", "xirq5b", "xirq6b", "xirq7b", + "xirq8b", "xirq9b", "xirq10b", "xirq11b", + /* none */ "xirq13b", "xirq14b", /* none */ + "xirq16b", "xirq17b", "xirq18b", "xirq19b", + "xirq20b", "xirq21b", "xirq22b", "xirq23b", +}; + +static const struct uniphier_pinmux_function uniphier_ld20_functions[] = { + UNIPHIER_PINMUX_FUNCTION(emmc), + UNIPHIER_PINMUX_FUNCTION(ether_rgmii), + UNIPHIER_PINMUX_FUNCTION(ether_rmii), + UNIPHIER_PINMUX_FUNCTION(i2c0), + UNIPHIER_PINMUX_FUNCTION(i2c1), + UNIPHIER_PINMUX_FUNCTION(i2c3), + UNIPHIER_PINMUX_FUNCTION(i2c4), + UNIPHIER_PINMUX_FUNCTION(nand), + UNIPHIER_PINMUX_FUNCTION(sd), + UNIPHIER_PINMUX_FUNCTION(system_bus), + UNIPHIER_PINMUX_FUNCTION(uart0), + UNIPHIER_PINMUX_FUNCTION(uart1), + UNIPHIER_PINMUX_FUNCTION(uart2), + UNIPHIER_PINMUX_FUNCTION(uart3), + UNIPHIER_PINMUX_FUNCTION(usb0), + UNIPHIER_PINMUX_FUNCTION(usb1), + UNIPHIER_PINMUX_FUNCTION(usb2), + UNIPHIER_PINMUX_FUNCTION(usb3), + UNIPHIER_PINMUX_FUNCTION(port), + UNIPHIER_PINMUX_FUNCTION(xirq), +}; + +static struct uniphier_pinctrl_socdata uniphier_ld20_pindata = { + .pins = uniphier_ld20_pins, + .npins = ARRAY_SIZE(uniphier_ld20_pins), + .groups = uniphier_ld20_groups, + .groups_count = ARRAY_SIZE(uniphier_ld20_groups), + .functions = uniphier_ld20_functions, + .functions_count = ARRAY_SIZE(uniphier_ld20_functions), + .caps = UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL, +}; + +static int uniphier_ld20_pinctrl_probe(struct platform_device *pdev) +{ + return uniphier_pinctrl_probe(pdev, &uniphier_ld20_pindata); +} + +static const struct of_device_id uniphier_ld20_pinctrl_match[] = { + { .compatible = "socionext,uniphier-ld20-pinctrl" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, uniphier_ld20_pinctrl_match); + +static struct platform_driver uniphier_ld20_pinctrl_driver = { + .probe = uniphier_ld20_pinctrl_probe, + .driver = { + .name = "uniphier-ld20-pinctrl", + .of_match_table = uniphier_ld20_pinctrl_match, + }, +}; +module_platform_driver(uniphier_ld20_pinctrl_driver); + +MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); +MODULE_DESCRIPTION("UniPhier PH1-LD20 pinctrl driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c index 4a0439c80aa0..3edfb6f9d6df 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld4.c @@ -19,544 +19,592 @@ #include "pinctrl-uniphier.h" -#define DRIVER_NAME "ph1-ld4-pinctrl" - -static const struct pinctrl_pin_desc ph1_ld4_pins[] = { +static const struct pinctrl_pin_desc uniphier_ld4_pins[] = { UNIPHIER_PINCTRL_PIN(0, "EA1", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_4_8, + 8, UNIPHIER_PIN_DRV_1BIT, 8, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(1, "EA2", UNIPHIER_PIN_IECTRL_NONE, - 9, UNIPHIER_PIN_DRV_4_8, + 9, UNIPHIER_PIN_DRV_1BIT, 9, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(2, "EA3", UNIPHIER_PIN_IECTRL_NONE, - 10, UNIPHIER_PIN_DRV_4_8, + 10, UNIPHIER_PIN_DRV_1BIT, 10, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(3, "EA4", UNIPHIER_PIN_IECTRL_NONE, - 11, UNIPHIER_PIN_DRV_4_8, + 11, UNIPHIER_PIN_DRV_1BIT, 11, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(4, "EA5", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_4_8, + 12, UNIPHIER_PIN_DRV_1BIT, 12, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(5, "EA6", UNIPHIER_PIN_IECTRL_NONE, - 13, UNIPHIER_PIN_DRV_4_8, + 13, UNIPHIER_PIN_DRV_1BIT, 13, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(6, "EA7", UNIPHIER_PIN_IECTRL_NONE, - 14, UNIPHIER_PIN_DRV_4_8, + 14, UNIPHIER_PIN_DRV_1BIT, 14, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(7, "EA8", 0, - 15, UNIPHIER_PIN_DRV_4_8, + 15, UNIPHIER_PIN_DRV_1BIT, 15, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(8, "EA9", 0, - 16, UNIPHIER_PIN_DRV_4_8, + 16, UNIPHIER_PIN_DRV_1BIT, 16, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(9, "EA10", 0, - 17, UNIPHIER_PIN_DRV_4_8, + 17, UNIPHIER_PIN_DRV_1BIT, 17, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(10, "EA11", 0, - 18, UNIPHIER_PIN_DRV_4_8, + 18, UNIPHIER_PIN_DRV_1BIT, 18, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(11, "EA12", 0, - 19, UNIPHIER_PIN_DRV_4_8, + 19, UNIPHIER_PIN_DRV_1BIT, 19, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(12, "EA13", 0, - 20, UNIPHIER_PIN_DRV_4_8, + 20, UNIPHIER_PIN_DRV_1BIT, 20, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(13, "EA14", 0, - 21, UNIPHIER_PIN_DRV_4_8, + 21, UNIPHIER_PIN_DRV_1BIT, 21, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(14, "EA15", 0, - 22, UNIPHIER_PIN_DRV_4_8, + 22, UNIPHIER_PIN_DRV_1BIT, 22, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(15, "ECLK", UNIPHIER_PIN_IECTRL_NONE, - 23, UNIPHIER_PIN_DRV_4_8, + 23, UNIPHIER_PIN_DRV_1BIT, 23, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(16, "XERWE0", UNIPHIER_PIN_IECTRL_NONE, - 24, UNIPHIER_PIN_DRV_4_8, + 24, UNIPHIER_PIN_DRV_1BIT, 24, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(17, "XERWE1", UNIPHIER_PIN_IECTRL_NONE, - 25, UNIPHIER_PIN_DRV_4_8, + 25, UNIPHIER_PIN_DRV_1BIT, 25, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(18, "ES0", UNIPHIER_PIN_IECTRL_NONE, - 27, UNIPHIER_PIN_DRV_4_8, + 27, UNIPHIER_PIN_DRV_1BIT, 27, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(19, "ES1", UNIPHIER_PIN_IECTRL_NONE, - 28, UNIPHIER_PIN_DRV_4_8, + 28, UNIPHIER_PIN_DRV_1BIT, 28, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(20, "ES2", UNIPHIER_PIN_IECTRL_NONE, - 29, UNIPHIER_PIN_DRV_4_8, + 29, UNIPHIER_PIN_DRV_1BIT, 29, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(21, "XERST", UNIPHIER_PIN_IECTRL_NONE, - 38, UNIPHIER_PIN_DRV_4_8, + 38, UNIPHIER_PIN_DRV_1BIT, 38, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(22, "MMCCLK", UNIPHIER_PIN_IECTRL_NONE, - 0, UNIPHIER_PIN_DRV_8_12_16_20, + 0, UNIPHIER_PIN_DRV_2BIT, 146, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(23, "MMCCMD", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_8_12_16_20, + 1, UNIPHIER_PIN_DRV_2BIT, 147, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(24, "MMCDAT0", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_8_12_16_20, + 2, UNIPHIER_PIN_DRV_2BIT, 148, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(25, "MMCDAT1", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_8_12_16_20, + 3, UNIPHIER_PIN_DRV_2BIT, 149, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(26, "MMCDAT2", UNIPHIER_PIN_IECTRL_NONE, - 16, UNIPHIER_PIN_DRV_8_12_16_20, + 4, UNIPHIER_PIN_DRV_2BIT, 150, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(27, "MMCDAT3", UNIPHIER_PIN_IECTRL_NONE, - 20, UNIPHIER_PIN_DRV_8_12_16_20, + 5, UNIPHIER_PIN_DRV_2BIT, 151, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(28, "MMCDAT4", UNIPHIER_PIN_IECTRL_NONE, - 24, UNIPHIER_PIN_DRV_8_12_16_20, + 6, UNIPHIER_PIN_DRV_2BIT, 152, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(29, "MMCDAT5", UNIPHIER_PIN_IECTRL_NONE, - 28, UNIPHIER_PIN_DRV_8_12_16_20, + 7, UNIPHIER_PIN_DRV_2BIT, 153, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(30, "MMCDAT6", UNIPHIER_PIN_IECTRL_NONE, - 32, UNIPHIER_PIN_DRV_8_12_16_20, + 8, UNIPHIER_PIN_DRV_2BIT, 154, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(31, "MMCDAT7", UNIPHIER_PIN_IECTRL_NONE, - 36, UNIPHIER_PIN_DRV_8_12_16_20, + 9, UNIPHIER_PIN_DRV_2BIT, 155, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(32, "RMII_RXD0", 6, - 39, UNIPHIER_PIN_DRV_4_8, + 39, UNIPHIER_PIN_DRV_1BIT, 39, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(33, "RMII_RXD1", 6, - 40, UNIPHIER_PIN_DRV_4_8, + 40, UNIPHIER_PIN_DRV_1BIT, 40, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(34, "RMII_CRS_DV", 6, - 41, UNIPHIER_PIN_DRV_4_8, + 41, UNIPHIER_PIN_DRV_1BIT, 41, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(35, "RMII_RXER", 6, - 42, UNIPHIER_PIN_DRV_4_8, + 42, UNIPHIER_PIN_DRV_1BIT, 42, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(36, "RMII_REFCLK", 6, - 43, UNIPHIER_PIN_DRV_4_8, + 43, UNIPHIER_PIN_DRV_1BIT, 43, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(37, "RMII_TXD0", 6, - 44, UNIPHIER_PIN_DRV_4_8, + 44, UNIPHIER_PIN_DRV_1BIT, 44, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(38, "RMII_TXD1", 6, - 45, UNIPHIER_PIN_DRV_4_8, + 45, UNIPHIER_PIN_DRV_1BIT, 45, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(39, "RMII_TXEN", 6, - 46, UNIPHIER_PIN_DRV_4_8, + 46, UNIPHIER_PIN_DRV_1BIT, 46, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(40, "MDC", 6, - 47, UNIPHIER_PIN_DRV_4_8, + 47, UNIPHIER_PIN_DRV_1BIT, 47, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(41, "MDIO", 6, - 48, UNIPHIER_PIN_DRV_4_8, + 48, UNIPHIER_PIN_DRV_1BIT, 48, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(42, "MDIO_INTL", 6, - 49, UNIPHIER_PIN_DRV_4_8, + 49, UNIPHIER_PIN_DRV_1BIT, 49, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(43, "PHYRSTL", 6, - 50, UNIPHIER_PIN_DRV_4_8, + 50, UNIPHIER_PIN_DRV_1BIT, 50, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(44, "SDCLK", UNIPHIER_PIN_IECTRL_NONE, - 40, UNIPHIER_PIN_DRV_8_12_16_20, + 10, UNIPHIER_PIN_DRV_2BIT, 156, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(45, "SDCMD", UNIPHIER_PIN_IECTRL_NONE, - 44, UNIPHIER_PIN_DRV_8_12_16_20, + 11, UNIPHIER_PIN_DRV_2BIT, 157, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(46, "SDDAT0", UNIPHIER_PIN_IECTRL_NONE, - 48, UNIPHIER_PIN_DRV_8_12_16_20, + 12, UNIPHIER_PIN_DRV_2BIT, 158, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(47, "SDDAT1", UNIPHIER_PIN_IECTRL_NONE, - 52, UNIPHIER_PIN_DRV_8_12_16_20, + 13, UNIPHIER_PIN_DRV_2BIT, 159, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(48, "SDDAT2", UNIPHIER_PIN_IECTRL_NONE, - 56, UNIPHIER_PIN_DRV_8_12_16_20, + 14, UNIPHIER_PIN_DRV_2BIT, 160, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(49, "SDDAT3", UNIPHIER_PIN_IECTRL_NONE, - 60, UNIPHIER_PIN_DRV_8_12_16_20, + 15, UNIPHIER_PIN_DRV_2BIT, 161, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(50, "SDCD", UNIPHIER_PIN_IECTRL_NONE, - 51, UNIPHIER_PIN_DRV_4_8, + 51, UNIPHIER_PIN_DRV_1BIT, 51, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(51, "SDWP", UNIPHIER_PIN_IECTRL_NONE, - 52, UNIPHIER_PIN_DRV_4_8, + 52, UNIPHIER_PIN_DRV_1BIT, 52, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(52, "SDVOLC", UNIPHIER_PIN_IECTRL_NONE, - 53, UNIPHIER_PIN_DRV_4_8, + 53, UNIPHIER_PIN_DRV_1BIT, 53, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(53, "USB0VBUS", 0, - 54, UNIPHIER_PIN_DRV_4_8, + 54, UNIPHIER_PIN_DRV_1BIT, 54, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(54, "USB0OD", 0, - 55, UNIPHIER_PIN_DRV_4_8, + 55, UNIPHIER_PIN_DRV_1BIT, 55, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(55, "USB1VBUS", 0, - 56, UNIPHIER_PIN_DRV_4_8, + 56, UNIPHIER_PIN_DRV_1BIT, 56, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(56, "USB1OD", 0, - 57, UNIPHIER_PIN_DRV_4_8, + 57, UNIPHIER_PIN_DRV_1BIT, 57, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(57, "PCRESET", 0, - 58, UNIPHIER_PIN_DRV_4_8, + 58, UNIPHIER_PIN_DRV_1BIT, 58, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(58, "PCREG", 0, - 59, UNIPHIER_PIN_DRV_4_8, + 59, UNIPHIER_PIN_DRV_1BIT, 59, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(59, "PCCE2", 0, - 60, UNIPHIER_PIN_DRV_4_8, + 60, UNIPHIER_PIN_DRV_1BIT, 60, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(60, "PCVS1", 0, - 61, UNIPHIER_PIN_DRV_4_8, + 61, UNIPHIER_PIN_DRV_1BIT, 61, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(61, "PCCD2", 0, - 62, UNIPHIER_PIN_DRV_4_8, + 62, UNIPHIER_PIN_DRV_1BIT, 62, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(62, "PCCD1", 0, - 63, UNIPHIER_PIN_DRV_4_8, + 63, UNIPHIER_PIN_DRV_1BIT, 63, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(63, "PCREADY", 0, - 64, UNIPHIER_PIN_DRV_4_8, + 64, UNIPHIER_PIN_DRV_1BIT, 64, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(64, "PCDOE", 0, - 65, UNIPHIER_PIN_DRV_4_8, + 65, UNIPHIER_PIN_DRV_1BIT, 65, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(65, "PCCE1", 0, - 66, UNIPHIER_PIN_DRV_4_8, + 66, UNIPHIER_PIN_DRV_1BIT, 66, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(66, "PCWE", 0, - 67, UNIPHIER_PIN_DRV_4_8, + 67, UNIPHIER_PIN_DRV_1BIT, 67, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(67, "PCOE", 0, - 68, UNIPHIER_PIN_DRV_4_8, + 68, UNIPHIER_PIN_DRV_1BIT, 68, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(68, "PCWAIT", 0, - 69, UNIPHIER_PIN_DRV_4_8, + 69, UNIPHIER_PIN_DRV_1BIT, 69, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(69, "PCIOWR", 0, - 70, UNIPHIER_PIN_DRV_4_8, + 70, UNIPHIER_PIN_DRV_1BIT, 70, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(70, "PCIORD", 0, - 71, UNIPHIER_PIN_DRV_4_8, + 71, UNIPHIER_PIN_DRV_1BIT, 71, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(71, "HS0DIN0", 0, - 72, UNIPHIER_PIN_DRV_4_8, + 72, UNIPHIER_PIN_DRV_1BIT, 72, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(72, "HS0DIN1", 0, - 73, UNIPHIER_PIN_DRV_4_8, + 73, UNIPHIER_PIN_DRV_1BIT, 73, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(73, "HS0DIN2", 0, - 74, UNIPHIER_PIN_DRV_4_8, + 74, UNIPHIER_PIN_DRV_1BIT, 74, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(74, "HS0DIN3", 0, - 75, UNIPHIER_PIN_DRV_4_8, + 75, UNIPHIER_PIN_DRV_1BIT, 75, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(75, "HS0DIN4", 0, - 76, UNIPHIER_PIN_DRV_4_8, + 76, UNIPHIER_PIN_DRV_1BIT, 76, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(76, "HS0DIN5", 0, - 77, UNIPHIER_PIN_DRV_4_8, + 77, UNIPHIER_PIN_DRV_1BIT, 77, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(77, "HS0DIN6", 0, - 78, UNIPHIER_PIN_DRV_4_8, + 78, UNIPHIER_PIN_DRV_1BIT, 78, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(78, "HS0DIN7", 0, - 79, UNIPHIER_PIN_DRV_4_8, + 79, UNIPHIER_PIN_DRV_1BIT, 79, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(79, "HS0BCLKIN", 0, - 80, UNIPHIER_PIN_DRV_4_8, + 80, UNIPHIER_PIN_DRV_1BIT, 80, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(80, "HS0VALIN", 0, - 81, UNIPHIER_PIN_DRV_4_8, + 81, UNIPHIER_PIN_DRV_1BIT, 81, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(81, "HS0SYNCIN", 0, - 82, UNIPHIER_PIN_DRV_4_8, + 82, UNIPHIER_PIN_DRV_1BIT, 82, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(82, "HSDOUT0", 0, - 83, UNIPHIER_PIN_DRV_4_8, + 83, UNIPHIER_PIN_DRV_1BIT, 83, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(83, "HSDOUT1", 0, - 84, UNIPHIER_PIN_DRV_4_8, + 84, UNIPHIER_PIN_DRV_1BIT, 84, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(84, "HSDOUT2", 0, - 85, UNIPHIER_PIN_DRV_4_8, + 85, UNIPHIER_PIN_DRV_1BIT, 85, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(85, "HSDOUT3", 0, - 86, UNIPHIER_PIN_DRV_4_8, + 86, UNIPHIER_PIN_DRV_1BIT, 86, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(86, "HSDOUT4", 0, - 87, UNIPHIER_PIN_DRV_4_8, + 87, UNIPHIER_PIN_DRV_1BIT, 87, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(87, "HSDOUT5", 0, - 88, UNIPHIER_PIN_DRV_4_8, + 88, UNIPHIER_PIN_DRV_1BIT, 88, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(88, "HSDOUT6", 0, - 89, UNIPHIER_PIN_DRV_4_8, + 89, UNIPHIER_PIN_DRV_1BIT, 89, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(89, "HSDOUT7", 0, - 90, UNIPHIER_PIN_DRV_4_8, + 90, UNIPHIER_PIN_DRV_1BIT, 90, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(90, "HSBCLKOUT", 0, - 91, UNIPHIER_PIN_DRV_4_8, + 91, UNIPHIER_PIN_DRV_1BIT, 91, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(91, "HSVALOUT", 0, - 92, UNIPHIER_PIN_DRV_4_8, + 92, UNIPHIER_PIN_DRV_1BIT, 92, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(92, "HSSYNCOUT", 0, - 93, UNIPHIER_PIN_DRV_4_8, + 93, UNIPHIER_PIN_DRV_1BIT, 93, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(93, "AGCI", 3, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 162, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(94, "AGCR", 4, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 163, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(95, "AGCBS", 5, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 164, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(96, "IECOUT", 0, - 94, UNIPHIER_PIN_DRV_4_8, + 94, UNIPHIER_PIN_DRV_1BIT, 94, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(97, "ASMCK", 0, - 95, UNIPHIER_PIN_DRV_4_8, + 95, UNIPHIER_PIN_DRV_1BIT, 95, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(98, "ABCKO", UNIPHIER_PIN_IECTRL_NONE, - 96, UNIPHIER_PIN_DRV_4_8, + 96, UNIPHIER_PIN_DRV_1BIT, 96, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(99, "ALRCKO", UNIPHIER_PIN_IECTRL_NONE, - 97, UNIPHIER_PIN_DRV_4_8, + 97, UNIPHIER_PIN_DRV_1BIT, 97, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(100, "ASDOUT0", UNIPHIER_PIN_IECTRL_NONE, - 98, UNIPHIER_PIN_DRV_4_8, + 98, UNIPHIER_PIN_DRV_1BIT, 98, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(101, "ARCOUT", 0, - 99, UNIPHIER_PIN_DRV_4_8, + 99, UNIPHIER_PIN_DRV_1BIT, 99, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(102, "SDA0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(103, "SCL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(104, "SDA1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(105, "SCL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(106, "DMDSDA0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(107, "DMDSCL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(108, "DMDSDA1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(109, "DMDSCL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(110, "SBO0", UNIPHIER_PIN_IECTRL_NONE, - 100, UNIPHIER_PIN_DRV_4_8, + 100, UNIPHIER_PIN_DRV_1BIT, 100, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(111, "SBI0", UNIPHIER_PIN_IECTRL_NONE, - 101, UNIPHIER_PIN_DRV_4_8, + 101, UNIPHIER_PIN_DRV_1BIT, 101, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(112, "HIN", 1, - -1, UNIPHIER_PIN_DRV_FIXED_5, + -1, UNIPHIER_PIN_DRV_FIXED5, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(113, "VIN", 2, - -1, UNIPHIER_PIN_DRV_FIXED_5, + -1, UNIPHIER_PIN_DRV_FIXED5, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(114, "TCON0", UNIPHIER_PIN_IECTRL_NONE, - 102, UNIPHIER_PIN_DRV_4_8, + 102, UNIPHIER_PIN_DRV_1BIT, 102, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(115, "TCON1", UNIPHIER_PIN_IECTRL_NONE, - 103, UNIPHIER_PIN_DRV_4_8, + 103, UNIPHIER_PIN_DRV_1BIT, 103, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(116, "TCON2", UNIPHIER_PIN_IECTRL_NONE, - 104, UNIPHIER_PIN_DRV_4_8, + 104, UNIPHIER_PIN_DRV_1BIT, 104, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(117, "TCON3", UNIPHIER_PIN_IECTRL_NONE, - 105, UNIPHIER_PIN_DRV_4_8, + 105, UNIPHIER_PIN_DRV_1BIT, 105, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(118, "TCON4", UNIPHIER_PIN_IECTRL_NONE, - 106, UNIPHIER_PIN_DRV_4_8, + 106, UNIPHIER_PIN_DRV_1BIT, 106, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(119, "TCON5", UNIPHIER_PIN_IECTRL_NONE, - 107, UNIPHIER_PIN_DRV_4_8, + 107, UNIPHIER_PIN_DRV_1BIT, 107, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(120, "TCON6", 0, - 108, UNIPHIER_PIN_DRV_4_8, + 108, UNIPHIER_PIN_DRV_1BIT, 108, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(121, "TCON7", 0, - 109, UNIPHIER_PIN_DRV_4_8, + 109, UNIPHIER_PIN_DRV_1BIT, 109, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(122, "PWMA", 0, - 110, UNIPHIER_PIN_DRV_4_8, + 110, UNIPHIER_PIN_DRV_1BIT, 110, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(123, "XIRQ1", 0, - 111, UNIPHIER_PIN_DRV_4_8, + 111, UNIPHIER_PIN_DRV_1BIT, 111, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(124, "XIRQ2", 0, - 112, UNIPHIER_PIN_DRV_4_8, + 112, UNIPHIER_PIN_DRV_1BIT, 112, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(125, "XIRQ3", 0, - 113, UNIPHIER_PIN_DRV_4_8, + 113, UNIPHIER_PIN_DRV_1BIT, 113, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(126, "XIRQ4", 0, - 114, UNIPHIER_PIN_DRV_4_8, + 114, UNIPHIER_PIN_DRV_1BIT, 114, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(127, "XIRQ5", 0, - 115, UNIPHIER_PIN_DRV_4_8, + 115, UNIPHIER_PIN_DRV_1BIT, 115, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(128, "XIRQ6", 0, - 116, UNIPHIER_PIN_DRV_4_8, + 116, UNIPHIER_PIN_DRV_1BIT, 116, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(129, "XIRQ7", 0, - 117, UNIPHIER_PIN_DRV_4_8, + 117, UNIPHIER_PIN_DRV_1BIT, 117, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(130, "XIRQ8", 0, - 118, UNIPHIER_PIN_DRV_4_8, + 118, UNIPHIER_PIN_DRV_1BIT, 118, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(131, "XIRQ9", 0, - 119, UNIPHIER_PIN_DRV_4_8, + 119, UNIPHIER_PIN_DRV_1BIT, 119, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(132, "XIRQ10", 0, - 120, UNIPHIER_PIN_DRV_4_8, + 120, UNIPHIER_PIN_DRV_1BIT, 120, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(133, "XIRQ11", 0, - 121, UNIPHIER_PIN_DRV_4_8, + 121, UNIPHIER_PIN_DRV_1BIT, 121, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(134, "XIRQ14", 0, - 122, UNIPHIER_PIN_DRV_4_8, + 122, UNIPHIER_PIN_DRV_1BIT, 122, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(135, "PORT00", 0, - 123, UNIPHIER_PIN_DRV_4_8, + 123, UNIPHIER_PIN_DRV_1BIT, 123, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(136, "PORT01", 0, - 124, UNIPHIER_PIN_DRV_4_8, + 124, UNIPHIER_PIN_DRV_1BIT, 124, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(137, "PORT02", 0, - 125, UNIPHIER_PIN_DRV_4_8, + 125, UNIPHIER_PIN_DRV_1BIT, 125, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(138, "PORT03", 0, - 126, UNIPHIER_PIN_DRV_4_8, + 126, UNIPHIER_PIN_DRV_1BIT, 126, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(139, "PORT04", 0, - 127, UNIPHIER_PIN_DRV_4_8, + 127, UNIPHIER_PIN_DRV_1BIT, 127, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(140, "PORT05", 0, - 128, UNIPHIER_PIN_DRV_4_8, + 128, UNIPHIER_PIN_DRV_1BIT, 128, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(141, "PORT06", 0, - 129, UNIPHIER_PIN_DRV_4_8, + 129, UNIPHIER_PIN_DRV_1BIT, 129, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(142, "PORT07", 0, - 130, UNIPHIER_PIN_DRV_4_8, + 130, UNIPHIER_PIN_DRV_1BIT, 130, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(143, "PORT10", 0, - 131, UNIPHIER_PIN_DRV_4_8, + 131, UNIPHIER_PIN_DRV_1BIT, 131, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(144, "PORT11", 0, - 132, UNIPHIER_PIN_DRV_4_8, + 132, UNIPHIER_PIN_DRV_1BIT, 132, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(145, "PORT12", 0, - 133, UNIPHIER_PIN_DRV_4_8, + 133, UNIPHIER_PIN_DRV_1BIT, 133, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(146, "PORT13", 0, - 134, UNIPHIER_PIN_DRV_4_8, + 134, UNIPHIER_PIN_DRV_1BIT, 134, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(147, "PORT14", 0, - 135, UNIPHIER_PIN_DRV_4_8, + 135, UNIPHIER_PIN_DRV_1BIT, 135, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(148, "PORT15", 0, - 136, UNIPHIER_PIN_DRV_4_8, + 136, UNIPHIER_PIN_DRV_1BIT, 136, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(149, "PORT16", 0, - 137, UNIPHIER_PIN_DRV_4_8, + 137, UNIPHIER_PIN_DRV_1BIT, 137, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(150, "PORT17", UNIPHIER_PIN_IECTRL_NONE, - 138, UNIPHIER_PIN_DRV_4_8, + 138, UNIPHIER_PIN_DRV_1BIT, 138, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(151, "PORT20", 0, - 139, UNIPHIER_PIN_DRV_4_8, + 139, UNIPHIER_PIN_DRV_1BIT, 139, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(152, "PORT21", 0, - 140, UNIPHIER_PIN_DRV_4_8, + 140, UNIPHIER_PIN_DRV_1BIT, 140, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(153, "PORT22", 0, - 141, UNIPHIER_PIN_DRV_4_8, + 141, UNIPHIER_PIN_DRV_1BIT, 141, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(154, "PORT23", 0, - 142, UNIPHIER_PIN_DRV_4_8, + 142, UNIPHIER_PIN_DRV_1BIT, 142, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(155, "PORT24", UNIPHIER_PIN_IECTRL_NONE, - 143, UNIPHIER_PIN_DRV_4_8, + 143, UNIPHIER_PIN_DRV_1BIT, 143, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(156, "PORT25", 0, - 144, UNIPHIER_PIN_DRV_4_8, + 144, UNIPHIER_PIN_DRV_1BIT, 144, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(157, "PORT26", 0, - 145, UNIPHIER_PIN_DRV_4_8, + 145, UNIPHIER_PIN_DRV_1BIT, 145, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(158, "XNFRE", UNIPHIER_PIN_IECTRL_NONE, - 31, UNIPHIER_PIN_DRV_4_8, + 31, UNIPHIER_PIN_DRV_1BIT, 31, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(159, "XNFWE", UNIPHIER_PIN_IECTRL_NONE, - 32, UNIPHIER_PIN_DRV_4_8, + 32, UNIPHIER_PIN_DRV_1BIT, 32, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(160, "NFALE", UNIPHIER_PIN_IECTRL_NONE, - 33, UNIPHIER_PIN_DRV_4_8, + 33, UNIPHIER_PIN_DRV_1BIT, 33, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(161, "NFCLE", UNIPHIER_PIN_IECTRL_NONE, - 34, UNIPHIER_PIN_DRV_4_8, + 34, UNIPHIER_PIN_DRV_1BIT, 34, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(162, "XNFWP", UNIPHIER_PIN_IECTRL_NONE, - 35, UNIPHIER_PIN_DRV_4_8, + 35, UNIPHIER_PIN_DRV_1BIT, 35, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(163, "XNFCE0", UNIPHIER_PIN_IECTRL_NONE, - 36, UNIPHIER_PIN_DRV_4_8, + 36, UNIPHIER_PIN_DRV_1BIT, 36, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(164, "NANDRYBY0", UNIPHIER_PIN_IECTRL_NONE, - 37, UNIPHIER_PIN_DRV_4_8, + 37, UNIPHIER_PIN_DRV_1BIT, 37, UNIPHIER_PIN_PULL_UP), + /* dedicated pins */ + UNIPHIER_PINCTRL_PIN(165, "ED0", -1, + 0, UNIPHIER_PIN_DRV_1BIT, + 0, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(166, "ED1", -1, + 1, UNIPHIER_PIN_DRV_1BIT, + 1, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(167, "ED2", -1, + 2, UNIPHIER_PIN_DRV_1BIT, + 2, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(168, "ED3", -1, + 3, UNIPHIER_PIN_DRV_1BIT, + 3, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(169, "ED4", -1, + 4, UNIPHIER_PIN_DRV_1BIT, + 4, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(170, "ED5", -1, + 5, UNIPHIER_PIN_DRV_1BIT, + 5, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(171, "ED6", -1, + 6, UNIPHIER_PIN_DRV_1BIT, + 6, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(172, "ED7", -1, + 7, UNIPHIER_PIN_DRV_1BIT, + 7, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(173, "ERXW", -1, + 26, UNIPHIER_PIN_DRV_1BIT, + 26, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(174, "XECS1", -1, + 30, UNIPHIER_PIN_DRV_1BIT, + 30, UNIPHIER_PIN_PULL_UP), }; static const unsigned emmc_pins[] = {21, 22, 23, 24, 25, 26, 27}; -static const unsigned emmc_muxvals[] = {0, 1, 1, 1, 1, 1, 1}; +static const int emmc_muxvals[] = {0, 1, 1, 1, 1, 1, 1}; static const unsigned emmc_dat8_pins[] = {28, 29, 30, 31}; -static const unsigned emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const int emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const unsigned ether_mii_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 136, 137, 138, 139, 140, + 141, 142}; +static const int ether_mii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 4, 4, 4, 4, 4, 4}; +static const unsigned ether_rmii_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43}; +static const int ether_rmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned i2c0_pins[] = {102, 103}; -static const unsigned i2c0_muxvals[] = {0, 0}; +static const int i2c0_muxvals[] = {0, 0}; static const unsigned i2c1_pins[] = {104, 105}; -static const unsigned i2c1_muxvals[] = {0, 0}; +static const int i2c1_muxvals[] = {0, 0}; static const unsigned i2c2_pins[] = {108, 109}; -static const unsigned i2c2_muxvals[] = {2, 2}; +static const int i2c2_muxvals[] = {2, 2}; static const unsigned i2c3_pins[] = {108, 109}; -static const unsigned i2c3_muxvals[] = {3, 3}; +static const int i2c3_muxvals[] = {3, 3}; static const unsigned nand_pins[] = {24, 25, 26, 27, 28, 29, 30, 31, 158, 159, 160, 161, 162, 163, 164}; -static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0}; +static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned nand_cs1_pins[] = {22, 23}; -static const unsigned nand_cs1_muxvals[] = {0, 0}; +static const int nand_cs1_muxvals[] = {0, 0}; static const unsigned sd_pins[] = {44, 45, 46, 47, 48, 49, 50, 51, 52}; -static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned system_bus_pins[] = {16, 17, 18, 19, 20, 165, 166, 167, + 168, 169, 170, 171, 172, 173}; +static const int system_bus_muxvals[] = {0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, + -1, -1, -1}; +static const unsigned system_bus_cs0_pins[] = {155}; +static const int system_bus_cs0_muxvals[] = {1}; +static const unsigned system_bus_cs1_pins[] = {174}; +static const int system_bus_cs1_muxvals[] = {-1}; +static const unsigned system_bus_cs2_pins[] = {64}; +static const int system_bus_cs2_muxvals[] = {1}; +static const unsigned system_bus_cs3_pins[] = {156}; +static const int system_bus_cs3_muxvals[] = {1}; static const unsigned uart0_pins[] = {85, 88}; -static const unsigned uart0_muxvals[] = {1, 1}; +static const int uart0_muxvals[] = {1, 1}; static const unsigned uart1_pins[] = {155, 156}; -static const unsigned uart1_muxvals[] = {13, 13}; +static const int uart1_muxvals[] = {13, 13}; static const unsigned uart1b_pins[] = {69, 70}; -static const unsigned uart1b_muxvals[] = {23, 23}; +static const int uart1b_muxvals[] = {23, 23}; static const unsigned uart2_pins[] = {128, 129}; -static const unsigned uart2_muxvals[] = {13, 13}; +static const int uart2_muxvals[] = {13, 13}; static const unsigned uart3_pins[] = {110, 111}; -static const unsigned uart3_muxvals[] = {1, 1}; +static const int uart3_muxvals[] = {1, 1}; static const unsigned usb0_pins[] = {53, 54}; -static const unsigned usb0_muxvals[] = {0, 0}; +static const int usb0_muxvals[] = {0, 0}; static const unsigned usb1_pins[] = {55, 56}; -static const unsigned usb1_muxvals[] = {0, 0}; +static const int usb1_muxvals[] = {0, 0}; static const unsigned usb2_pins[] = {155, 156}; -static const unsigned usb2_muxvals[] = {4, 4}; +static const int usb2_muxvals[] = {4, 4}; static const unsigned usb2b_pins[] = {67, 68}; -static const unsigned usb2b_muxvals[] = {23, 23}; +static const int usb2b_muxvals[] = {23, 23}; static const unsigned port_range0_pins[] = { 135, 136, 137, 138, 139, 140, 141, 142, /* PORT0x */ 143, 144, 145, 146, 147, 148, 149, 150, /* PORT1x */ @@ -574,7 +622,7 @@ static const unsigned port_range0_pins[] = { 98, 99, 100, 6, 101, 114, 115, 116, /* PORT13x */ 103, 108, 21, 22, 23, 117, 118, 119, /* PORT14x */ }; -static const unsigned port_range0_muxvals[] = { +static const int port_range0_muxvals[] = { 0, 0, 0, 0, 0, 0, 0, 0, /* PORT0x */ 0, 0, 0, 0, 0, 0, 0, 0, /* PORT1x */ 0, 0, 0, 0, 0, 0, 0, 15, /* PORT2x */ @@ -594,27 +642,29 @@ static const unsigned port_range0_muxvals[] = { static const unsigned port_range1_pins[] = { 7, /* PORT166 */ }; -static const unsigned port_range1_muxvals[] = { +static const int port_range1_muxvals[] = { 15, /* PORT166 */ }; static const unsigned xirq_range0_pins[] = { 151, 123, 124, 125, 126, 127, 128, 129, /* XIRQ0-7 */ 130, 131, 132, 133, 62, /* XIRQ8-12 */ }; -static const unsigned xirq_range0_muxvals[] = { +static const int xirq_range0_muxvals[] = { 14, 0, 0, 0, 0, 0, 0, 0, /* XIRQ0-7 */ 0, 0, 0, 0, 14, /* XIRQ8-12 */ }; static const unsigned xirq_range1_pins[] = { 134, 63, /* XIRQ14-15 */ }; -static const unsigned xirq_range1_muxvals[] = { +static const int xirq_range1_muxvals[] = { 0, 14, /* XIRQ14-15 */ }; -static const struct uniphier_pinctrl_group ph1_ld4_groups[] = { +static const struct uniphier_pinctrl_group uniphier_ld4_groups[] = { UNIPHIER_PINCTRL_GROUP(emmc), UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(ether_mii), + UNIPHIER_PINCTRL_GROUP(ether_rmii), UNIPHIER_PINCTRL_GROUP(i2c0), UNIPHIER_PINCTRL_GROUP(i2c1), UNIPHIER_PINCTRL_GROUP(i2c2), @@ -622,6 +672,11 @@ static const struct uniphier_pinctrl_group ph1_ld4_groups[] = { UNIPHIER_PINCTRL_GROUP(nand), UNIPHIER_PINCTRL_GROUP(nand_cs1), UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs0), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(system_bus_cs2), + UNIPHIER_PINCTRL_GROUP(system_bus_cs3), UNIPHIER_PINCTRL_GROUP(uart0), UNIPHIER_PINCTRL_GROUP(uart1), UNIPHIER_PINCTRL_GROUP(uart1b), @@ -774,12 +829,19 @@ static const struct uniphier_pinctrl_group ph1_ld4_groups[] = { }; static const char * const emmc_groups[] = {"emmc", "emmc_dat8"}; +static const char * const ether_mii_groups[] = {"ether_mii"}; +static const char * const ether_rmii_groups[] = {"ether_rmii"}; static const char * const i2c0_groups[] = {"i2c0"}; static const char * const i2c1_groups[] = {"i2c1"}; static const char * const i2c2_groups[] = {"i2c2"}; static const char * const i2c3_groups[] = {"i2c3"}; static const char * const nand_groups[] = {"nand", "nand_cs1"}; static const char * const sd_groups[] = {"sd"}; +static const char * const system_bus_groups[] = {"system_bus", + "system_bus_cs0", + "system_bus_cs1", + "system_bus_cs2", + "system_bus_cs3"}; static const char * const uart0_groups[] = {"uart0"}; static const char * const uart1_groups[] = {"uart1", "uart1b"}; static const char * const uart2_groups[] = {"uart2"}; @@ -828,14 +890,17 @@ static const char * const xirq_groups[] = { "xirq12", /* none*/ "xirq14", "xirq15", }; -static const struct uniphier_pinmux_function ph1_ld4_functions[] = { +static const struct uniphier_pinmux_function uniphier_ld4_functions[] = { UNIPHIER_PINMUX_FUNCTION(emmc), + UNIPHIER_PINMUX_FUNCTION(ether_mii), + UNIPHIER_PINMUX_FUNCTION(ether_rmii), UNIPHIER_PINMUX_FUNCTION(i2c0), UNIPHIER_PINMUX_FUNCTION(i2c1), UNIPHIER_PINMUX_FUNCTION(i2c2), UNIPHIER_PINMUX_FUNCTION(i2c3), UNIPHIER_PINMUX_FUNCTION(nand), UNIPHIER_PINMUX_FUNCTION(sd), + UNIPHIER_PINMUX_FUNCTION(system_bus), UNIPHIER_PINMUX_FUNCTION(uart0), UNIPHIER_PINMUX_FUNCTION(uart1), UNIPHIER_PINMUX_FUNCTION(uart2), @@ -847,43 +912,36 @@ static const struct uniphier_pinmux_function ph1_ld4_functions[] = { UNIPHIER_PINMUX_FUNCTION(xirq), }; -static struct uniphier_pinctrl_socdata ph1_ld4_pindata = { - .groups = ph1_ld4_groups, - .groups_count = ARRAY_SIZE(ph1_ld4_groups), - .functions = ph1_ld4_functions, - .functions_count = ARRAY_SIZE(ph1_ld4_functions), - .mux_bits = 8, - .reg_stride = 4, - .load_pinctrl = false, -}; - -static struct pinctrl_desc ph1_ld4_pinctrl_desc = { - .name = DRIVER_NAME, - .pins = ph1_ld4_pins, - .npins = ARRAY_SIZE(ph1_ld4_pins), - .owner = THIS_MODULE, +static struct uniphier_pinctrl_socdata uniphier_ld4_pindata = { + .pins = uniphier_ld4_pins, + .npins = ARRAY_SIZE(uniphier_ld4_pins), + .groups = uniphier_ld4_groups, + .groups_count = ARRAY_SIZE(uniphier_ld4_groups), + .functions = uniphier_ld4_functions, + .functions_count = ARRAY_SIZE(uniphier_ld4_functions), + .caps = 0, }; -static int ph1_ld4_pinctrl_probe(struct platform_device *pdev) +static int uniphier_ld4_pinctrl_probe(struct platform_device *pdev) { - return uniphier_pinctrl_probe(pdev, &ph1_ld4_pinctrl_desc, - &ph1_ld4_pindata); + return uniphier_pinctrl_probe(pdev, &uniphier_ld4_pindata); } -static const struct of_device_id ph1_ld4_pinctrl_match[] = { +static const struct of_device_id uniphier_ld4_pinctrl_match[] = { + { .compatible = "socionext,uniphier-ld4-pinctrl" }, { .compatible = "socionext,ph1-ld4-pinctrl" }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, ph1_ld4_pinctrl_match); +MODULE_DEVICE_TABLE(of, uniphier_ld4_pinctrl_match); -static struct platform_driver ph1_ld4_pinctrl_driver = { - .probe = ph1_ld4_pinctrl_probe, +static struct platform_driver uniphier_ld4_pinctrl_driver = { + .probe = uniphier_ld4_pinctrl_probe, .driver = { - .name = DRIVER_NAME, - .of_match_table = ph1_ld4_pinctrl_match, + .name = "uniphier-ld4-pinctrl", + .of_match_table = uniphier_ld4_pinctrl_match, }, }; -module_platform_driver(ph1_ld4_pinctrl_driver); +module_platform_driver(uniphier_ld4_pinctrl_driver); MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); MODULE_DESCRIPTION("UniPhier PH1-LD4 pinctrl driver"); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c index 150d33928df2..708e5100cf34 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c @@ -19,713 +19,711 @@ #include "pinctrl-uniphier.h" -#define DRIVER_NAME "ph1-ld6b-pinctrl" - -static const struct pinctrl_pin_desc ph1_ld6b_pins[] = { +static const struct pinctrl_pin_desc uniphier_ld6b_pins[] = { UNIPHIER_PINCTRL_PIN(0, "ED0", UNIPHIER_PIN_IECTRL_NONE, - 0, UNIPHIER_PIN_DRV_4_8, + 0, UNIPHIER_PIN_DRV_1BIT, 0, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(1, "ED1", UNIPHIER_PIN_IECTRL_NONE, - 1, UNIPHIER_PIN_DRV_4_8, + 1, UNIPHIER_PIN_DRV_1BIT, 1, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(2, "ED2", UNIPHIER_PIN_IECTRL_NONE, - 2, UNIPHIER_PIN_DRV_4_8, + 2, UNIPHIER_PIN_DRV_1BIT, 2, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(3, "ED3", UNIPHIER_PIN_IECTRL_NONE, - 3, UNIPHIER_PIN_DRV_4_8, + 3, UNIPHIER_PIN_DRV_1BIT, 3, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(4, "ED4", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_4_8, + 4, UNIPHIER_PIN_DRV_1BIT, 4, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(5, "ED5", UNIPHIER_PIN_IECTRL_NONE, - 5, UNIPHIER_PIN_DRV_4_8, + 5, UNIPHIER_PIN_DRV_1BIT, 5, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(6, "ED6", UNIPHIER_PIN_IECTRL_NONE, - 6, UNIPHIER_PIN_DRV_4_8, + 6, UNIPHIER_PIN_DRV_1BIT, 6, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(7, "ED7", UNIPHIER_PIN_IECTRL_NONE, - 7, UNIPHIER_PIN_DRV_4_8, + 7, UNIPHIER_PIN_DRV_1BIT, 7, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(8, "XERWE0", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_4_8, + 8, UNIPHIER_PIN_DRV_1BIT, 8, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(9, "XERWE1", UNIPHIER_PIN_IECTRL_NONE, - 9, UNIPHIER_PIN_DRV_4_8, + 9, UNIPHIER_PIN_DRV_1BIT, 9, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(10, "ERXW", UNIPHIER_PIN_IECTRL_NONE, - 10, UNIPHIER_PIN_DRV_4_8, + 10, UNIPHIER_PIN_DRV_1BIT, 10, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(11, "ES0", UNIPHIER_PIN_IECTRL_NONE, - 11, UNIPHIER_PIN_DRV_4_8, + 11, UNIPHIER_PIN_DRV_1BIT, 11, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(12, "ES1", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_4_8, + 12, UNIPHIER_PIN_DRV_1BIT, 12, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(13, "ES2", UNIPHIER_PIN_IECTRL_NONE, - 13, UNIPHIER_PIN_DRV_4_8, + 13, UNIPHIER_PIN_DRV_1BIT, 13, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(14, "XECS1", UNIPHIER_PIN_IECTRL_NONE, - 14, UNIPHIER_PIN_DRV_4_8, + 14, UNIPHIER_PIN_DRV_1BIT, 14, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(15, "PCA00", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 15, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(16, "PCA01", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 16, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(17, "PCA02", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 17, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(18, "PCA03", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 18, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(19, "PCA04", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 19, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(20, "PCA05", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 20, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(21, "PCA06", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 21, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(22, "PCA07", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 22, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(23, "PCA08", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 23, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(24, "PCA09", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 24, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(25, "PCA10", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 25, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(26, "PCA11", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 26, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(27, "PCA12", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 27, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(28, "PCA13", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 28, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(29, "PCA14", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 29, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(30, "XNFRE", UNIPHIER_PIN_IECTRL_NONE, - 30, UNIPHIER_PIN_DRV_4_8, + 30, UNIPHIER_PIN_DRV_1BIT, 30, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(31, "XNFWE", UNIPHIER_PIN_IECTRL_NONE, - 31, UNIPHIER_PIN_DRV_4_8, + 31, UNIPHIER_PIN_DRV_1BIT, 31, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(32, "NFALE", UNIPHIER_PIN_IECTRL_NONE, - 32, UNIPHIER_PIN_DRV_4_8, + 32, UNIPHIER_PIN_DRV_1BIT, 32, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(33, "NFCLE", UNIPHIER_PIN_IECTRL_NONE, - 33, UNIPHIER_PIN_DRV_4_8, + 33, UNIPHIER_PIN_DRV_1BIT, 33, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(34, "XNFWP", UNIPHIER_PIN_IECTRL_NONE, - 34, UNIPHIER_PIN_DRV_4_8, + 34, UNIPHIER_PIN_DRV_1BIT, 34, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(35, "XNFCE0", UNIPHIER_PIN_IECTRL_NONE, - 35, UNIPHIER_PIN_DRV_4_8, + 35, UNIPHIER_PIN_DRV_1BIT, 35, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(36, "NFRYBY0", UNIPHIER_PIN_IECTRL_NONE, - 36, UNIPHIER_PIN_DRV_4_8, + 36, UNIPHIER_PIN_DRV_1BIT, 36, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(37, "XNFCE1", UNIPHIER_PIN_IECTRL_NONE, - 37, UNIPHIER_PIN_DRV_4_8, + 37, UNIPHIER_PIN_DRV_1BIT, 37, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(38, "NFRYBY1", UNIPHIER_PIN_IECTRL_NONE, - 38, UNIPHIER_PIN_DRV_4_8, + 38, UNIPHIER_PIN_DRV_1BIT, 38, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(39, "NFD0", UNIPHIER_PIN_IECTRL_NONE, - 39, UNIPHIER_PIN_DRV_4_8, + 39, UNIPHIER_PIN_DRV_1BIT, 39, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(40, "NFD1", UNIPHIER_PIN_IECTRL_NONE, - 40, UNIPHIER_PIN_DRV_4_8, + 40, UNIPHIER_PIN_DRV_1BIT, 40, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(41, "NFD2", UNIPHIER_PIN_IECTRL_NONE, - 41, UNIPHIER_PIN_DRV_4_8, + 41, UNIPHIER_PIN_DRV_1BIT, 41, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(42, "NFD3", UNIPHIER_PIN_IECTRL_NONE, - 42, UNIPHIER_PIN_DRV_4_8, + 42, UNIPHIER_PIN_DRV_1BIT, 42, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(43, "NFD4", UNIPHIER_PIN_IECTRL_NONE, - 43, UNIPHIER_PIN_DRV_4_8, + 43, UNIPHIER_PIN_DRV_1BIT, 43, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(44, "NFD5", UNIPHIER_PIN_IECTRL_NONE, - 44, UNIPHIER_PIN_DRV_4_8, + 44, UNIPHIER_PIN_DRV_1BIT, 44, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(45, "NFD6", UNIPHIER_PIN_IECTRL_NONE, - 45, UNIPHIER_PIN_DRV_4_8, + 45, UNIPHIER_PIN_DRV_1BIT, 45, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(46, "NFD7", UNIPHIER_PIN_IECTRL_NONE, - 46, UNIPHIER_PIN_DRV_4_8, + 46, UNIPHIER_PIN_DRV_1BIT, 46, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(47, "SDCLK", UNIPHIER_PIN_IECTRL_NONE, - 0, UNIPHIER_PIN_DRV_8_12_16_20, + 0, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(48, "SDCMD", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_8_12_16_20, + 1, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(49, "SDDAT0", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_8_12_16_20, + 2, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(50, "SDDAT1", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_8_12_16_20, + 3, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(51, "SDDAT2", UNIPHIER_PIN_IECTRL_NONE, - 16, UNIPHIER_PIN_DRV_8_12_16_20, + 4, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(52, "SDDAT3", UNIPHIER_PIN_IECTRL_NONE, - 20, UNIPHIER_PIN_DRV_8_12_16_20, + 5, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(53, "SDCD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 53, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(54, "SDWP", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 54, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(55, "SDVOLC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 55, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(56, "USB0VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 56, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(57, "USB0OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 57, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(58, "USB1VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 58, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(59, "USB1OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 59, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(60, "USB2VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 60, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(61, "USB2OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 61, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(62, "USB3VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 62, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(63, "USB3OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 63, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(64, "HS0BCLKOUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 64, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(65, "HS0SYNCOUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 65, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(66, "HS0VALOUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 66, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(67, "HS0DOUT0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 67, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(68, "HS0DOUT1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 68, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(69, "HS0DOUT2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 69, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(70, "HS0DOUT3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 70, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(71, "HS0DOUT4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 71, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(72, "HS0DOUT5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 72, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(73, "HS0DOUT6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 73, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(74, "HS0DOUT7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 74, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(75, "HS1BCLKIN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 75, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(76, "HS1SYNCIN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 76, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(77, "HS1VALIN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 77, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(78, "HS1DIN0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 78, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(79, "HS1DIN1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 79, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(80, "HS1DIN2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 80, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(81, "HS1DIN3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 81, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(82, "HS1DIN4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 82, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(83, "HS1DIN5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 83, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(84, "HS1DIN6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 84, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(85, "HS1DIN7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 85, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(86, "HS2BCLKIN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 86, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(87, "HS2SYNCIN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 87, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(88, "HS2VALIN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 88, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(89, "HS2DIN0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 89, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(90, "HS2DIN1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 90, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(91, "HS2DIN2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 91, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(92, "HS2DIN3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 92, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(93, "HS2DIN4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 93, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(94, "HS2DIN5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 94, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(95, "HS2DIN6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 95, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(96, "HS2DIN7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 96, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(97, "AO1IEC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 97, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(98, "AO1DACCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 98, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(99, "AO1BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 99, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(100, "AO1LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 100, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(101, "AO1D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 101, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(102, "AO1D1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 102, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(103, "AO1D2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 103, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(104, "AO1D3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 104, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(105, "AO2DACCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 105, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(106, "AO2BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 106, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(107, "AO2LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 107, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(108, "AO2D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 108, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(109, "SDA0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 109, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(110, "SCL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 110, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(111, "SDA1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 111, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(112, "SCL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 112, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(113, "SBO0", 0, - 113, UNIPHIER_PIN_DRV_4_8, + 113, UNIPHIER_PIN_DRV_1BIT, 113, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(114, "SBI0", 0, - 114, UNIPHIER_PIN_DRV_4_8, + 114, UNIPHIER_PIN_DRV_1BIT, 114, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(115, "TXD1", 0, - 115, UNIPHIER_PIN_DRV_4_8, + 115, UNIPHIER_PIN_DRV_1BIT, 115, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(116, "RXD1", 0, - 116, UNIPHIER_PIN_DRV_4_8, + 116, UNIPHIER_PIN_DRV_1BIT, 116, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(117, "PWSRA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 117, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(118, "XIRQ0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 118, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(119, "XIRQ1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 119, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(120, "XIRQ2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 120, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(121, "XIRQ3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 121, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(122, "XIRQ4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 122, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(123, "XIRQ5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 123, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(124, "XIRQ6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 124, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(125, "XIRQ7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 125, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(126, "XIRQ8", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 126, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(127, "PORT00", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 127, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(128, "PORT01", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 128, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(129, "PORT02", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 129, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(130, "PORT03", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 130, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(131, "PORT04", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 131, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(132, "PORT05", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 132, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(133, "PORT06", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 133, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(134, "PORT07", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 134, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(135, "PORT10", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 135, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(136, "PORT11", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 136, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(137, "PORT12", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 137, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(138, "PORT13", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 138, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(139, "PORT14", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 139, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(140, "PORT15", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 140, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(141, "PORT16", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 141, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(142, "LPST", UNIPHIER_PIN_IECTRL_NONE, - 142, UNIPHIER_PIN_DRV_4_8, + 142, UNIPHIER_PIN_DRV_1BIT, 142, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(143, "MDC", 0, - 143, UNIPHIER_PIN_DRV_4_8, + 143, UNIPHIER_PIN_DRV_1BIT, 143, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(144, "MDIO", 0, - 144, UNIPHIER_PIN_DRV_4_8, + 144, UNIPHIER_PIN_DRV_1BIT, 144, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(145, "MDIO_INTL", 0, - 145, UNIPHIER_PIN_DRV_4_8, + 145, UNIPHIER_PIN_DRV_1BIT, 145, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(146, "PHYRSTL", 0, - 146, UNIPHIER_PIN_DRV_4_8, + 146, UNIPHIER_PIN_DRV_1BIT, 146, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(147, "RGMII_RXCLK", 0, - 147, UNIPHIER_PIN_DRV_4_8, + 147, UNIPHIER_PIN_DRV_1BIT, 147, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(148, "RGMII_RXD0", 0, - 148, UNIPHIER_PIN_DRV_4_8, + 148, UNIPHIER_PIN_DRV_1BIT, 148, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(149, "RGMII_RXD1", 0, - 149, UNIPHIER_PIN_DRV_4_8, + 149, UNIPHIER_PIN_DRV_1BIT, 149, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(150, "RGMII_RXD2", 0, - 150, UNIPHIER_PIN_DRV_4_8, + 150, UNIPHIER_PIN_DRV_1BIT, 150, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(151, "RGMII_RXD3", 0, - 151, UNIPHIER_PIN_DRV_4_8, + 151, UNIPHIER_PIN_DRV_1BIT, 151, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(152, "RGMII_RXCTL", 0, - 152, UNIPHIER_PIN_DRV_4_8, + 152, UNIPHIER_PIN_DRV_1BIT, 152, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(153, "RGMII_TXCLK", 0, - 153, UNIPHIER_PIN_DRV_4_8, + 153, UNIPHIER_PIN_DRV_1BIT, 153, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(154, "RGMII_TXD0", 0, - 154, UNIPHIER_PIN_DRV_4_8, + 154, UNIPHIER_PIN_DRV_1BIT, 154, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(155, "RGMII_TXD1", 0, - 155, UNIPHIER_PIN_DRV_4_8, + 155, UNIPHIER_PIN_DRV_1BIT, 155, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(156, "RGMII_TXD2", 0, - 156, UNIPHIER_PIN_DRV_4_8, + 156, UNIPHIER_PIN_DRV_1BIT, 156, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(157, "RGMII_TXD3", 0, - 157, UNIPHIER_PIN_DRV_4_8, + 157, UNIPHIER_PIN_DRV_1BIT, 157, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(158, "RGMII_TXCTL", 0, - 158, UNIPHIER_PIN_DRV_4_8, + 158, UNIPHIER_PIN_DRV_1BIT, 158, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(159, "A_D_PCD00OUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 159, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(160, "A_D_PCD01OUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 160, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(161, "A_D_PCD02OUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 161, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(162, "A_D_PCD03OUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 162, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(163, "A_D_PCD04OUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 163, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(164, "A_D_PCD05OUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 164, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(165, "A_D_PCD06OUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 165, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(166, "A_D_PCD07OUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 166, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(167, "A_D_PCD00IN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 167, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(168, "A_D_PCD01IN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 168, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(169, "A_D_PCD02IN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 169, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(170, "A_D_PCD03IN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 170, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(171, "A_D_PCD04IN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 171, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(172, "A_D_PCD05IN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 172, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(173, "A_D_PCD06IN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 173, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(174, "A_D_PCD07IN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 174, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(175, "A_D_PCDNOE", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 175, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(176, "A_D_PC0READY", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 176, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(177, "A_D_PC0CD1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 177, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(178, "A_D_PC0CD2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 178, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(179, "A_D_PC0WAIT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 179, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(180, "A_D_PC0RESET", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 180, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(181, "A_D_PC0CE1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 181, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(182, "A_D_PC0WE", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 182, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(183, "A_D_PC0OE", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 183, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(184, "A_D_PC0IOWR", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 184, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(185, "A_D_PC0IORD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 185, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(186, "A_D_PC0NOE", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 186, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(187, "A_D_HS0BCLKIN", 0, - 187, UNIPHIER_PIN_DRV_4_8, + 187, UNIPHIER_PIN_DRV_1BIT, 187, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(188, "A_D_HS0SYNCIN", 0, - 188, UNIPHIER_PIN_DRV_4_8, + 188, UNIPHIER_PIN_DRV_1BIT, 188, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(189, "A_D_HS0VALIN", 0, - 189, UNIPHIER_PIN_DRV_4_8, + 189, UNIPHIER_PIN_DRV_1BIT, 189, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(190, "A_D_HS0DIN0", 0, - 190, UNIPHIER_PIN_DRV_4_8, + 190, UNIPHIER_PIN_DRV_1BIT, 190, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(191, "A_D_HS0DIN1", 0, - 191, UNIPHIER_PIN_DRV_4_8, + 191, UNIPHIER_PIN_DRV_1BIT, 191, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(192, "A_D_HS0DIN2", 0, - 192, UNIPHIER_PIN_DRV_4_8, + 192, UNIPHIER_PIN_DRV_1BIT, 192, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(193, "A_D_HS0DIN3", 0, - 193, UNIPHIER_PIN_DRV_4_8, + 193, UNIPHIER_PIN_DRV_1BIT, 193, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(194, "A_D_HS0DIN4", 0, - 194, UNIPHIER_PIN_DRV_4_8, + 194, UNIPHIER_PIN_DRV_1BIT, 194, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(195, "A_D_HS0DIN5", 0, - 195, UNIPHIER_PIN_DRV_4_8, + 195, UNIPHIER_PIN_DRV_1BIT, 195, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(196, "A_D_HS0DIN6", 0, - 196, UNIPHIER_PIN_DRV_4_8, + 196, UNIPHIER_PIN_DRV_1BIT, 196, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(197, "A_D_HS0DIN7", 0, - 197, UNIPHIER_PIN_DRV_4_8, + 197, UNIPHIER_PIN_DRV_1BIT, 197, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(198, "A_D_AO1ARC", 0, - 198, UNIPHIER_PIN_DRV_4_8, + 198, UNIPHIER_PIN_DRV_1BIT, 198, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(199, "A_D_SPIXRST", UNIPHIER_PIN_IECTRL_NONE, - 199, UNIPHIER_PIN_DRV_4_8, + 199, UNIPHIER_PIN_DRV_1BIT, 199, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(200, "A_D_SPISCLK0", UNIPHIER_PIN_IECTRL_NONE, - 200, UNIPHIER_PIN_DRV_4_8, + 200, UNIPHIER_PIN_DRV_1BIT, 200, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(201, "A_D_SPITXD0", UNIPHIER_PIN_IECTRL_NONE, - 201, UNIPHIER_PIN_DRV_4_8, + 201, UNIPHIER_PIN_DRV_1BIT, 201, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(202, "A_D_SPIRXD0", UNIPHIER_PIN_IECTRL_NONE, - 202, UNIPHIER_PIN_DRV_4_8, + 202, UNIPHIER_PIN_DRV_1BIT, 202, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(203, "A_D_DMDCLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 203, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(204, "A_D_DMDPSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 204, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(205, "A_D_DMDVAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 205, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(206, "A_D_DMDDATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 206, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(207, "A_D_HDMIRXXIRQ", 0, - 207, UNIPHIER_PIN_DRV_4_8, + 207, UNIPHIER_PIN_DRV_1BIT, 207, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(208, "A_D_VBIXIRQ", 0, - 208, UNIPHIER_PIN_DRV_4_8, + 208, UNIPHIER_PIN_DRV_1BIT, 208, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(209, "A_D_HDMITXXIRQ", 0, - 209, UNIPHIER_PIN_DRV_4_8, + 209, UNIPHIER_PIN_DRV_1BIT, 209, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(210, "A_D_DMDIRQ", UNIPHIER_PIN_IECTRL_NONE, - 210, UNIPHIER_PIN_DRV_4_8, + 210, UNIPHIER_PIN_DRV_1BIT, 210, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(211, "A_D_SPICIRQ", UNIPHIER_PIN_IECTRL_NONE, - 211, UNIPHIER_PIN_DRV_4_8, + 211, UNIPHIER_PIN_DRV_1BIT, 211, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(212, "A_D_SPIBIRQ", UNIPHIER_PIN_IECTRL_NONE, - 212, UNIPHIER_PIN_DRV_4_8, + 212, UNIPHIER_PIN_DRV_1BIT, 212, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(213, "A_D_BESDAOUT", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 213, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(214, "A_D_BESDAIN", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 214, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(215, "A_D_BESCLOUT", UNIPHIER_PIN_IECTRL_NONE, - 215, UNIPHIER_PIN_DRV_4_8, + 215, UNIPHIER_PIN_DRV_1BIT, 215, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(216, "A_D_VDACCLKOUT", 0, - 216, UNIPHIER_PIN_DRV_4_8, + 216, UNIPHIER_PIN_DRV_1BIT, 216, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(217, "A_D_VDACDOUT5", 0, - 217, UNIPHIER_PIN_DRV_4_8, + 217, UNIPHIER_PIN_DRV_1BIT, 217, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(218, "A_D_VDACDOUT6", 0, - 218, UNIPHIER_PIN_DRV_4_8, + 218, UNIPHIER_PIN_DRV_1BIT, 218, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(219, "A_D_VDACDOUT7", 0, - 219, UNIPHIER_PIN_DRV_4_8, + 219, UNIPHIER_PIN_DRV_1BIT, 219, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(220, "A_D_VDACDOUT8", 0, - 220, UNIPHIER_PIN_DRV_4_8, + 220, UNIPHIER_PIN_DRV_1BIT, 220, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(221, "A_D_VDACDOUT9", 0, - 221, UNIPHIER_PIN_DRV_4_8, + 221, UNIPHIER_PIN_DRV_1BIT, 221, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(222, "A_D_SIFBCKIN", 0, - 222, UNIPHIER_PIN_DRV_4_8, + 222, UNIPHIER_PIN_DRV_1BIT, 222, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(223, "A_D_SIFLRCKIN", 0, - 223, UNIPHIER_PIN_DRV_4_8, + 223, UNIPHIER_PIN_DRV_1BIT, 223, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(224, "A_D_SIFDIN", 0, - 224, UNIPHIER_PIN_DRV_4_8, + 224, UNIPHIER_PIN_DRV_1BIT, 224, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(225, "A_D_LIBCKOUT", 0, - 225, UNIPHIER_PIN_DRV_4_8, + 225, UNIPHIER_PIN_DRV_1BIT, 225, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(226, "A_D_LILRCKOUT", 0, - 226, UNIPHIER_PIN_DRV_4_8, + 226, UNIPHIER_PIN_DRV_1BIT, 226, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(227, "A_D_LIDIN", 0, - 227, UNIPHIER_PIN_DRV_4_8, + 227, UNIPHIER_PIN_DRV_1BIT, 227, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(228, "A_D_LODOUT", 0, - 228, UNIPHIER_PIN_DRV_4_8, + 228, UNIPHIER_PIN_DRV_1BIT, 228, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(229, "A_D_HPDOUT", 0, - 229, UNIPHIER_PIN_DRV_4_8, + 229, UNIPHIER_PIN_DRV_1BIT, 229, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(230, "A_D_MCLK", 0, - 230, UNIPHIER_PIN_DRV_4_8, + 230, UNIPHIER_PIN_DRV_1BIT, 230, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(231, "A_D_A2PLLREFOUT", 0, - 231, UNIPHIER_PIN_DRV_4_8, + 231, UNIPHIER_PIN_DRV_1BIT, 231, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(232, "A_D_HDMI3DSDAOUT", 0, - 232, UNIPHIER_PIN_DRV_4_8, + 232, UNIPHIER_PIN_DRV_1BIT, 232, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(233, "A_D_HDMI3DSDAIN", 0, - 233, UNIPHIER_PIN_DRV_4_8, + 233, UNIPHIER_PIN_DRV_1BIT, 233, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(234, "A_D_HDMI3DSCLIN", 0, - 234, UNIPHIER_PIN_DRV_4_8, + 234, UNIPHIER_PIN_DRV_1BIT, 234, UNIPHIER_PIN_PULL_DOWN), }; @@ -737,52 +735,73 @@ static const unsigned adinter_pins[] = { 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, }; -static const unsigned adinter_muxvals[] = { +static const int adinter_muxvals[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42}; -static const unsigned emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; +static const int emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46}; -static const unsigned emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const int emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const unsigned ether_rgmii_pins[] = {143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, + 157, 158}; +static const int ether_rgmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; +static const unsigned ether_rmii_pins[] = {143, 144, 145, 146, 147, 148, 149, + 150, 152, 154, 155, 158}; +static const int ether_rmii_muxvals[] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1}; static const unsigned i2c0_pins[] = {109, 110}; -static const unsigned i2c0_muxvals[] = {0, 0}; +static const int i2c0_muxvals[] = {0, 0}; static const unsigned i2c1_pins[] = {111, 112}; -static const unsigned i2c1_muxvals[] = {0, 0}; +static const int i2c1_muxvals[] = {0, 0}; static const unsigned i2c2_pins[] = {115, 116}; -static const unsigned i2c2_muxvals[] = {1, 1}; +static const int i2c2_muxvals[] = {1, 1}; static const unsigned i2c3_pins[] = {118, 119}; -static const unsigned i2c3_muxvals[] = {1, 1}; +static const int i2c3_muxvals[] = {1, 1}; static const unsigned nand_pins[] = {30, 31, 32, 33, 34, 35, 36, 39, 40, 41, 42, 43, 44, 45, 46}; -static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0}; +static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned nand_cs1_pins[] = {37, 38}; -static const unsigned nand_cs1_muxvals[] = {0, 0}; +static const int nand_cs1_muxvals[] = {0, 0}; static const unsigned sd_pins[] = {47, 48, 49, 50, 51, 52, 53, 54, 55}; -static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned system_bus_pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13}; +static const int system_bus_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0}; +static const unsigned system_bus_cs1_pins[] = {14}; +static const int system_bus_cs1_muxvals[] = {0}; +static const unsigned system_bus_cs2_pins[] = {37}; +static const int system_bus_cs2_muxvals[] = {6}; +static const unsigned system_bus_cs3_pins[] = {38}; +static const int system_bus_cs3_muxvals[] = {6}; +static const unsigned system_bus_cs4_pins[] = {115}; +static const int system_bus_cs4_muxvals[] = {6}; +static const unsigned system_bus_cs5_pins[] = {55}; +static const int system_bus_cs5_muxvals[] = {6}; static const unsigned uart0_pins[] = {135, 136}; -static const unsigned uart0_muxvals[] = {3, 3}; +static const int uart0_muxvals[] = {3, 3}; static const unsigned uart0b_pins[] = {11, 12}; -static const unsigned uart0b_muxvals[] = {2, 2}; +static const int uart0b_muxvals[] = {2, 2}; static const unsigned uart1_pins[] = {115, 116}; -static const unsigned uart1_muxvals[] = {0, 0}; +static const int uart1_muxvals[] = {0, 0}; static const unsigned uart1b_pins[] = {113, 114}; -static const unsigned uart1b_muxvals[] = {1, 1}; +static const int uart1b_muxvals[] = {1, 1}; static const unsigned uart2_pins[] = {113, 114}; -static const unsigned uart2_muxvals[] = {2, 2}; +static const int uart2_muxvals[] = {2, 2}; static const unsigned uart2b_pins[] = {86, 87}; -static const unsigned uart2b_muxvals[] = {1, 1}; +static const int uart2b_muxvals[] = {1, 1}; static const unsigned usb0_pins[] = {56, 57}; -static const unsigned usb0_muxvals[] = {0, 0}; +static const int usb0_muxvals[] = {0, 0}; static const unsigned usb1_pins[] = {58, 59}; -static const unsigned usb1_muxvals[] = {0, 0}; +static const int usb1_muxvals[] = {0, 0}; static const unsigned usb2_pins[] = {60, 61}; -static const unsigned usb2_muxvals[] = {0, 0}; +static const int usb2_muxvals[] = {0, 0}; static const unsigned usb3_pins[] = {62, 63}; -static const unsigned usb3_muxvals[] = {0, 0}; +static const int usb3_muxvals[] = {0, 0}; static const unsigned port_range0_pins[] = { 127, 128, 129, 130, 131, 132, 133, 134, /* PORT0x */ 135, 136, 137, 138, 139, 140, 141, 142, /* PORT1x */ @@ -796,7 +815,7 @@ static const unsigned port_range0_pins[] = { 61, 62, 63, 64, 65, 66, 67, 68, /* PORT9x */ 69, 70, 71, 76, 77, 78, 79, 80, /* PORT10x */ }; -static const unsigned port_range0_muxvals[] = { +static const int port_range0_muxvals[] = { 15, 15, 15, 15, 15, 15, 15, 15, /* PORT0x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT1x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT2x */ @@ -828,7 +847,7 @@ static const unsigned port_range1_pins[] = { 218, 219, 220, 221, 223, 224, 225, 226, /* PORT27x */ 227, 228, 229, 230, 231, 232, 233, 234, /* PORT28x */ }; -static const unsigned port_range1_muxvals[] = { +static const int port_range1_muxvals[] = { 15, 15, 15, 15, 15, 15, 15, 15, /* PORT12x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT13x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT14x */ @@ -852,16 +871,18 @@ static const unsigned xirq_pins[] = { 126, 72, 73, 92, 177, 93, 94, 176, /* XIRQ8-15 */ 74, 91, 27, 28, 29, 75, 20, 26, /* XIRQ16-23 */ }; -static const unsigned xirq_muxvals[] = { +static const int xirq_muxvals[] = { 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ0-7 */ 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ8-15 */ 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ16-23 */ }; -static const struct uniphier_pinctrl_group ph1_ld6b_groups[] = { +static const struct uniphier_pinctrl_group uniphier_ld6b_groups[] = { UNIPHIER_PINCTRL_GROUP(adinter), UNIPHIER_PINCTRL_GROUP(emmc), UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(ether_rgmii), + UNIPHIER_PINCTRL_GROUP(ether_rmii), UNIPHIER_PINCTRL_GROUP(i2c0), UNIPHIER_PINCTRL_GROUP(i2c1), UNIPHIER_PINCTRL_GROUP(i2c2), @@ -869,6 +890,12 @@ static const struct uniphier_pinctrl_group ph1_ld6b_groups[] = { UNIPHIER_PINCTRL_GROUP(nand), UNIPHIER_PINCTRL_GROUP(nand_cs1), UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(system_bus_cs2), + UNIPHIER_PINCTRL_GROUP(system_bus_cs3), + UNIPHIER_PINCTRL_GROUP(system_bus_cs4), + UNIPHIER_PINCTRL_GROUP(system_bus_cs5), UNIPHIER_PINCTRL_GROUP(uart0), UNIPHIER_PINCTRL_GROUP(uart0b), UNIPHIER_PINCTRL_GROUP(uart1), @@ -1134,12 +1161,20 @@ static const struct uniphier_pinctrl_group ph1_ld6b_groups[] = { static const char * const adinter_groups[] = {"adinter"}; static const char * const emmc_groups[] = {"emmc", "emmc_dat8"}; +static const char * const ether_rgmii_groups[] = {"ether_rgmii"}; +static const char * const ether_rmii_groups[] = {"ether_rmii"}; static const char * const i2c0_groups[] = {"i2c0"}; static const char * const i2c1_groups[] = {"i2c1"}; static const char * const i2c2_groups[] = {"i2c2"}; static const char * const i2c3_groups[] = {"i2c3"}; static const char * const nand_groups[] = {"nand", "nand_cs1"}; static const char * const sd_groups[] = {"sd"}; +static const char * const system_bus_groups[] = {"system_bus", + "system_bus_cs1", + "system_bus_cs2", + "system_bus_cs3", + "system_bus_cs4", + "system_bus_cs5"}; static const char * const uart0_groups[] = {"uart0", "uart0b"}; static const char * const uart1_groups[] = {"uart1", "uart1b"}; static const char * const uart2_groups[] = {"uart2", "uart2b"}; @@ -1215,15 +1250,18 @@ static const char * const xirq_groups[] = { "xirq20", "xirq21", "xirq22", "xirq23", }; -static const struct uniphier_pinmux_function ph1_ld6b_functions[] = { +static const struct uniphier_pinmux_function uniphier_ld6b_functions[] = { UNIPHIER_PINMUX_FUNCTION(adinter), /* Achip-Dchip interconnect */ UNIPHIER_PINMUX_FUNCTION(emmc), + UNIPHIER_PINMUX_FUNCTION(ether_rgmii), + UNIPHIER_PINMUX_FUNCTION(ether_rmii), UNIPHIER_PINMUX_FUNCTION(i2c0), UNIPHIER_PINMUX_FUNCTION(i2c1), UNIPHIER_PINMUX_FUNCTION(i2c2), UNIPHIER_PINMUX_FUNCTION(i2c3), UNIPHIER_PINMUX_FUNCTION(nand), UNIPHIER_PINMUX_FUNCTION(sd), + UNIPHIER_PINMUX_FUNCTION(system_bus), UNIPHIER_PINMUX_FUNCTION(uart0), UNIPHIER_PINMUX_FUNCTION(uart1), UNIPHIER_PINMUX_FUNCTION(uart2), @@ -1235,43 +1273,36 @@ static const struct uniphier_pinmux_function ph1_ld6b_functions[] = { UNIPHIER_PINMUX_FUNCTION(xirq), }; -static struct uniphier_pinctrl_socdata ph1_ld6b_pindata = { - .groups = ph1_ld6b_groups, - .groups_count = ARRAY_SIZE(ph1_ld6b_groups), - .functions = ph1_ld6b_functions, - .functions_count = ARRAY_SIZE(ph1_ld6b_functions), - .mux_bits = 8, - .reg_stride = 4, - .load_pinctrl = false, -}; - -static struct pinctrl_desc ph1_ld6b_pinctrl_desc = { - .name = DRIVER_NAME, - .pins = ph1_ld6b_pins, - .npins = ARRAY_SIZE(ph1_ld6b_pins), - .owner = THIS_MODULE, +static struct uniphier_pinctrl_socdata uniphier_ld6b_pindata = { + .pins = uniphier_ld6b_pins, + .npins = ARRAY_SIZE(uniphier_ld6b_pins), + .groups = uniphier_ld6b_groups, + .groups_count = ARRAY_SIZE(uniphier_ld6b_groups), + .functions = uniphier_ld6b_functions, + .functions_count = ARRAY_SIZE(uniphier_ld6b_functions), + .caps = 0, }; -static int ph1_ld6b_pinctrl_probe(struct platform_device *pdev) +static int uniphier_ld6b_pinctrl_probe(struct platform_device *pdev) { - return uniphier_pinctrl_probe(pdev, &ph1_ld6b_pinctrl_desc, - &ph1_ld6b_pindata); + return uniphier_pinctrl_probe(pdev, &uniphier_ld6b_pindata); } -static const struct of_device_id ph1_ld6b_pinctrl_match[] = { +static const struct of_device_id uniphier_ld6b_pinctrl_match[] = { + { .compatible = "socionext,uniphier-ld6b-pinctrl" }, { .compatible = "socionext,ph1-ld6b-pinctrl" }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, ph1_ld6b_pinctrl_match); +MODULE_DEVICE_TABLE(of, uniphier_ld6b_pinctrl_match); -static struct platform_driver ph1_ld6b_pinctrl_driver = { - .probe = ph1_ld6b_pinctrl_probe, +static struct platform_driver uniphier_ld6b_pinctrl_driver = { + .probe = uniphier_ld6b_pinctrl_probe, .driver = { - .name = DRIVER_NAME, - .of_match_table = ph1_ld6b_pinctrl_match, + .name = "uniphier-ld6b-pinctrl", + .of_match_table = uniphier_ld6b_pinctrl_match, }, }; -module_platform_driver(ph1_ld6b_pinctrl_driver); +module_platform_driver(uniphier_ld6b_pinctrl_driver); MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); MODULE_DESCRIPTION("UniPhier PH1-LD6b pinctrl driver"); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c index b1f09e68f90e..c306e844f584 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro4.c @@ -19,1039 +19,1072 @@ #include "pinctrl-uniphier.h" -#define DRIVER_NAME "ph1-pro4-pinctrl" - -static const struct pinctrl_pin_desc ph1_pro4_pins[] = { +static const struct pinctrl_pin_desc uniphier_pro4_pins[] = { UNIPHIER_PINCTRL_PIN(0, "CK24O", UNIPHIER_PIN_IECTRL_NONE, - 0, UNIPHIER_PIN_DRV_4_8, + 0, UNIPHIER_PIN_DRV_1BIT, 0, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(1, "VC27A", UNIPHIER_PIN_IECTRL_NONE, - 1, UNIPHIER_PIN_DRV_4_8, + 1, UNIPHIER_PIN_DRV_1BIT, 1, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(2, "CK27AI", UNIPHIER_PIN_IECTRL_NONE, - 2, UNIPHIER_PIN_DRV_4_8, + 2, UNIPHIER_PIN_DRV_1BIT, 2, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(3, "CK27AO", UNIPHIER_PIN_IECTRL_NONE, - 3, UNIPHIER_PIN_DRV_4_8, + 3, UNIPHIER_PIN_DRV_1BIT, 3, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(4, "CKSEL", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_4_8, + 4, UNIPHIER_PIN_DRV_1BIT, 4, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(5, "CK27AV", UNIPHIER_PIN_IECTRL_NONE, - 5, UNIPHIER_PIN_DRV_4_8, + 5, UNIPHIER_PIN_DRV_1BIT, 5, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(6, "AEXCKA", UNIPHIER_PIN_IECTRL_NONE, - 6, UNIPHIER_PIN_DRV_4_8, + 6, UNIPHIER_PIN_DRV_1BIT, 6, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(7, "ASEL", UNIPHIER_PIN_IECTRL_NONE, - 7, UNIPHIER_PIN_DRV_4_8, + 7, UNIPHIER_PIN_DRV_1BIT, 7, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(8, "ARCRESET", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_4_8, + 8, UNIPHIER_PIN_DRV_1BIT, 8, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(9, "ARCUNLOCK", UNIPHIER_PIN_IECTRL_NONE, - 9, UNIPHIER_PIN_DRV_4_8, + 9, UNIPHIER_PIN_DRV_1BIT, 9, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(10, "XSRST", UNIPHIER_PIN_IECTRL_NONE, - 10, UNIPHIER_PIN_DRV_4_8, + 10, UNIPHIER_PIN_DRV_1BIT, 10, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(11, "XNMIRQ", UNIPHIER_PIN_IECTRL_NONE, - 11, UNIPHIER_PIN_DRV_4_8, + 11, UNIPHIER_PIN_DRV_1BIT, 11, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(12, "XSCIRQ", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_4_8, + 12, UNIPHIER_PIN_DRV_1BIT, 12, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(13, "EXTRG", UNIPHIER_PIN_IECTRL_NONE, - 13, UNIPHIER_PIN_DRV_4_8, + 13, UNIPHIER_PIN_DRV_1BIT, 13, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(14, "TRCCLK", UNIPHIER_PIN_IECTRL_NONE, - 14, UNIPHIER_PIN_DRV_4_8, + 14, UNIPHIER_PIN_DRV_1BIT, 14, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(15, "TRCCTL", UNIPHIER_PIN_IECTRL_NONE, - 15, UNIPHIER_PIN_DRV_4_8, + 15, UNIPHIER_PIN_DRV_1BIT, 15, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(16, "TRCD0", UNIPHIER_PIN_IECTRL_NONE, - 16, UNIPHIER_PIN_DRV_4_8, + 16, UNIPHIER_PIN_DRV_1BIT, 16, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(17, "TRCD1", UNIPHIER_PIN_IECTRL_NONE, - 17, UNIPHIER_PIN_DRV_4_8, + 17, UNIPHIER_PIN_DRV_1BIT, 17, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(18, "TRCD2", UNIPHIER_PIN_IECTRL_NONE, - 18, UNIPHIER_PIN_DRV_4_8, + 18, UNIPHIER_PIN_DRV_1BIT, 18, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(19, "TRCD3", UNIPHIER_PIN_IECTRL_NONE, - 19, UNIPHIER_PIN_DRV_4_8, + 19, UNIPHIER_PIN_DRV_1BIT, 19, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(20, "TRCD4", UNIPHIER_PIN_IECTRL_NONE, - 20, UNIPHIER_PIN_DRV_4_8, + 20, UNIPHIER_PIN_DRV_1BIT, 20, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(21, "TRCD5", UNIPHIER_PIN_IECTRL_NONE, - 21, UNIPHIER_PIN_DRV_4_8, + 21, UNIPHIER_PIN_DRV_1BIT, 21, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(22, "TRCD6", UNIPHIER_PIN_IECTRL_NONE, - 22, UNIPHIER_PIN_DRV_4_8, + 22, UNIPHIER_PIN_DRV_1BIT, 22, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(23, "TRCD7", UNIPHIER_PIN_IECTRL_NONE, - 23, UNIPHIER_PIN_DRV_4_8, + 23, UNIPHIER_PIN_DRV_1BIT, 23, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(24, "XECS1", UNIPHIER_PIN_IECTRL_NONE, - 24, UNIPHIER_PIN_DRV_4_8, + 24, UNIPHIER_PIN_DRV_1BIT, 24, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(25, "ERXW", UNIPHIER_PIN_IECTRL_NONE, - 25, UNIPHIER_PIN_DRV_4_8, + 25, UNIPHIER_PIN_DRV_1BIT, 25, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(26, "XERWE0", UNIPHIER_PIN_IECTRL_NONE, - 26, UNIPHIER_PIN_DRV_4_8, + 26, UNIPHIER_PIN_DRV_1BIT, 26, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(27, "XERWE1", UNIPHIER_PIN_IECTRL_NONE, - 27, UNIPHIER_PIN_DRV_4_8, + 27, UNIPHIER_PIN_DRV_1BIT, 27, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(28, "ES0", UNIPHIER_PIN_IECTRL_NONE, - 28, UNIPHIER_PIN_DRV_4_8, + 28, UNIPHIER_PIN_DRV_1BIT, 28, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(29, "ES1", UNIPHIER_PIN_IECTRL_NONE, - 29, UNIPHIER_PIN_DRV_4_8, + 29, UNIPHIER_PIN_DRV_1BIT, 29, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(30, "ES2", UNIPHIER_PIN_IECTRL_NONE, - 30, UNIPHIER_PIN_DRV_4_8, + 30, UNIPHIER_PIN_DRV_1BIT, 30, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(31, "ED0", UNIPHIER_PIN_IECTRL_NONE, - 31, UNIPHIER_PIN_DRV_4_8, + 31, UNIPHIER_PIN_DRV_1BIT, 31, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(32, "ED1", UNIPHIER_PIN_IECTRL_NONE, - 32, UNIPHIER_PIN_DRV_4_8, + 32, UNIPHIER_PIN_DRV_1BIT, 32, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(33, "ED2", UNIPHIER_PIN_IECTRL_NONE, - 33, UNIPHIER_PIN_DRV_4_8, + 33, UNIPHIER_PIN_DRV_1BIT, 33, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(34, "ED3", UNIPHIER_PIN_IECTRL_NONE, - 34, UNIPHIER_PIN_DRV_4_8, + 34, UNIPHIER_PIN_DRV_1BIT, 34, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(35, "ED4", UNIPHIER_PIN_IECTRL_NONE, - 35, UNIPHIER_PIN_DRV_4_8, + 35, UNIPHIER_PIN_DRV_1BIT, 35, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(36, "ED5", UNIPHIER_PIN_IECTRL_NONE, - 36, UNIPHIER_PIN_DRV_4_8, + 36, UNIPHIER_PIN_DRV_1BIT, 36, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(37, "ED6", UNIPHIER_PIN_IECTRL_NONE, - 37, UNIPHIER_PIN_DRV_4_8, + 37, UNIPHIER_PIN_DRV_1BIT, 37, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(38, "ED7", UNIPHIER_PIN_IECTRL_NONE, - 38, UNIPHIER_PIN_DRV_4_8, + 38, UNIPHIER_PIN_DRV_1BIT, 38, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(39, "BOOTSWAP", UNIPHIER_PIN_IECTRL_NONE, - 39, UNIPHIER_PIN_DRV_NONE, + -1, UNIPHIER_PIN_DRV_NONE, 39, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(40, "NFD0", UNIPHIER_PIN_IECTRL_NONE, - 2, UNIPHIER_PIN_DRV_8_12_16_20, + 2, UNIPHIER_PIN_DRV_2BIT, 40, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(41, "NFD1", UNIPHIER_PIN_IECTRL_NONE, - 3, UNIPHIER_PIN_DRV_8_12_16_20, + 3, UNIPHIER_PIN_DRV_2BIT, 41, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(42, "NFD2", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_8_12_16_20, + 4, UNIPHIER_PIN_DRV_2BIT, 42, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(43, "NFD3", UNIPHIER_PIN_IECTRL_NONE, - 5, UNIPHIER_PIN_DRV_8_12_16_20, + 5, UNIPHIER_PIN_DRV_2BIT, 43, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(44, "NFD4", UNIPHIER_PIN_IECTRL_NONE, - 6, UNIPHIER_PIN_DRV_8_12_16_20, + 6, UNIPHIER_PIN_DRV_2BIT, 44, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(45, "NFD5", UNIPHIER_PIN_IECTRL_NONE, - 7, UNIPHIER_PIN_DRV_8_12_16_20, + 7, UNIPHIER_PIN_DRV_2BIT, 45, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(46, "NFD6", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_8_12_16_20, + 8, UNIPHIER_PIN_DRV_2BIT, 46, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(47, "NFD7", UNIPHIER_PIN_IECTRL_NONE, - 9, UNIPHIER_PIN_DRV_8_12_16_20, + 9, UNIPHIER_PIN_DRV_2BIT, 47, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(48, "NFALE", UNIPHIER_PIN_IECTRL_NONE, - 48, UNIPHIER_PIN_DRV_4_8, + 48, UNIPHIER_PIN_DRV_1BIT, 48, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(49, "NFCLE", UNIPHIER_PIN_IECTRL_NONE, - 49, UNIPHIER_PIN_DRV_4_8, + 49, UNIPHIER_PIN_DRV_1BIT, 49, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(50, "XNFRE", UNIPHIER_PIN_IECTRL_NONE, - 50, UNIPHIER_PIN_DRV_4_8, + 50, UNIPHIER_PIN_DRV_1BIT, 50, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(51, "XNFWE", UNIPHIER_PIN_IECTRL_NONE, - 0, UNIPHIER_PIN_DRV_8_12_16_20, + 0, UNIPHIER_PIN_DRV_2BIT, 51, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(52, "XNFWP", UNIPHIER_PIN_IECTRL_NONE, - 52, UNIPHIER_PIN_DRV_4_8, + 52, UNIPHIER_PIN_DRV_1BIT, 52, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(53, "XNFCE0", UNIPHIER_PIN_IECTRL_NONE, - 1, UNIPHIER_PIN_DRV_8_12_16_20, + 1, UNIPHIER_PIN_DRV_2BIT, 53, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(54, "NRYBY0", UNIPHIER_PIN_IECTRL_NONE, - 54, UNIPHIER_PIN_DRV_4_8, + 54, UNIPHIER_PIN_DRV_1BIT, 54, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(55, "DMDSCLTST", UNIPHIER_PIN_IECTRL_NONE, -1, UNIPHIER_PIN_DRV_NONE, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(56, "DMDSDATST", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(57, "AGCI0", 3, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 55, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(58, "DMDSCL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(59, "DMDSDA0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(60, "AGCBS0", 5, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 56, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(61, "DMDSCL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(62, "DMDSDA1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(63, "ANTSHORT", UNIPHIER_PIN_IECTRL_NONE, - 57, UNIPHIER_PIN_DRV_4_8, + 57, UNIPHIER_PIN_DRV_1BIT, 57, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(64, "CH0CLK", UNIPHIER_PIN_IECTRL_NONE, - 58, UNIPHIER_PIN_DRV_4_8, + 58, UNIPHIER_PIN_DRV_1BIT, 58, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(65, "CH0VAL", UNIPHIER_PIN_IECTRL_NONE, - 59, UNIPHIER_PIN_DRV_4_8, + 59, UNIPHIER_PIN_DRV_1BIT, 59, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(66, "CH0PSYNC", UNIPHIER_PIN_IECTRL_NONE, - 60, UNIPHIER_PIN_DRV_4_8, + 60, UNIPHIER_PIN_DRV_1BIT, 60, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(67, "CH0DATA", UNIPHIER_PIN_IECTRL_NONE, - 61, UNIPHIER_PIN_DRV_4_8, + 61, UNIPHIER_PIN_DRV_1BIT, 61, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(68, "CH1CLK", UNIPHIER_PIN_IECTRL_NONE, - 62, UNIPHIER_PIN_DRV_4_8, + 62, UNIPHIER_PIN_DRV_1BIT, 62, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(69, "CH1VAL", UNIPHIER_PIN_IECTRL_NONE, - 63, UNIPHIER_PIN_DRV_4_8, + 63, UNIPHIER_PIN_DRV_1BIT, 63, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(70, "CH1PSYNC", UNIPHIER_PIN_IECTRL_NONE, - 64, UNIPHIER_PIN_DRV_4_8, + 64, UNIPHIER_PIN_DRV_1BIT, 64, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(71, "CH1DATA", UNIPHIER_PIN_IECTRL_NONE, - 65, UNIPHIER_PIN_DRV_4_8, + 65, UNIPHIER_PIN_DRV_1BIT, 65, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(72, "CH2CLK", UNIPHIER_PIN_IECTRL_NONE, - 66, UNIPHIER_PIN_DRV_4_8, + 66, UNIPHIER_PIN_DRV_1BIT, 66, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(73, "CH2VAL", UNIPHIER_PIN_IECTRL_NONE, - 67, UNIPHIER_PIN_DRV_4_8, + 67, UNIPHIER_PIN_DRV_1BIT, 67, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(74, "CH2PSYNC", UNIPHIER_PIN_IECTRL_NONE, - 68, UNIPHIER_PIN_DRV_4_8, + 68, UNIPHIER_PIN_DRV_1BIT, 68, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(75, "CH2DATA", UNIPHIER_PIN_IECTRL_NONE, - 69, UNIPHIER_PIN_DRV_4_8, + 69, UNIPHIER_PIN_DRV_1BIT, 69, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(76, "CH3CLK", UNIPHIER_PIN_IECTRL_NONE, - 70, UNIPHIER_PIN_DRV_4_8, + 70, UNIPHIER_PIN_DRV_1BIT, 70, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(77, "CH3VAL", UNIPHIER_PIN_IECTRL_NONE, - 71, UNIPHIER_PIN_DRV_4_8, + 71, UNIPHIER_PIN_DRV_1BIT, 71, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(78, "CH3PSYNC", UNIPHIER_PIN_IECTRL_NONE, - 72, UNIPHIER_PIN_DRV_4_8, + 72, UNIPHIER_PIN_DRV_1BIT, 72, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(79, "CH3DATA", UNIPHIER_PIN_IECTRL_NONE, - 73, UNIPHIER_PIN_DRV_4_8, + 73, UNIPHIER_PIN_DRV_1BIT, 73, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(80, "CH4CLK", UNIPHIER_PIN_IECTRL_NONE, - 74, UNIPHIER_PIN_DRV_4_8, + 74, UNIPHIER_PIN_DRV_1BIT, 74, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(81, "CH4VAL", UNIPHIER_PIN_IECTRL_NONE, - 75, UNIPHIER_PIN_DRV_4_8, + 75, UNIPHIER_PIN_DRV_1BIT, 75, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(82, "CH4PSYNC", UNIPHIER_PIN_IECTRL_NONE, - 76, UNIPHIER_PIN_DRV_4_8, + 76, UNIPHIER_PIN_DRV_1BIT, 76, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(83, "CH4DATA", UNIPHIER_PIN_IECTRL_NONE, - 77, UNIPHIER_PIN_DRV_4_8, + 77, UNIPHIER_PIN_DRV_1BIT, 77, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(84, "CH5CLK", UNIPHIER_PIN_IECTRL_NONE, - 78, UNIPHIER_PIN_DRV_4_8, + 78, UNIPHIER_PIN_DRV_1BIT, 78, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(85, "CH5VAL", UNIPHIER_PIN_IECTRL_NONE, - 79, UNIPHIER_PIN_DRV_4_8, + 79, UNIPHIER_PIN_DRV_1BIT, 79, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(86, "CH5PSYNC", UNIPHIER_PIN_IECTRL_NONE, - 80, UNIPHIER_PIN_DRV_4_8, + 80, UNIPHIER_PIN_DRV_1BIT, 80, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(87, "CH5DATA", UNIPHIER_PIN_IECTRL_NONE, - 81, UNIPHIER_PIN_DRV_4_8, + 81, UNIPHIER_PIN_DRV_1BIT, 81, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(88, "CH6CLK", UNIPHIER_PIN_IECTRL_NONE, - 82, UNIPHIER_PIN_DRV_4_8, + 82, UNIPHIER_PIN_DRV_1BIT, 82, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(89, "CH6VAL", UNIPHIER_PIN_IECTRL_NONE, - 83, UNIPHIER_PIN_DRV_4_8, + 83, UNIPHIER_PIN_DRV_1BIT, 83, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(90, "CH6PSYNC", UNIPHIER_PIN_IECTRL_NONE, - 84, UNIPHIER_PIN_DRV_4_8, + 84, UNIPHIER_PIN_DRV_1BIT, 84, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(91, "CH6DATA", UNIPHIER_PIN_IECTRL_NONE, - 85, UNIPHIER_PIN_DRV_4_8, + 85, UNIPHIER_PIN_DRV_1BIT, 85, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(92, "CKFEO", UNIPHIER_PIN_IECTRL_NONE, - 86, UNIPHIER_PIN_DRV_4_8, + 86, UNIPHIER_PIN_DRV_1BIT, 86, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(93, "XFERST", UNIPHIER_PIN_IECTRL_NONE, - 87, UNIPHIER_PIN_DRV_4_8, + 87, UNIPHIER_PIN_DRV_1BIT, 87, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(94, "P_FE_ON", UNIPHIER_PIN_IECTRL_NONE, - 88, UNIPHIER_PIN_DRV_4_8, + 88, UNIPHIER_PIN_DRV_1BIT, 88, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(95, "P_TU0_ON", UNIPHIER_PIN_IECTRL_NONE, - 89, UNIPHIER_PIN_DRV_4_8, + 89, UNIPHIER_PIN_DRV_1BIT, 89, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(96, "XFEIRQ0", UNIPHIER_PIN_IECTRL_NONE, - 90, UNIPHIER_PIN_DRV_4_8, + 90, UNIPHIER_PIN_DRV_1BIT, 90, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(97, "XFEIRQ1", UNIPHIER_PIN_IECTRL_NONE, - 91, UNIPHIER_PIN_DRV_4_8, + 91, UNIPHIER_PIN_DRV_1BIT, 91, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(98, "XFEIRQ2", UNIPHIER_PIN_IECTRL_NONE, - 92, UNIPHIER_PIN_DRV_4_8, + 92, UNIPHIER_PIN_DRV_1BIT, 92, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(99, "XFEIRQ3", UNIPHIER_PIN_IECTRL_NONE, - 93, UNIPHIER_PIN_DRV_4_8, + 93, UNIPHIER_PIN_DRV_1BIT, 93, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(100, "XFEIRQ4", UNIPHIER_PIN_IECTRL_NONE, - 94, UNIPHIER_PIN_DRV_4_8, + 94, UNIPHIER_PIN_DRV_1BIT, 94, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(101, "XFEIRQ5", UNIPHIER_PIN_IECTRL_NONE, - 95, UNIPHIER_PIN_DRV_4_8, + 95, UNIPHIER_PIN_DRV_1BIT, 95, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(102, "XFEIRQ6", UNIPHIER_PIN_IECTRL_NONE, - 96, UNIPHIER_PIN_DRV_4_8, + 96, UNIPHIER_PIN_DRV_1BIT, 96, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(103, "SMTCLK0", UNIPHIER_PIN_IECTRL_NONE, - 97, UNIPHIER_PIN_DRV_4_8, + 97, UNIPHIER_PIN_DRV_1BIT, 97, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(104, "SMTRST0", UNIPHIER_PIN_IECTRL_NONE, - 98, UNIPHIER_PIN_DRV_4_8, + 98, UNIPHIER_PIN_DRV_1BIT, 98, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(105, "SMTCMD0", UNIPHIER_PIN_IECTRL_NONE, - 99, UNIPHIER_PIN_DRV_4_8, + 99, UNIPHIER_PIN_DRV_1BIT, 99, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(106, "SMTD0", UNIPHIER_PIN_IECTRL_NONE, - 100, UNIPHIER_PIN_DRV_4_8, + 100, UNIPHIER_PIN_DRV_1BIT, 100, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(107, "SMTSEL0", UNIPHIER_PIN_IECTRL_NONE, - 101, UNIPHIER_PIN_DRV_4_8, + 101, UNIPHIER_PIN_DRV_1BIT, 101, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(108, "SMTDET0", UNIPHIER_PIN_IECTRL_NONE, - 102, UNIPHIER_PIN_DRV_4_8, + 102, UNIPHIER_PIN_DRV_1BIT, 102, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(109, "SMTCLK1", UNIPHIER_PIN_IECTRL_NONE, - 103, UNIPHIER_PIN_DRV_4_8, + 103, UNIPHIER_PIN_DRV_1BIT, 103, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(110, "SMTRST1", UNIPHIER_PIN_IECTRL_NONE, - 104, UNIPHIER_PIN_DRV_4_8, + 104, UNIPHIER_PIN_DRV_1BIT, 104, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(111, "SMTCMD1", UNIPHIER_PIN_IECTRL_NONE, - 105, UNIPHIER_PIN_DRV_4_8, + 105, UNIPHIER_PIN_DRV_1BIT, 105, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(112, "SMTD1", UNIPHIER_PIN_IECTRL_NONE, - 106, UNIPHIER_PIN_DRV_4_8, + 106, UNIPHIER_PIN_DRV_1BIT, 106, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(113, "SMTSEL1", UNIPHIER_PIN_IECTRL_NONE, - 107, UNIPHIER_PIN_DRV_4_8, + 107, UNIPHIER_PIN_DRV_1BIT, 107, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(114, "SMTDET1", UNIPHIER_PIN_IECTRL_NONE, - 108, UNIPHIER_PIN_DRV_4_8, + 108, UNIPHIER_PIN_DRV_1BIT, 108, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(115, "XINTM", UNIPHIER_PIN_IECTRL_NONE, - 109, UNIPHIER_PIN_DRV_4_8, + 109, UNIPHIER_PIN_DRV_1BIT, 109, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(116, "SCLKM", UNIPHIER_PIN_IECTRL_NONE, - 110, UNIPHIER_PIN_DRV_4_8, + 110, UNIPHIER_PIN_DRV_1BIT, 110, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(117, "SBMTP", UNIPHIER_PIN_IECTRL_NONE, - 111, UNIPHIER_PIN_DRV_4_8, + 111, UNIPHIER_PIN_DRV_1BIT, 111, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(118, "SBPTM", UNIPHIER_PIN_IECTRL_NONE, - 112, UNIPHIER_PIN_DRV_4_8, + 112, UNIPHIER_PIN_DRV_1BIT, 112, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(119, "XMPREQ", UNIPHIER_PIN_IECTRL_NONE, - 113, UNIPHIER_PIN_DRV_4_8, + 113, UNIPHIER_PIN_DRV_1BIT, 113, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(120, "XINTP", UNIPHIER_PIN_IECTRL_NONE, - 114, UNIPHIER_PIN_DRV_4_8, + 114, UNIPHIER_PIN_DRV_1BIT, 114, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(121, "LPST", UNIPHIER_PIN_IECTRL_NONE, - 115, UNIPHIER_PIN_DRV_4_8, + 115, UNIPHIER_PIN_DRV_1BIT, 115, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(122, "SDBOOT", UNIPHIER_PIN_IECTRL_NONE, - 116, UNIPHIER_PIN_DRV_4_8, + 116, UNIPHIER_PIN_DRV_1BIT, 116, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(123, "BFAIL", UNIPHIER_PIN_IECTRL_NONE, - 117, UNIPHIER_PIN_DRV_4_8, + 117, UNIPHIER_PIN_DRV_1BIT, 117, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(124, "XFWE", UNIPHIER_PIN_IECTRL_NONE, - 118, UNIPHIER_PIN_DRV_4_8, + 118, UNIPHIER_PIN_DRV_1BIT, 118, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(125, "RF_COM_RDY", UNIPHIER_PIN_IECTRL_NONE, - 119, UNIPHIER_PIN_DRV_4_8, + 119, UNIPHIER_PIN_DRV_1BIT, 119, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(126, "XDIAG0", UNIPHIER_PIN_IECTRL_NONE, - 120, UNIPHIER_PIN_DRV_4_8, + 120, UNIPHIER_PIN_DRV_1BIT, 120, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(127, "RXD0", UNIPHIER_PIN_IECTRL_NONE, - 121, UNIPHIER_PIN_DRV_4_8, + 121, UNIPHIER_PIN_DRV_1BIT, 121, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(128, "TXD0", UNIPHIER_PIN_IECTRL_NONE, - 122, UNIPHIER_PIN_DRV_4_8, + 122, UNIPHIER_PIN_DRV_1BIT, 122, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(129, "RXD1", UNIPHIER_PIN_IECTRL_NONE, - 123, UNIPHIER_PIN_DRV_4_8, + 123, UNIPHIER_PIN_DRV_1BIT, 123, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(130, "TXD1", UNIPHIER_PIN_IECTRL_NONE, - 124, UNIPHIER_PIN_DRV_4_8, + 124, UNIPHIER_PIN_DRV_1BIT, 124, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(131, "RXD2", UNIPHIER_PIN_IECTRL_NONE, - 125, UNIPHIER_PIN_DRV_4_8, + 125, UNIPHIER_PIN_DRV_1BIT, 125, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(132, "TXD2", UNIPHIER_PIN_IECTRL_NONE, - 126, UNIPHIER_PIN_DRV_4_8, + 126, UNIPHIER_PIN_DRV_1BIT, 126, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(133, "SS0CS", UNIPHIER_PIN_IECTRL_NONE, - 127, UNIPHIER_PIN_DRV_4_8, + 127, UNIPHIER_PIN_DRV_1BIT, 127, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(134, "SS0CLK", UNIPHIER_PIN_IECTRL_NONE, - 128, UNIPHIER_PIN_DRV_4_8, + 128, UNIPHIER_PIN_DRV_1BIT, 128, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(135, "SS0DO", UNIPHIER_PIN_IECTRL_NONE, - 129, UNIPHIER_PIN_DRV_4_8, + 129, UNIPHIER_PIN_DRV_1BIT, 129, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(136, "SS0DI", UNIPHIER_PIN_IECTRL_NONE, - 130, UNIPHIER_PIN_DRV_4_8, + 130, UNIPHIER_PIN_DRV_1BIT, 130, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(137, "MS0CS0", UNIPHIER_PIN_IECTRL_NONE, - 131, UNIPHIER_PIN_DRV_4_8, + 131, UNIPHIER_PIN_DRV_1BIT, 131, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(138, "MS0CLK", UNIPHIER_PIN_IECTRL_NONE, - 132, UNIPHIER_PIN_DRV_4_8, + 132, UNIPHIER_PIN_DRV_1BIT, 132, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(139, "MS0DI", UNIPHIER_PIN_IECTRL_NONE, - 133, UNIPHIER_PIN_DRV_4_8, + 133, UNIPHIER_PIN_DRV_1BIT, 133, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(140, "MS0DO", UNIPHIER_PIN_IECTRL_NONE, - 134, UNIPHIER_PIN_DRV_4_8, + 134, UNIPHIER_PIN_DRV_1BIT, 134, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(141, "XMDMRST", UNIPHIER_PIN_IECTRL_NONE, - 135, UNIPHIER_PIN_DRV_4_8, + 135, UNIPHIER_PIN_DRV_1BIT, 135, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(142, "SCL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(143, "SDA0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(144, "SCL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(145, "SDA1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(146, "SCL2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(147, "SDA2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(148, "SCL3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(149, "SDA3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(150, "SD0DAT0", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_8_12_16_20, + 12, UNIPHIER_PIN_DRV_2BIT, 136, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(151, "SD0DAT1", UNIPHIER_PIN_IECTRL_NONE, - 13, UNIPHIER_PIN_DRV_8_12_16_20, + 13, UNIPHIER_PIN_DRV_2BIT, 137, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(152, "SD0DAT2", UNIPHIER_PIN_IECTRL_NONE, - 14, UNIPHIER_PIN_DRV_8_12_16_20, + 14, UNIPHIER_PIN_DRV_2BIT, 138, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(153, "SD0DAT3", UNIPHIER_PIN_IECTRL_NONE, - 15, UNIPHIER_PIN_DRV_8_12_16_20, + 15, UNIPHIER_PIN_DRV_2BIT, 139, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(154, "SD0CMD", UNIPHIER_PIN_IECTRL_NONE, - 11, UNIPHIER_PIN_DRV_8_12_16_20, + 11, UNIPHIER_PIN_DRV_2BIT, 141, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(155, "SD0CLK", UNIPHIER_PIN_IECTRL_NONE, - 10, UNIPHIER_PIN_DRV_8_12_16_20, + 10, UNIPHIER_PIN_DRV_2BIT, 140, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(156, "SD0CD", UNIPHIER_PIN_IECTRL_NONE, - 142, UNIPHIER_PIN_DRV_4_8, + 142, UNIPHIER_PIN_DRV_1BIT, 142, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(157, "SD0WP", UNIPHIER_PIN_IECTRL_NONE, - 143, UNIPHIER_PIN_DRV_4_8, + 143, UNIPHIER_PIN_DRV_1BIT, 143, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(158, "SD0VTCG", UNIPHIER_PIN_IECTRL_NONE, - 144, UNIPHIER_PIN_DRV_4_8, + 144, UNIPHIER_PIN_DRV_1BIT, 144, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(159, "CK25O", UNIPHIER_PIN_IECTRL_NONE, - 145, UNIPHIER_PIN_DRV_4_8, + 145, UNIPHIER_PIN_DRV_1BIT, 145, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(160, "RGMII_TXCLK", 6, - 146, UNIPHIER_PIN_DRV_4_8, + 146, UNIPHIER_PIN_DRV_1BIT, 146, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(161, "RGMII_TXD0", 6, - 147, UNIPHIER_PIN_DRV_4_8, + 147, UNIPHIER_PIN_DRV_1BIT, 147, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(162, "RGMII_TXD1", 6, - 148, UNIPHIER_PIN_DRV_4_8, + 148, UNIPHIER_PIN_DRV_1BIT, 148, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(163, "RGMII_TXD2", 6, - 149, UNIPHIER_PIN_DRV_4_8, + 149, UNIPHIER_PIN_DRV_1BIT, 149, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(164, "RGMII_TXD3", 6, - 150, UNIPHIER_PIN_DRV_4_8, + 150, UNIPHIER_PIN_DRV_1BIT, 150, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(165, "RGMII_TXCTL", 6, - 151, UNIPHIER_PIN_DRV_4_8, + 151, UNIPHIER_PIN_DRV_1BIT, 151, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(166, "MII_TXER", UNIPHIER_PIN_IECTRL_NONE, - 152, UNIPHIER_PIN_DRV_4_8, + 152, UNIPHIER_PIN_DRV_1BIT, 152, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(167, "RGMII_RXCLK", 6, - 153, UNIPHIER_PIN_DRV_4_8, + 153, UNIPHIER_PIN_DRV_1BIT, 153, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(168, "RGMII_RXD0", 6, - 154, UNIPHIER_PIN_DRV_4_8, + 154, UNIPHIER_PIN_DRV_1BIT, 154, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(169, "RGMII_RXD1", 6, - 155, UNIPHIER_PIN_DRV_4_8, + 155, UNIPHIER_PIN_DRV_1BIT, 155, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(170, "RGMII_RXD2", 6, - 156, UNIPHIER_PIN_DRV_4_8, + 156, UNIPHIER_PIN_DRV_1BIT, 156, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(171, "RGMII_RXD3", 6, - 157, UNIPHIER_PIN_DRV_4_8, + 157, UNIPHIER_PIN_DRV_1BIT, 157, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(172, "RGMII_RXCTL", 6, - 158, UNIPHIER_PIN_DRV_4_8, + 158, UNIPHIER_PIN_DRV_1BIT, 158, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(173, "MII_RXER", 6, - 159, UNIPHIER_PIN_DRV_4_8, + 159, UNIPHIER_PIN_DRV_1BIT, 159, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(174, "MII_CRS", 6, - 160, UNIPHIER_PIN_DRV_4_8, + 160, UNIPHIER_PIN_DRV_1BIT, 160, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(175, "MII_COL", 6, - 161, UNIPHIER_PIN_DRV_4_8, + 161, UNIPHIER_PIN_DRV_1BIT, 161, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(176, "MDC", 6, - 162, UNIPHIER_PIN_DRV_4_8, + 162, UNIPHIER_PIN_DRV_1BIT, 162, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(177, "MDIO", 6, - 163, UNIPHIER_PIN_DRV_4_8, + 163, UNIPHIER_PIN_DRV_1BIT, 163, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(178, "MDIO_INTL", 6, - 164, UNIPHIER_PIN_DRV_4_8, + 164, UNIPHIER_PIN_DRV_1BIT, 164, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(179, "XETH_RST", 6, - 165, UNIPHIER_PIN_DRV_4_8, + 165, UNIPHIER_PIN_DRV_1BIT, 165, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(180, "USB0VBUS", UNIPHIER_PIN_IECTRL_NONE, - 166, UNIPHIER_PIN_DRV_4_8, + 166, UNIPHIER_PIN_DRV_1BIT, 166, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(181, "USB0OD", UNIPHIER_PIN_IECTRL_NONE, - 167, UNIPHIER_PIN_DRV_4_8, + 167, UNIPHIER_PIN_DRV_1BIT, 167, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(182, "USB1VBUS", UNIPHIER_PIN_IECTRL_NONE, - 168, UNIPHIER_PIN_DRV_4_8, + 168, UNIPHIER_PIN_DRV_1BIT, 168, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(183, "USB1OD", UNIPHIER_PIN_IECTRL_NONE, - 169, UNIPHIER_PIN_DRV_4_8, + 169, UNIPHIER_PIN_DRV_1BIT, 169, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(184, "USB2VBUS", UNIPHIER_PIN_IECTRL_NONE, - 170, UNIPHIER_PIN_DRV_4_8, + 170, UNIPHIER_PIN_DRV_1BIT, 170, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(185, "USB2OD", UNIPHIER_PIN_IECTRL_NONE, - 171, UNIPHIER_PIN_DRV_4_8, + 171, UNIPHIER_PIN_DRV_1BIT, 171, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(186, "USB2ID", UNIPHIER_PIN_IECTRL_NONE, - 172, UNIPHIER_PIN_DRV_4_8, + 172, UNIPHIER_PIN_DRV_1BIT, 172, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(187, "USB3VBUS", UNIPHIER_PIN_IECTRL_NONE, - 173, UNIPHIER_PIN_DRV_4_8, + 173, UNIPHIER_PIN_DRV_1BIT, 173, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(188, "USB3OD", UNIPHIER_PIN_IECTRL_NONE, - 174, UNIPHIER_PIN_DRV_4_8, + 174, UNIPHIER_PIN_DRV_1BIT, 174, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(189, "LINKCLK", UNIPHIER_PIN_IECTRL_NONE, - 175, UNIPHIER_PIN_DRV_4_8, + 175, UNIPHIER_PIN_DRV_1BIT, 175, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(190, "LINKREQ", UNIPHIER_PIN_IECTRL_NONE, - 176, UNIPHIER_PIN_DRV_4_8, + 176, UNIPHIER_PIN_DRV_1BIT, 176, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(191, "LINKCTL0", UNIPHIER_PIN_IECTRL_NONE, - 177, UNIPHIER_PIN_DRV_4_8, + 177, UNIPHIER_PIN_DRV_1BIT, 177, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(192, "LINKCTL1", UNIPHIER_PIN_IECTRL_NONE, - 178, UNIPHIER_PIN_DRV_4_8, + 178, UNIPHIER_PIN_DRV_1BIT, 178, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(193, "LINKDT0", UNIPHIER_PIN_IECTRL_NONE, - 179, UNIPHIER_PIN_DRV_4_8, + 179, UNIPHIER_PIN_DRV_1BIT, 179, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(194, "LINKDT1", UNIPHIER_PIN_IECTRL_NONE, - 180, UNIPHIER_PIN_DRV_4_8, + 180, UNIPHIER_PIN_DRV_1BIT, 180, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(195, "LINKDT2", UNIPHIER_PIN_IECTRL_NONE, - 181, UNIPHIER_PIN_DRV_4_8, + 181, UNIPHIER_PIN_DRV_1BIT, 181, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(196, "LINKDT3", UNIPHIER_PIN_IECTRL_NONE, - 182, UNIPHIER_PIN_DRV_4_8, + 182, UNIPHIER_PIN_DRV_1BIT, 182, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(197, "LINKDT4", UNIPHIER_PIN_IECTRL_NONE, - 183, UNIPHIER_PIN_DRV_4_8, + 183, UNIPHIER_PIN_DRV_1BIT, 183, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(198, "LINKDT5", UNIPHIER_PIN_IECTRL_NONE, - 184, UNIPHIER_PIN_DRV_4_8, + 184, UNIPHIER_PIN_DRV_1BIT, 184, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(199, "LINKDT6", UNIPHIER_PIN_IECTRL_NONE, - 185, UNIPHIER_PIN_DRV_4_8, + 185, UNIPHIER_PIN_DRV_1BIT, 185, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(200, "LINKDT7", UNIPHIER_PIN_IECTRL_NONE, - 186, UNIPHIER_PIN_DRV_4_8, + 186, UNIPHIER_PIN_DRV_1BIT, 186, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(201, "CKDVO", UNIPHIER_PIN_IECTRL_NONE, - 187, UNIPHIER_PIN_DRV_4_8, + 187, UNIPHIER_PIN_DRV_1BIT, 187, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(202, "PHY_PD", UNIPHIER_PIN_IECTRL_NONE, - 188, UNIPHIER_PIN_DRV_4_8, + 188, UNIPHIER_PIN_DRV_1BIT, 188, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(203, "X1394_RST", UNIPHIER_PIN_IECTRL_NONE, - 189, UNIPHIER_PIN_DRV_4_8, + 189, UNIPHIER_PIN_DRV_1BIT, 189, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(204, "VOUT_MUTE_L", UNIPHIER_PIN_IECTRL_NONE, - 190, UNIPHIER_PIN_DRV_4_8, + 190, UNIPHIER_PIN_DRV_1BIT, 190, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(205, "CLK54O", UNIPHIER_PIN_IECTRL_NONE, - 191, UNIPHIER_PIN_DRV_4_8, + 191, UNIPHIER_PIN_DRV_1BIT, 191, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(206, "CLK54I", UNIPHIER_PIN_IECTRL_NONE, - 192, UNIPHIER_PIN_DRV_NONE, + -1, UNIPHIER_PIN_DRV_NONE, 192, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(207, "YIN0", UNIPHIER_PIN_IECTRL_NONE, - 193, UNIPHIER_PIN_DRV_4_8, + 193, UNIPHIER_PIN_DRV_1BIT, 193, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(208, "YIN1", UNIPHIER_PIN_IECTRL_NONE, - 194, UNIPHIER_PIN_DRV_4_8, + 194, UNIPHIER_PIN_DRV_1BIT, 194, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(209, "YIN2", UNIPHIER_PIN_IECTRL_NONE, - 195, UNIPHIER_PIN_DRV_4_8, + 195, UNIPHIER_PIN_DRV_1BIT, 195, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(210, "YIN3", UNIPHIER_PIN_IECTRL_NONE, - 196, UNIPHIER_PIN_DRV_4_8, + 196, UNIPHIER_PIN_DRV_1BIT, 196, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(211, "YIN4", UNIPHIER_PIN_IECTRL_NONE, - 197, UNIPHIER_PIN_DRV_4_8, + 197, UNIPHIER_PIN_DRV_1BIT, 197, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(212, "YIN5", UNIPHIER_PIN_IECTRL_NONE, - 198, UNIPHIER_PIN_DRV_4_8, + 198, UNIPHIER_PIN_DRV_1BIT, 198, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(213, "CIN0", UNIPHIER_PIN_IECTRL_NONE, - 199, UNIPHIER_PIN_DRV_4_8, + 199, UNIPHIER_PIN_DRV_1BIT, 199, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(214, "CIN1", UNIPHIER_PIN_IECTRL_NONE, - 200, UNIPHIER_PIN_DRV_4_8, + 200, UNIPHIER_PIN_DRV_1BIT, 200, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(215, "CIN2", UNIPHIER_PIN_IECTRL_NONE, - 201, UNIPHIER_PIN_DRV_4_8, + 201, UNIPHIER_PIN_DRV_1BIT, 201, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(216, "CIN3", UNIPHIER_PIN_IECTRL_NONE, - 202, UNIPHIER_PIN_DRV_4_8, + 202, UNIPHIER_PIN_DRV_1BIT, 202, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(217, "CIN4", UNIPHIER_PIN_IECTRL_NONE, - 203, UNIPHIER_PIN_DRV_4_8, + 203, UNIPHIER_PIN_DRV_1BIT, 203, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(218, "CIN5", UNIPHIER_PIN_IECTRL_NONE, - 204, UNIPHIER_PIN_DRV_4_8, + 204, UNIPHIER_PIN_DRV_1BIT, 204, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(219, "GCP", UNIPHIER_PIN_IECTRL_NONE, - 205, UNIPHIER_PIN_DRV_4_8, + 205, UNIPHIER_PIN_DRV_1BIT, 205, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(220, "ADFLG", UNIPHIER_PIN_IECTRL_NONE, - 206, UNIPHIER_PIN_DRV_4_8, + 206, UNIPHIER_PIN_DRV_1BIT, 206, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(221, "CK27AIOF", UNIPHIER_PIN_IECTRL_NONE, - 207, UNIPHIER_PIN_DRV_4_8, + 207, UNIPHIER_PIN_DRV_1BIT, 207, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(222, "DACOUT", UNIPHIER_PIN_IECTRL_NONE, - 208, UNIPHIER_PIN_DRV_4_8, + 208, UNIPHIER_PIN_DRV_1BIT, 208, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(223, "DAFLG", UNIPHIER_PIN_IECTRL_NONE, - 209, UNIPHIER_PIN_DRV_4_8, + 209, UNIPHIER_PIN_DRV_1BIT, 209, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(224, "VBIH", UNIPHIER_PIN_IECTRL_NONE, - 210, UNIPHIER_PIN_DRV_4_8, + 210, UNIPHIER_PIN_DRV_1BIT, 210, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(225, "VBIL", UNIPHIER_PIN_IECTRL_NONE, - 211, UNIPHIER_PIN_DRV_4_8, + 211, UNIPHIER_PIN_DRV_1BIT, 211, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(226, "XSUB_RST", UNIPHIER_PIN_IECTRL_NONE, - 212, UNIPHIER_PIN_DRV_4_8, + 212, UNIPHIER_PIN_DRV_1BIT, 212, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(227, "XADC_PD", UNIPHIER_PIN_IECTRL_NONE, - 213, UNIPHIER_PIN_DRV_4_8, + 213, UNIPHIER_PIN_DRV_1BIT, 213, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(228, "AI1ADCCK", UNIPHIER_PIN_IECTRL_NONE, - 214, UNIPHIER_PIN_DRV_4_8, + 214, UNIPHIER_PIN_DRV_1BIT, 214, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(229, "AI1BCK", UNIPHIER_PIN_IECTRL_NONE, - 215, UNIPHIER_PIN_DRV_4_8, + 215, UNIPHIER_PIN_DRV_1BIT, 215, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(230, "AI1LRCK", UNIPHIER_PIN_IECTRL_NONE, - 216, UNIPHIER_PIN_DRV_4_8, + 216, UNIPHIER_PIN_DRV_1BIT, 216, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(231, "AI1DMIX", UNIPHIER_PIN_IECTRL_NONE, - 217, UNIPHIER_PIN_DRV_4_8, + 217, UNIPHIER_PIN_DRV_1BIT, 217, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(232, "CK27HD", UNIPHIER_PIN_IECTRL_NONE, - 218, UNIPHIER_PIN_DRV_4_8, + 218, UNIPHIER_PIN_DRV_1BIT, 218, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(233, "XHD_RST", UNIPHIER_PIN_IECTRL_NONE, - 219, UNIPHIER_PIN_DRV_4_8, + 219, UNIPHIER_PIN_DRV_1BIT, 219, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(234, "INTHD", UNIPHIER_PIN_IECTRL_NONE, - 220, UNIPHIER_PIN_DRV_4_8, + 220, UNIPHIER_PIN_DRV_1BIT, 220, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(235, "VO1HDCK", UNIPHIER_PIN_IECTRL_NONE, - 221, UNIPHIER_PIN_DRV_4_8, + 221, UNIPHIER_PIN_DRV_1BIT, 221, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(236, "VO1HSYNC", UNIPHIER_PIN_IECTRL_NONE, - 222, UNIPHIER_PIN_DRV_4_8, + 222, UNIPHIER_PIN_DRV_1BIT, 222, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(237, "VO1VSYNC", UNIPHIER_PIN_IECTRL_NONE, - 223, UNIPHIER_PIN_DRV_4_8, + 223, UNIPHIER_PIN_DRV_1BIT, 223, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(238, "VO1DE", UNIPHIER_PIN_IECTRL_NONE, - 224, UNIPHIER_PIN_DRV_4_8, + 224, UNIPHIER_PIN_DRV_1BIT, 224, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(239, "VO1Y0", UNIPHIER_PIN_IECTRL_NONE, - 225, UNIPHIER_PIN_DRV_4_8, + 225, UNIPHIER_PIN_DRV_1BIT, 225, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(240, "VO1Y1", UNIPHIER_PIN_IECTRL_NONE, - 226, UNIPHIER_PIN_DRV_4_8, + 226, UNIPHIER_PIN_DRV_1BIT, 226, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(241, "VO1Y2", UNIPHIER_PIN_IECTRL_NONE, - 227, UNIPHIER_PIN_DRV_4_8, + 227, UNIPHIER_PIN_DRV_1BIT, 227, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(242, "VO1Y3", UNIPHIER_PIN_IECTRL_NONE, - 228, UNIPHIER_PIN_DRV_4_8, + 228, UNIPHIER_PIN_DRV_1BIT, 228, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(243, "VO1Y4", UNIPHIER_PIN_IECTRL_NONE, - 229, UNIPHIER_PIN_DRV_4_8, + 229, UNIPHIER_PIN_DRV_1BIT, 229, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(244, "VO1Y5", UNIPHIER_PIN_IECTRL_NONE, - 230, UNIPHIER_PIN_DRV_4_8, + 230, UNIPHIER_PIN_DRV_1BIT, 230, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(245, "VO1Y6", UNIPHIER_PIN_IECTRL_NONE, - 231, UNIPHIER_PIN_DRV_4_8, + 231, UNIPHIER_PIN_DRV_1BIT, 231, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(246, "VO1Y7", UNIPHIER_PIN_IECTRL_NONE, - 232, UNIPHIER_PIN_DRV_4_8, + 232, UNIPHIER_PIN_DRV_1BIT, 232, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(247, "VO1Y8", UNIPHIER_PIN_IECTRL_NONE, - 233, UNIPHIER_PIN_DRV_4_8, + 233, UNIPHIER_PIN_DRV_1BIT, 233, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(248, "VO1Y9", UNIPHIER_PIN_IECTRL_NONE, - 234, UNIPHIER_PIN_DRV_4_8, + 234, UNIPHIER_PIN_DRV_1BIT, 234, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(249, "VO1Y10", UNIPHIER_PIN_IECTRL_NONE, - 235, UNIPHIER_PIN_DRV_4_8, + 235, UNIPHIER_PIN_DRV_1BIT, 235, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(250, "VO1Y11", UNIPHIER_PIN_IECTRL_NONE, - 236, UNIPHIER_PIN_DRV_4_8, + 236, UNIPHIER_PIN_DRV_1BIT, 236, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(251, "VO1CB0", UNIPHIER_PIN_IECTRL_NONE, - 237, UNIPHIER_PIN_DRV_4_8, + 237, UNIPHIER_PIN_DRV_1BIT, 237, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(252, "VO1CB1", UNIPHIER_PIN_IECTRL_NONE, - 238, UNIPHIER_PIN_DRV_4_8, + 238, UNIPHIER_PIN_DRV_1BIT, 238, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(253, "VO1CB2", UNIPHIER_PIN_IECTRL_NONE, - 239, UNIPHIER_PIN_DRV_4_8, + 239, UNIPHIER_PIN_DRV_1BIT, 239, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(254, "VO1CB3", UNIPHIER_PIN_IECTRL_NONE, - 240, UNIPHIER_PIN_DRV_4_8, + 240, UNIPHIER_PIN_DRV_1BIT, 240, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(255, "VO1CB4", UNIPHIER_PIN_IECTRL_NONE, - 241, UNIPHIER_PIN_DRV_4_8, + 241, UNIPHIER_PIN_DRV_1BIT, 241, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(256, "VO1CB5", UNIPHIER_PIN_IECTRL_NONE, - 242, UNIPHIER_PIN_DRV_4_8, + 242, UNIPHIER_PIN_DRV_1BIT, 242, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(257, "VO1CB6", UNIPHIER_PIN_IECTRL_NONE, - 243, UNIPHIER_PIN_DRV_4_8, + 243, UNIPHIER_PIN_DRV_1BIT, 243, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(258, "VO1CB7", UNIPHIER_PIN_IECTRL_NONE, - 244, UNIPHIER_PIN_DRV_4_8, + 244, UNIPHIER_PIN_DRV_1BIT, 244, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(259, "VO1CB8", UNIPHIER_PIN_IECTRL_NONE, - 245, UNIPHIER_PIN_DRV_4_8, + 245, UNIPHIER_PIN_DRV_1BIT, 245, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(260, "VO1CB9", UNIPHIER_PIN_IECTRL_NONE, - 246, UNIPHIER_PIN_DRV_4_8, + 246, UNIPHIER_PIN_DRV_1BIT, 246, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(261, "VO1CB10", UNIPHIER_PIN_IECTRL_NONE, - 247, UNIPHIER_PIN_DRV_4_8, + 247, UNIPHIER_PIN_DRV_1BIT, 247, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(262, "VO1CB11", UNIPHIER_PIN_IECTRL_NONE, - 248, UNIPHIER_PIN_DRV_4_8, + 248, UNIPHIER_PIN_DRV_1BIT, 248, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(263, "VO1CR0", UNIPHIER_PIN_IECTRL_NONE, - 249, UNIPHIER_PIN_DRV_4_8, + 249, UNIPHIER_PIN_DRV_1BIT, 249, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(264, "VO1CR1", UNIPHIER_PIN_IECTRL_NONE, - 250, UNIPHIER_PIN_DRV_4_8, + 250, UNIPHIER_PIN_DRV_1BIT, 250, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(265, "VO1CR2", UNIPHIER_PIN_IECTRL_NONE, - 251, UNIPHIER_PIN_DRV_4_8, + 251, UNIPHIER_PIN_DRV_1BIT, 251, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(266, "VO1CR3", UNIPHIER_PIN_IECTRL_NONE, - 252, UNIPHIER_PIN_DRV_4_8, + 252, UNIPHIER_PIN_DRV_1BIT, 252, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(267, "VO1CR4", UNIPHIER_PIN_IECTRL_NONE, - 253, UNIPHIER_PIN_DRV_4_8, + 253, UNIPHIER_PIN_DRV_1BIT, 253, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(268, "VO1CR5", UNIPHIER_PIN_IECTRL_NONE, - 254, UNIPHIER_PIN_DRV_4_8, + 254, UNIPHIER_PIN_DRV_1BIT, 254, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(269, "VO1CR6", UNIPHIER_PIN_IECTRL_NONE, - 255, UNIPHIER_PIN_DRV_4_8, + 255, UNIPHIER_PIN_DRV_1BIT, 255, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(270, "VO1CR7", UNIPHIER_PIN_IECTRL_NONE, - 256, UNIPHIER_PIN_DRV_4_8, + 256, UNIPHIER_PIN_DRV_1BIT, 256, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(271, "VO1CR8", UNIPHIER_PIN_IECTRL_NONE, - 257, UNIPHIER_PIN_DRV_4_8, + 257, UNIPHIER_PIN_DRV_1BIT, 257, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(272, "VO1CR9", UNIPHIER_PIN_IECTRL_NONE, - 258, UNIPHIER_PIN_DRV_4_8, + 258, UNIPHIER_PIN_DRV_1BIT, 258, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(273, "VO1CR10", UNIPHIER_PIN_IECTRL_NONE, - 259, UNIPHIER_PIN_DRV_4_8, + 259, UNIPHIER_PIN_DRV_1BIT, 259, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(274, "VO1CR11", UNIPHIER_PIN_IECTRL_NONE, - 260, UNIPHIER_PIN_DRV_4_8, + 260, UNIPHIER_PIN_DRV_1BIT, 260, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(275, "VO1EX0", UNIPHIER_PIN_IECTRL_NONE, - 261, UNIPHIER_PIN_DRV_4_8, + 261, UNIPHIER_PIN_DRV_1BIT, 261, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(276, "VO1EX1", UNIPHIER_PIN_IECTRL_NONE, - 262, UNIPHIER_PIN_DRV_4_8, + 262, UNIPHIER_PIN_DRV_1BIT, 262, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(277, "VO1EX2", UNIPHIER_PIN_IECTRL_NONE, - 263, UNIPHIER_PIN_DRV_4_8, + 263, UNIPHIER_PIN_DRV_1BIT, 263, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(278, "VO1EX3", UNIPHIER_PIN_IECTRL_NONE, - 264, UNIPHIER_PIN_DRV_4_8, + 264, UNIPHIER_PIN_DRV_1BIT, 264, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(279, "VEXCKA", UNIPHIER_PIN_IECTRL_NONE, - 265, UNIPHIER_PIN_DRV_4_8, + 265, UNIPHIER_PIN_DRV_1BIT, 265, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(280, "VSEL0", UNIPHIER_PIN_IECTRL_NONE, - 266, UNIPHIER_PIN_DRV_4_8, + 266, UNIPHIER_PIN_DRV_1BIT, 266, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(281, "VSEL1", UNIPHIER_PIN_IECTRL_NONE, - 267, UNIPHIER_PIN_DRV_4_8, + 267, UNIPHIER_PIN_DRV_1BIT, 267, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(282, "AO1DACCK", UNIPHIER_PIN_IECTRL_NONE, - 268, UNIPHIER_PIN_DRV_4_8, + 268, UNIPHIER_PIN_DRV_1BIT, 268, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(283, "AO1BCK", UNIPHIER_PIN_IECTRL_NONE, - 269, UNIPHIER_PIN_DRV_4_8, + 269, UNIPHIER_PIN_DRV_1BIT, 269, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(284, "AO1LRCK", UNIPHIER_PIN_IECTRL_NONE, - 270, UNIPHIER_PIN_DRV_4_8, + 270, UNIPHIER_PIN_DRV_1BIT, 270, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(285, "AO1D0", UNIPHIER_PIN_IECTRL_NONE, - 271, UNIPHIER_PIN_DRV_4_8, + 271, UNIPHIER_PIN_DRV_1BIT, 271, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(286, "AO1D1", UNIPHIER_PIN_IECTRL_NONE, - 272, UNIPHIER_PIN_DRV_4_8, + 272, UNIPHIER_PIN_DRV_1BIT, 272, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(287, "AO1D2", UNIPHIER_PIN_IECTRL_NONE, - 273, UNIPHIER_PIN_DRV_4_8, + 273, UNIPHIER_PIN_DRV_1BIT, 273, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(288, "AO1D3", UNIPHIER_PIN_IECTRL_NONE, - 274, UNIPHIER_PIN_DRV_4_8, + 274, UNIPHIER_PIN_DRV_1BIT, 274, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(289, "AO1IEC", UNIPHIER_PIN_IECTRL_NONE, - 275, UNIPHIER_PIN_DRV_4_8, + 275, UNIPHIER_PIN_DRV_1BIT, 275, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(290, "XDAC_PD", UNIPHIER_PIN_IECTRL_NONE, - 276, UNIPHIER_PIN_DRV_4_8, + 276, UNIPHIER_PIN_DRV_1BIT, 276, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(291, "EX_A_MUTE", UNIPHIER_PIN_IECTRL_NONE, - 277, UNIPHIER_PIN_DRV_4_8, + 277, UNIPHIER_PIN_DRV_1BIT, 277, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(292, "AO2DACCK", UNIPHIER_PIN_IECTRL_NONE, - 278, UNIPHIER_PIN_DRV_4_8, + 278, UNIPHIER_PIN_DRV_1BIT, 278, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(293, "AO2BCK", UNIPHIER_PIN_IECTRL_NONE, - 279, UNIPHIER_PIN_DRV_4_8, + 279, UNIPHIER_PIN_DRV_1BIT, 279, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(294, "AO2LRCK", UNIPHIER_PIN_IECTRL_NONE, - 280, UNIPHIER_PIN_DRV_4_8, + 280, UNIPHIER_PIN_DRV_1BIT, 280, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(295, "AO2DMIX", UNIPHIER_PIN_IECTRL_NONE, - 281, UNIPHIER_PIN_DRV_4_8, + 281, UNIPHIER_PIN_DRV_1BIT, 281, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(296, "AO2IEC", UNIPHIER_PIN_IECTRL_NONE, - 282, UNIPHIER_PIN_DRV_4_8, + 282, UNIPHIER_PIN_DRV_1BIT, 282, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(297, "HTHPD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_5, + -1, UNIPHIER_PIN_DRV_FIXED5, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(298, "HTSCL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_5, + -1, UNIPHIER_PIN_DRV_FIXED5, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(299, "HTSDA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_5, + -1, UNIPHIER_PIN_DRV_FIXED5, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(300, "PORT00", UNIPHIER_PIN_IECTRL_NONE, - 284, UNIPHIER_PIN_DRV_4_8, + 284, UNIPHIER_PIN_DRV_1BIT, 284, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(301, "PORT01", UNIPHIER_PIN_IECTRL_NONE, - 285, UNIPHIER_PIN_DRV_4_8, + 285, UNIPHIER_PIN_DRV_1BIT, 285, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(302, "PORT02", UNIPHIER_PIN_IECTRL_NONE, - 286, UNIPHIER_PIN_DRV_4_8, + 286, UNIPHIER_PIN_DRV_1BIT, 286, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(303, "PORT03", UNIPHIER_PIN_IECTRL_NONE, - 287, UNIPHIER_PIN_DRV_4_8, + 287, UNIPHIER_PIN_DRV_1BIT, 287, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(304, "PORT04", UNIPHIER_PIN_IECTRL_NONE, - 288, UNIPHIER_PIN_DRV_4_8, + 288, UNIPHIER_PIN_DRV_1BIT, 288, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(305, "PORT05", UNIPHIER_PIN_IECTRL_NONE, - 289, UNIPHIER_PIN_DRV_4_8, + 289, UNIPHIER_PIN_DRV_1BIT, 289, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(306, "PORT06", UNIPHIER_PIN_IECTRL_NONE, - 290, UNIPHIER_PIN_DRV_4_8, + 290, UNIPHIER_PIN_DRV_1BIT, 290, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(307, "PORT07", UNIPHIER_PIN_IECTRL_NONE, - 291, UNIPHIER_PIN_DRV_4_8, + 291, UNIPHIER_PIN_DRV_1BIT, 291, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(308, "PORT10", UNIPHIER_PIN_IECTRL_NONE, - 292, UNIPHIER_PIN_DRV_4_8, + 292, UNIPHIER_PIN_DRV_1BIT, 292, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(309, "PORT11", UNIPHIER_PIN_IECTRL_NONE, - 293, UNIPHIER_PIN_DRV_4_8, + 293, UNIPHIER_PIN_DRV_1BIT, 293, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(310, "PORT12", UNIPHIER_PIN_IECTRL_NONE, - 294, UNIPHIER_PIN_DRV_4_8, + 294, UNIPHIER_PIN_DRV_1BIT, 294, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(311, "PORT13", UNIPHIER_PIN_IECTRL_NONE, - 295, UNIPHIER_PIN_DRV_4_8, + 295, UNIPHIER_PIN_DRV_1BIT, 295, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(312, "PORT14", UNIPHIER_PIN_IECTRL_NONE, - 296, UNIPHIER_PIN_DRV_4_8, + 296, UNIPHIER_PIN_DRV_1BIT, 296, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(313, "PORT15", UNIPHIER_PIN_IECTRL_NONE, - 297, UNIPHIER_PIN_DRV_4_8, + 297, UNIPHIER_PIN_DRV_1BIT, 297, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(314, "PORT16", UNIPHIER_PIN_IECTRL_NONE, - 298, UNIPHIER_PIN_DRV_4_8, + 298, UNIPHIER_PIN_DRV_1BIT, 298, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(315, "PORT17", UNIPHIER_PIN_IECTRL_NONE, - 299, UNIPHIER_PIN_DRV_4_8, + 299, UNIPHIER_PIN_DRV_1BIT, 299, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(316, "PORT20", UNIPHIER_PIN_IECTRL_NONE, - 300, UNIPHIER_PIN_DRV_4_8, + 300, UNIPHIER_PIN_DRV_1BIT, 300, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(317, "PORT21", UNIPHIER_PIN_IECTRL_NONE, - 301, UNIPHIER_PIN_DRV_4_8, + 301, UNIPHIER_PIN_DRV_1BIT, 301, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(318, "PORT22", UNIPHIER_PIN_IECTRL_NONE, - 302, UNIPHIER_PIN_DRV_4_8, + 302, UNIPHIER_PIN_DRV_1BIT, 302, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(319, "SD1DAT0", UNIPHIER_PIN_IECTRL_NONE, - 303, UNIPHIER_PIN_DRV_4_8, + 303, UNIPHIER_PIN_DRV_1BIT, 303, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(320, "SD1DAT1", UNIPHIER_PIN_IECTRL_NONE, - 304, UNIPHIER_PIN_DRV_4_8, + 304, UNIPHIER_PIN_DRV_1BIT, 304, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(321, "SD1DAT2", UNIPHIER_PIN_IECTRL_NONE, - 305, UNIPHIER_PIN_DRV_4_8, + 305, UNIPHIER_PIN_DRV_1BIT, 305, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(322, "SD1DAT3", UNIPHIER_PIN_IECTRL_NONE, - 306, UNIPHIER_PIN_DRV_4_8, + 306, UNIPHIER_PIN_DRV_1BIT, 306, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(323, "SD1CMD", UNIPHIER_PIN_IECTRL_NONE, - 307, UNIPHIER_PIN_DRV_4_8, + 307, UNIPHIER_PIN_DRV_1BIT, 307, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(324, "SD1CLK", UNIPHIER_PIN_IECTRL_NONE, - 308, UNIPHIER_PIN_DRV_4_8, + 308, UNIPHIER_PIN_DRV_1BIT, 308, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(325, "SD1CD", UNIPHIER_PIN_IECTRL_NONE, - 309, UNIPHIER_PIN_DRV_4_8, + 309, UNIPHIER_PIN_DRV_1BIT, 309, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(326, "SD1WP", UNIPHIER_PIN_IECTRL_NONE, - 310, UNIPHIER_PIN_DRV_4_8, + 310, UNIPHIER_PIN_DRV_1BIT, 310, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(327, "SD1VTCG", UNIPHIER_PIN_IECTRL_NONE, - 311, UNIPHIER_PIN_DRV_4_8, + 311, UNIPHIER_PIN_DRV_1BIT, 311, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(328, "DMDISO", UNIPHIER_PIN_IECTRL_NONE, - 312, UNIPHIER_PIN_DRV_NONE, + -1, UNIPHIER_PIN_DRV_NONE, 312, UNIPHIER_PIN_PULL_DOWN), }; static const unsigned emmc_pins[] = {40, 41, 42, 43, 51, 52, 53}; -static const unsigned emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; +static const int emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; static const unsigned emmc_dat8_pins[] = {44, 45, 46, 47}; -static const unsigned emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const int emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const unsigned ether_mii_pins[] = {160, 161, 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179}; +static const int ether_mii_muxvals[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0}; +static const unsigned ether_rgmii_pins[] = {160, 161, 162, 163, 164, 165, 167, + 168, 169, 170, 171, 172, 176, 177, + 178, 179}; +static const int ether_rgmii_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; +static const unsigned ether_rmii_pins[] = {160, 161, 162, 165, 168, 169, 172, + 173, 176, 177, 178, 179}; +static const int ether_rmii_muxvals[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned ether_rmiib_pins[] = {161, 162, 165, 167, 168, 169, 172, + 173, 176, 177, 178, 179}; +static const int ether_rmiib_muxvals[] = {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned i2c0_pins[] = {142, 143}; -static const unsigned i2c0_muxvals[] = {0, 0}; +static const int i2c0_muxvals[] = {0, 0}; static const unsigned i2c1_pins[] = {144, 145}; -static const unsigned i2c1_muxvals[] = {0, 0}; +static const int i2c1_muxvals[] = {0, 0}; static const unsigned i2c2_pins[] = {146, 147}; -static const unsigned i2c2_muxvals[] = {0, 0}; +static const int i2c2_muxvals[] = {0, 0}; static const unsigned i2c3_pins[] = {148, 149}; -static const unsigned i2c3_muxvals[] = {0, 0}; +static const int i2c3_muxvals[] = {0, 0}; static const unsigned i2c6_pins[] = {308, 309}; -static const unsigned i2c6_muxvals[] = {6, 6}; +static const int i2c6_muxvals[] = {6, 6}; static const unsigned nand_pins[] = {40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54}; -static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0}; +static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned nand_cs1_pins[] = {131, 132}; -static const unsigned nand_cs1_muxvals[] = {1, 1}; +static const int nand_cs1_muxvals[] = {1, 1}; static const unsigned sd_pins[] = {150, 151, 152, 153, 154, 155, 156, 157, 158}; -static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned sd1_pins[] = {319, 320, 321, 322, 323, 324, 325, 326, 327}; -static const unsigned sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const int sd1_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned system_bus_pins[] = {25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38}; +static const int system_bus_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0}; +static const unsigned system_bus_cs0_pins[] = {318}; +static const int system_bus_cs0_muxvals[] = {5}; +static const unsigned system_bus_cs1_pins[] = {24}; +static const int system_bus_cs1_muxvals[] = {0}; +static const unsigned system_bus_cs2_pins[] = {315}; +static const int system_bus_cs2_muxvals[] = {5}; +static const unsigned system_bus_cs3_pins[] = {313}; +static const int system_bus_cs3_muxvals[] = {5}; +static const unsigned system_bus_cs4_pins[] = {305}; +static const int system_bus_cs4_muxvals[] = {5}; +static const unsigned system_bus_cs5_pins[] = {303}; +static const int system_bus_cs5_muxvals[] = {6}; +static const unsigned system_bus_cs6_pins[] = {307}; +static const int system_bus_cs6_muxvals[] = {6}; +static const unsigned system_bus_cs7_pins[] = {312}; +static const int system_bus_cs7_muxvals[] = {6}; static const unsigned uart0_pins[] = {127, 128}; -static const unsigned uart0_muxvals[] = {0, 0}; +static const int uart0_muxvals[] = {0, 0}; static const unsigned uart1_pins[] = {129, 130}; -static const unsigned uart1_muxvals[] = {0, 0}; +static const int uart1_muxvals[] = {0, 0}; static const unsigned uart2_pins[] = {131, 132}; -static const unsigned uart2_muxvals[] = {0, 0}; +static const int uart2_muxvals[] = {0, 0}; static const unsigned uart3_pins[] = {88, 89}; -static const unsigned uart3_muxvals[] = {2, 2}; +static const int uart3_muxvals[] = {2, 2}; static const unsigned usb0_pins[] = {180, 181}; -static const unsigned usb0_muxvals[] = {0, 0}; +static const int usb0_muxvals[] = {0, 0}; static const unsigned usb1_pins[] = {182, 183}; -static const unsigned usb1_muxvals[] = {0, 0}; +static const int usb1_muxvals[] = {0, 0}; static const unsigned usb2_pins[] = {184, 185}; -static const unsigned usb2_muxvals[] = {0, 0}; +static const int usb2_muxvals[] = {0, 0}; static const unsigned usb3_pins[] = {186, 187}; -static const unsigned usb3_muxvals[] = {0, 0}; +static const int usb3_muxvals[] = {0, 0}; static const unsigned port_range0_pins[] = { 300, 301, 302, 303, 304, 305, 306, 307, /* PORT0x */ 308, 309, 310, 311, 312, 313, 314, 315, /* PORT1x */ @@ -1069,7 +1102,7 @@ static const unsigned port_range0_pins[] = { 76, 77, 78, 79, 80, 81, 82, 83, /* PORT13x */ 84, 85, 86, 87, 88, 89, 90, 91, /* PORT14x */ }; -static const unsigned port_range0_muxvals[] = { +static const int port_range0_muxvals[] = { 7, 7, 7, 7, 7, 7, 7, 7, /* PORT0x */ 7, 7, 7, 7, 7, 7, 7, 7, /* PORT1x */ 7, 7, 7, 7, 7, 7, 7, 7, /* PORT2x */ @@ -1102,7 +1135,7 @@ static const unsigned port_range1_pins[] = { 251, 252, 261, 262, 263, 264, 273, 274, /* PORT29x */ 31, 32, 33, 34, 35, 36, 37, 38, /* PORT30x */ }; -static const unsigned port_range1_muxvals[] = { +static const int port_range1_muxvals[] = { 7, 7, 7, /* PORT175-177 */ 7, 7, 7, 7, 7, 7, 7, 7, /* PORT18x */ 7, 7, 7, 7, 7, 7, 7, 7, /* PORT19x */ @@ -1123,7 +1156,7 @@ static const unsigned xirq_pins[] = { 234, 186, 99, 100, 101, 102, 184, 301, /* XIRQ8-15 */ 302, 303, 304, 305, 306, /* XIRQ16-20 */ }; -static const unsigned xirq_muxvals[] = { +static const int xirq_muxvals[] = { 7, 7, 7, 7, 7, 7, 7, 7, /* XIRQ0-7 */ 7, 7, 7, 7, 7, 7, 2, 2, /* XIRQ8-15 */ 2, 2, 2, 2, 2, /* XIRQ16-20 */ @@ -1131,13 +1164,17 @@ static const unsigned xirq_muxvals[] = { static const unsigned xirq_alternatives_pins[] = { 184, 310, 316, }; -static const unsigned xirq_alternatives_muxvals[] = { +static const int xirq_alternatives_muxvals[] = { 2, 2, 2, }; -static const struct uniphier_pinctrl_group ph1_pro4_groups[] = { +static const struct uniphier_pinctrl_group uniphier_pro4_groups[] = { UNIPHIER_PINCTRL_GROUP(emmc), UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(ether_mii), + UNIPHIER_PINCTRL_GROUP(ether_rgmii), + UNIPHIER_PINCTRL_GROUP(ether_rmii), + UNIPHIER_PINCTRL_GROUP(ether_rmiib), UNIPHIER_PINCTRL_GROUP(i2c0), UNIPHIER_PINCTRL_GROUP(i2c1), UNIPHIER_PINCTRL_GROUP(i2c2), @@ -1147,6 +1184,15 @@ static const struct uniphier_pinctrl_group ph1_pro4_groups[] = { UNIPHIER_PINCTRL_GROUP(nand_cs1), UNIPHIER_PINCTRL_GROUP(sd), UNIPHIER_PINCTRL_GROUP(sd1), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs0), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(system_bus_cs2), + UNIPHIER_PINCTRL_GROUP(system_bus_cs3), + UNIPHIER_PINCTRL_GROUP(system_bus_cs4), + UNIPHIER_PINCTRL_GROUP(system_bus_cs5), + UNIPHIER_PINCTRL_GROUP(system_bus_cs6), + UNIPHIER_PINCTRL_GROUP(system_bus_cs7), UNIPHIER_PINCTRL_GROUP(uart0), UNIPHIER_PINCTRL_GROUP(uart1), UNIPHIER_PINCTRL_GROUP(uart2), @@ -1413,6 +1459,9 @@ static const struct uniphier_pinctrl_group ph1_pro4_groups[] = { }; static const char * const emmc_groups[] = {"emmc", "emmc_dat8"}; +static const char * const ether_mii_groups[] = {"ether_mii"}; +static const char * const ether_rgmii_groups[] = {"ether_rgmii"}; +static const char * const ether_rmii_groups[] = {"ether_rgmii", "ether_rgmiib"}; static const char * const i2c0_groups[] = {"i2c0"}; static const char * const i2c1_groups[] = {"i2c1"}; static const char * const i2c2_groups[] = {"i2c2"}; @@ -1421,6 +1470,15 @@ static const char * const i2c6_groups[] = {"i2c6"}; static const char * const nand_groups[] = {"nand", "nand_cs1"}; static const char * const sd_groups[] = {"sd"}; static const char * const sd1_groups[] = {"sd1"}; +static const char * const system_bus_groups[] = {"system_bus", + "system_bus_cs0", + "system_bus_cs1", + "system_bus_cs2", + "system_bus_cs3", + "system_bus_cs4", + "system_bus_cs5", + "system_bus_cs6", + "system_bus_cs7"}; static const char * const uart0_groups[] = {"uart0"}; static const char * const uart1_groups[] = {"uart1"}; static const char * const uart2_groups[] = {"uart2"}; @@ -1499,8 +1557,11 @@ static const char * const xirq_groups[] = { "xirq14b", "xirq17b", "xirq18b", }; -static const struct uniphier_pinmux_function ph1_pro4_functions[] = { +static const struct uniphier_pinmux_function uniphier_pro4_functions[] = { UNIPHIER_PINMUX_FUNCTION(emmc), + UNIPHIER_PINMUX_FUNCTION(ether_mii), + UNIPHIER_PINMUX_FUNCTION(ether_rgmii), + UNIPHIER_PINMUX_FUNCTION(ether_rmii), UNIPHIER_PINMUX_FUNCTION(i2c0), UNIPHIER_PINMUX_FUNCTION(i2c1), UNIPHIER_PINMUX_FUNCTION(i2c2), @@ -1509,6 +1570,7 @@ static const struct uniphier_pinmux_function ph1_pro4_functions[] = { UNIPHIER_PINMUX_FUNCTION(nand), UNIPHIER_PINMUX_FUNCTION(sd), UNIPHIER_PINMUX_FUNCTION(sd1), + UNIPHIER_PINMUX_FUNCTION(system_bus), UNIPHIER_PINMUX_FUNCTION(uart0), UNIPHIER_PINMUX_FUNCTION(uart1), UNIPHIER_PINMUX_FUNCTION(uart2), @@ -1521,43 +1583,36 @@ static const struct uniphier_pinmux_function ph1_pro4_functions[] = { UNIPHIER_PINMUX_FUNCTION(xirq), }; -static struct uniphier_pinctrl_socdata ph1_pro4_pindata = { - .groups = ph1_pro4_groups, - .groups_count = ARRAY_SIZE(ph1_pro4_groups), - .functions = ph1_pro4_functions, - .functions_count = ARRAY_SIZE(ph1_pro4_functions), - .mux_bits = 4, - .reg_stride = 8, - .load_pinctrl = true, -}; - -static struct pinctrl_desc ph1_pro4_pinctrl_desc = { - .name = DRIVER_NAME, - .pins = ph1_pro4_pins, - .npins = ARRAY_SIZE(ph1_pro4_pins), - .owner = THIS_MODULE, +static struct uniphier_pinctrl_socdata uniphier_pro4_pindata = { + .pins = uniphier_pro4_pins, + .npins = ARRAY_SIZE(uniphier_pro4_pins), + .groups = uniphier_pro4_groups, + .groups_count = ARRAY_SIZE(uniphier_pro4_groups), + .functions = uniphier_pro4_functions, + .functions_count = ARRAY_SIZE(uniphier_pro4_functions), + .caps = UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE, }; -static int ph1_pro4_pinctrl_probe(struct platform_device *pdev) +static int uniphier_pro4_pinctrl_probe(struct platform_device *pdev) { - return uniphier_pinctrl_probe(pdev, &ph1_pro4_pinctrl_desc, - &ph1_pro4_pindata); + return uniphier_pinctrl_probe(pdev, &uniphier_pro4_pindata); } -static const struct of_device_id ph1_pro4_pinctrl_match[] = { +static const struct of_device_id uniphier_pro4_pinctrl_match[] = { + { .compatible = "socionext,uniphier-pro4-pinctrl" }, { .compatible = "socionext,ph1-pro4-pinctrl" }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, ph1_pro4_pinctrl_match); +MODULE_DEVICE_TABLE(of, uniphier_pro4_pinctrl_match); -static struct platform_driver ph1_pro4_pinctrl_driver = { - .probe = ph1_pro4_pinctrl_probe, +static struct platform_driver uniphier_pro4_pinctrl_driver = { + .probe = uniphier_pro4_pinctrl_probe, .driver = { - .name = DRIVER_NAME, - .of_match_table = ph1_pro4_pinctrl_match, + .name = "uniphier-pro4-pinctrl", + .of_match_table = uniphier_pro4_pinctrl_match, }, }; -module_platform_driver(ph1_pro4_pinctrl_driver); +module_platform_driver(uniphier_pro4_pinctrl_driver); MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); MODULE_DESCRIPTION("UniPhier PH1-Pro4 pinctrl driver"); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c index 3087f76752a6..55d4a12282a0 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c @@ -19,823 +19,840 @@ #include "pinctrl-uniphier.h" -#define DRIVER_NAME "ph1-pro5-pinctrl" - -static const struct pinctrl_pin_desc ph1_pro5_pins[] = { +static const struct pinctrl_pin_desc uniphier_pro5_pins[] = { UNIPHIER_PINCTRL_PIN(0, "AEXCKA1", 0, - 0, UNIPHIER_PIN_DRV_4_8, + 0, UNIPHIER_PIN_DRV_1BIT, 0, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(1, "AEXCKA2", 0, - 1, UNIPHIER_PIN_DRV_4_8, + 1, UNIPHIER_PIN_DRV_1BIT, 1, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(2, "CK27EXI", 0, - 2, UNIPHIER_PIN_DRV_4_8, + 2, UNIPHIER_PIN_DRV_1BIT, 2, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(3, "CK54EXI", 0, - 3, UNIPHIER_PIN_DRV_4_8, + 3, UNIPHIER_PIN_DRV_1BIT, 3, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(4, "ED0", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_4_8, + 4, UNIPHIER_PIN_DRV_1BIT, 4, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(5, "ED1", UNIPHIER_PIN_IECTRL_NONE, - 5, UNIPHIER_PIN_DRV_4_8, + 5, UNIPHIER_PIN_DRV_1BIT, 5, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(6, "ED2", UNIPHIER_PIN_IECTRL_NONE, - 6, UNIPHIER_PIN_DRV_4_8, + 6, UNIPHIER_PIN_DRV_1BIT, 6, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(7, "ED3", UNIPHIER_PIN_IECTRL_NONE, - 7, UNIPHIER_PIN_DRV_4_8, + 7, UNIPHIER_PIN_DRV_1BIT, 7, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(8, "ED4", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_4_8, + 8, UNIPHIER_PIN_DRV_1BIT, 8, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(9, "ED5", UNIPHIER_PIN_IECTRL_NONE, - 9, UNIPHIER_PIN_DRV_4_8, + 9, UNIPHIER_PIN_DRV_1BIT, 9, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(10, "ED6", UNIPHIER_PIN_IECTRL_NONE, - 10, UNIPHIER_PIN_DRV_4_8, + 10, UNIPHIER_PIN_DRV_1BIT, 10, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(11, "ED7", UNIPHIER_PIN_IECTRL_NONE, - 11, UNIPHIER_PIN_DRV_4_8, + 11, UNIPHIER_PIN_DRV_1BIT, 11, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(12, "XERWE0", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_4_8, + 12, UNIPHIER_PIN_DRV_1BIT, 12, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(13, "XERWE1", UNIPHIER_PIN_IECTRL_NONE, - 13, UNIPHIER_PIN_DRV_4_8, + 13, UNIPHIER_PIN_DRV_1BIT, 13, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(14, "ERXW", UNIPHIER_PIN_IECTRL_NONE, - 14, UNIPHIER_PIN_DRV_4_8, + 14, UNIPHIER_PIN_DRV_1BIT, 14, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(15, "ES0", UNIPHIER_PIN_IECTRL_NONE, - 15, UNIPHIER_PIN_DRV_4_8, + 15, UNIPHIER_PIN_DRV_1BIT, 15, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(16, "ES1", UNIPHIER_PIN_IECTRL_NONE, - 16, UNIPHIER_PIN_DRV_4_8, + 16, UNIPHIER_PIN_DRV_1BIT, 16, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(17, "ES2", UNIPHIER_PIN_IECTRL_NONE, - 17, UNIPHIER_PIN_DRV_4_8, + 17, UNIPHIER_PIN_DRV_1BIT, 17, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(18, "XECS1", UNIPHIER_PIN_IECTRL_NONE, - 18, UNIPHIER_PIN_DRV_4_8, + 18, UNIPHIER_PIN_DRV_1BIT, 18, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(19, "XNFRE", UNIPHIER_PIN_IECTRL_NONE, - 19, UNIPHIER_PIN_DRV_4_8, + 19, UNIPHIER_PIN_DRV_1BIT, 19, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(20, "XNFWE", UNIPHIER_PIN_IECTRL_NONE, - 20, UNIPHIER_PIN_DRV_4_8, + 20, UNIPHIER_PIN_DRV_1BIT, 20, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(21, "NFALE", UNIPHIER_PIN_IECTRL_NONE, - 21, UNIPHIER_PIN_DRV_4_8, + 21, UNIPHIER_PIN_DRV_1BIT, 21, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(22, "NFCLE", UNIPHIER_PIN_IECTRL_NONE, - 22, UNIPHIER_PIN_DRV_4_8, + 22, UNIPHIER_PIN_DRV_1BIT, 22, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(23, "XNFWP", UNIPHIER_PIN_IECTRL_NONE, - 23, UNIPHIER_PIN_DRV_4_8, + 23, UNIPHIER_PIN_DRV_1BIT, 23, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(24, "XNFCE0", UNIPHIER_PIN_IECTRL_NONE, - 24, UNIPHIER_PIN_DRV_4_8, + 24, UNIPHIER_PIN_DRV_1BIT, 24, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(25, "NFRYBY0", UNIPHIER_PIN_IECTRL_NONE, - 25, UNIPHIER_PIN_DRV_4_8, + 25, UNIPHIER_PIN_DRV_1BIT, 25, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(26, "XNFCE1", UNIPHIER_PIN_IECTRL_NONE, - 26, UNIPHIER_PIN_DRV_4_8, + 26, UNIPHIER_PIN_DRV_1BIT, 26, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(27, "NFRYBY1", UNIPHIER_PIN_IECTRL_NONE, - 27, UNIPHIER_PIN_DRV_4_8, + 27, UNIPHIER_PIN_DRV_1BIT, 27, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(28, "NFD0", UNIPHIER_PIN_IECTRL_NONE, - 28, UNIPHIER_PIN_DRV_4_8, + 28, UNIPHIER_PIN_DRV_1BIT, 28, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(29, "NFD1", UNIPHIER_PIN_IECTRL_NONE, - 29, UNIPHIER_PIN_DRV_4_8, + 29, UNIPHIER_PIN_DRV_1BIT, 29, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(30, "NFD2", UNIPHIER_PIN_IECTRL_NONE, - 30, UNIPHIER_PIN_DRV_4_8, + 30, UNIPHIER_PIN_DRV_1BIT, 30, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(31, "NFD3", UNIPHIER_PIN_IECTRL_NONE, - 31, UNIPHIER_PIN_DRV_4_8, + 31, UNIPHIER_PIN_DRV_1BIT, 31, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(32, "NFD4", UNIPHIER_PIN_IECTRL_NONE, - 32, UNIPHIER_PIN_DRV_4_8, + 32, UNIPHIER_PIN_DRV_1BIT, 32, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(33, "NFD5", UNIPHIER_PIN_IECTRL_NONE, - 33, UNIPHIER_PIN_DRV_4_8, + 33, UNIPHIER_PIN_DRV_1BIT, 33, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(34, "NFD6", UNIPHIER_PIN_IECTRL_NONE, - 34, UNIPHIER_PIN_DRV_4_8, + 34, UNIPHIER_PIN_DRV_1BIT, 34, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(35, "NFD7", UNIPHIER_PIN_IECTRL_NONE, - 35, UNIPHIER_PIN_DRV_4_8, + 35, UNIPHIER_PIN_DRV_1BIT, 35, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(36, "XERST", UNIPHIER_PIN_IECTRL_NONE, - 36, UNIPHIER_PIN_DRV_4_8, + 36, UNIPHIER_PIN_DRV_1BIT, 36, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(37, "MMCCLK", UNIPHIER_PIN_IECTRL_NONE, - 37, UNIPHIER_PIN_DRV_4_8, + 37, UNIPHIER_PIN_DRV_1BIT, 37, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(38, "MMCCMD", UNIPHIER_PIN_IECTRL_NONE, - 38, UNIPHIER_PIN_DRV_4_8, + 38, UNIPHIER_PIN_DRV_1BIT, 38, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(39, "MMCDAT0", UNIPHIER_PIN_IECTRL_NONE, - 39, UNIPHIER_PIN_DRV_4_8, + 39, UNIPHIER_PIN_DRV_1BIT, 39, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(40, "MMCDAT1", UNIPHIER_PIN_IECTRL_NONE, - 40, UNIPHIER_PIN_DRV_4_8, + 40, UNIPHIER_PIN_DRV_1BIT, 40, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(41, "MMCDAT2", UNIPHIER_PIN_IECTRL_NONE, - 41, UNIPHIER_PIN_DRV_4_8, + 41, UNIPHIER_PIN_DRV_1BIT, 41, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(42, "MMCDAT3", UNIPHIER_PIN_IECTRL_NONE, - 42, UNIPHIER_PIN_DRV_4_8, + 42, UNIPHIER_PIN_DRV_1BIT, 42, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(43, "MMCDAT4", UNIPHIER_PIN_IECTRL_NONE, - 43, UNIPHIER_PIN_DRV_4_8, + 43, UNIPHIER_PIN_DRV_1BIT, 43, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(44, "MMCDAT5", UNIPHIER_PIN_IECTRL_NONE, - 44, UNIPHIER_PIN_DRV_4_8, + 44, UNIPHIER_PIN_DRV_1BIT, 44, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(45, "MMCDAT6", UNIPHIER_PIN_IECTRL_NONE, - 45, UNIPHIER_PIN_DRV_4_8, + 45, UNIPHIER_PIN_DRV_1BIT, 45, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(46, "MMCDAT7", UNIPHIER_PIN_IECTRL_NONE, - 46, UNIPHIER_PIN_DRV_4_8, + 46, UNIPHIER_PIN_DRV_1BIT, 46, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(47, "TXD0", 0, - 47, UNIPHIER_PIN_DRV_4_8, + 47, UNIPHIER_PIN_DRV_1BIT, 47, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(48, "RXD0", 0, - 48, UNIPHIER_PIN_DRV_4_8, + 48, UNIPHIER_PIN_DRV_1BIT, 48, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(49, "TXD1", 0, - 49, UNIPHIER_PIN_DRV_4_8, + 49, UNIPHIER_PIN_DRV_1BIT, 49, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(50, "RXD1", 0, - 50, UNIPHIER_PIN_DRV_4_8, + 50, UNIPHIER_PIN_DRV_1BIT, 50, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(51, "TXD2", UNIPHIER_PIN_IECTRL_NONE, - 51, UNIPHIER_PIN_DRV_4_8, + 51, UNIPHIER_PIN_DRV_1BIT, 51, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(52, "RXD2", UNIPHIER_PIN_IECTRL_NONE, - 52, UNIPHIER_PIN_DRV_4_8, + 52, UNIPHIER_PIN_DRV_1BIT, 52, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(53, "TXD3", 0, - 53, UNIPHIER_PIN_DRV_4_8, + 53, UNIPHIER_PIN_DRV_1BIT, 53, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(54, "RXD3", 0, - 54, UNIPHIER_PIN_DRV_4_8, + 54, UNIPHIER_PIN_DRV_1BIT, 54, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(55, "MS0CS0", 0, - 55, UNIPHIER_PIN_DRV_4_8, + 55, UNIPHIER_PIN_DRV_1BIT, 55, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(56, "MS0DO", 0, - 56, UNIPHIER_PIN_DRV_4_8, + 56, UNIPHIER_PIN_DRV_1BIT, 56, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(57, "MS0DI", 0, - 57, UNIPHIER_PIN_DRV_4_8, + 57, UNIPHIER_PIN_DRV_1BIT, 57, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(58, "MS0CLK", 0, - 58, UNIPHIER_PIN_DRV_4_8, + 58, UNIPHIER_PIN_DRV_1BIT, 58, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(59, "CSCLK", 0, - 59, UNIPHIER_PIN_DRV_4_8, + 59, UNIPHIER_PIN_DRV_1BIT, 59, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(60, "CSBPTM", 0, - 60, UNIPHIER_PIN_DRV_4_8, + 60, UNIPHIER_PIN_DRV_1BIT, 60, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(61, "CSBMTP", 0, - 61, UNIPHIER_PIN_DRV_4_8, + 61, UNIPHIER_PIN_DRV_1BIT, 61, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(62, "XCINTP", 0, - 62, UNIPHIER_PIN_DRV_4_8, + 62, UNIPHIER_PIN_DRV_1BIT, 62, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(63, "XCINTM", 0, - 63, UNIPHIER_PIN_DRV_4_8, + 63, UNIPHIER_PIN_DRV_1BIT, 63, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(64, "XCMPREQ", 0, - 64, UNIPHIER_PIN_DRV_4_8, + 64, UNIPHIER_PIN_DRV_1BIT, 64, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(65, "XSRST", 0, - 65, UNIPHIER_PIN_DRV_4_8, + 65, UNIPHIER_PIN_DRV_1BIT, 65, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(66, "LPST", UNIPHIER_PIN_IECTRL_NONE, - 66, UNIPHIER_PIN_DRV_4_8, + 66, UNIPHIER_PIN_DRV_1BIT, 66, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(67, "PWMA", 0, - 67, UNIPHIER_PIN_DRV_4_8, + 67, UNIPHIER_PIN_DRV_1BIT, 67, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(68, "XIRQ0", 0, - 68, UNIPHIER_PIN_DRV_4_8, + 68, UNIPHIER_PIN_DRV_1BIT, 68, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(69, "XIRQ1", 0, - 69, UNIPHIER_PIN_DRV_4_8, + 69, UNIPHIER_PIN_DRV_1BIT, 69, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(70, "XIRQ2", 0, - 70, UNIPHIER_PIN_DRV_4_8, + 70, UNIPHIER_PIN_DRV_1BIT, 70, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(71, "XIRQ3", 0, - 71, UNIPHIER_PIN_DRV_4_8, + 71, UNIPHIER_PIN_DRV_1BIT, 71, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(72, "XIRQ4", 0, - 72, UNIPHIER_PIN_DRV_4_8, + 72, UNIPHIER_PIN_DRV_1BIT, 72, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(73, "XIRQ5", 0, - 73, UNIPHIER_PIN_DRV_4_8, + 73, UNIPHIER_PIN_DRV_1BIT, 73, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(74, "XIRQ6", 0, - 74, UNIPHIER_PIN_DRV_4_8, + 74, UNIPHIER_PIN_DRV_1BIT, 74, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(75, "XIRQ7", 0, - 75, UNIPHIER_PIN_DRV_4_8, + 75, UNIPHIER_PIN_DRV_1BIT, 75, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(76, "XIRQ8", 0, - 76, UNIPHIER_PIN_DRV_4_8, + 76, UNIPHIER_PIN_DRV_1BIT, 76, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(77, "XIRQ9", 0, - 77, UNIPHIER_PIN_DRV_4_8, + 77, UNIPHIER_PIN_DRV_1BIT, 77, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(78, "XIRQ10", 0, - 78, UNIPHIER_PIN_DRV_4_8, + 78, UNIPHIER_PIN_DRV_1BIT, 78, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(79, "XIRQ11", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 79, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(80, "XIRQ12", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 80, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(81, "XIRQ13", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 81, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(82, "XIRQ14", 0, - 82, UNIPHIER_PIN_DRV_4_8, + 82, UNIPHIER_PIN_DRV_1BIT, 82, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(83, "XIRQ15", 0, - 83, UNIPHIER_PIN_DRV_4_8, + 83, UNIPHIER_PIN_DRV_1BIT, 83, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(84, "XIRQ16", 0, - 84, UNIPHIER_PIN_DRV_4_8, + 84, UNIPHIER_PIN_DRV_1BIT, 84, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(85, "XIRQ17", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 85, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(86, "XIRQ18", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 86, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(87, "XIRQ19", 0, - 87, UNIPHIER_PIN_DRV_4_8, + 87, UNIPHIER_PIN_DRV_1BIT, 87, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(88, "XIRQ20", 0, - 88, UNIPHIER_PIN_DRV_4_8, + 88, UNIPHIER_PIN_DRV_1BIT, 88, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(89, "PORT00", 0, - 89, UNIPHIER_PIN_DRV_4_8, + 89, UNIPHIER_PIN_DRV_1BIT, 89, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(90, "PORT01", 0, - 90, UNIPHIER_PIN_DRV_4_8, + 90, UNIPHIER_PIN_DRV_1BIT, 90, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(91, "PORT02", 0, - 91, UNIPHIER_PIN_DRV_4_8, + 91, UNIPHIER_PIN_DRV_1BIT, 91, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(92, "PORT03", 0, - 92, UNIPHIER_PIN_DRV_4_8, + 92, UNIPHIER_PIN_DRV_1BIT, 92, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(93, "PORT04", 0, - 93, UNIPHIER_PIN_DRV_4_8, + 93, UNIPHIER_PIN_DRV_1BIT, 93, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(94, "PORT05", 0, - 94, UNIPHIER_PIN_DRV_4_8, + 94, UNIPHIER_PIN_DRV_1BIT, 94, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(95, "PORT06", 0, - 95, UNIPHIER_PIN_DRV_4_8, + 95, UNIPHIER_PIN_DRV_1BIT, 95, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(96, "PORT07", 0, - 96, UNIPHIER_PIN_DRV_4_8, + 96, UNIPHIER_PIN_DRV_1BIT, 96, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(97, "PORT10", 0, - 97, UNIPHIER_PIN_DRV_4_8, + 97, UNIPHIER_PIN_DRV_1BIT, 97, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(98, "PORT11", 0, - 98, UNIPHIER_PIN_DRV_4_8, + 98, UNIPHIER_PIN_DRV_1BIT, 98, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(99, "PORT12", 0, - 99, UNIPHIER_PIN_DRV_4_8, + 99, UNIPHIER_PIN_DRV_1BIT, 99, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(100, "PORT13", 0, - 100, UNIPHIER_PIN_DRV_4_8, + 100, UNIPHIER_PIN_DRV_1BIT, 100, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(101, "PORT14", 0, - 101, UNIPHIER_PIN_DRV_4_8, + 101, UNIPHIER_PIN_DRV_1BIT, 101, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(102, "PORT15", 0, - 102, UNIPHIER_PIN_DRV_4_8, + 102, UNIPHIER_PIN_DRV_1BIT, 102, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(103, "PORT16", 0, - 103, UNIPHIER_PIN_DRV_4_8, + 103, UNIPHIER_PIN_DRV_1BIT, 103, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(104, "PORT17", 0, - 104, UNIPHIER_PIN_DRV_4_8, + 104, UNIPHIER_PIN_DRV_1BIT, 104, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(105, "T0HPD", 0, - 105, UNIPHIER_PIN_DRV_4_8, + 105, UNIPHIER_PIN_DRV_1BIT, 105, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(106, "T1HPD", 0, - 106, UNIPHIER_PIN_DRV_4_8, + 106, UNIPHIER_PIN_DRV_1BIT, 106, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(107, "R0HPD", 0, - 107, UNIPHIER_PIN_DRV_4_8, + 107, UNIPHIER_PIN_DRV_1BIT, 107, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(108, "R1HPD", 0, - 108, UNIPHIER_PIN_DRV_4_8, + 108, UNIPHIER_PIN_DRV_1BIT, 108, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(109, "XPERST", 0, - 109, UNIPHIER_PIN_DRV_4_8, + 109, UNIPHIER_PIN_DRV_1BIT, 109, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(110, "XPEWAKE", 0, - 110, UNIPHIER_PIN_DRV_4_8, + 110, UNIPHIER_PIN_DRV_1BIT, 110, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(111, "XPECLKRQ", 0, - 111, UNIPHIER_PIN_DRV_4_8, + 111, UNIPHIER_PIN_DRV_1BIT, 111, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(112, "SDA0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 112, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(113, "SCL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 113, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(114, "SDA1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 114, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(115, "SCL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 115, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(116, "SDA2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 116, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(117, "SCL2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 117, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(118, "SDA3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 118, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(119, "SCL3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 119, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(120, "SPISYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 120, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(121, "SPISCLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 121, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(122, "SPITXD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 122, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(123, "SPIRXD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 123, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(124, "USB0VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 124, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(125, "USB0OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 125, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(126, "USB1VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 126, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(127, "USB1OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 127, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(128, "USB2VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 128, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(129, "USB2OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 129, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(130, "SMTRST0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 130, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(131, "SMTCMD0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 131, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(132, "SMTD0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 132, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(133, "SMTSEL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 133, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(134, "SMTCLK0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 134, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(135, "SMTRST1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 135, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(136, "SMTCMD1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 136, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(137, "SMTD1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 137, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(138, "SMTSEL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 138, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(139, "SMTCLK1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 139, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(140, "CH0CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 140, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(141, "CH0PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 141, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(142, "CH0VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 142, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(143, "CH0DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 143, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(144, "CH1CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 144, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(145, "CH1PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 145, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(146, "CH1VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 146, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(147, "CH1DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 147, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(148, "CH2CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 148, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(149, "CH2PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 149, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(150, "CH2VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 150, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(151, "CH2DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 151, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(152, "CH3CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 152, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(153, "CH3PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 153, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(154, "CH3VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 154, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(155, "CH3DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 155, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(156, "CH4CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 156, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(157, "CH4PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 157, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(158, "CH4VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 158, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(159, "CH4DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 159, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(160, "CH5CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 160, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(161, "CH5PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 161, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(162, "CH5VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 162, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(163, "CH5DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 163, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(164, "CH6CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 164, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(165, "CH6PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 165, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(166, "CH6VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 166, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(167, "CH6DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 167, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(168, "CH7CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 168, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(169, "CH7PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 169, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(170, "CH7VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 170, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(171, "CH7DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 171, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(172, "AI1ADCCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 172, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(173, "AI1BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 173, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(174, "AI1LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 174, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(175, "AI1D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 175, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(176, "AI1D1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 176, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(177, "AI1D2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 177, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(178, "AI1D3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 178, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(179, "AI2ADCCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 179, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(180, "AI2BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 180, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(181, "AI2LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 181, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(182, "AI2D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 182, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(183, "AI2D1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 183, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(184, "AI2D2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 184, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(185, "AI2D3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 185, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(186, "AI3ADCCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 186, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(187, "AI3BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 187, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(188, "AI3LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 188, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(189, "AI3D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 189, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(190, "AO1IEC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 190, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(191, "AO1DACCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 191, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(192, "AO1BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 192, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(193, "AO1LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 193, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(194, "AO1D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 194, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(195, "AO1D1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 195, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(196, "AO1D2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 196, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(197, "AO1D3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 197, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(198, "AO2IEC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 198, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(199, "AO2DACCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 199, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(200, "AO2BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 200, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(201, "AO2LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 201, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(202, "AO2D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 202, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(203, "AO2D1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 203, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(204, "AO2D2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 204, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(205, "AO2D3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 205, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(206, "AO3DACCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 206, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(207, "AO3BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 207, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(208, "AO3LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 208, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(209, "AO3DMIX", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 209, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(210, "AO4DACCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 210, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(211, "AO4BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 211, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(212, "AO4LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 212, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(213, "AO4DMIX", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 213, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(214, "VI1CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 214, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(215, "VI1C0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 215, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(216, "VI1C1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 216, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(217, "VI1C2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 217, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(218, "VI1C3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 218, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(219, "VI1C4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 219, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(220, "VI1C5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 220, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(221, "VI1C6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 221, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(222, "VI1C7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 222, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(223, "VI1C8", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 223, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(224, "VI1C9", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 224, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(225, "VI1Y0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 225, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(226, "VI1Y1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 226, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(227, "VI1Y2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 227, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(228, "VI1Y3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 228, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(229, "VI1Y4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 229, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(230, "VI1Y5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 230, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(231, "VI1Y6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 231, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(232, "VI1Y7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 232, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(233, "VI1Y8", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 233, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(234, "VI1Y9", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 234, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(235, "VI1DE", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 235, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(236, "VI1HSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 236, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(237, "VI1VSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 237, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(238, "VO1CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 238, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(239, "VO1D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 239, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(240, "VO1D1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 240, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(241, "VO1D2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 241, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(242, "VO1D3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 242, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(243, "VO1D4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 243, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(244, "VO1D5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 244, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(245, "VO1D6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 245, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(246, "VO1D7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 246, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(247, "SDCD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 247, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(248, "SDWP", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 248, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(249, "SDVOLC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 249, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(250, "SDCLK", UNIPHIER_PIN_IECTRL_NONE, - 40, UNIPHIER_PIN_DRV_8_12_16_20, + 10, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(251, "SDCMD", UNIPHIER_PIN_IECTRL_NONE, - 44, UNIPHIER_PIN_DRV_8_12_16_20, + 11, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(252, "SDDAT0", UNIPHIER_PIN_IECTRL_NONE, - 48, UNIPHIER_PIN_DRV_8_12_16_20, + 12, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(253, "SDDAT1", UNIPHIER_PIN_IECTRL_NONE, - 52, UNIPHIER_PIN_DRV_8_12_16_20, + 13, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(254, "SDDAT2", UNIPHIER_PIN_IECTRL_NONE, - 56, UNIPHIER_PIN_DRV_8_12_16_20, + 14, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(255, "SDDAT3", UNIPHIER_PIN_IECTRL_NONE, - 60, UNIPHIER_PIN_DRV_8_12_16_20, + 15, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), }; static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42}; -static const unsigned emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0}; +static const int emmc_muxvals[] = {0, 0, 0, 0, 0, 0, 0}; static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46}; -static const unsigned emmc_dat8_muxvals[] = {0, 0, 0, 0}; +static const int emmc_dat8_muxvals[] = {0, 0, 0, 0}; static const unsigned i2c0_pins[] = {112, 113}; -static const unsigned i2c0_muxvals[] = {0, 0}; +static const int i2c0_muxvals[] = {0, 0}; static const unsigned i2c1_pins[] = {114, 115}; -static const unsigned i2c1_muxvals[] = {0, 0}; +static const int i2c1_muxvals[] = {0, 0}; static const unsigned i2c2_pins[] = {116, 117}; -static const unsigned i2c2_muxvals[] = {0, 0}; +static const int i2c2_muxvals[] = {0, 0}; static const unsigned i2c3_pins[] = {118, 119}; -static const unsigned i2c3_muxvals[] = {0, 0}; +static const int i2c3_muxvals[] = {0, 0}; static const unsigned i2c5_pins[] = {87, 88}; -static const unsigned i2c5_muxvals[] = {2, 2}; +static const int i2c5_muxvals[] = {2, 2}; static const unsigned i2c5b_pins[] = {196, 197}; -static const unsigned i2c5b_muxvals[] = {2, 2}; +static const int i2c5b_muxvals[] = {2, 2}; static const unsigned i2c5c_pins[] = {215, 216}; -static const unsigned i2c5c_muxvals[] = {2, 2}; +static const int i2c5c_muxvals[] = {2, 2}; static const unsigned i2c6_pins[] = {101, 102}; -static const unsigned i2c6_muxvals[] = {2, 2}; +static const int i2c6_muxvals[] = {2, 2}; static const unsigned nand_pins[] = {19, 20, 21, 22, 23, 24, 25, 28, 29, 30, 31, 32, 33, 34, 35}; -static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0}; +static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned nand_cs1_pins[] = {26, 27}; -static const unsigned nand_cs1_muxvals[] = {0, 0}; +static const int nand_cs1_muxvals[] = {0, 0}; static const unsigned sd_pins[] = {250, 251, 252, 253, 254, 255, 256, 257, 258}; -static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned system_bus_pins[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17}; +static const int system_bus_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0}; +static const unsigned system_bus_cs0_pins[] = {105}; +static const int system_bus_cs0_muxvals[] = {1}; +static const unsigned system_bus_cs1_pins[] = {18}; +static const int system_bus_cs1_muxvals[] = {0}; +static const unsigned system_bus_cs2_pins[] = {106}; +static const int system_bus_cs2_muxvals[] = {1}; +static const unsigned system_bus_cs3_pins[] = {100}; +static const int system_bus_cs3_muxvals[] = {1}; +static const unsigned system_bus_cs4_pins[] = {101}; +static const int system_bus_cs4_muxvals[] = {1}; +static const unsigned system_bus_cs5_pins[] = {102}; +static const int system_bus_cs5_muxvals[] = {1}; +static const unsigned system_bus_cs6_pins[] = {69}; +static const int system_bus_cs6_muxvals[] = {5}; +static const unsigned system_bus_cs7_pins[] = {70}; +static const int system_bus_cs7_muxvals[] = {5}; static const unsigned uart0_pins[] = {47, 48}; -static const unsigned uart0_muxvals[] = {0, 0}; +static const int uart0_muxvals[] = {0, 0}; static const unsigned uart0b_pins[] = {227, 228}; -static const unsigned uart0b_muxvals[] = {3, 3}; +static const int uart0b_muxvals[] = {3, 3}; static const unsigned uart1_pins[] = {49, 50}; -static const unsigned uart1_muxvals[] = {0, 0}; +static const int uart1_muxvals[] = {0, 0}; static const unsigned uart2_pins[] = {51, 52}; -static const unsigned uart2_muxvals[] = {0, 0}; +static const int uart2_muxvals[] = {0, 0}; static const unsigned uart3_pins[] = {53, 54}; -static const unsigned uart3_muxvals[] = {0, 0}; +static const int uart3_muxvals[] = {0, 0}; static const unsigned usb0_pins[] = {124, 125}; -static const unsigned usb0_muxvals[] = {0, 0}; +static const int usb0_muxvals[] = {0, 0}; static const unsigned usb1_pins[] = {126, 127}; -static const unsigned usb1_muxvals[] = {0, 0}; +static const int usb1_muxvals[] = {0, 0}; static const unsigned usb2_pins[] = {128, 129}; -static const unsigned usb2_muxvals[] = {0, 0}; +static const int usb2_muxvals[] = {0, 0}; static const unsigned port_range0_pins[] = { 89, 90, 91, 92, 93, 94, 95, 96, /* PORT0x */ 97, 98, 99, 100, 101, 102, 103, 104, /* PORT1x */ @@ -853,7 +870,7 @@ static const unsigned port_range0_pins[] = { 179, 180, 181, 182, 186, 187, 188, 189, /* PORT13x */ 4, 5, 6, 7, 8, 9, 10, 11, /* PORT14x */ }; -static const unsigned port_range0_muxvals[] = { +static const int port_range0_muxvals[] = { 15, 15, 15, 15, 15, 15, 15, 15, /* PORT0x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT1x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT2x */ @@ -886,7 +903,7 @@ static const unsigned port_range1_pins[] = { 105, 106, 18, 27, 36, 128, 132, 137, /* PORT29x */ 183, 184, 185, 84, 47, 48, 51, 52, /* PORT30x */ }; -static const unsigned port_range1_muxvals[] = { +static const int port_range1_muxvals[] = { 15, 15, 15, /* PORT175-177 */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT18x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT19x */ @@ -907,7 +924,7 @@ static const unsigned xirq_pins[] = { 76, 77, 78, 79, 80, 81, 82, 83, /* XIRQ8-15 */ 84, 85, 86, 87, 88, /* XIRQ16-20 */ }; -static const unsigned xirq_muxvals[] = { +static const int xirq_muxvals[] = { 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ0-7 */ 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ8-15 */ 14, 14, 14, 14, 14, /* XIRQ16-20 */ @@ -915,11 +932,11 @@ static const unsigned xirq_muxvals[] = { static const unsigned xirq_alternatives_pins[] = { 91, 92, 239, 144, 240, 156, 241, 106, 128, }; -static const unsigned xirq_alternatives_muxvals[] = { +static const int xirq_alternatives_muxvals[] = { 14, 14, 14, 14, 14, 14, 14, 14, 14, }; -static const struct uniphier_pinctrl_group ph1_pro5_groups[] = { +static const struct uniphier_pinctrl_group uniphier_pro5_groups[] = { UNIPHIER_PINCTRL_GROUP(nand), UNIPHIER_PINCTRL_GROUP(nand_cs1), UNIPHIER_PINCTRL_GROUP(emmc), @@ -933,6 +950,15 @@ static const struct uniphier_pinctrl_group ph1_pro5_groups[] = { UNIPHIER_PINCTRL_GROUP(i2c5c), UNIPHIER_PINCTRL_GROUP(i2c6), UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs0), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(system_bus_cs2), + UNIPHIER_PINCTRL_GROUP(system_bus_cs3), + UNIPHIER_PINCTRL_GROUP(system_bus_cs4), + UNIPHIER_PINCTRL_GROUP(system_bus_cs5), + UNIPHIER_PINCTRL_GROUP(system_bus_cs6), + UNIPHIER_PINCTRL_GROUP(system_bus_cs7), UNIPHIER_PINCTRL_GROUP(uart0), UNIPHIER_PINCTRL_GROUP(uart0b), UNIPHIER_PINCTRL_GROUP(uart1), @@ -1213,6 +1239,15 @@ static const char * const i2c5_groups[] = {"i2c5", "i2c5b", "i2c5c"}; static const char * const i2c6_groups[] = {"i2c6"}; static const char * const nand_groups[] = {"nand", "nand_cs1"}; static const char * const sd_groups[] = {"sd"}; +static const char * const system_bus_groups[] = {"system_bus", + "system_bus_cs0", + "system_bus_cs1", + "system_bus_cs2", + "system_bus_cs3", + "system_bus_cs4", + "system_bus_cs5", + "system_bus_cs6", + "system_bus_cs7"}; static const char * const uart0_groups[] = {"uart0", "uart0b"}; static const char * const uart1_groups[] = {"uart1"}; static const char * const uart2_groups[] = {"uart2"}; @@ -1291,7 +1326,7 @@ static const char * const xirq_groups[] = { "xirq18b", "xirq18c", "xirq19b", "xirq20b", }; -static const struct uniphier_pinmux_function ph1_pro5_functions[] = { +static const struct uniphier_pinmux_function uniphier_pro5_functions[] = { UNIPHIER_PINMUX_FUNCTION(emmc), UNIPHIER_PINMUX_FUNCTION(i2c0), UNIPHIER_PINMUX_FUNCTION(i2c1), @@ -1301,6 +1336,7 @@ static const struct uniphier_pinmux_function ph1_pro5_functions[] = { UNIPHIER_PINMUX_FUNCTION(i2c6), UNIPHIER_PINMUX_FUNCTION(nand), UNIPHIER_PINMUX_FUNCTION(sd), + UNIPHIER_PINMUX_FUNCTION(system_bus), UNIPHIER_PINMUX_FUNCTION(uart0), UNIPHIER_PINMUX_FUNCTION(uart1), UNIPHIER_PINMUX_FUNCTION(uart2), @@ -1312,43 +1348,36 @@ static const struct uniphier_pinmux_function ph1_pro5_functions[] = { UNIPHIER_PINMUX_FUNCTION(xirq), }; -static struct uniphier_pinctrl_socdata ph1_pro5_pindata = { - .groups = ph1_pro5_groups, - .groups_count = ARRAY_SIZE(ph1_pro5_groups), - .functions = ph1_pro5_functions, - .functions_count = ARRAY_SIZE(ph1_pro5_functions), - .mux_bits = 4, - .reg_stride = 8, - .load_pinctrl = true, -}; - -static struct pinctrl_desc ph1_pro5_pinctrl_desc = { - .name = DRIVER_NAME, - .pins = ph1_pro5_pins, - .npins = ARRAY_SIZE(ph1_pro5_pins), - .owner = THIS_MODULE, +static struct uniphier_pinctrl_socdata uniphier_pro5_pindata = { + .pins = uniphier_pro5_pins, + .npins = ARRAY_SIZE(uniphier_pro5_pins), + .groups = uniphier_pro5_groups, + .groups_count = ARRAY_SIZE(uniphier_pro5_groups), + .functions = uniphier_pro5_functions, + .functions_count = ARRAY_SIZE(uniphier_pro5_functions), + .caps = UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE, }; -static int ph1_pro5_pinctrl_probe(struct platform_device *pdev) +static int uniphier_pro5_pinctrl_probe(struct platform_device *pdev) { - return uniphier_pinctrl_probe(pdev, &ph1_pro5_pinctrl_desc, - &ph1_pro5_pindata); + return uniphier_pinctrl_probe(pdev, &uniphier_pro5_pindata); } -static const struct of_device_id ph1_pro5_pinctrl_match[] = { +static const struct of_device_id uniphier_pro5_pinctrl_match[] = { + { .compatible = "socionext,uniphier-pro5-pinctrl" }, { .compatible = "socionext,ph1-pro5-pinctrl" }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, ph1_pro5_pinctrl_match); +MODULE_DEVICE_TABLE(of, uniphier_pro5_pinctrl_match); -static struct platform_driver ph1_pro5_pinctrl_driver = { - .probe = ph1_pro5_pinctrl_probe, +static struct platform_driver uniphier_pro5_pinctrl_driver = { + .probe = uniphier_pro5_pinctrl_probe, .driver = { - .name = DRIVER_NAME, - .of_match_table = ph1_pro5_pinctrl_match, + .name = "uniphier-pro5-pinctrl", + .of_match_table = uniphier_pro5_pinctrl_match, }, }; -module_platform_driver(ph1_pro5_pinctrl_driver); +module_platform_driver(uniphier_pro5_pinctrl_driver); MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); MODULE_DESCRIPTION("UniPhier PH1-Pro5 pinctrl driver"); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c index e868030ff31c..85ca5e2d8a9c 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c @@ -19,760 +19,776 @@ #include "pinctrl-uniphier.h" -#define DRIVER_NAME "proxstream2-pinctrl" - -static const struct pinctrl_pin_desc proxstream2_pins[] = { +static const struct pinctrl_pin_desc uniphier_pxs2_pins[] = { UNIPHIER_PINCTRL_PIN(0, "ED0", UNIPHIER_PIN_IECTRL_NONE, - 0, UNIPHIER_PIN_DRV_4_8, + 0, UNIPHIER_PIN_DRV_1BIT, 0, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(1, "ED1", UNIPHIER_PIN_IECTRL_NONE, - 1, UNIPHIER_PIN_DRV_4_8, + 1, UNIPHIER_PIN_DRV_1BIT, 1, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(2, "ED2", UNIPHIER_PIN_IECTRL_NONE, - 2, UNIPHIER_PIN_DRV_4_8, + 2, UNIPHIER_PIN_DRV_1BIT, 2, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(3, "ED3", UNIPHIER_PIN_IECTRL_NONE, - 3, UNIPHIER_PIN_DRV_4_8, + 3, UNIPHIER_PIN_DRV_1BIT, 3, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(4, "ED4", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_4_8, + 4, UNIPHIER_PIN_DRV_1BIT, 4, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(5, "ED5", UNIPHIER_PIN_IECTRL_NONE, - 5, UNIPHIER_PIN_DRV_4_8, + 5, UNIPHIER_PIN_DRV_1BIT, 5, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(6, "ED6", UNIPHIER_PIN_IECTRL_NONE, - 6, UNIPHIER_PIN_DRV_4_8, + 6, UNIPHIER_PIN_DRV_1BIT, 6, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(7, "ED7", UNIPHIER_PIN_IECTRL_NONE, - 7, UNIPHIER_PIN_DRV_4_8, + 7, UNIPHIER_PIN_DRV_1BIT, 7, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(8, "XERWE0", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_4_8, + 8, UNIPHIER_PIN_DRV_1BIT, 8, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(9, "XERWE1", UNIPHIER_PIN_IECTRL_NONE, - 9, UNIPHIER_PIN_DRV_4_8, + 9, UNIPHIER_PIN_DRV_1BIT, 9, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(10, "ERXW", UNIPHIER_PIN_IECTRL_NONE, - 10, UNIPHIER_PIN_DRV_4_8, + 10, UNIPHIER_PIN_DRV_1BIT, 10, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(11, "ES0", UNIPHIER_PIN_IECTRL_NONE, - 11, UNIPHIER_PIN_DRV_4_8, + 11, UNIPHIER_PIN_DRV_1BIT, 11, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(12, "ES1", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_4_8, + 12, UNIPHIER_PIN_DRV_1BIT, 12, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(13, "ES2", UNIPHIER_PIN_IECTRL_NONE, - 13, UNIPHIER_PIN_DRV_4_8, + 13, UNIPHIER_PIN_DRV_1BIT, 13, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(14, "XECS1", UNIPHIER_PIN_IECTRL_NONE, - 14, UNIPHIER_PIN_DRV_4_8, + 14, UNIPHIER_PIN_DRV_1BIT, 14, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(15, "SMTRST0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 15, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(16, "SMTCMD0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 16, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(17, "SMTD0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 17, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(18, "SMTSEL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 18, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(19, "SMTCLK0CG", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 19, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(20, "SMTDET0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 20, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(21, "SMTRST1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 21, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(22, "SMTCMD1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 22, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(23, "SMTD1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 23, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(24, "SMTSEL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 24, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(25, "SMTCLK1CG", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 25, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(26, "SMTDET1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 26, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(27, "XIRQ18", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 27, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(28, "XIRQ19", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 28, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(29, "XIRQ20", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 29, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(30, "XNFRE", UNIPHIER_PIN_IECTRL_NONE, - 30, UNIPHIER_PIN_DRV_4_8, + 30, UNIPHIER_PIN_DRV_1BIT, 30, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(31, "XNFWE", UNIPHIER_PIN_IECTRL_NONE, - 31, UNIPHIER_PIN_DRV_4_8, + 31, UNIPHIER_PIN_DRV_1BIT, 31, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(32, "NFALE", UNIPHIER_PIN_IECTRL_NONE, - 32, UNIPHIER_PIN_DRV_4_8, + 32, UNIPHIER_PIN_DRV_1BIT, 32, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(33, "NFCLE", UNIPHIER_PIN_IECTRL_NONE, - 33, UNIPHIER_PIN_DRV_4_8, + 33, UNIPHIER_PIN_DRV_1BIT, 33, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(34, "XNFWP", UNIPHIER_PIN_IECTRL_NONE, - 34, UNIPHIER_PIN_DRV_4_8, + 34, UNIPHIER_PIN_DRV_1BIT, 34, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(35, "XNFCE0", UNIPHIER_PIN_IECTRL_NONE, - 35, UNIPHIER_PIN_DRV_4_8, + 35, UNIPHIER_PIN_DRV_1BIT, 35, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(36, "NFRYBY0", UNIPHIER_PIN_IECTRL_NONE, - 36, UNIPHIER_PIN_DRV_4_8, + 36, UNIPHIER_PIN_DRV_1BIT, 36, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(37, "XNFCE1", UNIPHIER_PIN_IECTRL_NONE, - 37, UNIPHIER_PIN_DRV_4_8, + 37, UNIPHIER_PIN_DRV_1BIT, 37, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(38, "NFRYBY1", UNIPHIER_PIN_IECTRL_NONE, - 38, UNIPHIER_PIN_DRV_4_8, + 38, UNIPHIER_PIN_DRV_1BIT, 38, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(39, "NFD0", UNIPHIER_PIN_IECTRL_NONE, - 39, UNIPHIER_PIN_DRV_4_8, + 39, UNIPHIER_PIN_DRV_1BIT, 39, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(40, "NFD1", UNIPHIER_PIN_IECTRL_NONE, - 40, UNIPHIER_PIN_DRV_4_8, + 40, UNIPHIER_PIN_DRV_1BIT, 40, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(41, "NFD2", UNIPHIER_PIN_IECTRL_NONE, - 41, UNIPHIER_PIN_DRV_4_8, + 41, UNIPHIER_PIN_DRV_1BIT, 41, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(42, "NFD3", UNIPHIER_PIN_IECTRL_NONE, - 42, UNIPHIER_PIN_DRV_4_8, + 42, UNIPHIER_PIN_DRV_1BIT, 42, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(43, "NFD4", UNIPHIER_PIN_IECTRL_NONE, - 43, UNIPHIER_PIN_DRV_4_8, + 43, UNIPHIER_PIN_DRV_1BIT, 43, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(44, "NFD5", UNIPHIER_PIN_IECTRL_NONE, - 44, UNIPHIER_PIN_DRV_4_8, + 44, UNIPHIER_PIN_DRV_1BIT, 44, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(45, "NFD6", UNIPHIER_PIN_IECTRL_NONE, - 45, UNIPHIER_PIN_DRV_4_8, + 45, UNIPHIER_PIN_DRV_1BIT, 45, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(46, "NFD7", UNIPHIER_PIN_IECTRL_NONE, - 46, UNIPHIER_PIN_DRV_4_8, + 46, UNIPHIER_PIN_DRV_1BIT, 46, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(47, "SDCLK", UNIPHIER_PIN_IECTRL_NONE, - 0, UNIPHIER_PIN_DRV_8_12_16_20, + 0, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(48, "SDCMD", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_8_12_16_20, + 1, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(49, "SDDAT0", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_8_12_16_20, + 2, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(50, "SDDAT1", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_8_12_16_20, + 3, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(51, "SDDAT2", UNIPHIER_PIN_IECTRL_NONE, - 16, UNIPHIER_PIN_DRV_8_12_16_20, + 4, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(52, "SDDAT3", UNIPHIER_PIN_IECTRL_NONE, - 20, UNIPHIER_PIN_DRV_8_12_16_20, + 5, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_UP_FIXED), UNIPHIER_PINCTRL_PIN(53, "SDCD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 53, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(54, "SDWP", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 54, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(55, "SDVOLC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 55, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(56, "USB0VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 56, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(57, "USB0OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 57, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(58, "USB1VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 58, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(59, "USB1OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 59, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(60, "USB2VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 60, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(61, "USB2OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 61, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(62, "USB3VBUS", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 62, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(63, "USB3OD", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 63, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(64, "CH0CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 64, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(65, "CH0PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 65, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(66, "CH0VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 66, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(67, "CH0DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 67, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(68, "CH1CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 68, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(69, "CH1PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 69, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(70, "CH1VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 70, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(71, "CH1DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 71, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(72, "XIRQ9", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 72, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(73, "XIRQ10", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 73, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(74, "XIRQ16", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 74, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(75, "CH4CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 75, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(76, "CH4PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 76, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(77, "CH4VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 77, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(78, "CH4DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 78, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(79, "CH5CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 79, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(80, "CH5PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 80, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(81, "CH5VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 81, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(82, "CH5DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 82, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(83, "CH6CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 83, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(84, "CH6PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 84, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(85, "CH6VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 85, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(86, "CH6DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 86, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(87, "STS0CLKO", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 87, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(88, "STS0SYNCO", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 88, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(89, "STS0VALO", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 89, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(90, "STS0DATAO", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 90, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(91, "XIRQ17", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 91, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(92, "PORT163", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 92, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(93, "PORT165", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 93, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(94, "PORT166", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 94, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(95, "PORT132", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 95, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(96, "PORT133", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 96, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(97, "AO2IEC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 97, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(98, "AI2ADCCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 98, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(99, "AI2BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 99, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(100, "AI2LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 100, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(101, "AI2D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 101, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(102, "AI2D1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 102, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(103, "AI2D2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 103, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(104, "AI2D3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 104, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(105, "AO3DACCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 105, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(106, "AO3BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 106, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(107, "AO3LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 107, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(108, "AO3DMIX", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 108, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(109, "SDA0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 109, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(110, "SCL0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 110, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(111, "SDA1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 111, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(112, "SCL1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 112, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(113, "TXD2", 0, - 113, UNIPHIER_PIN_DRV_4_8, + 113, UNIPHIER_PIN_DRV_1BIT, 113, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(114, "RXD2", 0, - 114, UNIPHIER_PIN_DRV_4_8, + 114, UNIPHIER_PIN_DRV_1BIT, 114, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(115, "TXD1", 0, - 115, UNIPHIER_PIN_DRV_4_8, + 115, UNIPHIER_PIN_DRV_1BIT, 115, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(116, "RXD1", 0, - 116, UNIPHIER_PIN_DRV_4_8, + 116, UNIPHIER_PIN_DRV_1BIT, 116, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(117, "PORT190", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 117, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(118, "VI1HSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 118, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(119, "VI1VSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 119, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(120, "VI1DE", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 120, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(121, "XIRQ3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 121, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(122, "XIRQ4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 122, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(123, "VI1G2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 123, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(124, "VI1G3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 124, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(125, "VI1G4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 125, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(126, "VI1G5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 126, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(127, "VI1G6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 127, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(128, "VI1G7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 128, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(129, "VI1G8", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 129, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(130, "VI1G9", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 130, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(131, "VI1CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 131, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(132, "PORT05", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 132, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(133, "PORT06", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 133, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(134, "VI1R2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 134, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(135, "VI1R3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 135, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(136, "VI1R4", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 136, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(137, "VI1R5", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 137, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(138, "VI1R6", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 138, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(139, "VI1R7", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 139, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(140, "VI1R8", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 140, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(141, "VI1R9", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 141, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(142, "LPST", UNIPHIER_PIN_IECTRL_NONE, - 142, UNIPHIER_PIN_DRV_4_8, + 142, UNIPHIER_PIN_DRV_1BIT, 142, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(143, "MDC", 0, - 143, UNIPHIER_PIN_DRV_4_8, + 143, UNIPHIER_PIN_DRV_1BIT, 143, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(144, "MDIO", 0, - 144, UNIPHIER_PIN_DRV_4_8, + 144, UNIPHIER_PIN_DRV_1BIT, 144, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(145, "MDIO_INTL", 0, - 145, UNIPHIER_PIN_DRV_4_8, + 145, UNIPHIER_PIN_DRV_1BIT, 145, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(146, "PHYRSTL", 0, - 146, UNIPHIER_PIN_DRV_4_8, + 146, UNIPHIER_PIN_DRV_1BIT, 146, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(147, "RGMII_RXCLK", 0, - 147, UNIPHIER_PIN_DRV_4_8, + 147, UNIPHIER_PIN_DRV_1BIT, 147, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(148, "RGMII_RXD0", 0, - 148, UNIPHIER_PIN_DRV_4_8, + 148, UNIPHIER_PIN_DRV_1BIT, 148, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(149, "RGMII_RXD1", 0, - 149, UNIPHIER_PIN_DRV_4_8, + 149, UNIPHIER_PIN_DRV_1BIT, 149, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(150, "RGMII_RXD2", 0, - 150, UNIPHIER_PIN_DRV_4_8, + 150, UNIPHIER_PIN_DRV_1BIT, 150, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(151, "RGMII_RXD3", 0, - 151, UNIPHIER_PIN_DRV_4_8, + 151, UNIPHIER_PIN_DRV_1BIT, 151, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(152, "RGMII_RXCTL", 0, - 152, UNIPHIER_PIN_DRV_4_8, + 152, UNIPHIER_PIN_DRV_1BIT, 152, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(153, "RGMII_TXCLK", 0, - 153, UNIPHIER_PIN_DRV_4_8, + 153, UNIPHIER_PIN_DRV_1BIT, 153, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(154, "RGMII_TXD0", 0, - 154, UNIPHIER_PIN_DRV_4_8, + 154, UNIPHIER_PIN_DRV_1BIT, 154, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(155, "RGMII_TXD1", 0, - 155, UNIPHIER_PIN_DRV_4_8, + 155, UNIPHIER_PIN_DRV_1BIT, 155, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(156, "RGMII_TXD2", 0, - 156, UNIPHIER_PIN_DRV_4_8, + 156, UNIPHIER_PIN_DRV_1BIT, 156, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(157, "RGMII_TXD3", 0, - 157, UNIPHIER_PIN_DRV_4_8, + 157, UNIPHIER_PIN_DRV_1BIT, 157, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(158, "RGMII_TXCTL", 0, - 158, UNIPHIER_PIN_DRV_4_8, + 158, UNIPHIER_PIN_DRV_1BIT, 158, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(159, "SDA3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 159, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(160, "SCL3", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 160, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(161, "AI1ADCCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 161, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(162, "AI1BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 162, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(163, "CH2CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 163, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(164, "CH2PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 164, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(165, "CH2VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 165, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(166, "CH2DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 166, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(167, "CH3CLK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 167, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(168, "CH3PSYNC", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 168, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(169, "CH3VAL", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 169, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(170, "CH3DATA", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 170, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(171, "SDA2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 171, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(172, "SCL2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 172, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(173, "AI1LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 173, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(174, "AI1D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 174, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(175, "AO2LRCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 175, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(176, "AO2D0", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 176, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(177, "AO2DACCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 177, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(178, "AO2BCK", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 178, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(179, "PORT222", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 179, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(180, "PORT223", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 180, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(181, "PORT224", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 181, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(182, "PORT225", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 182, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(183, "PORT226", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 183, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(184, "PORT227", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 184, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(185, "PORT230", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 185, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(186, "FANPWM", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 186, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(187, "HRDDCSDA0", 0, - 187, UNIPHIER_PIN_DRV_4_8, + 187, UNIPHIER_PIN_DRV_1BIT, 187, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(188, "HRDDCSCL0", 0, - 188, UNIPHIER_PIN_DRV_4_8, + 188, UNIPHIER_PIN_DRV_1BIT, 188, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(189, "HRDDCSDA1", 0, - 189, UNIPHIER_PIN_DRV_4_8, + 189, UNIPHIER_PIN_DRV_1BIT, 189, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(190, "HRDDCSCL1", 0, - 190, UNIPHIER_PIN_DRV_4_8, + 190, UNIPHIER_PIN_DRV_1BIT, 190, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(191, "HTDDCSDA0", 0, - 191, UNIPHIER_PIN_DRV_4_8, + 191, UNIPHIER_PIN_DRV_1BIT, 191, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(192, "HTDDCSCL0", 0, - 192, UNIPHIER_PIN_DRV_4_8, + 192, UNIPHIER_PIN_DRV_1BIT, 192, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(193, "HTDDCSDA1", 0, - 193, UNIPHIER_PIN_DRV_4_8, + 193, UNIPHIER_PIN_DRV_1BIT, 193, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(194, "HTDDCSCL1", 0, - 194, UNIPHIER_PIN_DRV_4_8, + 194, UNIPHIER_PIN_DRV_1BIT, 194, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(195, "PORT241", 0, - 195, UNIPHIER_PIN_DRV_4_8, + 195, UNIPHIER_PIN_DRV_1BIT, 195, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(196, "PORT242", 0, - 196, UNIPHIER_PIN_DRV_4_8, + 196, UNIPHIER_PIN_DRV_1BIT, 196, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(197, "PORT243", 0, - 197, UNIPHIER_PIN_DRV_4_8, + 197, UNIPHIER_PIN_DRV_1BIT, 197, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(198, "MVSYNC", 0, - 198, UNIPHIER_PIN_DRV_4_8, + 198, UNIPHIER_PIN_DRV_1BIT, 198, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(199, "SPISYNC0", UNIPHIER_PIN_IECTRL_NONE, - 199, UNIPHIER_PIN_DRV_4_8, + 199, UNIPHIER_PIN_DRV_1BIT, 199, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(200, "SPISCLK0", UNIPHIER_PIN_IECTRL_NONE, - 200, UNIPHIER_PIN_DRV_4_8, + 200, UNIPHIER_PIN_DRV_1BIT, 200, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(201, "SPITXD0", UNIPHIER_PIN_IECTRL_NONE, - 201, UNIPHIER_PIN_DRV_4_8, + 201, UNIPHIER_PIN_DRV_1BIT, 201, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(202, "SPIRXD0", UNIPHIER_PIN_IECTRL_NONE, - 202, UNIPHIER_PIN_DRV_4_8, + 202, UNIPHIER_PIN_DRV_1BIT, 202, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(203, "CK54EXI", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 203, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(204, "AEXCKA1", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 204, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(205, "AEXCKA2", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 205, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(206, "CK27EXI", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_8, + -1, UNIPHIER_PIN_DRV_FIXED8, 206, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(207, "STCDIN", 0, - 207, UNIPHIER_PIN_DRV_4_8, + 207, UNIPHIER_PIN_DRV_1BIT, 207, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(208, "PHSYNI", 0, - 208, UNIPHIER_PIN_DRV_4_8, + 208, UNIPHIER_PIN_DRV_1BIT, 208, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(209, "PVSYNI", 0, - 209, UNIPHIER_PIN_DRV_4_8, + 209, UNIPHIER_PIN_DRV_1BIT, 209, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(210, "MVSYN", UNIPHIER_PIN_IECTRL_NONE, - 210, UNIPHIER_PIN_DRV_4_8, + 210, UNIPHIER_PIN_DRV_1BIT, 210, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(211, "STCV", UNIPHIER_PIN_IECTRL_NONE, - 211, UNIPHIER_PIN_DRV_4_8, + 211, UNIPHIER_PIN_DRV_1BIT, 211, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(212, "PORT262", UNIPHIER_PIN_IECTRL_NONE, - 212, UNIPHIER_PIN_DRV_4_8, + 212, UNIPHIER_PIN_DRV_1BIT, 212, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(213, "USB0VBUS_IRQ", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 213, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(214, "USB1VBUS_IRQ", UNIPHIER_PIN_IECTRL_NONE, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 214, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(215, "PORT265", UNIPHIER_PIN_IECTRL_NONE, - 215, UNIPHIER_PIN_DRV_4_8, + 215, UNIPHIER_PIN_DRV_1BIT, 215, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(216, "CK25O", 0, - 216, UNIPHIER_PIN_DRV_4_8, + 216, UNIPHIER_PIN_DRV_1BIT, 216, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(217, "TXD0", 0, - 217, UNIPHIER_PIN_DRV_4_8, + 217, UNIPHIER_PIN_DRV_1BIT, 217, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(218, "RXD0", 0, - 218, UNIPHIER_PIN_DRV_4_8, + 218, UNIPHIER_PIN_DRV_1BIT, 218, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(219, "TXD3", 0, - 219, UNIPHIER_PIN_DRV_4_8, + 219, UNIPHIER_PIN_DRV_1BIT, 219, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(220, "RXD3", 0, - 220, UNIPHIER_PIN_DRV_4_8, + 220, UNIPHIER_PIN_DRV_1BIT, 220, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(221, "PORT273", 0, - 221, UNIPHIER_PIN_DRV_4_8, + 221, UNIPHIER_PIN_DRV_1BIT, 221, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(222, "STCDOUTC", 0, - 222, UNIPHIER_PIN_DRV_4_8, + 222, UNIPHIER_PIN_DRV_1BIT, 222, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(223, "PORT274", 0, - 223, UNIPHIER_PIN_DRV_4_8, + 223, UNIPHIER_PIN_DRV_1BIT, 223, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(224, "PORT275", 0, - 224, UNIPHIER_PIN_DRV_4_8, + 224, UNIPHIER_PIN_DRV_1BIT, 224, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(225, "PORT276", 0, - 225, UNIPHIER_PIN_DRV_4_8, + 225, UNIPHIER_PIN_DRV_1BIT, 225, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(226, "PORT277", 0, - 226, UNIPHIER_PIN_DRV_4_8, + 226, UNIPHIER_PIN_DRV_1BIT, 226, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(227, "PORT280", 0, - 227, UNIPHIER_PIN_DRV_4_8, + 227, UNIPHIER_PIN_DRV_1BIT, 227, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(228, "PORT281", 0, - 228, UNIPHIER_PIN_DRV_4_8, + 228, UNIPHIER_PIN_DRV_1BIT, 228, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(229, "PORT282", 0, - 229, UNIPHIER_PIN_DRV_4_8, + 229, UNIPHIER_PIN_DRV_1BIT, 229, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(230, "PORT283", 0, - 230, UNIPHIER_PIN_DRV_4_8, + 230, UNIPHIER_PIN_DRV_1BIT, 230, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(231, "PORT284", 0, - 231, UNIPHIER_PIN_DRV_4_8, + 231, UNIPHIER_PIN_DRV_1BIT, 231, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(232, "PORT285", 0, - 232, UNIPHIER_PIN_DRV_4_8, + 232, UNIPHIER_PIN_DRV_1BIT, 232, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(233, "T0HPD", 0, - 233, UNIPHIER_PIN_DRV_4_8, + 233, UNIPHIER_PIN_DRV_1BIT, 233, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(234, "T1HPD", 0, - 234, UNIPHIER_PIN_DRV_4_8, + 234, UNIPHIER_PIN_DRV_1BIT, 234, UNIPHIER_PIN_PULL_DOWN), }; static const unsigned emmc_pins[] = {36, 37, 38, 39, 40, 41, 42}; -static const unsigned emmc_muxvals[] = {9, 9, 9, 9, 9, 9, 9}; +static const int emmc_muxvals[] = {9, 9, 9, 9, 9, 9, 9}; static const unsigned emmc_dat8_pins[] = {43, 44, 45, 46}; -static const unsigned emmc_dat8_muxvals[] = {9, 9, 9, 9}; +static const int emmc_dat8_muxvals[] = {9, 9, 9, 9}; +static const unsigned ether_mii_pins[] = {143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, + 158, 159, 199, 200, 201, 202}; +static const int ether_mii_muxvals[] = {8, 8, 8, 8, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 12, 12, 12, 12}; +static const unsigned ether_rgmii_pins[] = {143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, + 157, 158}; +static const int ether_rgmii_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8}; +static const unsigned ether_rmii_pins[] = {143, 144, 145, 146, 147, 148, 149, + 150, 152, 154, 155, 158}; +static const int ether_rmii_muxvals[] = {8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9}; static const unsigned i2c0_pins[] = {109, 110}; -static const unsigned i2c0_muxvals[] = {8, 8}; +static const int i2c0_muxvals[] = {8, 8}; static const unsigned i2c1_pins[] = {111, 112}; -static const unsigned i2c1_muxvals[] = {8, 8}; +static const int i2c1_muxvals[] = {8, 8}; static const unsigned i2c2_pins[] = {171, 172}; -static const unsigned i2c2_muxvals[] = {8, 8}; +static const int i2c2_muxvals[] = {8, 8}; static const unsigned i2c3_pins[] = {159, 160}; -static const unsigned i2c3_muxvals[] = {8, 8}; +static const int i2c3_muxvals[] = {8, 8}; static const unsigned i2c5_pins[] = {183, 184}; -static const unsigned i2c5_muxvals[] = {11, 11}; +static const int i2c5_muxvals[] = {11, 11}; static const unsigned i2c6_pins[] = {185, 186}; -static const unsigned i2c6_muxvals[] = {11, 11}; +static const int i2c6_muxvals[] = {11, 11}; static const unsigned nand_pins[] = {30, 31, 32, 33, 34, 35, 36, 39, 40, 41, 42, 43, 44, 45, 46}; -static const unsigned nand_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8}; +static const int nand_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; static const unsigned nand_cs1_pins[] = {37, 38}; -static const unsigned nand_cs1_muxvals[] = {8, 8}; +static const int nand_cs1_muxvals[] = {8, 8}; static const unsigned sd_pins[] = {47, 48, 49, 50, 51, 52, 53, 54, 55}; -static const unsigned sd_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8}; +static const int sd_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8}; +static const unsigned system_bus_pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13}; +static const int system_bus_muxvals[] = {8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8}; +static const unsigned system_bus_cs1_pins[] = {14}; +static const int system_bus_cs1_muxvals[] = {8}; static const unsigned uart0_pins[] = {217, 218}; -static const unsigned uart0_muxvals[] = {8, 8}; +static const int uart0_muxvals[] = {8, 8}; static const unsigned uart0b_pins[] = {179, 180}; -static const unsigned uart0b_muxvals[] = {10, 10}; +static const int uart0b_muxvals[] = {10, 10}; static const unsigned uart1_pins[] = {115, 116}; -static const unsigned uart1_muxvals[] = {8, 8}; +static const int uart1_muxvals[] = {8, 8}; static const unsigned uart2_pins[] = {113, 114}; -static const unsigned uart2_muxvals[] = {8, 8}; +static const int uart2_muxvals[] = {8, 8}; static const unsigned uart3_pins[] = {219, 220}; -static const unsigned uart3_muxvals[] = {8, 8}; +static const int uart3_muxvals[] = {8, 8}; static const unsigned uart3b_pins[] = {181, 182}; -static const unsigned uart3b_muxvals[] = {10, 10}; +static const int uart3b_muxvals[] = {10, 10}; static const unsigned usb0_pins[] = {56, 57}; -static const unsigned usb0_muxvals[] = {8, 8}; +static const int usb0_muxvals[] = {8, 8}; static const unsigned usb1_pins[] = {58, 59}; -static const unsigned usb1_muxvals[] = {8, 8}; +static const int usb1_muxvals[] = {8, 8}; static const unsigned usb2_pins[] = {60, 61}; -static const unsigned usb2_muxvals[] = {8, 8}; +static const int usb2_muxvals[] = {8, 8}; static const unsigned usb3_pins[] = {62, 63}; -static const unsigned usb3_muxvals[] = {8, 8}; +static const int usb3_muxvals[] = {8, 8}; static const unsigned port_range0_pins[] = { 127, 128, 129, 130, 131, 132, 133, 134, /* PORT0x */ 135, 136, 137, 138, 139, 140, 141, 142, /* PORT1x */ @@ -786,7 +802,7 @@ static const unsigned port_range0_pins[] = { 61, 62, 63, 64, 65, 66, 67, 68, /* PORT9x */ 69, 70, 71, 76, 77, 78, 79, 80, /* PORT10x */ }; -static const unsigned port_range0_muxvals[] = { +static const int port_range0_muxvals[] = { 15, 15, 15, 15, 15, 15, 15, 15, /* PORT0x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT1x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT2x */ @@ -818,7 +834,7 @@ static const unsigned port_range1_pins[] = { 218, 219, 220, 221, 223, 224, 225, 226, /* PORT27x */ 227, 228, 229, 230, 231, 232, 233, 234, /* PORT28x */ }; -static const unsigned port_range1_muxvals[] = { +static const int port_range1_muxvals[] = { 15, 15, 15, 15, 15, 15, 15, 15, /* PORT12x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT13x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT14x */ @@ -842,15 +858,18 @@ static const unsigned xirq_pins[] = { 126, 72, 73, 92, 177, 93, 94, 176, /* XIRQ8-15 */ 74, 91, 27, 28, 29, 75, 20, 26, /* XIRQ16-23 */ }; -static const unsigned xirq_muxvals[] = { +static const int xirq_muxvals[] = { 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ0-7 */ 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ8-15 */ 14, 14, 14, 14, 14, 14, 14, 14, /* XIRQ16-23 */ }; -static const struct uniphier_pinctrl_group proxstream2_groups[] = { +static const struct uniphier_pinctrl_group uniphier_pxs2_groups[] = { UNIPHIER_PINCTRL_GROUP(emmc), UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(ether_mii), + UNIPHIER_PINCTRL_GROUP(ether_rgmii), + UNIPHIER_PINCTRL_GROUP(ether_rmii), UNIPHIER_PINCTRL_GROUP(i2c0), UNIPHIER_PINCTRL_GROUP(i2c1), UNIPHIER_PINCTRL_GROUP(i2c2), @@ -860,6 +879,8 @@ static const struct uniphier_pinctrl_group proxstream2_groups[] = { UNIPHIER_PINCTRL_GROUP(nand), UNIPHIER_PINCTRL_GROUP(nand_cs1), UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), UNIPHIER_PINCTRL_GROUP(uart0), UNIPHIER_PINCTRL_GROUP(uart0b), UNIPHIER_PINCTRL_GROUP(uart1), @@ -1124,6 +1145,9 @@ static const struct uniphier_pinctrl_group proxstream2_groups[] = { }; static const char * const emmc_groups[] = {"emmc", "emmc_dat8"}; +static const char * const ether_mii_groups[] = {"ether_mii"}; +static const char * const ether_rgmii_groups[] = {"ether_rgmii"}; +static const char * const ether_rmii_groups[] = {"ether_rmii"}; static const char * const i2c0_groups[] = {"i2c0"}; static const char * const i2c1_groups[] = {"i2c1"}; static const char * const i2c2_groups[] = {"i2c2"}; @@ -1132,6 +1156,8 @@ static const char * const i2c5_groups[] = {"i2c5"}; static const char * const i2c6_groups[] = {"i2c6"}; static const char * const nand_groups[] = {"nand", "nand_cs1"}; static const char * const sd_groups[] = {"sd"}; +static const char * const system_bus_groups[] = {"system_bus", + "system_bus_cs1"}; static const char * const uart0_groups[] = {"uart0", "uart0b"}; static const char * const uart1_groups[] = {"uart1"}; static const char * const uart2_groups[] = {"uart2"}; @@ -1208,8 +1234,11 @@ static const char * const xirq_groups[] = { "xirq20", "xirq21", "xirq22", "xirq23", }; -static const struct uniphier_pinmux_function proxstream2_functions[] = { +static const struct uniphier_pinmux_function uniphier_pxs2_functions[] = { UNIPHIER_PINMUX_FUNCTION(emmc), + UNIPHIER_PINMUX_FUNCTION(ether_mii), + UNIPHIER_PINMUX_FUNCTION(ether_rgmii), + UNIPHIER_PINMUX_FUNCTION(ether_rmii), UNIPHIER_PINMUX_FUNCTION(i2c0), UNIPHIER_PINMUX_FUNCTION(i2c1), UNIPHIER_PINMUX_FUNCTION(i2c2), @@ -1218,6 +1247,7 @@ static const struct uniphier_pinmux_function proxstream2_functions[] = { UNIPHIER_PINMUX_FUNCTION(i2c6), UNIPHIER_PINMUX_FUNCTION(nand), UNIPHIER_PINMUX_FUNCTION(sd), + UNIPHIER_PINMUX_FUNCTION(system_bus), UNIPHIER_PINMUX_FUNCTION(uart0), UNIPHIER_PINMUX_FUNCTION(uart1), UNIPHIER_PINMUX_FUNCTION(uart2), @@ -1230,43 +1260,36 @@ static const struct uniphier_pinmux_function proxstream2_functions[] = { UNIPHIER_PINMUX_FUNCTION(xirq), }; -static struct uniphier_pinctrl_socdata proxstream2_pindata = { - .groups = proxstream2_groups, - .groups_count = ARRAY_SIZE(proxstream2_groups), - .functions = proxstream2_functions, - .functions_count = ARRAY_SIZE(proxstream2_functions), - .mux_bits = 8, - .reg_stride = 4, - .load_pinctrl = false, -}; - -static struct pinctrl_desc proxstream2_pinctrl_desc = { - .name = DRIVER_NAME, - .pins = proxstream2_pins, - .npins = ARRAY_SIZE(proxstream2_pins), - .owner = THIS_MODULE, +static struct uniphier_pinctrl_socdata uniphier_pxs2_pindata = { + .pins = uniphier_pxs2_pins, + .npins = ARRAY_SIZE(uniphier_pxs2_pins), + .groups = uniphier_pxs2_groups, + .groups_count = ARRAY_SIZE(uniphier_pxs2_groups), + .functions = uniphier_pxs2_functions, + .functions_count = ARRAY_SIZE(uniphier_pxs2_functions), + .caps = 0, }; -static int proxstream2_pinctrl_probe(struct platform_device *pdev) +static int uniphier_pxs2_pinctrl_probe(struct platform_device *pdev) { - return uniphier_pinctrl_probe(pdev, &proxstream2_pinctrl_desc, - &proxstream2_pindata); + return uniphier_pinctrl_probe(pdev, &uniphier_pxs2_pindata); } -static const struct of_device_id proxstream2_pinctrl_match[] = { +static const struct of_device_id uniphier_pxs2_pinctrl_match[] = { + { .compatible = "socionext,uniphier-pxs2-pinctrl" }, { .compatible = "socionext,proxstream2-pinctrl" }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, proxstream2_pinctrl_match); +MODULE_DEVICE_TABLE(of, uniphier_pxs2_pinctrl_match); -static struct platform_driver proxstream2_pinctrl_driver = { - .probe = proxstream2_pinctrl_probe, +static struct platform_driver uniphier_pxs2_pinctrl_driver = { + .probe = uniphier_pxs2_pinctrl_probe, .driver = { - .name = DRIVER_NAME, - .of_match_table = proxstream2_pinctrl_match, + .name = "uniphier-pxs2-pinctrl", + .of_match_table = uniphier_pxs2_pinctrl_match, }, }; -module_platform_driver(proxstream2_pinctrl_driver); +module_platform_driver(uniphier_pxs2_pinctrl_driver); MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); MODULE_DESCRIPTION("UniPhier ProXstream2 pinctrl driver"); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c index ceb7a9899bde..da689d880f46 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-sld8.c @@ -19,453 +19,518 @@ #include "pinctrl-uniphier.h" -#define DRIVER_NAME "ph1-sld8-pinctrl" - -static const struct pinctrl_pin_desc ph1_sld8_pins[] = { +static const struct pinctrl_pin_desc uniphier_sld8_pins[] = { UNIPHIER_PINCTRL_PIN(0, "PCA00", 0, - 15, UNIPHIER_PIN_DRV_4_8, + 15, UNIPHIER_PIN_DRV_1BIT, 15, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(1, "PCA01", 0, - 16, UNIPHIER_PIN_DRV_4_8, + 16, UNIPHIER_PIN_DRV_1BIT, 16, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(2, "PCA02", 0, - 17, UNIPHIER_PIN_DRV_4_8, + 17, UNIPHIER_PIN_DRV_1BIT, 17, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(3, "PCA03", 0, - 18, UNIPHIER_PIN_DRV_4_8, + 18, UNIPHIER_PIN_DRV_1BIT, 18, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(4, "PCA04", 0, - 19, UNIPHIER_PIN_DRV_4_8, + 19, UNIPHIER_PIN_DRV_1BIT, 19, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(5, "PCA05", 0, - 20, UNIPHIER_PIN_DRV_4_8, + 20, UNIPHIER_PIN_DRV_1BIT, 20, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(6, "PCA06", 0, - 21, UNIPHIER_PIN_DRV_4_8, + 21, UNIPHIER_PIN_DRV_1BIT, 21, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(7, "PCA07", 0, - 22, UNIPHIER_PIN_DRV_4_8, + 22, UNIPHIER_PIN_DRV_1BIT, 22, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(8, "PCA08", 0, - 23, UNIPHIER_PIN_DRV_4_8, + 23, UNIPHIER_PIN_DRV_1BIT, 23, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(9, "PCA09", 0, - 24, UNIPHIER_PIN_DRV_4_8, + 24, UNIPHIER_PIN_DRV_1BIT, 24, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(10, "PCA10", 0, - 25, UNIPHIER_PIN_DRV_4_8, + 25, UNIPHIER_PIN_DRV_1BIT, 25, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(11, "PCA11", 0, - 26, UNIPHIER_PIN_DRV_4_8, + 26, UNIPHIER_PIN_DRV_1BIT, 26, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(12, "PCA12", 0, - 27, UNIPHIER_PIN_DRV_4_8, + 27, UNIPHIER_PIN_DRV_1BIT, 27, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(13, "PCA13", 0, - 28, UNIPHIER_PIN_DRV_4_8, + 28, UNIPHIER_PIN_DRV_1BIT, 28, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(14, "PCA14", 0, - 29, UNIPHIER_PIN_DRV_4_8, + 29, UNIPHIER_PIN_DRV_1BIT, 29, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(15, "XNFRE_GB", UNIPHIER_PIN_IECTRL_NONE, - 30, UNIPHIER_PIN_DRV_4_8, + 30, UNIPHIER_PIN_DRV_1BIT, 30, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(16, "XNFWE_GB", UNIPHIER_PIN_IECTRL_NONE, - 31, UNIPHIER_PIN_DRV_4_8, + 31, UNIPHIER_PIN_DRV_1BIT, 31, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(17, "NFALE_GB", UNIPHIER_PIN_IECTRL_NONE, - 32, UNIPHIER_PIN_DRV_4_8, + 32, UNIPHIER_PIN_DRV_1BIT, 32, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(18, "NFCLE_GB", UNIPHIER_PIN_IECTRL_NONE, - 33, UNIPHIER_PIN_DRV_4_8, + 33, UNIPHIER_PIN_DRV_1BIT, 33, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(19, "XNFWP_GB", UNIPHIER_PIN_IECTRL_NONE, - 34, UNIPHIER_PIN_DRV_4_8, + 34, UNIPHIER_PIN_DRV_1BIT, 34, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(20, "XNFCE0_GB", UNIPHIER_PIN_IECTRL_NONE, - 35, UNIPHIER_PIN_DRV_4_8, + 35, UNIPHIER_PIN_DRV_1BIT, 35, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(21, "NANDRYBY0_GB", UNIPHIER_PIN_IECTRL_NONE, - 36, UNIPHIER_PIN_DRV_4_8, + 36, UNIPHIER_PIN_DRV_1BIT, 36, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(22, "XNFCE1_GB", UNIPHIER_PIN_IECTRL_NONE, - 0, UNIPHIER_PIN_DRV_8_12_16_20, + 0, UNIPHIER_PIN_DRV_2BIT, 119, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(23, "NANDRYBY1_GB", UNIPHIER_PIN_IECTRL_NONE, - 4, UNIPHIER_PIN_DRV_8_12_16_20, + 1, UNIPHIER_PIN_DRV_2BIT, 120, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(24, "NFD0_GB", UNIPHIER_PIN_IECTRL_NONE, - 8, UNIPHIER_PIN_DRV_8_12_16_20, + 2, UNIPHIER_PIN_DRV_2BIT, 121, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(25, "NFD1_GB", UNIPHIER_PIN_IECTRL_NONE, - 12, UNIPHIER_PIN_DRV_8_12_16_20, + 3, UNIPHIER_PIN_DRV_2BIT, 122, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(26, "NFD2_GB", UNIPHIER_PIN_IECTRL_NONE, - 16, UNIPHIER_PIN_DRV_8_12_16_20, + 4, UNIPHIER_PIN_DRV_2BIT, 123, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(27, "NFD3_GB", UNIPHIER_PIN_IECTRL_NONE, - 20, UNIPHIER_PIN_DRV_8_12_16_20, + 5, UNIPHIER_PIN_DRV_2BIT, 124, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(28, "NFD4_GB", UNIPHIER_PIN_IECTRL_NONE, - 24, UNIPHIER_PIN_DRV_8_12_16_20, + 6, UNIPHIER_PIN_DRV_2BIT, 125, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(29, "NFD5_GB", UNIPHIER_PIN_IECTRL_NONE, - 28, UNIPHIER_PIN_DRV_8_12_16_20, + 7, UNIPHIER_PIN_DRV_2BIT, 126, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(30, "NFD6_GB", UNIPHIER_PIN_IECTRL_NONE, - 32, UNIPHIER_PIN_DRV_8_12_16_20, + 8, UNIPHIER_PIN_DRV_2BIT, 127, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(31, "NFD7_GB", UNIPHIER_PIN_IECTRL_NONE, - 36, UNIPHIER_PIN_DRV_8_12_16_20, + 9, UNIPHIER_PIN_DRV_2BIT, 128, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(32, "SDCLK", 8, - 40, UNIPHIER_PIN_DRV_8_12_16_20, + 10, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(33, "SDCMD", 8, - 44, UNIPHIER_PIN_DRV_8_12_16_20, + 11, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(34, "SDDAT0", 8, - 48, UNIPHIER_PIN_DRV_8_12_16_20, + 12, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(35, "SDDAT1", 8, - 52, UNIPHIER_PIN_DRV_8_12_16_20, + 13, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(36, "SDDAT2", 8, - 56, UNIPHIER_PIN_DRV_8_12_16_20, + 14, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(37, "SDDAT3", 8, - 60, UNIPHIER_PIN_DRV_8_12_16_20, + 15, UNIPHIER_PIN_DRV_2BIT, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(38, "SDCD", 8, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 129, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(39, "SDWP", 8, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 130, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(40, "SDVOLC", 9, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 131, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(41, "USB0VBUS", 0, - 37, UNIPHIER_PIN_DRV_4_8, + 37, UNIPHIER_PIN_DRV_1BIT, 37, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(42, "USB0OD", 0, - 38, UNIPHIER_PIN_DRV_4_8, + 38, UNIPHIER_PIN_DRV_1BIT, 38, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(43, "USB1VBUS", 0, - 39, UNIPHIER_PIN_DRV_4_8, + 39, UNIPHIER_PIN_DRV_1BIT, 39, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(44, "USB1OD", 0, - 40, UNIPHIER_PIN_DRV_4_8, + 40, UNIPHIER_PIN_DRV_1BIT, 40, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(45, "PCRESET", 0, - 41, UNIPHIER_PIN_DRV_4_8, + 41, UNIPHIER_PIN_DRV_1BIT, 41, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(46, "PCREG", 0, - 42, UNIPHIER_PIN_DRV_4_8, + 42, UNIPHIER_PIN_DRV_1BIT, 42, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(47, "PCCE2", 0, - 43, UNIPHIER_PIN_DRV_4_8, + 43, UNIPHIER_PIN_DRV_1BIT, 43, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(48, "PCVS1", 0, - 44, UNIPHIER_PIN_DRV_4_8, + 44, UNIPHIER_PIN_DRV_1BIT, 44, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(49, "PCCD2", 0, - 45, UNIPHIER_PIN_DRV_4_8, + 45, UNIPHIER_PIN_DRV_1BIT, 45, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(50, "PCCD1", 0, - 46, UNIPHIER_PIN_DRV_4_8, + 46, UNIPHIER_PIN_DRV_1BIT, 46, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(51, "PCREADY", 0, - 47, UNIPHIER_PIN_DRV_4_8, + 47, UNIPHIER_PIN_DRV_1BIT, 47, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(52, "PCDOE", 0, - 48, UNIPHIER_PIN_DRV_4_8, + 48, UNIPHIER_PIN_DRV_1BIT, 48, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(53, "PCCE1", 0, - 49, UNIPHIER_PIN_DRV_4_8, + 49, UNIPHIER_PIN_DRV_1BIT, 49, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(54, "PCWE", 0, - 50, UNIPHIER_PIN_DRV_4_8, + 50, UNIPHIER_PIN_DRV_1BIT, 50, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(55, "PCOE", 0, - 51, UNIPHIER_PIN_DRV_4_8, + 51, UNIPHIER_PIN_DRV_1BIT, 51, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(56, "PCWAIT", 0, - 52, UNIPHIER_PIN_DRV_4_8, + 52, UNIPHIER_PIN_DRV_1BIT, 52, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(57, "PCIOWR", 0, - 53, UNIPHIER_PIN_DRV_4_8, + 53, UNIPHIER_PIN_DRV_1BIT, 53, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(58, "PCIORD", 0, - 54, UNIPHIER_PIN_DRV_4_8, + 54, UNIPHIER_PIN_DRV_1BIT, 54, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(59, "HS0DIN0", 0, - 55, UNIPHIER_PIN_DRV_4_8, + 55, UNIPHIER_PIN_DRV_1BIT, 55, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(60, "HS0DIN1", 0, - 56, UNIPHIER_PIN_DRV_4_8, + 56, UNIPHIER_PIN_DRV_1BIT, 56, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(61, "HS0DIN2", 0, - 57, UNIPHIER_PIN_DRV_4_8, + 57, UNIPHIER_PIN_DRV_1BIT, 57, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(62, "HS0DIN3", 0, - 58, UNIPHIER_PIN_DRV_4_8, + 58, UNIPHIER_PIN_DRV_1BIT, 58, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(63, "HS0DIN4", 0, - 59, UNIPHIER_PIN_DRV_4_8, + 59, UNIPHIER_PIN_DRV_1BIT, 59, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(64, "HS0DIN5", 0, - 60, UNIPHIER_PIN_DRV_4_8, + 60, UNIPHIER_PIN_DRV_1BIT, 60, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(65, "HS0DIN6", 0, - 61, UNIPHIER_PIN_DRV_4_8, + 61, UNIPHIER_PIN_DRV_1BIT, 61, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(66, "HS0DIN7", 0, - 62, UNIPHIER_PIN_DRV_4_8, + 62, UNIPHIER_PIN_DRV_1BIT, 62, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(67, "HS0BCLKIN", 0, - 63, UNIPHIER_PIN_DRV_4_8, + 63, UNIPHIER_PIN_DRV_1BIT, 63, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(68, "HS0VALIN", 0, - 64, UNIPHIER_PIN_DRV_4_8, + 64, UNIPHIER_PIN_DRV_1BIT, 64, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(69, "HS0SYNCIN", 0, - 65, UNIPHIER_PIN_DRV_4_8, + 65, UNIPHIER_PIN_DRV_1BIT, 65, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(70, "HSDOUT0", 0, - 66, UNIPHIER_PIN_DRV_4_8, + 66, UNIPHIER_PIN_DRV_1BIT, 66, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(71, "HSDOUT1", 0, - 67, UNIPHIER_PIN_DRV_4_8, + 67, UNIPHIER_PIN_DRV_1BIT, 67, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(72, "HSDOUT2", 0, - 68, UNIPHIER_PIN_DRV_4_8, + 68, UNIPHIER_PIN_DRV_1BIT, 68, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(73, "HSDOUT3", 0, - 69, UNIPHIER_PIN_DRV_4_8, + 69, UNIPHIER_PIN_DRV_1BIT, 69, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(74, "HSDOUT4", 0, - 70, UNIPHIER_PIN_DRV_4_8, + 70, UNIPHIER_PIN_DRV_1BIT, 70, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(75, "HSDOUT5", 0, - 71, UNIPHIER_PIN_DRV_4_8, + 71, UNIPHIER_PIN_DRV_1BIT, 71, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(76, "HSDOUT6", 0, - 72, UNIPHIER_PIN_DRV_4_8, + 72, UNIPHIER_PIN_DRV_1BIT, 72, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(77, "HSDOUT7", 0, - 73, UNIPHIER_PIN_DRV_4_8, + 73, UNIPHIER_PIN_DRV_1BIT, 73, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(78, "HSBCLKOUT", 0, - 74, UNIPHIER_PIN_DRV_4_8, + 74, UNIPHIER_PIN_DRV_1BIT, 74, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(79, "HSVALOUT", 0, - 75, UNIPHIER_PIN_DRV_4_8, + 75, UNIPHIER_PIN_DRV_1BIT, 75, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(80, "HSSYNCOUT", 0, - 76, UNIPHIER_PIN_DRV_4_8, + 76, UNIPHIER_PIN_DRV_1BIT, 76, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(81, "HS1DIN0", 0, - 77, UNIPHIER_PIN_DRV_4_8, + 77, UNIPHIER_PIN_DRV_1BIT, 77, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(82, "HS1DIN1", 0, - 78, UNIPHIER_PIN_DRV_4_8, + 78, UNIPHIER_PIN_DRV_1BIT, 78, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(83, "HS1DIN2", 0, - 79, UNIPHIER_PIN_DRV_4_8, + 79, UNIPHIER_PIN_DRV_1BIT, 79, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(84, "HS1DIN3", 0, - 80, UNIPHIER_PIN_DRV_4_8, + 80, UNIPHIER_PIN_DRV_1BIT, 80, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(85, "HS1DIN4", 0, - 81, UNIPHIER_PIN_DRV_4_8, + 81, UNIPHIER_PIN_DRV_1BIT, 81, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(86, "HS1DIN5", 0, - 82, UNIPHIER_PIN_DRV_4_8, + 82, UNIPHIER_PIN_DRV_1BIT, 82, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(87, "HS1DIN6", 0, - 83, UNIPHIER_PIN_DRV_4_8, + 83, UNIPHIER_PIN_DRV_1BIT, 83, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(88, "HS1DIN7", 0, - 84, UNIPHIER_PIN_DRV_4_8, + 84, UNIPHIER_PIN_DRV_1BIT, 84, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(89, "HS1BCLKIN", 0, - 85, UNIPHIER_PIN_DRV_4_8, + 85, UNIPHIER_PIN_DRV_1BIT, 85, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(90, "HS1VALIN", 0, - 86, UNIPHIER_PIN_DRV_4_8, + 86, UNIPHIER_PIN_DRV_1BIT, 86, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(91, "HS1SYNCIN", 0, - 87, UNIPHIER_PIN_DRV_4_8, + 87, UNIPHIER_PIN_DRV_1BIT, 87, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(92, "AGCI", 3, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 132, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(93, "AGCR", 4, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 133, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(94, "AGCBS", 5, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, 134, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(95, "IECOUT", 0, - 88, UNIPHIER_PIN_DRV_4_8, + 88, UNIPHIER_PIN_DRV_1BIT, 88, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(96, "ASMCK", 0, - 89, UNIPHIER_PIN_DRV_4_8, + 89, UNIPHIER_PIN_DRV_1BIT, 89, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(97, "ABCKO", UNIPHIER_PIN_IECTRL_NONE, - 90, UNIPHIER_PIN_DRV_4_8, + 90, UNIPHIER_PIN_DRV_1BIT, 90, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(98, "ALRCKO", UNIPHIER_PIN_IECTRL_NONE, - 91, UNIPHIER_PIN_DRV_4_8, + 91, UNIPHIER_PIN_DRV_1BIT, 91, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(99, "ASDOUT0", UNIPHIER_PIN_IECTRL_NONE, - 92, UNIPHIER_PIN_DRV_4_8, + 92, UNIPHIER_PIN_DRV_1BIT, 92, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(100, "ASDOUT1", UNIPHIER_PIN_IECTRL_NONE, - 93, UNIPHIER_PIN_DRV_4_8, + 93, UNIPHIER_PIN_DRV_1BIT, 93, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(101, "ARCOUT", 0, - 94, UNIPHIER_PIN_DRV_4_8, + 94, UNIPHIER_PIN_DRV_1BIT, 94, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(102, "SDA0", 10, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(103, "SCL0", 10, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(104, "SDA1", 11, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(105, "SCL1", 11, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(106, "DMDSDA0", 12, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(107, "DMDSCL0", 12, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(108, "DMDSDA1", 13, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(109, "DMDSCL1", 13, - -1, UNIPHIER_PIN_DRV_FIXED_4, + -1, UNIPHIER_PIN_DRV_FIXED4, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(110, "SBO0", UNIPHIER_PIN_IECTRL_NONE, - 95, UNIPHIER_PIN_DRV_4_8, + 95, UNIPHIER_PIN_DRV_1BIT, 95, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(111, "SBI0", UNIPHIER_PIN_IECTRL_NONE, - 96, UNIPHIER_PIN_DRV_4_8, + 96, UNIPHIER_PIN_DRV_1BIT, 96, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(112, "SBO1", 0, - 97, UNIPHIER_PIN_DRV_4_8, + 97, UNIPHIER_PIN_DRV_1BIT, 97, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(113, "SBI1", 0, - 98, UNIPHIER_PIN_DRV_4_8, + 98, UNIPHIER_PIN_DRV_1BIT, 98, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(114, "TXD1", 0, - 99, UNIPHIER_PIN_DRV_4_8, + 99, UNIPHIER_PIN_DRV_1BIT, 99, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(115, "RXD1", 0, - 100, UNIPHIER_PIN_DRV_4_8, + 100, UNIPHIER_PIN_DRV_1BIT, 100, UNIPHIER_PIN_PULL_UP), UNIPHIER_PINCTRL_PIN(116, "HIN", 1, - -1, UNIPHIER_PIN_DRV_FIXED_5, + -1, UNIPHIER_PIN_DRV_FIXED5, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(117, "VIN", 2, - -1, UNIPHIER_PIN_DRV_FIXED_5, + -1, UNIPHIER_PIN_DRV_FIXED5, -1, UNIPHIER_PIN_PULL_NONE), UNIPHIER_PINCTRL_PIN(118, "TCON0", 0, - 101, UNIPHIER_PIN_DRV_4_8, + 101, UNIPHIER_PIN_DRV_1BIT, 101, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(119, "TCON1", 0, - 102, UNIPHIER_PIN_DRV_4_8, + 102, UNIPHIER_PIN_DRV_1BIT, 102, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(120, "TCON2", 0, - 103, UNIPHIER_PIN_DRV_4_8, + 103, UNIPHIER_PIN_DRV_1BIT, 103, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(121, "TCON3", 0, - 104, UNIPHIER_PIN_DRV_4_8, + 104, UNIPHIER_PIN_DRV_1BIT, 104, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(122, "TCON4", 0, - 105, UNIPHIER_PIN_DRV_4_8, + 105, UNIPHIER_PIN_DRV_1BIT, 105, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(123, "TCON5", 0, - 106, UNIPHIER_PIN_DRV_4_8, + 106, UNIPHIER_PIN_DRV_1BIT, 106, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(124, "TCON6", 0, - 107, UNIPHIER_PIN_DRV_4_8, + 107, UNIPHIER_PIN_DRV_1BIT, 107, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(125, "TCON7", 0, - 108, UNIPHIER_PIN_DRV_4_8, + 108, UNIPHIER_PIN_DRV_1BIT, 108, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(126, "TCON8", 0, - 109, UNIPHIER_PIN_DRV_4_8, + 109, UNIPHIER_PIN_DRV_1BIT, 109, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(127, "PWMA", 0, - 110, UNIPHIER_PIN_DRV_4_8, + 110, UNIPHIER_PIN_DRV_1BIT, 110, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(128, "XIRQ0", 0, - 111, UNIPHIER_PIN_DRV_4_8, + 111, UNIPHIER_PIN_DRV_1BIT, 111, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(129, "XIRQ1", 0, - 112, UNIPHIER_PIN_DRV_4_8, + 112, UNIPHIER_PIN_DRV_1BIT, 112, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(130, "XIRQ2", 0, - 113, UNIPHIER_PIN_DRV_4_8, + 113, UNIPHIER_PIN_DRV_1BIT, 113, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(131, "XIRQ3", 0, - 114, UNIPHIER_PIN_DRV_4_8, + 114, UNIPHIER_PIN_DRV_1BIT, 114, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(132, "XIRQ4", 0, - 115, UNIPHIER_PIN_DRV_4_8, + 115, UNIPHIER_PIN_DRV_1BIT, 115, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(133, "XIRQ5", 0, - 116, UNIPHIER_PIN_DRV_4_8, + 116, UNIPHIER_PIN_DRV_1BIT, 116, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(134, "XIRQ6", 0, - 117, UNIPHIER_PIN_DRV_4_8, + 117, UNIPHIER_PIN_DRV_1BIT, 117, UNIPHIER_PIN_PULL_DOWN), UNIPHIER_PINCTRL_PIN(135, "XIRQ7", 0, - 118, UNIPHIER_PIN_DRV_4_8, + 118, UNIPHIER_PIN_DRV_1BIT, 118, UNIPHIER_PIN_PULL_DOWN), + /* dedicated pins */ + UNIPHIER_PINCTRL_PIN(136, "ED0", -1, + 0, UNIPHIER_PIN_DRV_1BIT, + 0, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(137, "ED1", -1, + 1, UNIPHIER_PIN_DRV_1BIT, + 1, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(138, "ED2", -1, + 2, UNIPHIER_PIN_DRV_1BIT, + 2, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(139, "ED3", -1, + 3, UNIPHIER_PIN_DRV_1BIT, + 3, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(140, "ED4", -1, + 4, UNIPHIER_PIN_DRV_1BIT, + 4, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(141, "ED5", -1, + 5, UNIPHIER_PIN_DRV_1BIT, + 5, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(142, "ED6", -1, + 6, UNIPHIER_PIN_DRV_1BIT, + 6, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(143, "ED7", -1, + 7, UNIPHIER_PIN_DRV_1BIT, + 7, UNIPHIER_PIN_PULL_DOWN), + UNIPHIER_PINCTRL_PIN(144, "XERWE0", -1, + 8, UNIPHIER_PIN_DRV_1BIT, + 8, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(145, "XERWE1", -1, + 9, UNIPHIER_PIN_DRV_1BIT, + 9, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(146, "ERXW", -1, + 10, UNIPHIER_PIN_DRV_1BIT, + 10, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(147, "ES0", -1, + 11, UNIPHIER_PIN_DRV_1BIT, + 11, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(148, "ES1", -1, + 12, UNIPHIER_PIN_DRV_1BIT, + 12, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(149, "ES2", -1, + 13, UNIPHIER_PIN_DRV_1BIT, + 13, UNIPHIER_PIN_PULL_UP), + UNIPHIER_PINCTRL_PIN(150, "XECS1", -1, + 14, UNIPHIER_PIN_DRV_1BIT, + 14, UNIPHIER_PIN_PULL_DOWN), }; static const unsigned emmc_pins[] = {21, 22, 23, 24, 25, 26, 27}; -static const unsigned emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; +static const int emmc_muxvals[] = {1, 1, 1, 1, 1, 1, 1}; static const unsigned emmc_dat8_pins[] = {28, 29, 30, 31}; -static const unsigned emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const int emmc_dat8_muxvals[] = {1, 1, 1, 1}; +static const unsigned ether_mii_pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 14, + 61, 63, 64, 65, 66, 67, 68}; +static const int ether_mii_muxvals[] = {13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 27, 27, 27, 27, 27, 27, 27}; +static const unsigned ether_rmii_pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, + 14}; +static const int ether_rmii_muxvals[] = {13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13}; static const unsigned i2c0_pins[] = {102, 103}; -static const unsigned i2c0_muxvals[] = {0, 0}; +static const int i2c0_muxvals[] = {0, 0}; static const unsigned i2c1_pins[] = {104, 105}; -static const unsigned i2c1_muxvals[] = {0, 0}; +static const int i2c1_muxvals[] = {0, 0}; static const unsigned i2c2_pins[] = {108, 109}; -static const unsigned i2c2_muxvals[] = {2, 2}; +static const int i2c2_muxvals[] = {2, 2}; static const unsigned i2c3_pins[] = {108, 109}; -static const unsigned i2c3_muxvals[] = {3, 3}; +static const int i2c3_muxvals[] = {3, 3}; static const unsigned nand_pins[] = {15, 16, 17, 18, 19, 20, 21, 24, 25, 26, 27, 28, 29, 30, 31}; -static const unsigned nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0}; +static const int nand_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; static const unsigned nand_cs1_pins[] = {22, 23}; -static const unsigned nand_cs1_muxvals[] = {0, 0}; +static const int nand_cs1_muxvals[] = {0, 0}; static const unsigned sd_pins[] = {32, 33, 34, 35, 36, 37, 38, 39, 40}; -static const unsigned sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const int sd_muxvals[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; +static const unsigned system_bus_pins[] = {136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149}; +static const int system_bus_muxvals[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1}; +static const unsigned system_bus_cs1_pins[] = {150}; +static const int system_bus_cs1_muxvals[] = {-1}; +static const unsigned system_bus_cs2_pins[] = {10}; +static const int system_bus_cs2_muxvals[] = {1}; +static const unsigned system_bus_cs3_pins[] = {11}; +static const int system_bus_cs3_muxvals[] = {1}; +static const unsigned system_bus_cs4_pins[] = {12}; +static const int system_bus_cs4_muxvals[] = {1}; +static const unsigned system_bus_cs5_pins[] = {13}; +static const int system_bus_cs5_muxvals[] = {1}; static const unsigned uart0_pins[] = {70, 71}; -static const unsigned uart0_muxvals[] = {3, 3}; +static const int uart0_muxvals[] = {3, 3}; static const unsigned uart1_pins[] = {114, 115}; -static const unsigned uart1_muxvals[] = {0, 0}; +static const int uart1_muxvals[] = {0, 0}; static const unsigned uart2_pins[] = {112, 113}; -static const unsigned uart2_muxvals[] = {1, 1}; +static const int uart2_muxvals[] = {1, 1}; static const unsigned uart3_pins[] = {110, 111}; -static const unsigned uart3_muxvals[] = {1, 1}; +static const int uart3_muxvals[] = {1, 1}; static const unsigned usb0_pins[] = {41, 42}; -static const unsigned usb0_muxvals[] = {0, 0}; +static const int usb0_muxvals[] = {0, 0}; static const unsigned usb1_pins[] = {43, 44}; -static const unsigned usb1_muxvals[] = {0, 0}; +static const int usb1_muxvals[] = {0, 0}; static const unsigned usb2_pins[] = {114, 115}; -static const unsigned usb2_muxvals[] = {1, 1}; +static const int usb2_muxvals[] = {1, 1}; static const unsigned port_range0_pins[] = { 0, 1, 2, 3, 4, 5, 6, 7, /* PORT0x */ 8, 9, 10, 11, 12, 13, 14, 15, /* PORT1x */ @@ -481,7 +546,7 @@ static const unsigned port_range0_pins[] = { 48, 49, 46, 45, 123, 124, 125, 126, /* PORT11x */ 47, 127, 20, 56, 22, /* PORT120-124 */ }; -static const unsigned port_range0_muxvals[] = { +static const int port_range0_muxvals[] = { 15, 15, 15, 15, 15, 15, 15, 15, /* PORT0x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT1x */ 15, 15, 15, 15, 15, 15, 15, 15, /* PORT2x */ @@ -499,39 +564,41 @@ static const unsigned port_range0_muxvals[] = { static const unsigned port_range1_pins[] = { 116, 117, /* PORT130-131 */ }; -static const unsigned port_range1_muxvals[] = { +static const int port_range1_muxvals[] = { 15, 15, /* PORT130-131 */ }; static const unsigned port_range2_pins[] = { 102, 103, 104, 105, 106, 107, 108, 109, /* PORT14x */ }; -static const unsigned port_range2_muxvals[] = { +static const int port_range2_muxvals[] = { 15, 15, 15, 15, 15, 15, 15, 15, /* PORT14x */ }; static const unsigned port_range3_pins[] = { 23, /* PORT166 */ }; -static const unsigned port_range3_muxvals[] = { +static const int port_range3_muxvals[] = { 15, /* PORT166 */ }; static const unsigned xirq_range0_pins[] = { 128, 129, 130, 131, 132, 133, 134, 135, /* XIRQ0-7 */ 82, 87, 88, 50, 51, /* XIRQ8-12 */ }; -static const unsigned xirq_range0_muxvals[] = { +static const int xirq_range0_muxvals[] = { 0, 0, 0, 0, 0, 0, 0, 0, /* XIRQ0-7 */ 14, 14, 14, 14, 14, /* XIRQ8-12 */ }; static const unsigned xirq_range1_pins[] = { 52, 58, /* XIRQ14-15 */ }; -static const unsigned xirq_range1_muxvals[] = { +static const int xirq_range1_muxvals[] = { 14, 14, /* XIRQ14-15 */ }; -static const struct uniphier_pinctrl_group ph1_sld8_groups[] = { +static const struct uniphier_pinctrl_group uniphier_sld8_groups[] = { UNIPHIER_PINCTRL_GROUP(emmc), UNIPHIER_PINCTRL_GROUP(emmc_dat8), + UNIPHIER_PINCTRL_GROUP(ether_mii), + UNIPHIER_PINCTRL_GROUP(ether_rmii), UNIPHIER_PINCTRL_GROUP(i2c0), UNIPHIER_PINCTRL_GROUP(i2c1), UNIPHIER_PINCTRL_GROUP(i2c2), @@ -539,6 +606,12 @@ static const struct uniphier_pinctrl_group ph1_sld8_groups[] = { UNIPHIER_PINCTRL_GROUP(nand), UNIPHIER_PINCTRL_GROUP(nand_cs1), UNIPHIER_PINCTRL_GROUP(sd), + UNIPHIER_PINCTRL_GROUP(system_bus), + UNIPHIER_PINCTRL_GROUP(system_bus_cs1), + UNIPHIER_PINCTRL_GROUP(system_bus_cs2), + UNIPHIER_PINCTRL_GROUP(system_bus_cs3), + UNIPHIER_PINCTRL_GROUP(system_bus_cs4), + UNIPHIER_PINCTRL_GROUP(system_bus_cs5), UNIPHIER_PINCTRL_GROUP(uart0), UNIPHIER_PINCTRL_GROUP(uart1), UNIPHIER_PINCTRL_GROUP(uart2), @@ -682,12 +755,20 @@ static const struct uniphier_pinctrl_group ph1_sld8_groups[] = { }; static const char * const emmc_groups[] = {"emmc", "emmc_dat8"}; +static const char * const ether_mii_groups[] = {"ether_mii"}; +static const char * const ether_rmii_groups[] = {"ether_rmii"}; static const char * const i2c0_groups[] = {"i2c0"}; static const char * const i2c1_groups[] = {"i2c1"}; static const char * const i2c2_groups[] = {"i2c2"}; static const char * const i2c3_groups[] = {"i2c3"}; static const char * const nand_groups[] = {"nand", "nand_cs1"}; static const char * const sd_groups[] = {"sd"}; +static const char * const system_bus_groups[] = {"system_bus", + "system_bus_cs1", + "system_bus_cs2", + "system_bus_cs3", + "system_bus_cs4", + "system_bus_cs5"}; static const char * const uart0_groups[] = {"uart0"}; static const char * const uart1_groups[] = {"uart1"}; static const char * const uart2_groups[] = {"uart2"}; @@ -736,14 +817,17 @@ static const char * const xirq_groups[] = { "xirq12", /* none*/ "xirq14", "xirq15", }; -static const struct uniphier_pinmux_function ph1_sld8_functions[] = { +static const struct uniphier_pinmux_function uniphier_sld8_functions[] = { UNIPHIER_PINMUX_FUNCTION(emmc), + UNIPHIER_PINMUX_FUNCTION(ether_mii), + UNIPHIER_PINMUX_FUNCTION(ether_rmii), UNIPHIER_PINMUX_FUNCTION(i2c0), UNIPHIER_PINMUX_FUNCTION(i2c1), UNIPHIER_PINMUX_FUNCTION(i2c2), UNIPHIER_PINMUX_FUNCTION(i2c3), UNIPHIER_PINMUX_FUNCTION(nand), UNIPHIER_PINMUX_FUNCTION(sd), + UNIPHIER_PINMUX_FUNCTION(system_bus), UNIPHIER_PINMUX_FUNCTION(uart0), UNIPHIER_PINMUX_FUNCTION(uart1), UNIPHIER_PINMUX_FUNCTION(uart2), @@ -755,43 +839,36 @@ static const struct uniphier_pinmux_function ph1_sld8_functions[] = { UNIPHIER_PINMUX_FUNCTION(xirq), }; -static struct uniphier_pinctrl_socdata ph1_sld8_pindata = { - .groups = ph1_sld8_groups, - .groups_count = ARRAY_SIZE(ph1_sld8_groups), - .functions = ph1_sld8_functions, - .functions_count = ARRAY_SIZE(ph1_sld8_functions), - .mux_bits = 8, - .reg_stride = 4, - .load_pinctrl = false, -}; - -static struct pinctrl_desc ph1_sld8_pinctrl_desc = { - .name = DRIVER_NAME, - .pins = ph1_sld8_pins, - .npins = ARRAY_SIZE(ph1_sld8_pins), - .owner = THIS_MODULE, +static struct uniphier_pinctrl_socdata uniphier_sld8_pindata = { + .pins = uniphier_sld8_pins, + .npins = ARRAY_SIZE(uniphier_sld8_pins), + .groups = uniphier_sld8_groups, + .groups_count = ARRAY_SIZE(uniphier_sld8_groups), + .functions = uniphier_sld8_functions, + .functions_count = ARRAY_SIZE(uniphier_sld8_functions), + .caps = 0, }; -static int ph1_sld8_pinctrl_probe(struct platform_device *pdev) +static int uniphier_sld8_pinctrl_probe(struct platform_device *pdev) { - return uniphier_pinctrl_probe(pdev, &ph1_sld8_pinctrl_desc, - &ph1_sld8_pindata); + return uniphier_pinctrl_probe(pdev, &uniphier_sld8_pindata); } -static const struct of_device_id ph1_sld8_pinctrl_match[] = { +static const struct of_device_id uniphier_sld8_pinctrl_match[] = { + { .compatible = "socionext,uniphier-sld8-pinctrl" }, { .compatible = "socionext,ph1-sld8-pinctrl" }, { /* sentinel */ } }; -MODULE_DEVICE_TABLE(of, ph1_sld8_pinctrl_match); +MODULE_DEVICE_TABLE(of, uniphier_sld8_pinctrl_match); -static struct platform_driver ph1_sld8_pinctrl_driver = { - .probe = ph1_sld8_pinctrl_probe, +static struct platform_driver uniphier_sld8_pinctrl_driver = { + .probe = uniphier_sld8_pinctrl_probe, .driver = { - .name = DRIVER_NAME, - .of_match_table = ph1_sld8_pinctrl_match, + .name = "uniphier-sld8-pinctrl", + .of_match_table = uniphier_sld8_pinctrl_match, }, }; -module_platform_driver(ph1_sld8_pinctrl_driver); +module_platform_driver(uniphier_sld8_pinctrl_driver); MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro@socionext.com>"); MODULE_DESCRIPTION("UniPhier PH1-sLD8 pinctrl driver"); diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier.h b/drivers/pinctrl/uniphier/pinctrl-uniphier.h index a21154f4b453..923f36cb245d 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier.h +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier.h @@ -15,14 +15,18 @@ #ifndef __PINCTRL_UNIPHIER_H__ #define __PINCTRL_UNIPHIER_H__ +#include <linux/bitops.h> #include <linux/bug.h> #include <linux/kernel.h> #include <linux/types.h> +struct platform_device; + #define UNIPHIER_PINCTRL_PINMUX_BASE 0x0 #define UNIPHIER_PINCTRL_LOAD_PINMUX 0x700 #define UNIPHIER_PINCTRL_DRVCTRL_BASE 0x800 #define UNIPHIER_PINCTRL_DRV2CTRL_BASE 0x900 +#define UNIPHIER_PINCTRL_DRV3CTRL_BASE 0x980 #define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0xa00 #define UNIPHIER_PINCTRL_IECTRL 0xd00 @@ -39,16 +43,16 @@ #define UNIPHIER_PIN_DRVCTRL_MASK ((1UL << (UNIPHIER_PIN_DRVCTRL_BITS)) \ - 1) -/* supported drive strength (mA) */ -#define UNIPHIER_PIN_DRV_STR_SHIFT ((UNIPHIER_PIN_DRVCTRL_SHIFT) + \ +/* drive control type */ +#define UNIPHIER_PIN_DRV_TYPE_SHIFT ((UNIPHIER_PIN_DRVCTRL_SHIFT) + \ (UNIPHIER_PIN_DRVCTRL_BITS)) -#define UNIPHIER_PIN_DRV_STR_BITS 3 -#define UNIPHIER_PIN_DRV_STR_MASK ((1UL << (UNIPHIER_PIN_DRV_STR_BITS)) \ +#define UNIPHIER_PIN_DRV_TYPE_BITS 3 +#define UNIPHIER_PIN_DRV_TYPE_MASK ((1UL << (UNIPHIER_PIN_DRV_TYPE_BITS)) \ - 1) /* pull-up / pull-down register number */ -#define UNIPHIER_PIN_PUPDCTRL_SHIFT ((UNIPHIER_PIN_DRV_STR_SHIFT) + \ - (UNIPHIER_PIN_DRV_STR_BITS)) +#define UNIPHIER_PIN_PUPDCTRL_SHIFT ((UNIPHIER_PIN_DRV_TYPE_SHIFT) + \ + (UNIPHIER_PIN_DRV_TYPE_BITS)) #define UNIPHIER_PIN_PUPDCTRL_BITS 9 #define UNIPHIER_PIN_PUPDCTRL_MASK ((1UL << (UNIPHIER_PIN_PUPDCTRL_BITS))\ - 1) @@ -66,13 +70,14 @@ #define UNIPHIER_PIN_IECTRL_NONE (UNIPHIER_PIN_IECTRL_MASK) -/* selectable drive strength */ -enum uniphier_pin_drv_str { - UNIPHIER_PIN_DRV_4_8, /* 2 level control: 4/8 mA */ - UNIPHIER_PIN_DRV_8_12_16_20, /* 4 level control: 8/12/16/20 mA */ - UNIPHIER_PIN_DRV_FIXED_4, /* fixed to 4mA */ - UNIPHIER_PIN_DRV_FIXED_5, /* fixed to 5mA */ - UNIPHIER_PIN_DRV_FIXED_8, /* fixed to 8mA */ +/* drive control type */ +enum uniphier_pin_drv_type { + UNIPHIER_PIN_DRV_1BIT, /* 2 level control: 4/8 mA */ + UNIPHIER_PIN_DRV_2BIT, /* 4 level control: 8/12/16/20 mA */ + UNIPHIER_PIN_DRV_3BIT, /* 8 level control: 4/5/7/9/11/12/14/16 mA */ + UNIPHIER_PIN_DRV_FIXED4, /* fixed to 4mA */ + UNIPHIER_PIN_DRV_FIXED5, /* fixed to 5mA */ + UNIPHIER_PIN_DRV_FIXED8, /* fixed to 8mA */ UNIPHIER_PIN_DRV_NONE, /* no support (input only pin) */ }; @@ -89,17 +94,17 @@ enum uniphier_pin_pull_dir { (((x) & (UNIPHIER_PIN_IECTRL_MASK)) << (UNIPHIER_PIN_IECTRL_SHIFT)) #define UNIPHIER_PIN_DRVCTRL(x) \ (((x) & (UNIPHIER_PIN_DRVCTRL_MASK)) << (UNIPHIER_PIN_DRVCTRL_SHIFT)) -#define UNIPHIER_PIN_DRV_STR(x) \ - (((x) & (UNIPHIER_PIN_DRV_STR_MASK)) << (UNIPHIER_PIN_DRV_STR_SHIFT)) +#define UNIPHIER_PIN_DRV_TYPE(x) \ + (((x) & (UNIPHIER_PIN_DRV_TYPE_MASK)) << (UNIPHIER_PIN_DRV_TYPE_SHIFT)) #define UNIPHIER_PIN_PUPDCTRL(x) \ (((x) & (UNIPHIER_PIN_PUPDCTRL_MASK)) << (UNIPHIER_PIN_PUPDCTRL_SHIFT)) #define UNIPHIER_PIN_PULL_DIR(x) \ (((x) & (UNIPHIER_PIN_PULL_DIR_MASK)) << (UNIPHIER_PIN_PULL_DIR_SHIFT)) -#define UNIPHIER_PIN_ATTR_PACKED(iectrl, drvctrl, drv_str, pupdctrl, pull_dir)\ +#define UNIPHIER_PIN_ATTR_PACKED(iectrl, drvctrl, drv_type, pupdctrl, pull_dir)\ (UNIPHIER_PIN_IECTRL(iectrl) | \ UNIPHIER_PIN_DRVCTRL(drvctrl) | \ - UNIPHIER_PIN_DRV_STR(drv_str) | \ + UNIPHIER_PIN_DRV_TYPE(drv_type) | \ UNIPHIER_PIN_PUPDCTRL(pupdctrl) | \ UNIPHIER_PIN_PULL_DIR(pull_dir)) @@ -115,10 +120,10 @@ static inline unsigned int uniphier_pin_get_drvctrl(void *drv_data) UNIPHIER_PIN_DRVCTRL_MASK; } -static inline unsigned int uniphier_pin_get_drv_str(void *drv_data) +static inline unsigned int uniphier_pin_get_drv_type(void *drv_data) { - return ((unsigned long)drv_data >> UNIPHIER_PIN_DRV_STR_SHIFT) & - UNIPHIER_PIN_DRV_STR_MASK; + return ((unsigned long)drv_data >> UNIPHIER_PIN_DRV_TYPE_SHIFT) & + UNIPHIER_PIN_DRV_TYPE_MASK; } static inline unsigned int uniphier_pin_get_pupdctrl(void *drv_data) @@ -143,7 +148,7 @@ struct uniphier_pinctrl_group { const char *name; const unsigned *pins; unsigned num_pins; - const unsigned *muxvals; + const int *muxvals; enum uniphier_pinmux_gpio_range_type range_type; }; @@ -154,13 +159,15 @@ struct uniphier_pinmux_function { }; struct uniphier_pinctrl_socdata { + const struct pinctrl_pin_desc *pins; + unsigned int npins; const struct uniphier_pinctrl_group *groups; int groups_count; const struct uniphier_pinmux_function *functions; int functions_count; - unsigned mux_bits; - unsigned reg_stride; - bool load_pinctrl; + unsigned int caps; +#define UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL BIT(1) +#define UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE BIT(0) }; #define UNIPHIER_PINCTRL_PIN(a, b, c, d, e, f, g) \ @@ -205,11 +212,7 @@ struct uniphier_pinctrl_socdata { .num_groups = ARRAY_SIZE(func##_groups), \ } -struct platform_device; -struct pinctrl_desc; - int uniphier_pinctrl_probe(struct platform_device *pdev, - struct pinctrl_desc *desc, struct uniphier_pinctrl_socdata *socdata); #endif /* __PINCTRL_UNIPHIER_H__ */ diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 72e97d7a5209..1a8bf76a925f 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -77,6 +77,20 @@ config DA8XX_REMOTEPROC It's safe to say n here if you're not interested in multimedia offloading. +config QCOM_MDT_LOADER + tristate + +config QCOM_Q6V5_PIL + tristate "Qualcomm Hexagon V5 Peripherial Image Loader" + depends on OF && ARCH_QCOM + depends on QCOM_SMEM + select MFD_SYSCON + select QCOM_MDT_LOADER + select REMOTEPROC + help + Say y here to support the Qualcomm Peripherial Image Loader for the + Hexagon V5 based remote processors. + config ST_REMOTEPROC tristate "ST remoteproc support" depends on ARCH_STI diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index 279cb2edc880..92d3758bd15c 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -11,4 +11,6 @@ obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o obj-$(CONFIG_STE_MODEM_RPROC) += ste_modem_rproc.o obj-$(CONFIG_WKUP_M3_RPROC) += wkup_m3_rproc.o obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o +obj-$(CONFIG_QCOM_MDT_LOADER) += qcom_mdt_loader.o +obj-$(CONFIG_QCOM_Q6V5_PIL) += qcom_q6v5_pil.o obj-$(CONFIG_ST_REMOTEPROC) += st_remoteproc.o diff --git a/drivers/remoteproc/qcom_mdt_loader.c b/drivers/remoteproc/qcom_mdt_loader.c new file mode 100644 index 000000000000..114e8e4cef67 --- /dev/null +++ b/drivers/remoteproc/qcom_mdt_loader.c @@ -0,0 +1,179 @@ +/* + * Qualcomm Peripheral Image Loader + * + * Copyright (C) 2016 Linaro Ltd + * Copyright (C) 2015 Sony Mobile Communications Inc + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/elf.h> +#include <linux/firmware.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/remoteproc.h> +#include <linux/slab.h> + +#include "remoteproc_internal.h" +#include "qcom_mdt_loader.h" + +/** + * qcom_mdt_find_rsc_table() - provide dummy resource table for remoteproc + * @rproc: remoteproc handle + * @fw: firmware header + * @tablesz: outgoing size of the table + * + * Returns a dummy table. + */ +struct resource_table *qcom_mdt_find_rsc_table(struct rproc *rproc, + const struct firmware *fw, + int *tablesz) +{ + static struct resource_table table = { .ver = 1, }; + + *tablesz = sizeof(table); + return &table; +} +EXPORT_SYMBOL_GPL(qcom_mdt_find_rsc_table); + +/** + * qcom_mdt_parse() - extract useful parameters from the mdt header + * @fw: firmware handle + * @fw_addr: optional reference for base of the firmware's memory region + * @fw_size: optional reference for size of the firmware's memory region + * @fw_relocate: optional reference for flagging if the firmware is relocatable + * + * Returns 0 on success, negative errno otherwise. + */ +int qcom_mdt_parse(const struct firmware *fw, phys_addr_t *fw_addr, + size_t *fw_size, bool *fw_relocate) +{ + const struct elf32_phdr *phdrs; + const struct elf32_phdr *phdr; + const struct elf32_hdr *ehdr; + phys_addr_t min_addr = (phys_addr_t)ULLONG_MAX; + phys_addr_t max_addr = 0; + bool relocate = false; + int i; + + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(ehdr + 1); + + for (i = 0; i < ehdr->e_phnum; i++) { + phdr = &phdrs[i]; + + if (phdr->p_type != PT_LOAD) + continue; + + if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) + continue; + + if (!phdr->p_memsz) + continue; + + if (phdr->p_flags & QCOM_MDT_RELOCATABLE) + relocate = true; + + if (phdr->p_paddr < min_addr) + min_addr = phdr->p_paddr; + + if (phdr->p_paddr + phdr->p_memsz > max_addr) + max_addr = ALIGN(phdr->p_paddr + phdr->p_memsz, SZ_4K); + } + + if (fw_addr) + *fw_addr = min_addr; + if (fw_size) + *fw_size = max_addr - min_addr; + if (fw_relocate) + *fw_relocate = relocate; + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_mdt_parse); + +/** + * qcom_mdt_load() - load the firmware which header is defined in fw + * @rproc: rproc handle + * @fw: frimware object for the header + * @firmware: filename of the firmware, for building .bXX names + * + * Returns 0 on success, negative errno otherwise. + */ +int qcom_mdt_load(struct rproc *rproc, + const struct firmware *fw, + const char *firmware) +{ + const struct elf32_phdr *phdrs; + const struct elf32_phdr *phdr; + const struct elf32_hdr *ehdr; + size_t fw_name_len; + char *fw_name; + void *ptr; + int ret; + int i; + + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(ehdr + 1); + + fw_name_len = strlen(firmware); + if (fw_name_len <= 4) + return -EINVAL; + + fw_name = kstrdup(firmware, GFP_KERNEL); + if (!fw_name) + return -ENOMEM; + + for (i = 0; i < ehdr->e_phnum; i++) { + phdr = &phdrs[i]; + + if (phdr->p_type != PT_LOAD) + continue; + + if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) + continue; + + if (!phdr->p_memsz) + continue; + + ptr = rproc_da_to_va(rproc, phdr->p_paddr, phdr->p_memsz); + if (!ptr) { + dev_err(&rproc->dev, "segment outside memory range\n"); + ret = -EINVAL; + break; + } + + if (phdr->p_filesz) { + sprintf(fw_name + fw_name_len - 3, "b%02d", i); + ret = request_firmware(&fw, fw_name, &rproc->dev); + if (ret) { + dev_err(&rproc->dev, "failed to load %s\n", + fw_name); + break; + } + + memcpy(ptr, fw->data, fw->size); + + release_firmware(fw); + } + + if (phdr->p_memsz > phdr->p_filesz) + memset(ptr + phdr->p_filesz, 0, phdr->p_memsz - phdr->p_filesz); + } + + kfree(fw_name); + + return ret; +} +EXPORT_SYMBOL_GPL(qcom_mdt_load); + +MODULE_DESCRIPTION("Firmware parser for Qualcomm MDT format"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/remoteproc/qcom_mdt_loader.h b/drivers/remoteproc/qcom_mdt_loader.h new file mode 100644 index 000000000000..c5d7122755b6 --- /dev/null +++ b/drivers/remoteproc/qcom_mdt_loader.h @@ -0,0 +1,13 @@ +#ifndef __QCOM_MDT_LOADER_H__ +#define __QCOM_MDT_LOADER_H__ + +#define QCOM_MDT_TYPE_MASK (7 << 24) +#define QCOM_MDT_TYPE_HASH (2 << 24) +#define QCOM_MDT_RELOCATABLE BIT(27) + +struct resource_table * qcom_mdt_find_rsc_table(struct rproc *rproc, const struct firmware *fw, int *tablesz); +int qcom_mdt_load(struct rproc *rproc, const struct firmware *fw, const char *fw_name); + +int qcom_mdt_parse(const struct firmware *fw, phys_addr_t *fw_addr, size_t *fw_size, bool *fw_relocate); + +#endif diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c new file mode 100644 index 000000000000..24791886219a --- /dev/null +++ b/drivers/remoteproc/qcom_q6v5_pil.c @@ -0,0 +1,908 @@ +/* + * Qualcomm Peripheral Image Loader + * + * Copyright (C) 2016 Linaro Ltd. + * Copyright (C) 2014 Sony Mobile Communications AB + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of_address.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/regulator/consumer.h> +#include <linux/remoteproc.h> +#include <linux/reset.h> +#include <linux/soc/qcom/smem.h> +#include <linux/soc/qcom/smem_state.h> + +#include "remoteproc_internal.h" +#include "qcom_mdt_loader.h" + +#include <linux/qcom_scm.h> + +#define MBA_FIRMWARE_NAME "mba.b00" +#define MPSS_FIRMWARE_NAME "modem.mdt" + +#define MPSS_CRASH_REASON_SMEM 421 + +/* RMB Status Register Values */ +#define RMB_PBL_SUCCESS 0x1 + +#define RMB_MBA_XPU_UNLOCKED 0x1 +#define RMB_MBA_XPU_UNLOCKED_SCRIBBLED 0x2 +#define RMB_MBA_META_DATA_AUTH_SUCCESS 0x3 +#define RMB_MBA_AUTH_COMPLETE 0x4 + +/* PBL/MBA interface registers */ +#define RMB_MBA_IMAGE_REG 0x00 +#define RMB_PBL_STATUS_REG 0x04 +#define RMB_MBA_COMMAND_REG 0x08 +#define RMB_MBA_STATUS_REG 0x0C +#define RMB_PMI_META_DATA_REG 0x10 +#define RMB_PMI_CODE_START_REG 0x14 +#define RMB_PMI_CODE_LENGTH_REG 0x18 + +#define RMB_CMD_META_DATA_READY 0x1 +#define RMB_CMD_LOAD_READY 0x2 + +/* QDSP6SS Register Offsets */ +#define QDSP6SS_RESET_REG 0x014 +#define QDSP6SS_GFMUX_CTL_REG 0x020 +#define QDSP6SS_PWR_CTL_REG 0x030 + +/* AXI Halt Register Offsets */ +#define AXI_HALTREQ_REG 0x0 +#define AXI_HALTACK_REG 0x4 +#define AXI_IDLE_REG 0x8 + +#define HALT_ACK_TIMEOUT_MS 100 + +/* QDSP6SS_RESET */ +#define Q6SS_STOP_CORE BIT(0) +#define Q6SS_CORE_ARES BIT(1) +#define Q6SS_BUS_ARES_ENABLE BIT(2) + +/* QDSP6SS_GFMUX_CTL */ +#define Q6SS_CLK_ENABLE BIT(1) + +/* QDSP6SS_PWR_CTL */ +#define Q6SS_L2DATA_SLP_NRET_N_0 BIT(0) +#define Q6SS_L2DATA_SLP_NRET_N_1 BIT(1) +#define Q6SS_L2DATA_SLP_NRET_N_2 BIT(2) +#define Q6SS_L2TAG_SLP_NRET_N BIT(16) +#define Q6SS_ETB_SLP_NRET_N BIT(17) +#define Q6SS_L2DATA_STBY_N BIT(18) +#define Q6SS_SLP_RET_N BIT(19) +#define Q6SS_CLAMP_IO BIT(20) +#define QDSS_BHS_ON BIT(21) +#define QDSS_LDO_BYP BIT(22) + +struct q6v5 { + struct device *dev; + struct rproc *rproc; + + void __iomem *reg_base; + void __iomem *rmb_base; + + struct regmap *halt_map; + u32 halt_q6; + u32 halt_modem; + u32 halt_nc; + + struct reset_control *mss_restart; + + struct qcom_smem_state *state; + unsigned stop_bit; + + struct regulator_bulk_data supply[4]; + + struct clk *ahb_clk; + struct clk *axi_clk; + struct clk *rom_clk; + + struct completion start_done; + struct completion stop_done; + bool running; + + phys_addr_t mba_phys; + void *mba_region; + size_t mba_size; + + phys_addr_t mpss_phys; + phys_addr_t mpss_reloc; + void *mpss_region; + size_t mpss_size; +}; + +enum { + Q6V5_SUPPLY_CX, + Q6V5_SUPPLY_MX, + Q6V5_SUPPLY_MSS, + Q6V5_SUPPLY_PLL, +}; + +static int q6v5_regulator_init(struct q6v5 *qproc) +{ + int ret; + + qproc->supply[Q6V5_SUPPLY_CX].supply = "cx"; + qproc->supply[Q6V5_SUPPLY_MX].supply = "mx"; + qproc->supply[Q6V5_SUPPLY_MSS].supply = "mss"; + qproc->supply[Q6V5_SUPPLY_PLL].supply = "pll"; + + ret = devm_regulator_bulk_get(qproc->dev, + ARRAY_SIZE(qproc->supply), qproc->supply); + if (ret < 0) { + dev_err(qproc->dev, "failed to get supplies\n"); + return ret; + } + + regulator_set_load(qproc->supply[Q6V5_SUPPLY_CX].consumer, 100000); + regulator_set_load(qproc->supply[Q6V5_SUPPLY_MSS].consumer, 100000); + regulator_set_load(qproc->supply[Q6V5_SUPPLY_PLL].consumer, 10000); + + return 0; +} + +static int q6v5_regulator_enable(struct q6v5 *qproc) +{ + struct regulator *mss = qproc->supply[Q6V5_SUPPLY_MSS].consumer; + struct regulator *mx = qproc->supply[Q6V5_SUPPLY_MX].consumer; + int ret; + + /* TODO: Q6V5_SUPPLY_CX is supposed to be set to super-turbo here */ + + ret = regulator_set_voltage(mx, 1050000, INT_MAX); + if (ret) + return ret; + + regulator_set_voltage(mss, 1000000, 1150000); + + return regulator_bulk_enable(ARRAY_SIZE(qproc->supply), qproc->supply); +} + +static void q6v5_regulator_disable(struct q6v5 *qproc) +{ + struct regulator *mss = qproc->supply[Q6V5_SUPPLY_MSS].consumer; + struct regulator *mx = qproc->supply[Q6V5_SUPPLY_MX].consumer; + + /* TODO: Q6V5_SUPPLY_CX corner votes should be released */ + + regulator_bulk_disable(ARRAY_SIZE(qproc->supply), qproc->supply); + regulator_set_voltage(mx, 0, INT_MAX); + regulator_set_voltage(mss, 0, 1150000); +} + +static int q6v5_load(struct rproc *rproc, const struct firmware *fw) +{ + struct q6v5 *qproc = rproc->priv; + + memcpy(qproc->mba_region, fw->data, fw->size); + + return 0; +} + +static const struct rproc_fw_ops q6v5_fw_ops = { + .find_rsc_table = qcom_mdt_find_rsc_table, + .load = q6v5_load, +}; + +static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms) +{ + unsigned long timeout; + s32 val; + + timeout = jiffies + msecs_to_jiffies(ms); + for (;;) { + val = readl(qproc->rmb_base + RMB_PBL_STATUS_REG); + if (val) + break; + + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + msleep(1); + } + + return val; +} + +static int q6v5_rmb_mba_wait(struct q6v5 *qproc, u32 status, int ms) +{ + + unsigned long timeout; + s32 val; + + timeout = jiffies + msecs_to_jiffies(ms); + for (;;) { + val = readl(qproc->rmb_base + RMB_MBA_STATUS_REG); + if (val < 0) + break; + + if (!status && val) + break; + else if (status && val == status) + break; + + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + + msleep(1); + } + + return val; +} + +static int q6v5proc_reset(struct q6v5 *qproc) +{ + u32 val; + int ret; + + /* Assert resets, stop core */ + val = readl(qproc->reg_base + QDSP6SS_RESET_REG); + val |= (Q6SS_CORE_ARES | Q6SS_BUS_ARES_ENABLE | Q6SS_STOP_CORE); + writel(val, qproc->reg_base + QDSP6SS_RESET_REG); + + /* Enable power block headswitch, and wait for it to stabilize */ + val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); + val |= QDSS_BHS_ON | QDSS_LDO_BYP; + writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); + udelay(1); + + /* + * Turn on memories. L2 banks should be done individually + * to minimize inrush current. + */ + val = readl(qproc->reg_base + QDSP6SS_PWR_CTL_REG); + val |= Q6SS_SLP_RET_N | Q6SS_L2TAG_SLP_NRET_N | + Q6SS_ETB_SLP_NRET_N | Q6SS_L2DATA_STBY_N; + writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); + val |= Q6SS_L2DATA_SLP_NRET_N_2; + writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); + val |= Q6SS_L2DATA_SLP_NRET_N_1; + writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); + val |= Q6SS_L2DATA_SLP_NRET_N_0; + writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); + + /* Remove IO clamp */ + val &= ~Q6SS_CLAMP_IO; + writel(val, qproc->reg_base + QDSP6SS_PWR_CTL_REG); + + /* Bring core out of reset */ + val = readl(qproc->reg_base + QDSP6SS_RESET_REG); + val &= ~Q6SS_CORE_ARES; + writel(val, qproc->reg_base + QDSP6SS_RESET_REG); + + /* Turn on core clock */ + val = readl(qproc->reg_base + QDSP6SS_GFMUX_CTL_REG); + val |= Q6SS_CLK_ENABLE; + writel(val, qproc->reg_base + QDSP6SS_GFMUX_CTL_REG); + + /* Start core execution */ + val = readl(qproc->reg_base + QDSP6SS_RESET_REG); + val &= ~Q6SS_STOP_CORE; + writel(val, qproc->reg_base + QDSP6SS_RESET_REG); + + /* Wait for PBL status */ + ret = q6v5_rmb_pbl_wait(qproc, 1000); + if (ret == -ETIMEDOUT) { + dev_err(qproc->dev, "PBL boot timed out\n"); + } else if (ret != RMB_PBL_SUCCESS) { + dev_err(qproc->dev, "PBL returned unexpected status %d\n", ret); + ret = -EINVAL; + } else { + ret = 0; + } + + return ret; +} + +static void q6v5proc_halt_axi_port(struct q6v5 *qproc, + struct regmap *halt_map, + u32 offset) +{ + unsigned long timeout; + unsigned int val; + int ret; + + /* Check if we're already idle */ + ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); + if (!ret && val) + return; + + /* Assert halt request */ + regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1); + + /* Wait for halt */ + timeout = jiffies + msecs_to_jiffies(HALT_ACK_TIMEOUT_MS); + for (;;) { + ret = regmap_read(halt_map, offset + AXI_HALTACK_REG, &val); + if (ret || val || time_after(jiffies, timeout)) + break; + + msleep(1); + } + + ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val); + if (ret || !val) + dev_err(qproc->dev, "port failed halt\n"); + + /* Clear halt request (port will remain halted until reset) */ + regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0); +} + +static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw) +{ + DEFINE_DMA_ATTRS(attrs); + dma_addr_t phys; + void *ptr; + int ret; + + dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, &attrs); + ptr = dma_alloc_attrs(qproc->dev, fw->size, &phys, GFP_KERNEL, &attrs); + if (!ptr) { + dev_err(qproc->dev, "failed to allocate mdt buffer\n"); + return -ENOMEM; + } + + memcpy(ptr, fw->data, fw->size); + + writel(phys, qproc->rmb_base + RMB_PMI_META_DATA_REG); + writel(RMB_CMD_META_DATA_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); + + ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_META_DATA_AUTH_SUCCESS, 1000); + if (ret == -ETIMEDOUT) + dev_err(qproc->dev, "MPSS header authentication timed out\n"); + else if (ret < 0) + dev_err(qproc->dev, "MPSS header authentication failed: %d\n", ret); + + dma_free_attrs(qproc->dev, fw->size, ptr, phys, &attrs); + + return ret < 0 ? ret : 0; +} + +static int q6v5_mpss_validate(struct q6v5 *qproc, const struct firmware *fw) +{ + const struct elf32_phdr *phdrs; + const struct elf32_phdr *phdr; + struct elf32_hdr *ehdr; + phys_addr_t boot_addr; + phys_addr_t fw_addr; + bool relocate; + size_t size; + int ret; + int i; + + ret = qcom_mdt_parse(fw, &fw_addr, NULL, &relocate); + if (ret) { + dev_err(qproc->dev, "failed to parse mdt header\n"); + return ret; + } + + if (relocate) + boot_addr = qproc->mpss_phys; + else + boot_addr = fw_addr; + + ehdr = (struct elf32_hdr *)fw->data; + phdrs = (struct elf32_phdr *)(ehdr + 1); + for (i = 0; i < ehdr->e_phnum; i++, phdr++) { + phdr = &phdrs[i]; + + if (phdr->p_type != PT_LOAD) + continue; + + if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) + continue; + + if (!phdr->p_memsz) + continue; + + size = readl(qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); + if (!size) { + writel(boot_addr, qproc->rmb_base + RMB_PMI_CODE_START_REG); + writel(RMB_CMD_LOAD_READY, qproc->rmb_base + RMB_MBA_COMMAND_REG); + } + + size += phdr->p_memsz; + writel(size, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); + } + + ret = q6v5_rmb_mba_wait(qproc, RMB_MBA_AUTH_COMPLETE, 10000); + if (ret == -ETIMEDOUT) + dev_err(qproc->dev, "MPSS authentication timed out\n"); + else if (ret < 0) + dev_err(qproc->dev, "MPSS authentication failed: %d\n", ret); + + return ret < 0 ? ret : 0; +} + +static int q6v5_mpss_load(struct q6v5 *qproc) +{ + const struct firmware *fw; + phys_addr_t fw_addr; + bool relocate; + int ret; + + ret = request_firmware(&fw, MPSS_FIRMWARE_NAME, qproc->dev); + if (ret < 0) { + dev_err(qproc->dev, "unable to load " MPSS_FIRMWARE_NAME "\n"); + return ret; + } + + ret = qcom_mdt_parse(fw, &fw_addr, NULL, &relocate); + if (ret) { + dev_err(qproc->dev, "failed to parse mdt header\n"); + goto release_firmware; + } + + if (relocate) + qproc->mpss_reloc = fw_addr; + + /* Initialize the RMB validator */ + writel(0, qproc->rmb_base + RMB_PMI_CODE_LENGTH_REG); + + ret = q6v5_mpss_init_image(qproc, fw); + if (ret) + goto release_firmware; + + ret = qcom_mdt_load(qproc->rproc, fw, MPSS_FIRMWARE_NAME); + if (ret) + goto release_firmware; + + ret = q6v5_mpss_validate(qproc, fw); + +release_firmware: + release_firmware(fw); + + return ret < 0 ? ret : 0; +} + +static int q6v5_start(struct rproc *rproc) +{ + struct q6v5 *qproc = (struct q6v5 *)rproc->priv; + int ret; + + ret = q6v5_regulator_enable(qproc); + if (ret) { + dev_err(qproc->dev, "failed to enable supplies\n"); + return ret; + } + + ret = reset_control_deassert(qproc->mss_restart); + if (ret) { + dev_err(qproc->dev, "failed to deassert mss restart\n"); + goto disable_vdd; + } + + ret = clk_prepare_enable(qproc->ahb_clk); + if (ret) + goto assert_reset; + + ret = clk_prepare_enable(qproc->axi_clk); + if (ret) + goto disable_ahb_clk; + + ret = clk_prepare_enable(qproc->rom_clk); + if (ret) + goto disable_axi_clk; + + writel(qproc->mba_phys, qproc->rmb_base + RMB_MBA_IMAGE_REG); + + ret = q6v5proc_reset(qproc); + if (ret) + goto halt_axi_ports; + + ret = q6v5_rmb_mba_wait(qproc, 0, 5000); + if (ret == -ETIMEDOUT) { + dev_err(qproc->dev, "MBA boot timed out\n"); + goto halt_axi_ports; + } else if (ret != RMB_MBA_XPU_UNLOCKED && + ret != RMB_MBA_XPU_UNLOCKED_SCRIBBLED) { + dev_err(qproc->dev, "MBA returned unexpected status %d\n", ret); + ret = -EINVAL; + goto halt_axi_ports; + } + + dev_info(qproc->dev, "MBA booted, loading mpss\n"); + + ret = q6v5_mpss_load(qproc); + if (ret) + goto halt_axi_ports; + + ret = wait_for_completion_timeout(&qproc->start_done, + msecs_to_jiffies(5000)); + if (ret == 0) { + dev_err(qproc->dev, "start timed out\n"); + ret = -ETIMEDOUT; + goto halt_axi_ports; + } + + qproc->running = true; + + /* TODO: All done, release the handover resources */ + + return 0; + +halt_axi_ports: + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6); + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem); + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); + + clk_disable_unprepare(qproc->rom_clk); +disable_axi_clk: + clk_disable_unprepare(qproc->axi_clk); +disable_ahb_clk: + clk_disable_unprepare(qproc->ahb_clk); +assert_reset: + reset_control_assert(qproc->mss_restart); +disable_vdd: + q6v5_regulator_disable(qproc); + + return ret; +} + +static int q6v5_stop(struct rproc *rproc) +{ + struct q6v5 *qproc = (struct q6v5 *)rproc->priv; + int ret; + + qproc->running = false; + + qcom_smem_state_update_bits(qproc->state, + BIT(qproc->stop_bit), BIT(qproc->stop_bit)); + + ret = wait_for_completion_timeout(&qproc->stop_done, + msecs_to_jiffies(5000)); + if (ret == 0) + dev_err(qproc->dev, "timed out on wait\n"); + + qcom_smem_state_update_bits(qproc->state, BIT(qproc->stop_bit), 0); + + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6); + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem); + q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc); + + reset_control_assert(qproc->mss_restart); + clk_disable_unprepare(qproc->rom_clk); + clk_disable_unprepare(qproc->axi_clk); + clk_disable_unprepare(qproc->ahb_clk); + q6v5_regulator_disable(qproc); + + return 0; +} + +static void *q6v5_da_to_va(struct rproc *rproc, u64 da, int len) +{ + struct q6v5 *qproc = rproc->priv; + int offset; + + offset = da - qproc->mpss_reloc; + if (offset < 0 || offset + len > qproc->mpss_size) + return NULL; + + return qproc->mpss_region + offset; +} + +static const struct rproc_ops q6v5_ops = { + .start = q6v5_start, + .stop = q6v5_stop, + .da_to_va = q6v5_da_to_va, +}; + +static irqreturn_t q6v5_wdog_interrupt(int irq, void *dev) +{ + struct q6v5 *qproc = dev; + size_t len; + char *msg; + + /* Sometimes the stop triggers a watchdog rather than a stop-ack */ + if (!qproc->running) { + complete(&qproc->stop_done); + return IRQ_HANDLED; + } + + msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, MPSS_CRASH_REASON_SMEM, &len); + if (!IS_ERR(msg) && len > 0 && msg[0]) + dev_err(qproc->dev, "watchdog received: %s\n", msg); + else + dev_err(qproc->dev, "watchdog without message\n"); + + rproc_report_crash(qproc->rproc, RPROC_WATCHDOG); + + if (!IS_ERR(msg)) + msg[0] = '\0'; + + return IRQ_HANDLED; +} + +static irqreturn_t q6v5_fatal_interrupt(int irq, void *dev) +{ + struct q6v5 *qproc = dev; + size_t len; + char *msg; + + msg = qcom_smem_get(QCOM_SMEM_HOST_ANY, MPSS_CRASH_REASON_SMEM, &len); + if (!IS_ERR(msg) && len > 0 && msg[0]) + dev_err(qproc->dev, "fatal error received: %s\n", msg); + else + dev_err(qproc->dev, "fatal error without message\n"); + + rproc_report_crash(qproc->rproc, RPROC_FATAL_ERROR); + + if (!IS_ERR(msg)) + msg[0] = '\0'; + + return IRQ_HANDLED; +} + +static irqreturn_t q6v5_handover_interrupt(int irq, void *dev) +{ + struct q6v5 *qproc = dev; + + complete(&qproc->start_done); + return IRQ_HANDLED; +} + +static irqreturn_t q6v5_stop_ack_interrupt(int irq, void *dev) +{ + struct q6v5 *qproc = dev; + + complete(&qproc->stop_done); + return IRQ_HANDLED; +} + +static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev) +{ + struct of_phandle_args args; + struct resource *res; + int ret; + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "qdsp6"); + qproc->reg_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(qproc->reg_base)) + return PTR_ERR(qproc->reg_base); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rmb"); + qproc->rmb_base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(qproc->rmb_base)) + return PTR_ERR(qproc->rmb_base); + + ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node, + "qcom,halt-regs", 3, 0, &args); + if (ret < 0) { + dev_err(&pdev->dev, "failed to parse qcom,halt-regs\n"); + return -EINVAL; + } + + qproc->halt_map = syscon_node_to_regmap(args.np); + of_node_put(args.np); + if (IS_ERR(qproc->halt_map)) + return PTR_ERR(qproc->halt_map); + + qproc->halt_q6 = args.args[0]; + qproc->halt_modem = args.args[1]; + qproc->halt_nc = args.args[2]; + + return 0; +} + +static int q6v5_init_clocks(struct q6v5 *qproc) +{ + qproc->ahb_clk = devm_clk_get(qproc->dev, "iface"); + if (IS_ERR(qproc->ahb_clk)) { + dev_err(qproc->dev, "failed to get iface clock\n"); + return PTR_ERR(qproc->ahb_clk); + } + + qproc->axi_clk = devm_clk_get(qproc->dev, "bus"); + if (IS_ERR(qproc->axi_clk)) { + dev_err(qproc->dev, "failed to get bus clock\n"); + return PTR_ERR(qproc->axi_clk); + } + + qproc->rom_clk = devm_clk_get(qproc->dev, "mem"); + if (IS_ERR(qproc->rom_clk)) { + dev_err(qproc->dev, "failed to get mem clock\n"); + return PTR_ERR(qproc->rom_clk); + } + + return 0; +} + +static int q6v5_init_reset(struct q6v5 *qproc) +{ + qproc->mss_restart = devm_reset_control_get(qproc->dev, NULL); + if (IS_ERR(qproc->mss_restart)) { + dev_err(qproc->dev, "failed to acquire mss restart\n"); + return PTR_ERR(qproc->mss_restart); + } + + return 0; +} + +static int q6v5_request_irq(struct q6v5 *qproc, + struct platform_device *pdev, + const char *name, + irq_handler_t thread_fn) +{ + int ret; + + ret = platform_get_irq_byname(pdev, name); + if (ret < 0) { + dev_err(&pdev->dev, "no %s IRQ defined\n", name); + return ret; + } + + ret = devm_request_threaded_irq(&pdev->dev, ret, + NULL, thread_fn, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + "q6v5", qproc); + if (ret) + dev_err(&pdev->dev, "request %s IRQ failed\n", name); + + return ret; +} + +static int q6v5_alloc_memory_region(struct q6v5 *qproc) +{ + struct device_node *child; + struct device_node *node; + struct resource r; + int ret; + + child = of_get_child_by_name(qproc->dev->of_node, "mba"); + node = of_parse_phandle(child, "memory-region", 0); + ret = of_address_to_resource(node, 0, &r); + if (ret) { + dev_err(qproc->dev, "unable to resolve mba region\n"); + return ret; + } + + qproc->mba_phys = r.start; + qproc->mba_size = resource_size(&r); + qproc->mba_region = devm_ioremap_wc(qproc->dev, qproc->mba_phys, qproc->mba_size); + if (!qproc->mba_region) { + dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", + &r.start, qproc->mba_size); + return -EBUSY; + } + + child = of_get_child_by_name(qproc->dev->of_node, "mpss"); + node = of_parse_phandle(child, "memory-region", 0); + ret = of_address_to_resource(node, 0, &r); + if (ret) { + dev_err(qproc->dev, "unable to resolve mpss region\n"); + return ret; + } + + qproc->mpss_phys = qproc->mpss_reloc = r.start; + qproc->mpss_size = resource_size(&r); + qproc->mpss_region = devm_ioremap_wc(qproc->dev, qproc->mpss_phys, qproc->mpss_size); + if (!qproc->mpss_region) { + dev_err(qproc->dev, "unable to map memory region: %pa+%zx\n", + &r.start, qproc->mpss_size); + return -EBUSY; + } + + return 0; +} + +static int q6v5_probe(struct platform_device *pdev) +{ + struct q6v5 *qproc; + struct rproc *rproc; + int ret; + + rproc = rproc_alloc(&pdev->dev, pdev->name, &q6v5_ops, + MBA_FIRMWARE_NAME, sizeof(*qproc)); + if (!rproc) { + dev_err(&pdev->dev, "failed to allocate rproc\n"); + return -ENOMEM; + } + + rproc->fw_ops = &q6v5_fw_ops; + + qproc = (struct q6v5 *)rproc->priv; + qproc->dev = &pdev->dev; + qproc->rproc = rproc; + platform_set_drvdata(pdev, qproc); + + init_completion(&qproc->start_done); + init_completion(&qproc->stop_done); + + ret = q6v5_init_mem(qproc, pdev); + if (ret) + goto free_rproc; + + ret = q6v5_alloc_memory_region(qproc); + if (ret) + goto free_rproc; + + ret = q6v5_init_clocks(qproc); + if (ret) + goto free_rproc; + + ret = q6v5_regulator_init(qproc); + if (ret) + goto free_rproc; + + ret = q6v5_init_reset(qproc); + if (ret) + goto free_rproc; + + ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt); + if (ret < 0) + goto free_rproc; + + ret = q6v5_request_irq(qproc, pdev, "fatal", q6v5_fatal_interrupt); + if (ret < 0) + goto free_rproc; + + ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt); + if (ret < 0) + goto free_rproc; + + ret = q6v5_request_irq(qproc, pdev, "stop-ack", q6v5_stop_ack_interrupt); + if (ret < 0) + goto free_rproc; + + qproc->state = qcom_smem_state_get(&pdev->dev, "stop", &qproc->stop_bit); + if (IS_ERR(qproc->state)) + goto free_rproc; + + ret = rproc_add(rproc); + if (ret) + goto free_rproc; + + return 0; + +free_rproc: + rproc_put(rproc); + + return ret; +} + +static int q6v5_remove(struct platform_device *pdev) +{ + struct q6v5 *qproc = platform_get_drvdata(pdev); + + rproc_del(qproc->rproc); + rproc_put(qproc->rproc); + + return 0; +} + +static const struct of_device_id q6v5_of_match[] = { + { .compatible = "qcom,q6v5-pil", }, + { }, +}; + +static struct platform_driver q6v5_driver = { + .probe = q6v5_probe, + .remove = q6v5_remove, + .driver = { + .name = "qcom-q6v5-pil", + .of_match_table = q6v5_of_match, + }, +}; +module_platform_driver(q6v5_driver); + +MODULE_DESCRIPTION("Peripheral Image Loader for Hexagon"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index db3958b3f094..fe0539ed9cb5 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -1264,11 +1264,6 @@ int rproc_add(struct rproc *rproc) if (ret < 0) return ret; - /* expose to rproc_get_by_phandle users */ - mutex_lock(&rproc_list_mutex); - list_add(&rproc->node, &rproc_list); - mutex_unlock(&rproc_list_mutex); - dev_info(dev, "%s is available\n", rproc->name); dev_info(dev, "Note: remoteproc is still under development and considered experimental.\n"); @@ -1276,8 +1271,16 @@ int rproc_add(struct rproc *rproc) /* create debugfs entries */ rproc_create_debug_dir(rproc); + ret = rproc_add_virtio_devices(rproc); + if (ret < 0) + return ret; - return rproc_add_virtio_devices(rproc); + /* expose to rproc_get_by_phandle users */ + mutex_lock(&rproc_list_mutex); + list_add(&rproc->node, &rproc_list); + mutex_unlock(&rproc_list_mutex); + + return 0; } EXPORT_SYMBOL(rproc_add); diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index fac1b51ea0de..9d66b4fb174b 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -31,7 +31,7 @@ static void dcssblk_release(struct gendisk *disk, fmode_t mode); static blk_qc_t dcssblk_make_request(struct request_queue *q, struct bio *bio); static long dcssblk_direct_access(struct block_device *bdev, sector_t secnum, - void __pmem **kaddr, pfn_t *pfn, long size); + void **kaddr, pfn_t *pfn, long size); static char dcssblk_segments[DCSSBLK_PARM_LEN] = "\0"; @@ -884,7 +884,7 @@ fail: static long dcssblk_direct_access (struct block_device *bdev, sector_t secnum, - void __pmem **kaddr, pfn_t *pfn, long size) + void **kaddr, pfn_t *pfn, long size) { struct dcssblk_dev_info *dev_info; unsigned long offset, dev_sz; @@ -894,7 +894,7 @@ dcssblk_direct_access (struct block_device *bdev, sector_t secnum, return -ENODEV; dev_sz = dev_info->end - dev_info->start; offset = secnum * 512; - *kaddr = (void __pmem *) (dev_info->start + offset); + *kaddr = (void *) dev_info->start + offset; *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV); return dev_sz - offset; diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h index 59c477883a73..6201dce3553b 100644 --- a/drivers/scsi/qla2xxx/qla_nx.h +++ b/drivers/scsi/qla2xxx/qla_nx.h @@ -1183,7 +1183,6 @@ static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 0x410000AC, #define CRB_NIU_XG_PAUSE_CTL_P1 0x8 #define qla82xx_get_temp_val(x) ((x) >> 16) -#define qla82xx_get_temp_val1(x) ((x) && 0x0000FFFF) #define qla82xx_get_temp_state(x) ((x) & 0xffff) #define qla82xx_encode_temp(val, state) (((val) << 16) | (state)) diff --git a/drivers/staging/android/lowmemorykiller.c b/drivers/staging/android/lowmemorykiller.c index 24d2745e9437..45a1b4ec4ca3 100644 --- a/drivers/staging/android/lowmemorykiller.c +++ b/drivers/staging/android/lowmemorykiller.c @@ -72,10 +72,10 @@ static unsigned long lowmem_deathpending_timeout; static unsigned long lowmem_count(struct shrinker *s, struct shrink_control *sc) { - return global_page_state(NR_ACTIVE_ANON) + - global_page_state(NR_ACTIVE_FILE) + - global_page_state(NR_INACTIVE_ANON) + - global_page_state(NR_INACTIVE_FILE); + return global_node_page_state(NR_ACTIVE_ANON) + + global_node_page_state(NR_ACTIVE_FILE) + + global_node_page_state(NR_INACTIVE_ANON) + + global_node_page_state(NR_INACTIVE_FILE); } static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) @@ -91,8 +91,8 @@ static unsigned long lowmem_scan(struct shrinker *s, struct shrink_control *sc) short selected_oom_score_adj; int array_size = ARRAY_SIZE(lowmem_adj); int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages; - int other_file = global_page_state(NR_FILE_PAGES) - - global_page_state(NR_SHMEM) - + int other_file = global_node_page_state(NR_FILE_PAGES) - + global_node_page_state(NR_SHMEM) - total_swapcache_pages(); if (lowmem_adj_size < array_size) diff --git a/drivers/staging/lustre/lustre/llite/statahead.c b/drivers/staging/lustre/lustre/llite/statahead.c index f77524294c27..8e52722266fe 100644 --- a/drivers/staging/lustre/lustre/llite/statahead.c +++ b/drivers/staging/lustre/lustre/llite/statahead.c @@ -170,7 +170,8 @@ static inline int is_omitted_entry(struct ll_statahead_info *sai, __u64 index) * Insert it into sai_entries tail when init. */ static struct ll_sa_entry * -ll_sa_entry_alloc(struct ll_statahead_info *sai, __u64 index, +ll_sa_entry_alloc(struct dentry *parent, + struct ll_statahead_info *sai, __u64 index, const char *name, int len) { struct ll_inode_info *lli; @@ -217,7 +218,8 @@ ll_sa_entry_alloc(struct ll_statahead_info *sai, __u64 index, dname = (char *)entry + sizeof(struct ll_sa_entry); memcpy(dname, name, len); dname[len] = 0; - entry->se_qstr.hash = full_name_hash(name, len); + + entry->se_qstr.hash = full_name_hash(parent, name, len); entry->se_qstr.len = len; entry->se_qstr.name = dname; @@ -898,7 +900,7 @@ static void ll_statahead_one(struct dentry *parent, const char *entry_name, int rc; int rc1; - entry = ll_sa_entry_alloc(sai, sai->sai_index, entry_name, + entry = ll_sa_entry_alloc(parent, sai, sai->sai_index, entry_name, entry_name_len); if (IS_ERR(entry)) return; diff --git a/drivers/staging/lustre/lustre/osc/osc_cache.c b/drivers/staging/lustre/lustre/osc/osc_cache.c index d1a7d6beee60..d011135802d5 100644 --- a/drivers/staging/lustre/lustre/osc/osc_cache.c +++ b/drivers/staging/lustre/lustre/osc/osc_cache.c @@ -1864,7 +1864,8 @@ void osc_dec_unstable_pages(struct ptlrpc_request *req) LASSERT(page_count >= 0); for (i = 0; i < page_count; i++) - dec_zone_page_state(desc->bd_iov[i].kiov_page, NR_UNSTABLE_NFS); + dec_node_page_state(desc->bd_iov[i].kiov_page, + NR_UNSTABLE_NFS); atomic_sub(page_count, &cli->cl_cache->ccc_unstable_nr); LASSERT(atomic_read(&cli->cl_cache->ccc_unstable_nr) >= 0); @@ -1898,7 +1899,8 @@ void osc_inc_unstable_pages(struct ptlrpc_request *req) LASSERT(page_count >= 0); for (i = 0; i < page_count; i++) - inc_zone_page_state(desc->bd_iov[i].kiov_page, NR_UNSTABLE_NFS); + inc_node_page_state(desc->bd_iov[i].kiov_page, + NR_UNSTABLE_NFS); LASSERT(atomic_read(&cli->cl_cache->ccc_unstable_nr) >= 0); atomic_add(page_count, &cli->cl_cache->ccc_unstable_nr); diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 6e705971d637..eb8f8d37cd95 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig @@ -79,15 +79,6 @@ config USB_LCD To compile this driver as a module, choose M here: the module will be called usblcd. -config USB_LED - tristate "USB LED driver support" - help - Say Y here if you want to connect an USBLED device to your - computer's USB port. - - To compile this driver as a module, choose M here: the - module will be called usbled. - config USB_CYPRESS_CY7C63 tristate "Cypress CY7C63xxx USB driver support" help diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 2769cf6351b4..3d79faaad2fb 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile @@ -15,7 +15,6 @@ obj-$(CONFIG_USB_IOWARRIOR) += iowarrior.o obj-$(CONFIG_USB_ISIGHTFW) += isight_firmware.o obj-$(CONFIG_USB_LCD) += usblcd.o obj-$(CONFIG_USB_LD) += ldusb.o -obj-$(CONFIG_USB_LED) += usbled.o obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o obj-$(CONFIG_USB_RIO500) += rio500.o obj-$(CONFIG_USB_TEST) += usbtest.o diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c deleted file mode 100644 index bdef0d6eb91d..000000000000 --- a/drivers/usb/misc/usbled.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * USB LED driver - * - * Copyright (C) 2004 Greg Kroah-Hartman (greg@kroah.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation, version 2. - * - */ - -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/usb.h> - - -#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com" -#define DRIVER_DESC "USB LED Driver" - -enum led_type { - DELCOM_VISUAL_SIGNAL_INDICATOR, - DREAM_CHEEKY_WEBMAIL_NOTIFIER, - RISO_KAGAKU_LED -}; - -/* the Webmail LED made by RISO KAGAKU CORP. decodes a color index - internally, we want to keep the red+green+blue sysfs api, so we decode - from 1-bit RGB to the riso kagaku color index according to this table... */ - -static unsigned const char riso_kagaku_tbl[] = { -/* R+2G+4B -> riso kagaku color index */ - [0] = 0, /* black */ - [1] = 2, /* red */ - [2] = 1, /* green */ - [3] = 5, /* yellow */ - [4] = 3, /* blue */ - [5] = 6, /* magenta */ - [6] = 4, /* cyan */ - [7] = 7 /* white */ -}; - -#define RISO_KAGAKU_IX(r,g,b) riso_kagaku_tbl[((r)?1:0)+((g)?2:0)+((b)?4:0)] - -/* table of devices that work with this driver */ -static const struct usb_device_id id_table[] = { - { USB_DEVICE(0x0fc5, 0x1223), - .driver_info = DELCOM_VISUAL_SIGNAL_INDICATOR }, - { USB_DEVICE(0x1d34, 0x0004), - .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, - { USB_DEVICE(0x1d34, 0x000a), - .driver_info = DREAM_CHEEKY_WEBMAIL_NOTIFIER }, - { USB_DEVICE(0x1294, 0x1320), - .driver_info = RISO_KAGAKU_LED }, - { }, -}; -MODULE_DEVICE_TABLE(usb, id_table); - -struct usb_led { - struct usb_device *udev; - unsigned char blue; - unsigned char red; - unsigned char green; - enum led_type type; -}; - -static void change_color(struct usb_led *led) -{ - int retval = 0; - unsigned char *buffer; - int actlength; - - buffer = kmalloc(8, GFP_KERNEL); - if (!buffer) { - dev_err(&led->udev->dev, "out of memory\n"); - return; - } - - switch (led->type) { - case DELCOM_VISUAL_SIGNAL_INDICATOR: { - unsigned char color = 0x07; - - if (led->blue) - color &= ~0x04; - if (led->red) - color &= ~0x02; - if (led->green) - color &= ~0x01; - dev_dbg(&led->udev->dev, - "blue = %d, red = %d, green = %d, color = %.2x\n", - led->blue, led->red, led->green, color); - - retval = usb_control_msg(led->udev, - usb_sndctrlpipe(led->udev, 0), - 0x12, - 0xc8, - (0x02 * 0x100) + 0x0a, - (0x00 * 0x100) + color, - buffer, - 8, - 2000); - break; - } - - case DREAM_CHEEKY_WEBMAIL_NOTIFIER: - dev_dbg(&led->udev->dev, - "red = %d, green = %d, blue = %d\n", - led->red, led->green, led->blue); - - buffer[0] = led->red; - buffer[1] = led->green; - buffer[2] = led->blue; - buffer[3] = buffer[4] = buffer[5] = 0; - buffer[6] = 0x1a; - buffer[7] = 0x05; - - retval = usb_control_msg(led->udev, - usb_sndctrlpipe(led->udev, 0), - 0x09, - 0x21, - 0x200, - 0, - buffer, - 8, - 2000); - break; - - case RISO_KAGAKU_LED: - buffer[0] = RISO_KAGAKU_IX(led->red, led->green, led->blue); - buffer[1] = 0; - buffer[2] = 0; - buffer[3] = 0; - buffer[4] = 0; - - retval = usb_interrupt_msg(led->udev, - usb_sndctrlpipe(led->udev, 2), - buffer, 5, &actlength, 1000 /*ms timeout*/); - break; - - default: - dev_err(&led->udev->dev, "unknown device type %d\n", led->type); - } - - if (retval) - dev_dbg(&led->udev->dev, "retval = %d\n", retval); - kfree(buffer); -} - -#define show_set(value) \ -static ssize_t show_##value(struct device *dev, struct device_attribute *attr,\ - char *buf) \ -{ \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct usb_led *led = usb_get_intfdata(intf); \ - \ - return sprintf(buf, "%d\n", led->value); \ -} \ -static ssize_t set_##value(struct device *dev, struct device_attribute *attr,\ - const char *buf, size_t count) \ -{ \ - struct usb_interface *intf = to_usb_interface(dev); \ - struct usb_led *led = usb_get_intfdata(intf); \ - int temp = simple_strtoul(buf, NULL, 10); \ - \ - led->value = temp; \ - change_color(led); \ - return count; \ -} \ -static DEVICE_ATTR(value, S_IRUGO | S_IWUSR, show_##value, set_##value); -show_set(blue); -show_set(red); -show_set(green); - -static int led_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct usb_device *udev = interface_to_usbdev(interface); - struct usb_led *dev = NULL; - int retval = -ENOMEM; - - dev = kzalloc(sizeof(struct usb_led), GFP_KERNEL); - if (dev == NULL) { - dev_err(&interface->dev, "out of memory\n"); - goto error_mem; - } - - dev->udev = usb_get_dev(udev); - dev->type = id->driver_info; - - usb_set_intfdata(interface, dev); - - retval = device_create_file(&interface->dev, &dev_attr_blue); - if (retval) - goto error; - retval = device_create_file(&interface->dev, &dev_attr_red); - if (retval) - goto error; - retval = device_create_file(&interface->dev, &dev_attr_green); - if (retval) - goto error; - - if (dev->type == DREAM_CHEEKY_WEBMAIL_NOTIFIER) { - unsigned char *enable; - - enable = kmemdup("\x1f\x02\0\x5f\0\0\x1a\x03", 8, GFP_KERNEL); - if (!enable) { - dev_err(&interface->dev, "out of memory\n"); - retval = -ENOMEM; - goto error; - } - - retval = usb_control_msg(udev, - usb_sndctrlpipe(udev, 0), - 0x09, - 0x21, - 0x200, - 0, - enable, - 8, - 2000); - - kfree(enable); - if (retval != 8) - goto error; - } - - dev_info(&interface->dev, "USB LED device now attached\n"); - return 0; - -error: - device_remove_file(&interface->dev, &dev_attr_blue); - device_remove_file(&interface->dev, &dev_attr_red); - device_remove_file(&interface->dev, &dev_attr_green); - usb_set_intfdata(interface, NULL); - usb_put_dev(dev->udev); - kfree(dev); -error_mem: - return retval; -} - -static void led_disconnect(struct usb_interface *interface) -{ - struct usb_led *dev; - - dev = usb_get_intfdata(interface); - - device_remove_file(&interface->dev, &dev_attr_blue); - device_remove_file(&interface->dev, &dev_attr_red); - device_remove_file(&interface->dev, &dev_attr_green); - - /* first remove the files, then set the pointer to NULL */ - usb_set_intfdata(interface, NULL); - - usb_put_dev(dev->udev); - - kfree(dev); - - dev_info(&interface->dev, "USB LED now disconnected\n"); -} - -static struct usb_driver led_driver = { - .name = "usbled", - .probe = led_probe, - .disconnect = led_disconnect, - .id_table = id_table, -}; - -module_usb_driver(led_driver); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); |