mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2026-01-09 16:51:30 +00:00
Merge pull request #18 from opencomputeproject/master
merge from upstream
This commit is contained in:
@@ -1065,7 +1065,7 @@ class InitrdContext(SubprocessMixin):
|
||||
if "efivarfs" not in buf:
|
||||
cmd = ('modprobe', 'efivarfs',)
|
||||
try:
|
||||
self.check_call(cmd, vmode=self.V1)
|
||||
self.check_output(cmd, vmode=self.V1, stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError:
|
||||
pass
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
import pprint
|
||||
import json
|
||||
import os
|
||||
import os, sys
|
||||
import re
|
||||
import yaml
|
||||
import onl.YamlUtils
|
||||
@@ -386,6 +386,9 @@ class OnlPlatformBase(object):
|
||||
rv[field['name']] = v['data'][field['key']]
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
if 'dmidecodemod' in sys.modules:
|
||||
sys.modules['dmidecodemod'].clear_warnings()
|
||||
return rv
|
||||
|
||||
def upgrade_manifest(self, type_, override_dir=None):
|
||||
|
||||
@@ -67,6 +67,13 @@ def baseconfig():
|
||||
f.write(dmidecode.QuerySection('system')['0x0001']['data']['Version'])
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
if 'dmidecodemod' in sys.modules:
|
||||
mod = sys.modules['dmidecodemod']
|
||||
buf = mod.get_warnings()
|
||||
if buf:
|
||||
[msg("*** %s\n" % x) for x in buf.splitlines(False)]
|
||||
mod.clear_warnings()
|
||||
|
||||
if not platform.baseconfig():
|
||||
msg("*** platform class baseconfig failed.\n", fatal=True)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
kernel-3.16*
|
||||
linux-*
|
||||
|
||||
lib/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/powerpc 3.16.53 Kernel Configuration
|
||||
# Linux/powerpc 3.16.56 Kernel Configuration
|
||||
#
|
||||
# CONFIG_PPC64 is not set
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
kernel-3.16*
|
||||
linux-*
|
||||
|
||||
lib/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/x86_64 3.16.53 Kernel Configuration
|
||||
# Linux/x86_64 3.16.56 Kernel Configuration
|
||||
#
|
||||
CONFIG_64BIT=y
|
||||
CONFIG_X86_64=y
|
||||
@@ -354,6 +354,7 @@ CONFIG_FREEZER=y
|
||||
CONFIG_ZONE_DMA=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_X86_MPPARSE=y
|
||||
CONFIG_RETPOLINE=y
|
||||
# CONFIG_X86_EXTENDED_PLATFORM is not set
|
||||
# CONFIG_X86_INTEL_LPSS is not set
|
||||
CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y
|
||||
@@ -1119,6 +1120,7 @@ CONFIG_FW_LOADER_USER_HELPER=y
|
||||
# CONFIG_SYS_HYPERVISOR is not set
|
||||
# CONFIG_GENERIC_CPU_DEVICES is not set
|
||||
CONFIG_GENERIC_CPU_AUTOPROBE=y
|
||||
CONFIG_GENERIC_CPU_VULNERABILITIES=y
|
||||
# CONFIG_DMA_SHARED_BUFFER is not set
|
||||
|
||||
#
|
||||
|
||||
@@ -25,6 +25,6 @@
|
||||
THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
K_MAJOR_VERSION := 3
|
||||
K_PATCH_LEVEL := 16
|
||||
K_SUB_LEVEL := 53
|
||||
K_SUB_LEVEL := 56
|
||||
K_SUFFIX :=
|
||||
K_PATCH_DIR := $(THIS_DIR)/patches
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,3 +28,4 @@ driver-support-intel-igb-bcm50210-phy.patch
|
||||
driver-igb-netberg-aurora.patch
|
||||
driver-hid-cp2112-mods.patch
|
||||
gcc-no-pie.patch
|
||||
driver-ixgbe-version-5.2.4.patch
|
||||
|
||||
4
packages/base/any/kernels/3.18.25/.gitignore
vendored
4
packages/base/any/kernels/3.18.25/.gitignore
vendored
@@ -1,4 +0,0 @@
|
||||
linux-3.18.25
|
||||
linux-3.18.25-mbuild
|
||||
linux-3.18.25-dtbs
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
kernel-*
|
||||
@@ -1,28 +0,0 @@
|
||||
############################################################
|
||||
#
|
||||
# Default 3.18.25 configuration for arm64 platforms.
|
||||
#
|
||||
############################################################
|
||||
THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
include $(ONL)/make/config.mk
|
||||
|
||||
ifndef K_TARGET_DIR
|
||||
K_TARGET_DIR := $(THIS_DIR)
|
||||
endif
|
||||
|
||||
MODSYNCLIST_EXTRA = arch/arm64/include arch/arm64/Makefile arch/arm64/lib
|
||||
K_PATCH_SERIES=series.arm64
|
||||
|
||||
include ../../kconfig.mk
|
||||
K_CONFIG := arm64-all.config
|
||||
K_BUILD_TARGET := Image Image.gz arm64-nxp-ls2080ardb-r0.dtb arm64-nxp-ls2088ardb-r1.dtb
|
||||
K_COPY_SRC := arch/arm64/boot/Image
|
||||
K_COPY_GZIP := 1
|
||||
ifndef K_COPY_DST
|
||||
K_COPY_DST := kernel-3.18.25-arm64-all.bin.gz
|
||||
endif
|
||||
|
||||
export ARCH=arm64
|
||||
DTS_LIST := arm64-nxp-ls2080ardb-r0
|
||||
|
||||
include $(ONL)/make/kbuild.mk
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
kernel-3.18-x86_64-all
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
33877
packages/base/any/kernels/3.18.25/patches/aufs.patch
vendored
33877
packages/base/any/kernels/3.18.25/patches/aufs.patch
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,67 +0,0 @@
|
||||
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
|
||||
index 051ea94..2a04baa 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
|
||||
@@ -286,6 +286,9 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
|
||||
phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580;
|
||||
phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88;
|
||||
break;
|
||||
+ case BCM54616_E_PHY_ID:
|
||||
+ phy->type = e1000_phy_bcm54616;
|
||||
+ break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
goto out;
|
||||
@@ -1550,6 +1553,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
case e1000_i350:
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
+ case e1000_i354:
|
||||
phpm_reg = rd32(E1000_82580_PHY_POWER_MGMT);
|
||||
phpm_reg &= ~E1000_82580_PM_GO_LINKD;
|
||||
wr32(E1000_82580_PHY_POWER_MGMT, phpm_reg);
|
||||
@@ -1593,6 +1597,8 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
case e1000_phy_82580:
|
||||
ret_val = igb_copper_link_setup_82580(hw);
|
||||
break;
|
||||
+ case e1000_phy_bcm54616:
|
||||
+ break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
break;
|
||||
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
|
||||
index 217f813..5322fbf 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
|
||||
@@ -860,6 +860,7 @@
|
||||
#define M88_VENDOR 0x0141
|
||||
#define I210_I_PHY_ID 0x01410C00
|
||||
#define M88E1543_E_PHY_ID 0x01410EA0
|
||||
+#define BCM54616_E_PHY_ID 0x3625D10
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
|
||||
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
|
||||
index 2003b37..d82c96b 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
|
||||
@@ -128,6 +128,7 @@ enum e1000_phy_type {
|
||||
e1000_phy_ife,
|
||||
e1000_phy_82580,
|
||||
e1000_phy_i210,
|
||||
+ e1000_phy_bcm54616,
|
||||
};
|
||||
|
||||
enum e1000_bus_type {
|
||||
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
|
||||
index e0f3664..013c1f1 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/igb_main.c
|
||||
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
|
||||
@@ -108,6 +108,7 @@ static const struct pci_device_id igb_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_COPPER), board_82575 },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575EB_FIBER_SERDES), board_82575 },
|
||||
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82575GB_QUAD_COPPER), board_82575 },
|
||||
+ { PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_SGMII), board_82575 },
|
||||
/* required last entry */
|
||||
{0, }
|
||||
};
|
||||
@@ -1,327 +0,0 @@
|
||||
diff -uNr a/drivers/soc/fsl/Kconfig.arm b/drivers/soc/fsl/Kconfig.arm
|
||||
--- a/drivers/soc/fsl/Kconfig.arm 2017-06-05 17:37:14.530348991 +0530
|
||||
+++ b/drivers/soc/fsl/Kconfig.arm 2017-06-05 17:32:18.630348990 +0530
|
||||
@@ -23,3 +23,7 @@
|
||||
if LS1_SOC_DRIVERS
|
||||
source "drivers/soc/fsl/ls1/Kconfig"
|
||||
endif
|
||||
+
|
||||
+if LS_SOC_DRIVERS
|
||||
+ source "drivers/soc/fsl/ls2-console/Kconfig"
|
||||
+endif
|
||||
diff -uNr a/drivers/soc/fsl/ls2-console/Kconfig b/drivers/soc/fsl/ls2-console/Kconfig
|
||||
--- a/drivers/soc/fsl/ls2-console/Kconfig 1970-01-01 05:30:00.000000000 +0530
|
||||
+++ b/drivers/soc/fsl/ls2-console/Kconfig 2017-06-05 17:32:52.582348990 +0530
|
||||
@@ -0,0 +1,4 @@
|
||||
+config FSL_LS2_CONSOLE
|
||||
+ tristate "Layerscape MC and AIOP console support"
|
||||
+ depends on ARCH_LAYERSCAPE
|
||||
+ default y
|
||||
diff -uNr a/drivers/soc/fsl/ls2-console/ls2-console.c b/drivers/soc/fsl/ls2-console/ls2-console.c
|
||||
--- a/drivers/soc/fsl/ls2-console/ls2-console.c 1970-01-01 05:30:00.000000000 +0530
|
||||
+++ b/drivers/soc/fsl/ls2-console/ls2-console.c 2017-06-05 17:50:42.494348990 +0530
|
||||
@@ -0,0 +1,291 @@
|
||||
+/* Copyright 2015-2016 Freescale Semiconductor Inc.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without
|
||||
+ * modification, are permitted provided that the following conditions are met:
|
||||
+ * * Redistributions of source code must retain the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer.
|
||||
+ * * Redistributions in binary form must reproduce the above copyright
|
||||
+ * notice, this list of conditions and the following disclaimer in the
|
||||
+ * documentation and/or other materials provided with the distribution.
|
||||
+ * * Neither the name of the above-listed copyright holders nor the
|
||||
+ * names of any contributors may be used to endorse or promote products
|
||||
+ * derived from this software without specific prior written permission.
|
||||
+ *
|
||||
+ *
|
||||
+ * ALTERNATIVELY, this software may be distributed under the terms of the
|
||||
+ * GNU General Public License ("GPL") as published by the Free Software
|
||||
+ * Foundation, either version 2 of that License or (at your option) any
|
||||
+ * later version.
|
||||
+ *
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
||||
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
+ * POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/miscdevice.h>
|
||||
+#include <linux/uaccess.h>
|
||||
+#include <linux/poll.h>
|
||||
+#include <linux/compat.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/io.h>
|
||||
+
|
||||
+/* SoC address for the MC firmware base low/high registers */
|
||||
+#define SOC_CCSR_MC_FW_BASE_ADDR_REGS 0x8340020
|
||||
+#define SOC_CCSR_MC_FW_BASE_ADDR_REGS_SIZE 2
|
||||
+/* MC firmware base low/high registers indexes */
|
||||
+#define MCFBALR_OFFSET 0
|
||||
+#define MCFBAHR_OFFSET 1
|
||||
+
|
||||
+/* Bit mask used to obtain the most significant part of the MC base address */
|
||||
+#define MC_FW_HIGH_ADDR_MASK 0x1FFFF
|
||||
+/* Bit mask used to obtain the least significant part of the MC base address */
|
||||
+#define MC_FW_LOW_ADDR_MASK 0xE0000000
|
||||
+
|
||||
+#define MC_BUFFER_OFFSET 0x01000000
|
||||
+#define MC_BUFFER_SIZE (1024*1024*16)
|
||||
+#define MC_OFFSET_DELTA (MC_BUFFER_OFFSET)
|
||||
+
|
||||
+#define AIOP_BUFFER_OFFSET 0x06000000
|
||||
+#define AIOP_BUFFER_SIZE (1024*1024*16)
|
||||
+#define AIOP_OFFSET_DELTA (0)
|
||||
+
|
||||
+struct log_header {
|
||||
+ char magic_word[8]; /* magic word */
|
||||
+ uint32_t buf_start; /* holds the 32-bit little-endian
|
||||
+ offset of the start of the buffer */
|
||||
+ uint32_t buf_length; /* holds the 32-bit little-endian
|
||||
+ length of the buffer */
|
||||
+ uint32_t last_byte; /* holds the 32-bit little-endian offset
|
||||
+ of the byte after the last byte that was written */
|
||||
+ char reserved[44];
|
||||
+};
|
||||
+
|
||||
+#define LOG_HEADER_FLAG_BUFFER_WRAPAROUND 0x80000000
|
||||
+#define LOG_VERSION_MAJOR 1
|
||||
+#define LOG_VERSION_MINOR 0
|
||||
+
|
||||
+
|
||||
+#define invalidate(p) { asm volatile("dc ivac, %0" : : "r" (p) : "memory"); }
|
||||
+
|
||||
+struct console_data {
|
||||
+ char *map_addr;
|
||||
+ struct log_header *hdr;
|
||||
+ char *start_addr; /* Start of buffer */
|
||||
+ char *end_addr; /* End of buffer */
|
||||
+ char *end_of_data; /* Current end of data */
|
||||
+ char *cur_ptr; /* Last data sent to console */
|
||||
+};
|
||||
+
|
||||
+#define LAST_BYTE(a) ((a) & ~(LOG_HEADER_FLAG_BUFFER_WRAPAROUND))
|
||||
+
|
||||
+static inline void __adjust_end(struct console_data *cd)
|
||||
+{
|
||||
+ cd->end_of_data = cd->start_addr
|
||||
+ + LAST_BYTE(le32_to_cpu(cd->hdr->last_byte));
|
||||
+}
|
||||
+
|
||||
+static inline void adjust_end(struct console_data *cd)
|
||||
+{
|
||||
+ invalidate(cd->hdr);
|
||||
+ __adjust_end(cd);
|
||||
+}
|
||||
+
|
||||
+static inline uint64_t get_mc_fw_base_address(void) {
|
||||
+ uint32_t* mcfbaregs = (uint32_t*) ioremap(SOC_CCSR_MC_FW_BASE_ADDR_REGS,
|
||||
+ SOC_CCSR_MC_FW_BASE_ADDR_REGS_SIZE);
|
||||
+ uint64_t mcfwbase = 0ULL;
|
||||
+ mcfwbase = readl(mcfbaregs + MCFBAHR_OFFSET) & MC_FW_HIGH_ADDR_MASK;
|
||||
+ mcfwbase <<= 32;
|
||||
+ mcfwbase |= readl(mcfbaregs + MCFBALR_OFFSET) & MC_FW_LOW_ADDR_MASK;
|
||||
+ iounmap(mcfbaregs);
|
||||
+ pr_info("fsl-ls2-console: MC base address at 0x%016llx\n", mcfwbase);
|
||||
+ return mcfwbase;
|
||||
+}
|
||||
+
|
||||
+static int fsl_ls2_generic_console_open(struct inode *node, struct file *fp,
|
||||
+ u64 offset, u64 size,
|
||||
+ uint8_t *emagic, uint8_t magic_len,
|
||||
+ u32 offset_delta)
|
||||
+{
|
||||
+ struct console_data *cd;
|
||||
+ uint8_t *magic;
|
||||
+ uint32_t wrapped;
|
||||
+
|
||||
+ cd = kmalloc(sizeof(*cd), GFP_KERNEL);
|
||||
+ if (cd == NULL)
|
||||
+ return -ENOMEM;
|
||||
+ fp->private_data = cd;
|
||||
+ cd->map_addr = ioremap(get_mc_fw_base_address() + offset, size);
|
||||
+
|
||||
+ cd->hdr = (struct log_header *) cd->map_addr;
|
||||
+ invalidate(cd->hdr);
|
||||
+
|
||||
+ magic = cd->hdr->magic_word;
|
||||
+ if (memcmp(magic, emagic, magic_len)) {
|
||||
+ pr_info("magic didn't match!\n");
|
||||
+ pr_info("expected: %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
+ emagic[0], emagic[1], emagic[2], emagic[3],
|
||||
+ emagic[4], emagic[5], emagic[6], emagic[7]);
|
||||
+ pr_info(" seen: %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
+ magic[0], magic[1], magic[2], magic[3],
|
||||
+ magic[4], magic[5], magic[6], magic[7]);
|
||||
+ kfree(cd);
|
||||
+ iounmap(cd->map_addr);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ cd->start_addr = cd->map_addr
|
||||
+ + le32_to_cpu(cd->hdr->buf_start) - offset_delta;
|
||||
+ cd->end_addr = cd->start_addr + le32_to_cpu(cd->hdr->buf_length);
|
||||
+
|
||||
+ wrapped = le32_to_cpu(cd->hdr->last_byte)
|
||||
+ & LOG_HEADER_FLAG_BUFFER_WRAPAROUND;
|
||||
+
|
||||
+ __adjust_end(cd);
|
||||
+ if (wrapped && (cd->end_of_data != cd->end_addr))
|
||||
+ cd->cur_ptr = cd->end_of_data+1;
|
||||
+ else
|
||||
+ cd->cur_ptr = cd->start_addr;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int fsl_ls2_mc_console_open(struct inode *node, struct file *fp)
|
||||
+{
|
||||
+ uint8_t magic_word[] = { 0, 1, 'C', 'M' };
|
||||
+
|
||||
+ return fsl_ls2_generic_console_open(node, fp,
|
||||
+ MC_BUFFER_OFFSET, MC_BUFFER_SIZE,
|
||||
+ magic_word, sizeof(magic_word),
|
||||
+ MC_OFFSET_DELTA);
|
||||
+}
|
||||
+
|
||||
+static int fsl_ls2_aiop_console_open(struct inode *node, struct file *fp)
|
||||
+{
|
||||
+ uint8_t magic_word[] = { 'P', 'O', 'I', 'A' };
|
||||
+
|
||||
+ return fsl_ls2_generic_console_open(node, fp,
|
||||
+ AIOP_BUFFER_OFFSET, AIOP_BUFFER_SIZE,
|
||||
+ magic_word, sizeof(magic_word),
|
||||
+ AIOP_OFFSET_DELTA);
|
||||
+}
|
||||
+
|
||||
+static int fsl_ls2_console_close(struct inode *node, struct file *fp)
|
||||
+{
|
||||
+ struct console_data *cd = fp->private_data;
|
||||
+
|
||||
+ iounmap(cd->map_addr);
|
||||
+ kfree(cd);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+ssize_t fsl_ls2_console_read(struct file *fp, char __user *buf, size_t count,
|
||||
+ loff_t *f_pos)
|
||||
+{
|
||||
+ struct console_data *cd = fp->private_data;
|
||||
+ size_t bytes = 0;
|
||||
+ char data;
|
||||
+
|
||||
+ /* Check if we need to adjust the end of data addr */
|
||||
+ adjust_end(cd);
|
||||
+
|
||||
+ while ((count != bytes) && (cd->end_of_data != cd->cur_ptr)) {
|
||||
+ if (((u64)cd->cur_ptr) % 64 == 0)
|
||||
+ invalidate(cd->cur_ptr);
|
||||
+
|
||||
+ data = *(cd->cur_ptr);
|
||||
+ if (copy_to_user(&buf[bytes], &data, 1))
|
||||
+ return -EFAULT;
|
||||
+ cd->cur_ptr++;
|
||||
+ if (cd->cur_ptr >= cd->end_addr)
|
||||
+ cd->cur_ptr = cd->start_addr;
|
||||
+ ++bytes;
|
||||
+ }
|
||||
+ return bytes;
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fsl_ls2_mc_console_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = fsl_ls2_mc_console_open,
|
||||
+ .release = fsl_ls2_console_close,
|
||||
+ .read = fsl_ls2_console_read,
|
||||
+};
|
||||
+
|
||||
+static struct miscdevice fsl_ls2_mc_console_dev = {
|
||||
+ .minor = MISC_DYNAMIC_MINOR,
|
||||
+ .name = "fsl_mc_console",
|
||||
+ .fops = &fsl_ls2_mc_console_fops
|
||||
+};
|
||||
+
|
||||
+static const struct file_operations fsl_ls2_aiop_console_fops = {
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .open = fsl_ls2_aiop_console_open,
|
||||
+ .release = fsl_ls2_console_close,
|
||||
+ .read = fsl_ls2_console_read,
|
||||
+};
|
||||
+
|
||||
+static struct miscdevice fsl_ls2_aiop_console_dev = {
|
||||
+ .minor = MISC_DYNAMIC_MINOR,
|
||||
+ .name = "fsl_aiop_console",
|
||||
+ .fops = &fsl_ls2_aiop_console_fops
|
||||
+};
|
||||
+
|
||||
+static int __init fsl_ls2_console_init(void)
|
||||
+{
|
||||
+ int err = 0;
|
||||
+
|
||||
+ pr_info("Freescale LS2 console driver\n");
|
||||
+ err = misc_register(&fsl_ls2_mc_console_dev);
|
||||
+ if (err) {
|
||||
+ pr_err("fsl_mc_console: cannot register device\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+ pr_info("fsl-ls2-console: device %s registered\n",
|
||||
+ fsl_ls2_mc_console_dev.name);
|
||||
+
|
||||
+ err = misc_register(&fsl_ls2_aiop_console_dev);
|
||||
+ if (err) {
|
||||
+ pr_err("fsl_aiop_console: cannot register device\n");
|
||||
+ return err;
|
||||
+ }
|
||||
+ pr_info("fsl-ls2-console: device %s registered\n",
|
||||
+ fsl_ls2_aiop_console_dev.name);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __exit fsl_ls2_console_exit(void)
|
||||
+{
|
||||
+ int err = misc_deregister(&fsl_ls2_mc_console_dev);
|
||||
+
|
||||
+ if (err)
|
||||
+ pr_err("Failed to deregister device %s code %d\n",
|
||||
+ fsl_ls2_mc_console_dev.name, err);
|
||||
+ else
|
||||
+ pr_info("device %s deregistered\n",
|
||||
+ fsl_ls2_mc_console_dev.name);
|
||||
+
|
||||
+ err = misc_deregister(&fsl_ls2_aiop_console_dev);
|
||||
+ if (err)
|
||||
+ pr_err("Failed to deregister device %s code %d\n",
|
||||
+ fsl_ls2_aiop_console_dev.name, err);
|
||||
+ else
|
||||
+ pr_info("device %s deregistered\n",
|
||||
+ fsl_ls2_aiop_console_dev.name);
|
||||
+}
|
||||
+
|
||||
+module_init(fsl_ls2_console_init);
|
||||
+module_exit(fsl_ls2_console_exit);
|
||||
+
|
||||
+MODULE_AUTHOR("Roy Pledge <roy.pledge@freescale.com>");
|
||||
+MODULE_LICENSE("Dual BSD/GPL");
|
||||
+MODULE_DESCRIPTION("Freescale LS2 console driver");
|
||||
diff -uNr a/drivers/soc/fsl/ls2-console/Makefile b/drivers/soc/fsl/ls2-console/Makefile
|
||||
--- a/drivers/soc/fsl/ls2-console/Makefile 1970-01-01 05:30:00.000000000 +0530
|
||||
+++ b/drivers/soc/fsl/ls2-console/Makefile 2017-06-05 17:32:52.582348990 +0530
|
||||
@@ -0,0 +1 @@
|
||||
+obj-$(CONFIG_FSL_LS2_CONSOLE) += ls2-console.o
|
||||
diff -uNr a/drivers/soc/fsl/Makefile b/drivers/soc/fsl/Makefile
|
||||
--- a/drivers/soc/fsl/Makefile 2017-06-05 17:37:14.530348991 +0530
|
||||
+++ b/drivers/soc/fsl/Makefile 2017-06-05 17:33:54.022348991 +0530
|
||||
@@ -4,3 +4,4 @@
|
||||
|
||||
obj-$(CONFIG_LS1_SOC_DRIVERS) += ls1/
|
||||
obj-$(CONFIG_FSL_GUTS) += guts.o
|
||||
+obj-$(CONFIG_LS_SOC_DRIVERS) += ls2-console/
|
||||
@@ -1,3 +0,0 @@
|
||||
aufs.patch
|
||||
driver-support-intel-igb-bcm54616-phy.patch
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
0001-Patch-set-for-booting-ls2088rdb-with-vfio.patch
|
||||
ls2_mc_console.patch
|
||||
1842
packages/base/any/kernels/4.14-lts/configs/x86_64-all/x86_64-all.config
Normal file → Executable file
1842
packages/base/any/kernels/4.14-lts/configs/x86_64-all/x86_64-all.config
Normal file → Executable file
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,7 @@
|
||||
THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
|
||||
K_MAJOR_VERSION := 4
|
||||
K_PATCH_LEVEL := 14
|
||||
K_SUB_LEVEL := 34
|
||||
K_SUB_LEVEL := 49
|
||||
K_SUFFIX :=
|
||||
K_PATCH_DIR := $(THIS_DIR)/patches
|
||||
K_MODSYNCLIST := tools/objtool
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
|
||||
index 0f5c8fc..f93099c 100644
|
||||
--- a/drivers/i2c/muxes/Kconfig
|
||||
+++ b/drivers/i2c/muxes/Kconfig
|
||||
@@ -73,6 +73,13 @@ config I2C_MUX_PCA954x
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called i2c-mux-pca954x.
|
||||
|
||||
+config I2C_MUX_PCA954X_DESELECT_ON_EXIT
|
||||
+ bool "Enable deselect-on-exit feature for PCA954X devices."
|
||||
+ depends on I2C_MUX_PCA954x
|
||||
+ help
|
||||
+ If you say yes here you enable the deselect-on-exit feature in
|
||||
+ the pca954x i2c driver.
|
||||
+
|
||||
config I2C_MUX_PINCTRL
|
||||
tristate "pinctrl-based I2C multiplexer"
|
||||
depends on PINCTRL
|
||||
diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
|
||||
index 7b992db..bdca051 100644
|
||||
--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
|
||||
+++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
|
||||
@@ -218,8 +218,10 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
|
||||
struct pca954x *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
|
||||
+#if !defined(CONFIG_I2C_MUX_PCA954X_DESELECT_ON_EXIT)
|
||||
if (!(data->deselect & (1 << chan)))
|
||||
return 0;
|
||||
+#endif
|
||||
|
||||
/* Deselect active channel */
|
||||
data->last_chan = 0;
|
||||
|
||||
@@ -0,0 +1,241 @@
|
||||
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
|
||||
index c37cc8b..41c0ff2 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
|
||||
@@ -340,6 +340,12 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
|
||||
phy->ops.set_d3_lplu_state = igb_set_d3_lplu_state_82580;
|
||||
phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88;
|
||||
break;
|
||||
+ case BCM5461S_PHY_ID:
|
||||
+ phy->type = e1000_phy_bcm5461s;
|
||||
+ phy->ops.check_polarity = NULL;
|
||||
+ phy->ops.get_cable_length = NULL;
|
||||
+ phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_82580;
|
||||
+ break;
|
||||
case BCM54616_E_PHY_ID:
|
||||
phy->type = e1000_phy_bcm54616;
|
||||
break;
|
||||
@@ -902,6 +908,16 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
|
||||
goto out;
|
||||
}
|
||||
ret_val = igb_get_phy_id(hw);
|
||||
+ if (ret_val && hw->mac.type == e1000_i354) {
|
||||
+ /* we do a special check for bcm5461s phy by setting
|
||||
+ * the phy->addr to 5 and doing the phy check again. This
|
||||
+ * call will succeed and retrieve a valid phy id if we have
|
||||
+ * the bcm5461s phy
|
||||
+ */
|
||||
+ phy->addr = 5;
|
||||
+ phy->type = e1000_phy_bcm5461s;
|
||||
+ ret_val = igb_get_phy_id(hw);
|
||||
+ }
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1289,6 +1305,9 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw)
|
||||
(hw->phy.type == e1000_phy_igp_3))
|
||||
igb_phy_init_script_igp3(hw);
|
||||
|
||||
+ if (hw->phy.type == e1000_phy_bcm5461s)
|
||||
+ igb_phy_init_script_5461s(hw);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1618,6 +1637,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
case e1000_i350:
|
||||
case e1000_i210:
|
||||
case e1000_i211:
|
||||
+ case e1000_i354:
|
||||
phpm_reg = rd32(E1000_82580_PHY_POWER_MGMT);
|
||||
phpm_reg &= ~E1000_82580_PM_GO_LINKD;
|
||||
wr32(E1000_82580_PHY_POWER_MGMT, phpm_reg);
|
||||
@@ -1663,7 +1683,8 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
|
||||
ret_val = igb_copper_link_setup_82580(hw);
|
||||
break;
|
||||
case e1000_phy_bcm54616:
|
||||
- ret_val = 0;
|
||||
+ break;
|
||||
+ case e1000_phy_bcm5461s:
|
||||
break;
|
||||
default:
|
||||
ret_val = -E1000_ERR_PHY;
|
||||
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
|
||||
index 1de82f2..0703c3e 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
|
||||
@@ -890,6 +890,7 @@
|
||||
#define M88E1543_E_PHY_ID 0x01410EA0
|
||||
#define M88E1512_E_PHY_ID 0x01410DD0
|
||||
#define BCM54616_E_PHY_ID 0x03625D10
|
||||
+#define BCM5461S_PHY_ID 0x002060C0
|
||||
|
||||
/* M88E1000 Specific Registers */
|
||||
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
|
||||
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
|
||||
index 6c9485a..2a0b83b 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
|
||||
@@ -129,6 +129,7 @@ enum e1000_phy_type {
|
||||
e1000_phy_82580,
|
||||
e1000_phy_i210,
|
||||
e1000_phy_bcm54616,
|
||||
+ e1000_phy_bcm5461s,
|
||||
};
|
||||
|
||||
enum e1000_bus_type {
|
||||
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
|
||||
index 413025b..4c2a5ff 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
|
||||
@@ -146,6 +146,13 @@ s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
|
||||
* Control register. The MAC will take care of interfacing with the
|
||||
* PHY to retrieve the desired data.
|
||||
*/
|
||||
+ if (phy->type == e1000_phy_bcm5461s) {
|
||||
+ mdic = rd32(E1000_MDICNFG);
|
||||
+ mdic &= ~E1000_MDICNFG_PHY_MASK;
|
||||
+ mdic |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
|
||||
+ wr32(E1000_MDICNFG, mdic);
|
||||
+ }
|
||||
+
|
||||
mdic = ((offset << E1000_MDIC_REG_SHIFT) |
|
||||
(phy->addr << E1000_MDIC_PHY_SHIFT) |
|
||||
(E1000_MDIC_OP_READ));
|
||||
@@ -202,6 +209,13 @@ s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
|
||||
* Control register. The MAC will take care of interfacing with the
|
||||
* PHY to retrieve the desired data.
|
||||
*/
|
||||
+ if (phy->type == e1000_phy_bcm5461s) {
|
||||
+ mdic = rd32(E1000_MDICNFG);
|
||||
+ mdic &= ~E1000_MDICNFG_PHY_MASK;
|
||||
+ mdic |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
|
||||
+ wr32(E1000_MDICNFG, mdic);
|
||||
+ }
|
||||
+
|
||||
mdic = (((u32)data) |
|
||||
(offset << E1000_MDIC_REG_SHIFT) |
|
||||
(phy->addr << E1000_MDIC_PHY_SHIFT) |
|
||||
@@ -1113,11 +1127,13 @@ s32 igb_setup_copper_link(struct e1000_hw *hw)
|
||||
* depending on user settings.
|
||||
*/
|
||||
hw_dbg("Forcing Speed and Duplex\n");
|
||||
- ret_val = hw->phy.ops.force_speed_duplex(hw);
|
||||
- if (ret_val) {
|
||||
- hw_dbg("Error Forcing Speed and Duplex\n");
|
||||
- goto out;
|
||||
- }
|
||||
+ if (hw->phy.ops.force_speed_duplex) {
|
||||
+ ret_val = hw->phy.ops.force_speed_duplex(hw);
|
||||
+ if (ret_val) {
|
||||
+ hw_dbg("Error Forcing Speed and Duplex\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Check link status. Wait up to 100 microseconds for link to become
|
||||
@@ -2647,3 +2663,66 @@ static s32 igb_set_master_slave_mode(struct e1000_hw *hw)
|
||||
|
||||
return hw->phy.ops.write_reg(hw, PHY_1000T_CTRL, phy_data);
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * igb_phy_init_script_5461s - Inits the BCM5461S PHY
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ *
|
||||
+ * Initializes a Broadcom Gigabit PHY.
|
||||
+ **/
|
||||
+s32 igb_phy_init_script_5461s(struct e1000_hw *hw)
|
||||
+{
|
||||
+ u16 mii_reg_led = 0;
|
||||
+
|
||||
+ /* 1. Speed LED (Set the Link LED mode), Shadow 00010, 0x1C.bit2=1 */
|
||||
+ hw->phy.ops.write_reg(hw, 0x1C, 0x0800);
|
||||
+ hw->phy.ops.read_reg(hw, 0x1C, &mii_reg_led);
|
||||
+ mii_reg_led |= 0x0004;
|
||||
+ hw->phy.ops.write_reg(hw, 0x1C, mii_reg_led | 0x8000);
|
||||
+
|
||||
+ /* 2. Active LED (Set the Link LED mode), Shadow 01001, 0x1C.bit4=1, 0x10.bit5=0 */
|
||||
+ hw->phy.ops.write_reg(hw, 0x1C, 0x2400);
|
||||
+ hw->phy.ops.read_reg(hw, 0x1C, &mii_reg_led);
|
||||
+ mii_reg_led |= 0x0010;
|
||||
+ hw->phy.ops.write_reg(hw, 0x1C, mii_reg_led | 0x8000);
|
||||
+ hw->phy.ops.read_reg(hw, 0x10, &mii_reg_led);
|
||||
+ mii_reg_led &= 0xffdf;
|
||||
+ hw->phy.ops.write_reg(hw, 0x10, mii_reg_led);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * igb_get_phy_info_5461s - Retrieve 5461s PHY information
|
||||
+ * @hw: pointer to the HW structure
|
||||
+ *
|
||||
+ * Read PHY status to determine if link is up. If link is up, then
|
||||
+ * set/determine 10base-T extended distance and polarity correction. Read
|
||||
+ * PHY port status to determine MDI/MDIx and speed. Based on the speed,
|
||||
+ * determine on the cable length, local and remote receiver.
|
||||
+ **/
|
||||
+s32 igb_get_phy_info_5461s(struct e1000_hw *hw)
|
||||
+{
|
||||
+ struct e1000_phy_info *phy = &hw->phy;
|
||||
+ s32 ret_val;
|
||||
+ bool link;
|
||||
+
|
||||
+ ret_val = igb_phy_has_link(hw, 1, 0, &link);
|
||||
+ if (ret_val)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!link) {
|
||||
+ ret_val = -E1000_ERR_CONFIG;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ phy->polarity_correction = true;
|
||||
+
|
||||
+ phy->is_mdix = true;
|
||||
+ phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
|
||||
+ phy->local_rx = e1000_1000t_rx_status_ok;
|
||||
+ phy->remote_rx = e1000_1000t_rx_status_ok;
|
||||
+
|
||||
+out:
|
||||
+ return ret_val;
|
||||
+}
|
||||
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h
|
||||
index 9b622b3..3b28873 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/e1000_phy.h
|
||||
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.h
|
||||
@@ -61,6 +61,8 @@ s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
|
||||
void igb_power_up_phy_copper(struct e1000_hw *hw);
|
||||
void igb_power_down_phy_copper(struct e1000_hw *hw);
|
||||
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
|
||||
+s32 igb_phy_init_script_5461s(struct e1000_hw *hw);
|
||||
+s32 igb_get_phy_info_5461s(struct e1000_hw *hw);
|
||||
s32 igb_initialize_M88E1512_phy(struct e1000_hw *hw);
|
||||
s32 igb_initialize_M88E1543_phy(struct e1000_hw *hw);
|
||||
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
|
||||
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
|
||||
index d1a44a8..1399989 100644
|
||||
--- a/drivers/net/ethernet/intel/igb/igb_main.c
|
||||
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
|
||||
@@ -7730,11 +7730,19 @@ static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
|
||||
data->phy_id = adapter->hw.phy.addr;
|
||||
break;
|
||||
case SIOCGMIIREG:
|
||||
+ adapter->hw.phy.addr = data->phy_id;
|
||||
if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
|
||||
&data->val_out))
|
||||
return -EIO;
|
||||
break;
|
||||
case SIOCSMIIREG:
|
||||
+ if (!capable(CAP_NET_ADMIN))
|
||||
+ return -EPERM;
|
||||
+ adapter->hw.phy.addr = data->phy_id;
|
||||
+ if (igb_write_phy_reg(&adapter->hw, data->reg_num & 0x1F,
|
||||
+ data->val_in))
|
||||
+ return -EIO;
|
||||
+ break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
0001-drivers-i2c-muxes-pca954x-deselect-on-exit.patch
|
||||
0002-driver-support-intel-igb-bcm5461S-phy.patch
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
kernel-3.16*
|
||||
kernel-*
|
||||
linux-*
|
||||
|
||||
lib/
|
||||
|
||||
@@ -4000,7 +4000,7 @@ CONFIG_HUGETLBFS=y
|
||||
CONFIG_HUGETLB_PAGE=y
|
||||
CONFIG_ARCH_HAS_GIGANTIC_PAGE=y
|
||||
# CONFIG_CONFIGFS_FS is not set
|
||||
CONFIG_EFIVAR_FS=m
|
||||
CONFIG_EFIVAR_FS=y
|
||||
CONFIG_MISC_FILESYSTEMS=y
|
||||
# CONFIG_ORANGEFS_FS is not set
|
||||
# CONFIG_ADFS_FS is not set
|
||||
|
||||
@@ -196,7 +196,7 @@ onlp_psu_show(onlp_oid_t id, aim_pvs_t* pvs, uint32_t flags)
|
||||
}
|
||||
else {
|
||||
iof_iprintf(&iof, "Status: Running");
|
||||
iof_iprintf(&iof, "Model: %s", pi.model[0] ? pi.model : "Unknown");
|
||||
if(pi.model[0]) iof_iprintf(&iof, "Model: %s", pi.model);
|
||||
if(pi.serial[0]) iof_iprintf(&iof, "SN: %s", pi.serial);
|
||||
if(pi.caps & ONLP_PSU_CAPS_AC) {
|
||||
iof_iprintf(&iof, "Type: AC");
|
||||
|
||||
@@ -55,6 +55,8 @@ sff_module_types: &sff_module_types
|
||||
desc: "100G-CWDM4"
|
||||
- 100G_PSM4:
|
||||
desc: "100G-PSM4"
|
||||
- 100G_SWDM4:
|
||||
desc: "100G-SWDM4"
|
||||
- 40G_BASE_CR4:
|
||||
desc: "40GBASE-CR4"
|
||||
- 40G_BASE_SR4:
|
||||
@@ -103,6 +105,8 @@ sff_module_types: &sff_module_types
|
||||
desc: "1GBASE-SX"
|
||||
- 1G_BASE_LX:
|
||||
desc: "1GBASE-LX"
|
||||
- 1G_BASE_ZX:
|
||||
desc: "1GBASE-ZX"
|
||||
- 1G_BASE_CX:
|
||||
desc: "1GBASE-CX"
|
||||
- 1G_BASE_T:
|
||||
|
||||
@@ -209,6 +209,9 @@
|
||||
#define SFF8472_MEDIA_XGE_ER(idprom) \
|
||||
((idprom[3] & SFF8472_CC3_XGE_BASE_ER) != 0)
|
||||
|
||||
#define SFF8472_MEDIA_LENGTH_ZX(idprom) \
|
||||
(idprom[14] >= 70)
|
||||
|
||||
/*
|
||||
* some CR cables identify as infiniband copper
|
||||
* some CR cables identify as FC twinax
|
||||
|
||||
@@ -135,6 +135,8 @@
|
||||
#define SFF8636_CC192_100GE_CR4 0x0B
|
||||
#define SFF8636_CC192_25GE_CR_S 0x0C
|
||||
#define SFF8636_CC192_25GE_CR_N 0x0D
|
||||
#define SFF8636_CC192_40GE_SWDM4 0x1F
|
||||
#define SFF8636_CC192_100GE_SWDM4 0x20
|
||||
|
||||
#define SFF8636_MEDIA_100GE_AOC(idprom) \
|
||||
(idprom[192] == SFF8636_CC192_100GE_AOC)
|
||||
@@ -148,6 +150,10 @@
|
||||
(idprom[192] == SFF8636_CC192_100GE_PSM4)
|
||||
#define SFF8636_MEDIA_100GE_CR4(idprom) \
|
||||
(idprom[192] == SFF8636_CC192_100GE_CR4)
|
||||
#define SFF8636_MEDIA_100GE_SWDM4(idprom) \
|
||||
(idprom[192] == SFF8636_CC192_100GE_SWDM4)
|
||||
#define SFF8636_MEDIA_40GE_SWDM4(idprom) \
|
||||
(idprom[192] == SFF8636_CC192_40GE_SWDM4)
|
||||
#define SFF8636_MEDIA_25GE_CR_S(idprom) \
|
||||
(idprom[192] == SFF8636_CC192_25GE_CR_S)
|
||||
#define SFF8636_MEDIA_25GE_CR_N(idprom) \
|
||||
|
||||
@@ -103,6 +103,7 @@ typedef enum sff_module_type_e {
|
||||
SFF_MODULE_TYPE_100G_BASE_LR4,
|
||||
SFF_MODULE_TYPE_100G_CWDM4,
|
||||
SFF_MODULE_TYPE_100G_PSM4,
|
||||
SFF_MODULE_TYPE_100G_SWDM4,
|
||||
SFF_MODULE_TYPE_40G_BASE_CR4,
|
||||
SFF_MODULE_TYPE_40G_BASE_SR4,
|
||||
SFF_MODULE_TYPE_40G_BASE_LR4,
|
||||
@@ -127,6 +128,7 @@ typedef enum sff_module_type_e {
|
||||
SFF_MODULE_TYPE_10G_BASE_SRL,
|
||||
SFF_MODULE_TYPE_1G_BASE_SX,
|
||||
SFF_MODULE_TYPE_1G_BASE_LX,
|
||||
SFF_MODULE_TYPE_1G_BASE_ZX,
|
||||
SFF_MODULE_TYPE_1G_BASE_CX,
|
||||
SFF_MODULE_TYPE_1G_BASE_T,
|
||||
SFF_MODULE_TYPE_100_BASE_LX,
|
||||
@@ -146,6 +148,7 @@ typedef enum sff_module_type_e {
|
||||
"100G_BASE_LR4", \
|
||||
"100G_CWDM4", \
|
||||
"100G_PSM4", \
|
||||
"100G_SWDM4", \
|
||||
"40G_BASE_CR4", \
|
||||
"40G_BASE_SR4", \
|
||||
"40G_BASE_LR4", \
|
||||
@@ -170,6 +173,7 @@ typedef enum sff_module_type_e {
|
||||
"10G_BASE_SRL", \
|
||||
"1G_BASE_SX", \
|
||||
"1G_BASE_LX", \
|
||||
"1G_BASE_ZX", \
|
||||
"1G_BASE_CX", \
|
||||
"1G_BASE_T", \
|
||||
"100_BASE_LX", \
|
||||
|
||||
@@ -13,6 +13,7 @@ SFF_MEDIA_TYPE_ENTRY(100G_BASE_SR4, 100GBASE-SR4)
|
||||
SFF_MEDIA_TYPE_ENTRY(100G_BASE_LR4, 100GBASE-LR4)
|
||||
SFF_MEDIA_TYPE_ENTRY(100G_CWDM4, 100G-CWDM4)
|
||||
SFF_MEDIA_TYPE_ENTRY(100G_PSM4, 100G-PSM4)
|
||||
SFF_MEDIA_TYPE_ENTRY(100G_SWDM4, 100G-SWDM4)
|
||||
SFF_MEDIA_TYPE_ENTRY(40G_BASE_CR4, 40GBASE-CR4)
|
||||
SFF_MEDIA_TYPE_ENTRY(40G_BASE_SR4, 40GBASE-SR4)
|
||||
SFF_MEDIA_TYPE_ENTRY(40G_BASE_LR4, 40GBASE-LR4)
|
||||
@@ -37,6 +38,7 @@ SFF_MEDIA_TYPE_ENTRY(10G_BASE_ZR, 10GBASE-ZR)
|
||||
SFF_MEDIA_TYPE_ENTRY(10G_BASE_SRL, 10GBASE-SRL)
|
||||
SFF_MEDIA_TYPE_ENTRY(1G_BASE_SX, 1GBASE-SX)
|
||||
SFF_MEDIA_TYPE_ENTRY(1G_BASE_LX, 1GBASE-LX)
|
||||
SFF_MEDIA_TYPE_ENTRY(1G_BASE_ZX, 1GBASE-ZX)
|
||||
SFF_MEDIA_TYPE_ENTRY(1G_BASE_CX, 1GBASE-CX)
|
||||
SFF_MEDIA_TYPE_ENTRY(1G_BASE_T, 1GBASE-T)
|
||||
SFF_MEDIA_TYPE_ENTRY(100_BASE_LX, 100BASE-LX)
|
||||
@@ -62,6 +64,7 @@ SFF_MODULE_TYPE_ENTRY(100G_BASE_SR4, 100GBASE-SR4)
|
||||
SFF_MODULE_TYPE_ENTRY(100G_BASE_LR4, 100GBASE-LR4)
|
||||
SFF_MODULE_TYPE_ENTRY(100G_CWDM4, 100G-CWDM4)
|
||||
SFF_MODULE_TYPE_ENTRY(100G_PSM4, 100G-PSM4)
|
||||
SFF_MODULE_TYPE_ENTRY(100G_SWDM4, 100G-SWDM4)
|
||||
SFF_MODULE_TYPE_ENTRY(40G_BASE_CR4, 40GBASE-CR4)
|
||||
SFF_MODULE_TYPE_ENTRY(40G_BASE_SR4, 40GBASE-SR4)
|
||||
SFF_MODULE_TYPE_ENTRY(40G_BASE_LR4, 40GBASE-LR4)
|
||||
@@ -86,6 +89,7 @@ SFF_MODULE_TYPE_ENTRY(10G_BASE_ZR, 10GBASE-ZR)
|
||||
SFF_MODULE_TYPE_ENTRY(10G_BASE_SRL, 10GBASE-SRL)
|
||||
SFF_MODULE_TYPE_ENTRY(1G_BASE_SX, 1GBASE-SX)
|
||||
SFF_MODULE_TYPE_ENTRY(1G_BASE_LX, 1GBASE-LX)
|
||||
SFF_MODULE_TYPE_ENTRY(1G_BASE_ZX, 1GBASE-ZX)
|
||||
SFF_MODULE_TYPE_ENTRY(1G_BASE_CX, 1GBASE-CX)
|
||||
SFF_MODULE_TYPE_ENTRY(1G_BASE_T, 1GBASE-T)
|
||||
SFF_MODULE_TYPE_ENTRY(100_BASE_LX, 100BASE-LX)
|
||||
|
||||
@@ -33,35 +33,37 @@ class SFF_MODULE_TYPE(Enumeration):
|
||||
_100G_BASE_LR4 = 3
|
||||
_100G_CWDM4 = 4
|
||||
_100G_PSM4 = 5
|
||||
_40G_BASE_CR4 = 6
|
||||
_40G_BASE_SR4 = 7
|
||||
_40G_BASE_LR4 = 8
|
||||
_40G_BASE_LM4 = 9
|
||||
_40G_BASE_ACTIVE = 10
|
||||
_40G_BASE_CR = 11
|
||||
_40G_BASE_SR2 = 12
|
||||
_40G_BASE_SM4 = 13
|
||||
_40G_BASE_ER4 = 14
|
||||
_25G_BASE_CR = 15
|
||||
_25G_BASE_SR = 16
|
||||
_25G_BASE_LR = 17
|
||||
_25G_BASE_AOC = 18
|
||||
_10G_BASE_SR = 19
|
||||
_10G_BASE_LR = 20
|
||||
_10G_BASE_LRM = 21
|
||||
_10G_BASE_ER = 22
|
||||
_10G_BASE_CR = 23
|
||||
_10G_BASE_SX = 24
|
||||
_10G_BASE_LX = 25
|
||||
_10G_BASE_ZR = 26
|
||||
_10G_BASE_SRL = 27
|
||||
_1G_BASE_SX = 28
|
||||
_1G_BASE_LX = 29
|
||||
_1G_BASE_CX = 30
|
||||
_1G_BASE_T = 31
|
||||
_100_BASE_LX = 32
|
||||
_100_BASE_FX = 33
|
||||
_4X_MUX = 34
|
||||
_100G_SWDM4 = 6
|
||||
_40G_BASE_CR4 = 7
|
||||
_40G_BASE_SR4 = 8
|
||||
_40G_BASE_LR4 = 9
|
||||
_40G_BASE_LM4 = 10
|
||||
_40G_BASE_ACTIVE = 11
|
||||
_40G_BASE_CR = 12
|
||||
_40G_BASE_SR2 = 13
|
||||
_40G_BASE_SM4 = 14
|
||||
_40G_BASE_ER4 = 15
|
||||
_25G_BASE_CR = 16
|
||||
_25G_BASE_SR = 17
|
||||
_25G_BASE_LR = 18
|
||||
_25G_BASE_AOC = 19
|
||||
_10G_BASE_SR = 20
|
||||
_10G_BASE_LR = 21
|
||||
_10G_BASE_LRM = 22
|
||||
_10G_BASE_ER = 23
|
||||
_10G_BASE_CR = 24
|
||||
_10G_BASE_SX = 25
|
||||
_10G_BASE_LX = 26
|
||||
_10G_BASE_ZR = 27
|
||||
_10G_BASE_SRL = 28
|
||||
_1G_BASE_SX = 29
|
||||
_1G_BASE_LX = 30
|
||||
_1G_BASE_ZX = 31
|
||||
_1G_BASE_CX = 32
|
||||
_1G_BASE_T = 33
|
||||
_100_BASE_LX = 34
|
||||
_100_BASE_FX = 35
|
||||
_4X_MUX = 36
|
||||
|
||||
|
||||
class SFF_SFP_TYPE(Enumeration):
|
||||
|
||||
@@ -82,6 +82,11 @@ sff_module_type_get(const uint8_t* eeprom)
|
||||
&& SFF8636_MEDIA_100GE_PSM4(eeprom))
|
||||
return SFF_MODULE_TYPE_100G_PSM4;
|
||||
|
||||
if (SFF8636_MODULE_QSFP28(eeprom)
|
||||
&& SFF8636_MEDIA_EXTENDED(eeprom)
|
||||
&& SFF8636_MEDIA_100GE_SWDM4(eeprom))
|
||||
return SFF_MODULE_TYPE_100G_SWDM4;
|
||||
|
||||
if (SFF8436_MODULE_QSFP_PLUS_V2(eeprom)
|
||||
&& SFF8436_MEDIA_40GE_CR4(eeprom))
|
||||
return SFF_MODULE_TYPE_40G_BASE_CR4;
|
||||
@@ -208,8 +213,13 @@ sff_module_type_get(const uint8_t* eeprom)
|
||||
return SFF_MODULE_TYPE_1G_BASE_SX;
|
||||
|
||||
if (SFF8472_MODULE_SFP(eeprom)
|
||||
&& SFF8472_MEDIA_GBE_LX(eeprom))
|
||||
return SFF_MODULE_TYPE_1G_BASE_LX;
|
||||
&& SFF8472_MEDIA_GBE_LX(eeprom)) {
|
||||
if (SFF8472_MEDIA_LENGTH_ZX(eeprom)) {
|
||||
return SFF_MODULE_TYPE_1G_BASE_ZX;
|
||||
} else {
|
||||
return SFF_MODULE_TYPE_1G_BASE_LX;
|
||||
}
|
||||
}
|
||||
|
||||
if (SFF8472_MODULE_SFP(eeprom)
|
||||
&& SFF8472_MEDIA_GBE_CX(eeprom))
|
||||
@@ -219,10 +229,6 @@ sff_module_type_get(const uint8_t* eeprom)
|
||||
&& SFF8472_MEDIA_GBE_T(eeprom))
|
||||
return SFF_MODULE_TYPE_1G_BASE_T;
|
||||
|
||||
if (SFF8472_MODULE_SFP(eeprom)
|
||||
&& SFF8472_MEDIA_GBE_LX(eeprom))
|
||||
return SFF_MODULE_TYPE_1G_BASE_LX;
|
||||
|
||||
if (SFF8472_MODULE_SFP(eeprom)
|
||||
&& SFF8472_MEDIA_CBE_LX(eeprom))
|
||||
return SFF_MODULE_TYPE_100_BASE_LX;
|
||||
@@ -263,6 +269,7 @@ sff_media_type_get(sff_module_type_t mt)
|
||||
case SFF_MODULE_TYPE_100G_BASE_LR4:
|
||||
case SFF_MODULE_TYPE_100G_CWDM4:
|
||||
case SFF_MODULE_TYPE_100G_PSM4:
|
||||
case SFF_MODULE_TYPE_100G_SWDM4:
|
||||
case SFF_MODULE_TYPE_40G_BASE_SR4:
|
||||
case SFF_MODULE_TYPE_40G_BASE_LR4:
|
||||
case SFF_MODULE_TYPE_40G_BASE_LM4:
|
||||
@@ -283,6 +290,7 @@ sff_media_type_get(sff_module_type_t mt)
|
||||
case SFF_MODULE_TYPE_10G_BASE_SRL:
|
||||
case SFF_MODULE_TYPE_1G_BASE_SX:
|
||||
case SFF_MODULE_TYPE_1G_BASE_LX:
|
||||
case SFF_MODULE_TYPE_1G_BASE_ZX:
|
||||
case SFF_MODULE_TYPE_100_BASE_LX:
|
||||
case SFF_MODULE_TYPE_100_BASE_FX:
|
||||
case SFF_MODULE_TYPE_4X_MUX:
|
||||
@@ -312,6 +320,7 @@ sff_module_caps_get(sff_module_type_t mt, uint32_t *caps)
|
||||
case SFF_MODULE_TYPE_100G_BASE_CR4:
|
||||
case SFF_MODULE_TYPE_100G_CWDM4:
|
||||
case SFF_MODULE_TYPE_100G_PSM4:
|
||||
case SFF_MODULE_TYPE_100G_SWDM4:
|
||||
*caps |= SFF_MODULE_CAPS_F_100G;
|
||||
return 0;
|
||||
|
||||
@@ -347,6 +356,7 @@ sff_module_caps_get(sff_module_type_t mt, uint32_t *caps)
|
||||
|
||||
case SFF_MODULE_TYPE_1G_BASE_SX:
|
||||
case SFF_MODULE_TYPE_1G_BASE_LX:
|
||||
case SFF_MODULE_TYPE_1G_BASE_ZX:
|
||||
case SFF_MODULE_TYPE_1G_BASE_CX:
|
||||
case SFF_MODULE_TYPE_1G_BASE_T:
|
||||
*caps |= SFF_MODULE_CAPS_F_1G;
|
||||
@@ -664,7 +674,7 @@ sff_eeprom_parse_nonstandard__(sff_eeprom_t* se, uint8_t* eeprom)
|
||||
}
|
||||
|
||||
if (strncmp(se->info.vendor, "Amphenol", 8) == 0 &&
|
||||
strncmp(se->info.model, "625960001", 9) == 0 &&
|
||||
(strncmp(se->info.model, "625960001", 9) == 0 || strncmp(se->info.model, "659900001", 9) == 0) &&
|
||||
(se->eeprom[240] == 0x0f) &&
|
||||
(se->eeprom[241] == 0x10) &&
|
||||
((se->eeprom[243] & 0xF0) == 0xE0)) {
|
||||
@@ -716,6 +726,7 @@ sff_info_init(sff_info_t* info, sff_module_type_t mt,
|
||||
case SFF_MODULE_TYPE_100G_BASE_LR4:
|
||||
case SFF_MODULE_TYPE_100G_CWDM4:
|
||||
case SFF_MODULE_TYPE_100G_PSM4:
|
||||
case SFF_MODULE_TYPE_100G_SWDM4:
|
||||
info->sfp_type = SFF_SFP_TYPE_QSFP28;
|
||||
info->media_type = SFF_MEDIA_TYPE_FIBER;
|
||||
info->caps = SFF_MODULE_CAPS_F_100G;
|
||||
@@ -782,6 +793,7 @@ sff_info_init(sff_info_t* info, sff_module_type_t mt,
|
||||
|
||||
case SFF_MODULE_TYPE_1G_BASE_SX:
|
||||
case SFF_MODULE_TYPE_1G_BASE_LX:
|
||||
case SFF_MODULE_TYPE_1G_BASE_ZX:
|
||||
info->sfp_type = SFF_SFP_TYPE_SFP;
|
||||
info->media_type = SFF_MEDIA_TYPE_FIBER;
|
||||
info->caps = SFF_MODULE_CAPS_F_1G;
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
#define SFF_100G_PSM4_PROPERTIES \
|
||||
SFF_SFP_TYPE_QSFP28, "QSFP28", SFF_MODULE_TYPE_100G_PSM4, "100G-PSM4", SFF_MEDIA_TYPE_FIBER, "Fiber", SFF_MODULE_CAPS_F_100G
|
||||
|
||||
#define SFF_100G_SWDM4_PROPERTIES \
|
||||
SFF_SFP_TYPE_QSFP28, "QSFP28", SFF_MODULE_TYPE_100G_SWDM4, "100G-SWDM4", SFF_MEDIA_TYPE_FIBER, "Fiber", SFF_MODULE_CAPS_F_100G
|
||||
|
||||
static sff_db_entry_t sff_database__[] =
|
||||
{
|
||||
|
||||
@@ -137,6 +137,7 @@ aim_map_si_t sff_module_type_map[] =
|
||||
{ "100G_BASE_LR4", SFF_MODULE_TYPE_100G_BASE_LR4 },
|
||||
{ "100G_CWDM4", SFF_MODULE_TYPE_100G_CWDM4 },
|
||||
{ "100G_PSM4", SFF_MODULE_TYPE_100G_PSM4 },
|
||||
{ "100G_SWDM4", SFF_MODULE_TYPE_100G_SWDM4 },
|
||||
{ "40G_BASE_CR4", SFF_MODULE_TYPE_40G_BASE_CR4 },
|
||||
{ "40G_BASE_SR4", SFF_MODULE_TYPE_40G_BASE_SR4 },
|
||||
{ "40G_BASE_LR4", SFF_MODULE_TYPE_40G_BASE_LR4 },
|
||||
@@ -161,6 +162,7 @@ aim_map_si_t sff_module_type_map[] =
|
||||
{ "10G_BASE_SRL", SFF_MODULE_TYPE_10G_BASE_SRL },
|
||||
{ "1G_BASE_SX", SFF_MODULE_TYPE_1G_BASE_SX },
|
||||
{ "1G_BASE_LX", SFF_MODULE_TYPE_1G_BASE_LX },
|
||||
{ "1G_BASE_ZX", SFF_MODULE_TYPE_1G_BASE_ZX },
|
||||
{ "1G_BASE_CX", SFF_MODULE_TYPE_1G_BASE_CX },
|
||||
{ "1G_BASE_T", SFF_MODULE_TYPE_1G_BASE_T },
|
||||
{ "100_BASE_LX", SFF_MODULE_TYPE_100_BASE_LX },
|
||||
@@ -177,6 +179,7 @@ aim_map_si_t sff_module_type_desc_map[] =
|
||||
{ "100GBASE-LR4", SFF_MODULE_TYPE_100G_BASE_LR4 },
|
||||
{ "100G-CWDM4", SFF_MODULE_TYPE_100G_CWDM4 },
|
||||
{ "100G-PSM4", SFF_MODULE_TYPE_100G_PSM4 },
|
||||
{ "100G-SWDM4", SFF_MODULE_TYPE_100G_SWDM4 },
|
||||
{ "40GBASE-CR4", SFF_MODULE_TYPE_40G_BASE_CR4 },
|
||||
{ "40GBASE-SR4", SFF_MODULE_TYPE_40G_BASE_SR4 },
|
||||
{ "40GBASE-LR4", SFF_MODULE_TYPE_40G_BASE_LR4 },
|
||||
@@ -201,6 +204,7 @@ aim_map_si_t sff_module_type_desc_map[] =
|
||||
{ "10GBASE-SRL", SFF_MODULE_TYPE_10G_BASE_SRL },
|
||||
{ "1GBASE-SX", SFF_MODULE_TYPE_1G_BASE_SX },
|
||||
{ "1GBASE-LX", SFF_MODULE_TYPE_1G_BASE_LX },
|
||||
{ "1GBASE-ZX", SFF_MODULE_TYPE_1G_BASE_ZX },
|
||||
{ "1GBASE-CX", SFF_MODULE_TYPE_1G_BASE_CX },
|
||||
{ "1GBASE-T", SFF_MODULE_TYPE_1G_BASE_T },
|
||||
{ "100BASE-LX", SFF_MODULE_TYPE_100_BASE_LX },
|
||||
|
||||
Submodule packages/platforms-closed updated: 93a3eee233...19e7296d30
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/arch-vendor-modules.yml ARCH=amd64 VENDOR=accton KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/arch-vendor-modules.yml ARCH=amd64 VENDOR=accton KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := common
|
||||
|
||||
384
packages/platforms/accton/x86-64/modules/builds/optoe.c
Normal file → Executable file
384
packages/platforms/accton/x86-64/modules/builds/optoe.c
Normal file → Executable file
@@ -21,16 +21,16 @@
|
||||
* c) 256 bytes are mapped at a time. 'Lower page 00h' is the first 128
|
||||
* bytes of address space, and always references the same
|
||||
* location, independent of the page select register.
|
||||
* All mapped pages are mapped into the upper 128 bytes
|
||||
* All mapped pages are mapped into the upper 128 bytes
|
||||
* (offset 128-255) of the i2c address.
|
||||
* d) Devices with one I2C address (eg QSFP) use I2C address 0x50
|
||||
* d) Devices with one I2C address (eg QSFP) use I2C address 0x50
|
||||
* (A0h in the spec), and map all pages in the upper 128 bytes
|
||||
* of that address.
|
||||
* e) Devices with two I2C addresses (eg SFP) have 256 bytes of data
|
||||
* at I2C address 0x50, and 256 bytes of data at I2C address
|
||||
* 0x51 (A2h in the spec). Page selection and paged access
|
||||
* only apply to this second I2C address (0x51).
|
||||
* e) The address space is presented, by the driver, as a linear
|
||||
* e) The address space is presented, by the driver, as a linear
|
||||
* address space. For devices with one I2C client at address
|
||||
* 0x50 (eg QSFP), offset 0-127 are in the lower
|
||||
* half of address 50/A0h/client[0]. Offset 128-255 are in
|
||||
@@ -39,7 +39,7 @@
|
||||
* half, offset 0-127).
|
||||
* f) For devices with two I2C clients at address 0x50 and 0x51 (eg SFP),
|
||||
* the address space places offset 0-127 in the lower
|
||||
* half of 50/A0/client[0], offset 128-255 in the upper
|
||||
* half of 50/A0/client[0], offset 128-255 in the upper
|
||||
* half. Offset 256-383 is in the lower half of 51/A2/client[1].
|
||||
* Offset 384-511 is in page 0, in the upper half of 51/A2/...
|
||||
* Offset 512-639 is in page 1, in the upper half of 51/A2/...
|
||||
@@ -118,29 +118,6 @@
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/memory.h>
|
||||
|
||||
/*
|
||||
* The optoe driver is for read/write access to the EEPROM on standard
|
||||
* I2C based optical transceivers (SFP, QSFP, etc)
|
||||
*
|
||||
* While based on the at24 driver, it eliminates code that supports other
|
||||
* types of I2C EEPROMs, and adds support for pages accessed through the
|
||||
* page-select register at offset 127.
|
||||
*/
|
||||
|
||||
struct optoe_platform_data {
|
||||
u32 byte_len; /* size (sum of all addr) */
|
||||
u16 page_size; /* for writes */
|
||||
u8 flags;
|
||||
|
||||
void (*setup)(struct memory_accessor *, void *context);
|
||||
void *context;
|
||||
#ifdef EEPROM_CLASS
|
||||
struct eeprom_platform_data *eeprom_data; /* extra data for the eeprom_class */
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef EEPROM_CLASS
|
||||
#include <linux/eeprom_class.h>
|
||||
@@ -148,6 +125,22 @@ struct optoe_platform_data {
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/* The maximum length of a port name */
|
||||
#define MAX_PORT_NAME_LEN 20
|
||||
|
||||
struct optoe_platform_data {
|
||||
u32 byte_len; /* size (sum of all addr) */
|
||||
u16 page_size; /* for writes */
|
||||
u8 flags;
|
||||
void *dummy1; /* backward compatibility */
|
||||
void *dummy2; /* backward compatibility */
|
||||
|
||||
#ifdef EEPROM_CLASS
|
||||
struct eeprom_platform_data *eeprom_data;
|
||||
#endif
|
||||
char port_name[MAX_PORT_NAME_LEN];
|
||||
};
|
||||
|
||||
/* fundamental unit of addressing for EEPROM */
|
||||
#define OPTOE_PAGE_SIZE 128
|
||||
/*
|
||||
@@ -158,13 +151,14 @@ struct optoe_platform_data {
|
||||
#define OPTOE_ARCH_PAGES 256
|
||||
#define ONE_ADDR_EEPROM_SIZE ((1 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE)
|
||||
#define ONE_ADDR_EEPROM_UNPAGED_SIZE (2 * OPTOE_PAGE_SIZE)
|
||||
/*
|
||||
/*
|
||||
* Dual address devices (eg SFP) have 256 pages, plus the unpaged
|
||||
* low 128 bytes, plus 256 bytes at 0x50. If the device does not
|
||||
* low 128 bytes, plus 256 bytes at 0x50. If the device does not
|
||||
* support paging, it is 4 'pages' long.
|
||||
*/
|
||||
#define TWO_ADDR_EEPROM_SIZE ((3 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE)
|
||||
#define TWO_ADDR_EEPROM_UNPAGED_SIZE (4 * OPTOE_PAGE_SIZE)
|
||||
#define TWO_ADDR_NO_0X51_SIZE (2 * OPTOE_PAGE_SIZE)
|
||||
|
||||
/* a few constants to find our way around the EEPROM */
|
||||
#define OPTOE_PAGE_SELECT_REG 0x7F
|
||||
@@ -172,13 +166,15 @@ struct optoe_platform_data {
|
||||
#define ONE_ADDR_NOT_PAGEABLE (1<<2)
|
||||
#define TWO_ADDR_PAGEABLE_REG 0x40
|
||||
#define TWO_ADDR_PAGEABLE (1<<4)
|
||||
#define TWO_ADDR_0X51_REG 92
|
||||
#define TWO_ADDR_0X51_SUPP (1<<6)
|
||||
#define OPTOE_ID_REG 0
|
||||
#define OPTOE_READ_OP 0
|
||||
#define OPTOE_WRITE_OP 1
|
||||
#define OPTOE_EOF 0 /* used for access beyond end of device */
|
||||
|
||||
/* The maximum length of a port name */
|
||||
#define MAX_PORT_NAME_LEN 20
|
||||
struct optoe_data {
|
||||
struct optoe_platform_data chip;
|
||||
struct memory_accessor macc;
|
||||
int use_smbus;
|
||||
char port_name[MAX_PORT_NAME_LEN];
|
||||
|
||||
@@ -191,9 +187,9 @@ struct optoe_data {
|
||||
struct attribute_group attr_group;
|
||||
|
||||
u8 *writebuf;
|
||||
unsigned write_max;
|
||||
unsigned int write_max;
|
||||
|
||||
unsigned num_addresses;
|
||||
unsigned int num_addresses;
|
||||
|
||||
#ifdef EEPROM_CLASS
|
||||
struct eeprom_device *eeprom_dev;
|
||||
@@ -205,10 +201,6 @@ struct optoe_data {
|
||||
struct i2c_client *client[];
|
||||
};
|
||||
|
||||
typedef enum optoe_opcode {
|
||||
OPTOE_READ_OP = 0,
|
||||
OPTOE_WRITE_OP = 1
|
||||
} optoe_opcode_e;
|
||||
|
||||
/*
|
||||
* This parameter is to help this driver avoid blocking other drivers out
|
||||
@@ -219,13 +211,13 @@ typedef enum optoe_opcode {
|
||||
*
|
||||
* This value is forced to be a power of two so that writes align on pages.
|
||||
*/
|
||||
static unsigned io_limit = OPTOE_PAGE_SIZE;
|
||||
static unsigned int io_limit = OPTOE_PAGE_SIZE;
|
||||
|
||||
/*
|
||||
* specs often allow 5 msec for a page write, sometimes 20 msec;
|
||||
* it's important to recover from write timeouts.
|
||||
*/
|
||||
static unsigned write_timeout = 25;
|
||||
static unsigned int write_timeout = 25;
|
||||
|
||||
/*
|
||||
* flags to distinguish one-address (QSFP family) from two-address (SFP family)
|
||||
@@ -251,7 +243,7 @@ MODULE_DEVICE_TABLE(i2c, optoe_ids);
|
||||
* Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51),
|
||||
* the page, and the offset.
|
||||
*
|
||||
* Handles both single address (eg QSFP) and two address (eg SFP).
|
||||
* Handles both single address (eg QSFP) and two address (eg SFP).
|
||||
* For SFP, offset 0-255 are on client[0], >255 is on client[1]
|
||||
* Offset 256-383 are on the lower half of client[1]
|
||||
* Pages are accessible on the upper half of client[1].
|
||||
@@ -265,7 +257,7 @@ MODULE_DEVICE_TABLE(i2c, optoe_ids);
|
||||
* Callers must not read/write beyond the end of a client or a page
|
||||
* without recomputing the client/page. Hence offset (within page)
|
||||
* plus length must be less than or equal to 128. (Note that this
|
||||
* routine does not have access to the length of the call, hence
|
||||
* routine does not have access to the length of the call, hence
|
||||
* cannot do the validity check.)
|
||||
*
|
||||
* Offset within Lower Page 00h and Upper Page 00h are not recomputed
|
||||
@@ -274,7 +266,7 @@ MODULE_DEVICE_TABLE(i2c, optoe_ids);
|
||||
static uint8_t optoe_translate_offset(struct optoe_data *optoe,
|
||||
loff_t *offset, struct i2c_client **client)
|
||||
{
|
||||
unsigned page = 0;
|
||||
unsigned int page = 0;
|
||||
|
||||
*client = optoe->client[0];
|
||||
|
||||
@@ -283,7 +275,7 @@ static uint8_t optoe_translate_offset(struct optoe_data *optoe,
|
||||
if (*offset > 255) {
|
||||
/* like QSFP, but shifted to client[1] */
|
||||
*client = optoe->client[1];
|
||||
*offset -= 256;
|
||||
*offset -= 256;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +297,7 @@ static uint8_t optoe_translate_offset(struct optoe_data *optoe,
|
||||
|
||||
static ssize_t optoe_eeprom_read(struct optoe_data *optoe,
|
||||
struct i2c_client *client,
|
||||
char *buf, unsigned offset, size_t count)
|
||||
char *buf, unsigned int offset, size_t count)
|
||||
{
|
||||
struct i2c_msg msg[2];
|
||||
u8 msgbuf[2];
|
||||
@@ -393,21 +385,21 @@ static ssize_t optoe_eeprom_read(struct optoe_data *optoe,
|
||||
return status;
|
||||
|
||||
/* REVISIT: at HZ=100, this is sloooow */
|
||||
msleep(1);
|
||||
usleep_range(1000, 2000);
|
||||
} while (time_before(read_time, timeout));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static ssize_t optoe_eeprom_write(struct optoe_data *optoe,
|
||||
struct i2c_client *client,
|
||||
struct i2c_client *client,
|
||||
const char *buf,
|
||||
unsigned offset, size_t count)
|
||||
unsigned int offset, size_t count)
|
||||
{
|
||||
struct i2c_msg msg;
|
||||
ssize_t status;
|
||||
unsigned long timeout, write_time;
|
||||
unsigned next_page_start;
|
||||
unsigned int next_page_start;
|
||||
int i = 0;
|
||||
|
||||
/* write max is at most a page
|
||||
@@ -496,7 +488,7 @@ static ssize_t optoe_eeprom_write(struct optoe_data *optoe,
|
||||
return count;
|
||||
|
||||
/* REVISIT: at HZ=100, this is sloooow */
|
||||
msleep(1);
|
||||
usleep_range(1000, 2000);
|
||||
} while (time_before(write_time, timeout));
|
||||
|
||||
return -ETIMEDOUT;
|
||||
@@ -504,8 +496,8 @@ static ssize_t optoe_eeprom_write(struct optoe_data *optoe,
|
||||
|
||||
|
||||
static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe,
|
||||
char *buf, loff_t off,
|
||||
size_t count, optoe_opcode_e opcode)
|
||||
char *buf, loff_t off,
|
||||
size_t count, int opcode)
|
||||
{
|
||||
struct i2c_client *client;
|
||||
ssize_t retval = 0;
|
||||
@@ -515,10 +507,10 @@ static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe,
|
||||
|
||||
page = optoe_translate_offset(optoe, &phy_offset, &client);
|
||||
dev_dbg(&client->dev,
|
||||
"optoe_eeprom_update_client off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n",
|
||||
off, page, phy_offset, (long int) count, opcode);
|
||||
"%s off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n",
|
||||
__func__, off, page, phy_offset, (long int) count, opcode);
|
||||
if (page > 0) {
|
||||
ret = optoe_eeprom_write(optoe, client, &page,
|
||||
ret = optoe_eeprom_write(optoe, client, &page,
|
||||
OPTOE_PAGE_SELECT_REG, 1);
|
||||
if (ret < 0) {
|
||||
dev_dbg(&client->dev,
|
||||
@@ -553,13 +545,14 @@ static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe,
|
||||
if (page > 0) {
|
||||
/* return the page register to page 0 (why?) */
|
||||
page = 0;
|
||||
ret = optoe_eeprom_write(optoe, client, &page,
|
||||
ret = optoe_eeprom_write(optoe, client, &page,
|
||||
OPTOE_PAGE_SELECT_REG, 1);
|
||||
if (ret < 0) {
|
||||
dev_err(&client->dev,
|
||||
"Restore page register to 0 failed:%d!\n", ret);
|
||||
/* error only if nothing has been transferred */
|
||||
if (retval == 0) retval = ret;
|
||||
if (retval == 0)
|
||||
retval = ret;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
@@ -575,9 +568,9 @@ static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe,
|
||||
* Returns updated len for this access:
|
||||
* - entire access is legal, original len is returned.
|
||||
* - access begins legal but is too long, len is truncated to fit.
|
||||
* - initial offset exceeds supported pages, return -EINVAL
|
||||
* - initial offset exceeds supported pages, return OPTOE_EOF (zero)
|
||||
*/
|
||||
static ssize_t optoe_page_legal(struct optoe_data *optoe,
|
||||
static ssize_t optoe_page_legal(struct optoe_data *optoe,
|
||||
loff_t off, size_t len)
|
||||
{
|
||||
struct i2c_client *client = optoe->client[0];
|
||||
@@ -585,24 +578,44 @@ static ssize_t optoe_page_legal(struct optoe_data *optoe,
|
||||
int status;
|
||||
size_t maxlen;
|
||||
|
||||
if (off < 0) return -EINVAL;
|
||||
if (off < 0)
|
||||
return -EINVAL;
|
||||
if (optoe->dev_class == TWO_ADDR) {
|
||||
/* SFP case */
|
||||
/* if no pages needed, we're good */
|
||||
if ((off + len) <= TWO_ADDR_EEPROM_UNPAGED_SIZE) return len;
|
||||
/* if only using addr 0x50 (first 256 bytes) we're good */
|
||||
if ((off + len) <= TWO_ADDR_NO_0X51_SIZE)
|
||||
return len;
|
||||
/* if offset exceeds possible pages, we're not good */
|
||||
if (off >= TWO_ADDR_EEPROM_SIZE) return -EINVAL;
|
||||
if (off >= TWO_ADDR_EEPROM_SIZE)
|
||||
return OPTOE_EOF;
|
||||
/* in between, are pages supported? */
|
||||
status = optoe_eeprom_read(optoe, client, ®val,
|
||||
status = optoe_eeprom_read(optoe, client, ®val,
|
||||
TWO_ADDR_PAGEABLE_REG, 1);
|
||||
if (status < 0) return status; /* error out (no module?) */
|
||||
if (status < 0)
|
||||
return status; /* error out (no module?) */
|
||||
if (regval & TWO_ADDR_PAGEABLE) {
|
||||
/* Pages supported, trim len to the end of pages */
|
||||
maxlen = TWO_ADDR_EEPROM_SIZE - off;
|
||||
} else {
|
||||
/* pages not supported, trim len to unpaged size */
|
||||
if (off >= TWO_ADDR_EEPROM_UNPAGED_SIZE) return -EINVAL;
|
||||
maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off;
|
||||
if (off >= TWO_ADDR_EEPROM_UNPAGED_SIZE)
|
||||
return OPTOE_EOF;
|
||||
|
||||
/* will be accessing addr 0x51, is that supported? */
|
||||
/* byte 92, bit 6 implies DDM support, 0x51 support */
|
||||
status = optoe_eeprom_read(optoe, client, ®val,
|
||||
TWO_ADDR_0X51_REG, 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
if (regval & TWO_ADDR_0X51_SUPP) {
|
||||
/* addr 0x51 is OK */
|
||||
maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off;
|
||||
} else {
|
||||
/* addr 0x51 NOT supported, trim to 256 max */
|
||||
if (off >= TWO_ADDR_NO_0X51_SIZE)
|
||||
return OPTOE_EOF;
|
||||
maxlen = TWO_ADDR_NO_0X51_SIZE - off;
|
||||
}
|
||||
}
|
||||
len = (len > maxlen) ? maxlen : len;
|
||||
dev_dbg(&client->dev,
|
||||
@@ -611,16 +624,20 @@ static ssize_t optoe_page_legal(struct optoe_data *optoe,
|
||||
} else {
|
||||
/* QSFP case */
|
||||
/* if no pages needed, we're good */
|
||||
if ((off + len) <= ONE_ADDR_EEPROM_UNPAGED_SIZE) return len;
|
||||
if ((off + len) <= ONE_ADDR_EEPROM_UNPAGED_SIZE)
|
||||
return len;
|
||||
/* if offset exceeds possible pages, we're not good */
|
||||
if (off >= ONE_ADDR_EEPROM_SIZE) return -EINVAL;
|
||||
if (off >= ONE_ADDR_EEPROM_SIZE)
|
||||
return OPTOE_EOF;
|
||||
/* in between, are pages supported? */
|
||||
status = optoe_eeprom_read(optoe, client, ®val,
|
||||
status = optoe_eeprom_read(optoe, client, ®val,
|
||||
ONE_ADDR_PAGEABLE_REG, 1);
|
||||
if (status < 0) return status; /* error out (no module?) */
|
||||
if (status < 0)
|
||||
return status; /* error out (no module?) */
|
||||
if (regval & ONE_ADDR_NOT_PAGEABLE) {
|
||||
/* pages not supported, trim len to unpaged size */
|
||||
if (off >= ONE_ADDR_EEPROM_UNPAGED_SIZE) return -EINVAL;
|
||||
if (off >= ONE_ADDR_EEPROM_UNPAGED_SIZE)
|
||||
return OPTOE_EOF;
|
||||
maxlen = ONE_ADDR_EEPROM_UNPAGED_SIZE - off;
|
||||
} else {
|
||||
/* Pages supported, trim len to the end of pages */
|
||||
@@ -635,7 +652,7 @@ static ssize_t optoe_page_legal(struct optoe_data *optoe,
|
||||
}
|
||||
|
||||
static ssize_t optoe_read_write(struct optoe_data *optoe,
|
||||
char *buf, loff_t off, size_t len, optoe_opcode_e opcode)
|
||||
char *buf, loff_t off, size_t len, int opcode)
|
||||
{
|
||||
struct i2c_client *client = optoe->client[0];
|
||||
int chunk;
|
||||
@@ -645,8 +662,9 @@ static ssize_t optoe_read_write(struct optoe_data *optoe,
|
||||
loff_t chunk_offset = 0, chunk_start_offset = 0;
|
||||
|
||||
dev_dbg(&client->dev,
|
||||
"optoe_read_write: off %lld len:%ld, opcode:%s\n",
|
||||
off, (long int) len, (opcode == OPTOE_READ_OP) ? "r": "w");
|
||||
"%s: off %lld len:%ld, opcode:%s\n",
|
||||
__func__, off, (long int) len,
|
||||
(opcode == OPTOE_READ_OP) ? "r" : "w");
|
||||
if (unlikely(!len))
|
||||
return len;
|
||||
|
||||
@@ -655,13 +673,14 @@ static ssize_t optoe_read_write(struct optoe_data *optoe,
|
||||
* from this host, but not from other I2C masters.
|
||||
*/
|
||||
mutex_lock(&optoe->lock);
|
||||
|
||||
|
||||
/*
|
||||
* Confirm this access fits within the device suppored addr range
|
||||
* Confirm this access fits within the device suppored addr range
|
||||
*/
|
||||
status = optoe_page_legal(optoe, off, len);
|
||||
if (status < 0) {
|
||||
goto err;
|
||||
if ((status == OPTOE_EOF) || (status < 0)) {
|
||||
mutex_unlock(&optoe->lock);
|
||||
return status;
|
||||
}
|
||||
len = status;
|
||||
|
||||
@@ -670,7 +689,7 @@ static ssize_t optoe_read_write(struct optoe_data *optoe,
|
||||
* separate call to sff_eeprom_update_client(), to
|
||||
* ensure that each access recalculates the client/page
|
||||
* and writes the page register as needed.
|
||||
* Note that chunk to page mapping is confusing, is different for
|
||||
* Note that chunk to page mapping is confusing, is different for
|
||||
* QSFP and SFP, and never needs to be done. Don't try!
|
||||
*/
|
||||
pending_len = len; /* amount remaining to transfer */
|
||||
@@ -711,18 +730,22 @@ static ssize_t optoe_read_write(struct optoe_data *optoe,
|
||||
off, (long int) len, chunk_start_offset, chunk_offset,
|
||||
(long int) chunk_len, (long int) pending_len);
|
||||
|
||||
/*
|
||||
* note: chunk_offset is from the start of the EEPROM,
|
||||
* not the start of the chunk
|
||||
/*
|
||||
* note: chunk_offset is from the start of the EEPROM,
|
||||
* not the start of the chunk
|
||||
*/
|
||||
status = optoe_eeprom_update_client(optoe, buf,
|
||||
status = optoe_eeprom_update_client(optoe, buf,
|
||||
chunk_offset, chunk_len, opcode);
|
||||
if (status != chunk_len) {
|
||||
/* This is another 'no device present' path */
|
||||
dev_dbg(&client->dev,
|
||||
"optoe_update_client for chunk %d chunk_offset %lld chunk_len %ld failed %d!\n",
|
||||
chunk, chunk_offset, (long int) chunk_len, status);
|
||||
goto err;
|
||||
dev_dbg(&client->dev,
|
||||
"o_u_c: chunk %d c_offset %lld c_len %ld failed %d!\n",
|
||||
chunk, chunk_offset, (long int) chunk_len, status);
|
||||
if (status > 0)
|
||||
retval += status;
|
||||
if (retval == 0)
|
||||
retval = status;
|
||||
break;
|
||||
}
|
||||
buf += status;
|
||||
pending_len -= status;
|
||||
@@ -731,11 +754,6 @@ static ssize_t optoe_read_write(struct optoe_data *optoe,
|
||||
mutex_unlock(&optoe->lock);
|
||||
|
||||
return retval;
|
||||
|
||||
err:
|
||||
mutex_unlock(&optoe->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static ssize_t optoe_bin_read(struct file *filp, struct kobject *kobj,
|
||||
@@ -760,34 +778,6 @@ static ssize_t optoe_bin_write(struct file *filp, struct kobject *kobj,
|
||||
|
||||
return optoe_read_write(optoe, buf, off, count, OPTOE_WRITE_OP);
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* This lets other kernel code access the eeprom data. For example, it
|
||||
* might hold a board's Ethernet address, or board-specific calibration
|
||||
* data generated on the manufacturing floor.
|
||||
*/
|
||||
|
||||
static ssize_t optoe_macc_read(struct memory_accessor *macc,
|
||||
char *buf, off_t offset, size_t count)
|
||||
{
|
||||
struct optoe_data *optoe = container_of(macc,
|
||||
struct optoe_data, macc);
|
||||
|
||||
return optoe_read_write(optoe, buf, offset, count, OPTOE_READ_OP);
|
||||
}
|
||||
|
||||
static ssize_t optoe_macc_write(struct memory_accessor *macc,
|
||||
const char *buf, off_t offset, size_t count)
|
||||
{
|
||||
struct optoe_data *optoe = container_of(macc,
|
||||
struct optoe_data, macc);
|
||||
|
||||
return optoe_read_write(optoe, (char *) buf, offset,
|
||||
count, OPTOE_WRITE_OP);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int optoe_remove(struct i2c_client *client)
|
||||
{
|
||||
@@ -810,6 +800,51 @@ static int optoe_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t show_dev_class(struct device *dev,
|
||||
struct device_attribute *dattr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct optoe_data *optoe = i2c_get_clientdata(client);
|
||||
ssize_t count;
|
||||
|
||||
mutex_lock(&optoe->lock);
|
||||
count = sprintf(buf, "%d\n", optoe->dev_class);
|
||||
mutex_unlock(&optoe->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_dev_class(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct optoe_data *optoe = i2c_get_clientdata(client);
|
||||
int dev_class;
|
||||
|
||||
/*
|
||||
* dev_class is actually the number of i2c addresses used, thus
|
||||
* legal values are "1" (QSFP class) and "2" (SFP class)
|
||||
*/
|
||||
|
||||
if (kstrtoint(buf, 0, &dev_class) != 0 ||
|
||||
dev_class < 1 || dev_class > 2)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&optoe->lock);
|
||||
optoe->dev_class = dev_class;
|
||||
mutex_unlock(&optoe->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* if using the EEPROM CLASS driver, we don't report a port_name,
|
||||
* the EEPROM CLASS drive handles that. Hence all this code is
|
||||
* only compiled if we are NOT using the EEPROM CLASS driver.
|
||||
*/
|
||||
#ifndef EEPROM_CLASS
|
||||
|
||||
static ssize_t show_port_name(struct device *dev,
|
||||
struct device_attribute *dattr, char *buf)
|
||||
{
|
||||
@@ -844,51 +879,15 @@ static ssize_t set_port_name(struct device *dev,
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(port_name, S_IRUGO | S_IWUSR,
|
||||
show_port_name, set_port_name);
|
||||
static DEVICE_ATTR(port_name, 0644, show_port_name, set_port_name);
|
||||
#endif /* if NOT defined EEPROM_CLASS, the common case */
|
||||
|
||||
static ssize_t show_dev_class(struct device *dev,
|
||||
struct device_attribute *dattr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct optoe_data *optoe = i2c_get_clientdata(client);
|
||||
ssize_t count;
|
||||
|
||||
mutex_lock(&optoe->lock);
|
||||
count = sprintf(buf, "%d\n", optoe->dev_class);
|
||||
mutex_unlock(&optoe->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t set_dev_class(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct optoe_data *optoe = i2c_get_clientdata(client);
|
||||
int dev_class;
|
||||
|
||||
/*
|
||||
* dev_class is actually the number of sfp ports used, thus
|
||||
* legal values are "1" (QSFP class) and "2" (SFP class)
|
||||
*/
|
||||
if (sscanf(buf, "%d", &dev_class) != 1 ||
|
||||
dev_class < 1 || dev_class > 2)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&optoe->lock);
|
||||
optoe->dev_class = dev_class;
|
||||
mutex_unlock(&optoe->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(dev_class, S_IRUGO | S_IWUSR,
|
||||
show_dev_class, set_dev_class);
|
||||
static DEVICE_ATTR(dev_class, 0644, show_dev_class, set_dev_class);
|
||||
|
||||
static struct attribute *optoe_attrs[] = {
|
||||
#ifndef EEPROM_CLASS
|
||||
&dev_attr_port_name.attr,
|
||||
#endif
|
||||
&dev_attr_dev_class.attr,
|
||||
NULL,
|
||||
};
|
||||
@@ -905,7 +904,7 @@ static int optoe_probe(struct i2c_client *client,
|
||||
struct optoe_platform_data chip;
|
||||
struct optoe_data *optoe;
|
||||
int num_addresses = 0;
|
||||
int i = 0;
|
||||
char port_name[MAX_PORT_NAME_LEN];
|
||||
|
||||
if (client->addr != 0x50) {
|
||||
dev_dbg(&client->dev, "probe, bad i2c addr: 0x%x\n",
|
||||
@@ -916,16 +915,23 @@ static int optoe_probe(struct i2c_client *client,
|
||||
|
||||
if (client->dev.platform_data) {
|
||||
chip = *(struct optoe_platform_data *)client->dev.platform_data;
|
||||
dev_dbg(&client->dev, "probe, chip provided, flags:0x%x; name: %s\n", chip.flags, client->name);
|
||||
/* take the port name from the supplied platform data */
|
||||
#ifdef EEPROM_CLASS
|
||||
strncpy(port_name, chip.eeprom_data->label, MAX_PORT_NAME_LEN);
|
||||
#else
|
||||
memcpy(port_name, chip.port_name, MAX_PORT_NAME_LEN);
|
||||
#endif
|
||||
dev_dbg(&client->dev,
|
||||
"probe, chip provided, flags:0x%x; name: %s\n",
|
||||
chip.flags, client->name);
|
||||
} else {
|
||||
if (!id->driver_data) {
|
||||
err = -ENODEV;
|
||||
goto exit;
|
||||
}
|
||||
dev_dbg(&client->dev, "probe, building chip\n");
|
||||
strcpy(port_name, "unitialized");
|
||||
chip.flags = 0;
|
||||
chip.setup = NULL;
|
||||
chip.context = NULL;
|
||||
#ifdef EEPROM_CLASS
|
||||
chip.eeprom_data = NULL;
|
||||
#endif
|
||||
@@ -965,7 +971,7 @@ static int optoe_probe(struct i2c_client *client,
|
||||
mutex_init(&optoe->lock);
|
||||
|
||||
/* determine whether this is a one-address or two-address module */
|
||||
if ((strcmp(client->name, "optoe1") == 0) ||
|
||||
if ((strcmp(client->name, "optoe1") == 0) ||
|
||||
(strcmp(client->name, "sff8436") == 0)) {
|
||||
/* one-address (eg QSFP) family */
|
||||
optoe->dev_class = ONE_ADDR;
|
||||
@@ -985,7 +991,7 @@ static int optoe_probe(struct i2c_client *client,
|
||||
optoe->use_smbus = use_smbus;
|
||||
optoe->chip = chip;
|
||||
optoe->num_addresses = num_addresses;
|
||||
strcpy(optoe->port_name, "unitialized");
|
||||
memcpy(optoe->port_name, port_name, MAX_PORT_NAME_LEN);
|
||||
|
||||
/*
|
||||
* Export the EEPROM bytes through sysfs, since that's convenient.
|
||||
@@ -993,12 +999,10 @@ static int optoe_probe(struct i2c_client *client,
|
||||
*/
|
||||
sysfs_bin_attr_init(&optoe->bin);
|
||||
optoe->bin.attr.name = "eeprom";
|
||||
optoe->bin.attr.mode = S_IRUGO;
|
||||
optoe->bin.attr.mode = 0444;
|
||||
optoe->bin.read = optoe_bin_read;
|
||||
optoe->bin.size = chip.byte_len;
|
||||
|
||||
optoe->macc.read = optoe_macc_read;
|
||||
|
||||
if (!use_smbus ||
|
||||
(i2c_check_functionality(client->adapter,
|
||||
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) ||
|
||||
@@ -1013,12 +1017,10 @@ static int optoe_probe(struct i2c_client *client,
|
||||
* 2 byte writes are acceptable for PE and Vout changes per
|
||||
* Application Note AN-2071.
|
||||
*/
|
||||
unsigned write_max = 1;
|
||||
|
||||
optoe->macc.write = optoe_macc_write;
|
||||
unsigned int write_max = 1;
|
||||
|
||||
optoe->bin.write = optoe_bin_write;
|
||||
optoe->bin.attr.mode |= S_IWUSR;
|
||||
optoe->bin.attr.mode |= 0200;
|
||||
|
||||
if (write_max > io_limit)
|
||||
write_max = io_limit;
|
||||
@@ -1033,19 +1035,17 @@ static int optoe_probe(struct i2c_client *client,
|
||||
goto exit_kfree;
|
||||
}
|
||||
} else {
|
||||
dev_warn(&client->dev,
|
||||
"cannot write due to controller restrictions.");
|
||||
dev_warn(&client->dev,
|
||||
"cannot write due to controller restrictions.");
|
||||
}
|
||||
|
||||
optoe->client[0] = client;
|
||||
|
||||
/* use a dummy I2C device for two-address chips */
|
||||
for (i = 1; i < num_addresses; i++) {
|
||||
optoe->client[i] = i2c_new_dummy(client->adapter,
|
||||
client->addr + i);
|
||||
if (!optoe->client[i]) {
|
||||
dev_err(&client->dev, "address 0x%02x unavailable\n",
|
||||
client->addr + i);
|
||||
/* SFF-8472 spec requires that the second I2C address be 0x51 */
|
||||
if (num_addresses == 2) {
|
||||
optoe->client[1] = i2c_new_dummy(client->adapter, 0x51);
|
||||
if (!optoe->client[1]) {
|
||||
dev_err(&client->dev, "address 0x51 unavailable\n");
|
||||
err = -EADDRINUSE;
|
||||
goto err_struct;
|
||||
}
|
||||
@@ -1063,6 +1063,7 @@ static int optoe_probe(struct i2c_client *client,
|
||||
dev_err(&client->dev, "failed to create sysfs attribute group.\n");
|
||||
goto err_struct;
|
||||
}
|
||||
|
||||
#ifdef EEPROM_CLASS
|
||||
optoe->eeprom_dev = eeprom_device_register(&client->dev,
|
||||
chip.eeprom_data);
|
||||
@@ -1081,14 +1082,11 @@ static int optoe_probe(struct i2c_client *client,
|
||||
|
||||
if (use_smbus == I2C_SMBUS_WORD_DATA ||
|
||||
use_smbus == I2C_SMBUS_BYTE_DATA) {
|
||||
dev_notice(&client->dev, "Falling back to %s reads, "
|
||||
"performance will suffer\n", use_smbus ==
|
||||
I2C_SMBUS_WORD_DATA ? "word" : "byte");
|
||||
dev_notice(&client->dev,
|
||||
"Falling back to %s reads, performance will suffer\n",
|
||||
use_smbus == I2C_SMBUS_WORD_DATA ? "word" : "byte");
|
||||
}
|
||||
|
||||
if (chip.setup)
|
||||
chip.setup(&optoe->macc, chip.context);
|
||||
|
||||
return 0;
|
||||
|
||||
#ifdef EEPROM_CLASS
|
||||
@@ -1098,9 +1096,9 @@ err_sysfs_cleanup:
|
||||
#endif
|
||||
|
||||
err_struct:
|
||||
for (i = 1; i < num_addresses; i++) {
|
||||
if (optoe->client[i])
|
||||
i2c_unregister_device(optoe->client[i]);
|
||||
if (num_addresses == 2) {
|
||||
if (optoe->client[1])
|
||||
i2c_unregister_device(optoe->client[1]);
|
||||
}
|
||||
|
||||
kfree(optoe->writebuf);
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5512-54x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5512-54x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5512-54x
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
extern int accton_i2c_cpld_read(unsigned short cpld_addr, u8 reg);
|
||||
extern int accton_i2c_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "as5512_54x_led"
|
||||
|
||||
struct accton_as5512_54x_led_data {
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5512-54x-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5712-54x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5712-54x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5712-54x
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/*
|
||||
* I2C multiplexer
|
||||
* An I2C multiplexer dirver for accton as5712 CPLD
|
||||
*
|
||||
* Copyright (C) Brandon Chuang <brandon_chuang@accton.com.tw>
|
||||
* Copyright (C) 2015 Accton Technology Corporation.
|
||||
* Brandon Chuang <brandon_chuang@accton.com.tw>
|
||||
*
|
||||
* This module supports the accton cpld that hold the channel select
|
||||
* mechanism for other i2c slave devices, such as SFP.
|
||||
@@ -46,8 +47,6 @@
|
||||
#define CPLD_CHANNEL_SELECT_REG 0x2
|
||||
#define CPLD_DESELECT_CHANNEL 0xFF
|
||||
|
||||
#define ACCTON_I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD3_CHANS
|
||||
|
||||
static LIST_HEAD(cpld_client_list);
|
||||
static struct mutex list_lock;
|
||||
|
||||
@@ -64,7 +63,7 @@ enum cpld_mux_type {
|
||||
|
||||
struct as5712_54x_cpld_data {
|
||||
enum cpld_mux_type type;
|
||||
struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS];
|
||||
struct i2c_client *client;
|
||||
u8 last_chan; /* last register value */
|
||||
|
||||
struct device *hwmon_dev;
|
||||
@@ -595,8 +594,9 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
|
||||
int i, status, num_regs = 0;
|
||||
u8 values[4] = {0};
|
||||
u8 regs[] = {0x6, 0x7, 0x8, 0x14};
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
@@ -638,8 +638,9 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
|
||||
int i, status;
|
||||
u8 values[3] = {0};
|
||||
u8 regs[] = {0xF, 0x10, 0x11};
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
@@ -668,7 +669,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
int status = 0;
|
||||
u8 reg = 0, mask = 0, revert = 0;
|
||||
|
||||
@@ -819,8 +821,9 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
long disable;
|
||||
int status;
|
||||
u8 reg = 0, mask = 0;
|
||||
@@ -890,10 +893,11 @@ exit:
|
||||
static ssize_t access(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
int status;
|
||||
u32 addr, val;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
|
||||
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
|
||||
return -EINVAL;
|
||||
@@ -949,32 +953,34 @@ static int as5712_54x_cpld_mux_reg_write(struct i2c_adapter *adap,
|
||||
return res;
|
||||
}
|
||||
|
||||
static int as5712_54x_cpld_mux_select_chan(struct i2c_adapter *adap,
|
||||
void *client, u32 chan)
|
||||
static int as5712_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
|
||||
u32 chan)
|
||||
{
|
||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
u8 regval;
|
||||
int ret = 0;
|
||||
regval = chan;
|
||||
|
||||
/* Only select the channel if its different from the last channel */
|
||||
regval = chan;
|
||||
/* Only select the channel if its different from the last channel */
|
||||
if (data->last_chan != regval) {
|
||||
ret = as5712_54x_cpld_mux_reg_write(adap, client, regval);
|
||||
ret = as5712_54x_cpld_mux_reg_write(muxc->parent, client, regval);
|
||||
data->last_chan = regval;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as5712_54x_cpld_mux_deselect_mux(struct i2c_adapter *adap,
|
||||
void *client, u32 chan)
|
||||
static int as5712_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc,
|
||||
u32 chan)
|
||||
{
|
||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
|
||||
/* Deselect active channel */
|
||||
data->last_chan = chips[data->type].deselectChan;
|
||||
|
||||
return as5712_54x_cpld_mux_reg_write(adap, client, data->last_chan);
|
||||
return as5712_54x_cpld_mux_reg_write(muxc->parent, client, data->last_chan);
|
||||
}
|
||||
|
||||
static void as5712_54x_cpld_add_client(struct i2c_client *client)
|
||||
@@ -1001,8 +1007,7 @@ static void as5712_54x_cpld_remove_client(struct i2c_client *client)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client == client) {
|
||||
@@ -1039,44 +1044,43 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c
|
||||
static int as5712_54x_cpld_mux_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
int chan=0;
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
int num, force, class;
|
||||
struct i2c_mux_core *muxc;
|
||||
struct as5712_54x_cpld_data *data;
|
||||
int ret = -ENODEV;
|
||||
const struct attribute_group *group = NULL;
|
||||
int ret = 0;
|
||||
const struct attribute_group *group = NULL;
|
||||
|
||||
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
|
||||
goto exit;
|
||||
return -ENODEV;
|
||||
|
||||
data = kzalloc(sizeof(struct as5712_54x_cpld_data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
muxc = i2c_mux_alloc(adap, &client->dev,
|
||||
chips[id->driver_data].nchans, sizeof(*data), 0,
|
||||
as5712_54x_cpld_mux_select_chan, as5712_54x_cpld_mux_deselect_mux);
|
||||
if (!muxc)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
i2c_set_clientdata(client, muxc);
|
||||
data = i2c_mux_priv(muxc);
|
||||
data->client = client;
|
||||
data->type = id->driver_data;
|
||||
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
||||
mutex_init(&data->update_lock);
|
||||
data->type = id->driver_data;
|
||||
|
||||
if (data->type == as5712_54x_cpld2 || data->type == as5712_54x_cpld3) {
|
||||
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
||||
/* Now create an adapter for each channel */
|
||||
for (num = 0; num < chips[data->type].nchans; num++) {
|
||||
force = 0; /* dynamic adap number */
|
||||
class = 0; /* no class by default */
|
||||
|
||||
/* Now create an adapter for each channel */
|
||||
for (chan = 0; chan < chips[data->type].nchans; chan++) {
|
||||
data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, 0,
|
||||
as5712_54x_cpld_mux_select_chan,
|
||||
as5712_54x_cpld_mux_deselect_mux);
|
||||
ret = i2c_mux_add_adapter(muxc, force, num, class);
|
||||
|
||||
if (data->virt_adaps[chan] == NULL) {
|
||||
ret = -ENODEV;
|
||||
dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan);
|
||||
goto exit_mux_register;
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n",
|
||||
chan, client->name);
|
||||
}
|
||||
if (ret) {
|
||||
dev_err(&client->dev,
|
||||
"failed to register multiplexed adapter"
|
||||
" %d as bus %d\n", num, force);
|
||||
goto add_mux_failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register sysfs hooks */
|
||||
switch (data->type) {
|
||||
@@ -1095,33 +1099,37 @@ static int as5712_54x_cpld_mux_probe(struct i2c_client *client,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (group) {
|
||||
ret = sysfs_create_group(&client->dev.kobj, group);
|
||||
if (ret) {
|
||||
goto exit_mux_register;
|
||||
goto add_mux_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (chips[data->type].nchans) {
|
||||
dev_info(&client->dev,
|
||||
"registered %d multiplexed busses for I2C %s\n",
|
||||
num, client->name);
|
||||
}
|
||||
else {
|
||||
dev_info(&client->dev,
|
||||
"device %s registered\n", client->name);
|
||||
}
|
||||
|
||||
as5712_54x_cpld_add_client(client);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_mux_register:
|
||||
for (chan--; chan >= 0; chan--) {
|
||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
||||
}
|
||||
kfree(data);
|
||||
exit:
|
||||
add_mux_failed:
|
||||
i2c_mux_del_adapters(muxc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as5712_54x_cpld_mux_remove(struct i2c_client *client)
|
||||
{
|
||||
struct as5712_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
const struct chip_desc *chip = &chips[data->type];
|
||||
int chan;
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5712_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
const struct attribute_group *group = NULL;
|
||||
|
||||
as5712_54x_cpld_remove_client(client);
|
||||
@@ -1145,14 +1153,7 @@ static int as5712_54x_cpld_mux_remove(struct i2c_client *client)
|
||||
sysfs_remove_group(&client->dev.kobj, group);
|
||||
}
|
||||
|
||||
for (chan = 0; chan < chip->nchans; ++chan) {
|
||||
if (data->virt_adaps[chan]) {
|
||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
||||
data->virt_adaps[chan] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(data);
|
||||
i2c_mux_del_adapters(muxc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1201,8 +1202,7 @@ int as5712_54x_cpld_read(unsigned short cpld_addr, u8 reg)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client->addr == cpld_addr) {
|
||||
@@ -1225,8 +1225,7 @@ int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client->addr == cpld_addr) {
|
||||
@@ -1263,7 +1262,7 @@ static void __exit as5712_54x_cpld_mux_exit(void)
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
|
||||
MODULE_DESCRIPTION("Accton I2C CPLD mux driver");
|
||||
MODULE_DESCRIPTION("Accton as5712-54x CPLD driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(as5712_54x_cpld_mux_init);
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
extern int as5712_54x_cpld_read (unsigned short cpld_addr, u8 reg);
|
||||
extern int as5712_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "as5712_54x_led"
|
||||
|
||||
struct accton_as5712_54x_led_data {
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5712-54x-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5812-54t ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5812-54t ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5812-54t
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
extern int as5812_54t_cpld_read(unsigned short cpld_addr, u8 reg);
|
||||
extern int as5812_54t_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "as5812_54t_led"
|
||||
|
||||
struct accton_as5812_54t_led_data {
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5812-54t-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5812-54x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5812-54x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5812-54x
|
||||
|
||||
@@ -65,7 +65,7 @@ enum cpld_mux_type {
|
||||
|
||||
struct as5812_54x_cpld_data {
|
||||
enum cpld_mux_type type;
|
||||
struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS];
|
||||
struct i2c_client *client;
|
||||
u8 last_chan; /* last register value */
|
||||
|
||||
struct device *hwmon_dev;
|
||||
@@ -100,7 +100,6 @@ static const struct i2c_device_id as5812_54x_cpld_mux_id[] = {
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, as5812_54x_cpld_mux_id);
|
||||
|
||||
#define TRANSCEIVER_PRESENT_ATTR_ID(index) MODULE_PRESENT_##index
|
||||
#define TRANSCEIVER_TXDISABLE_ATTR_ID(index) MODULE_TXDISABLE_##index
|
||||
#define TRANSCEIVER_RXLOS_ATTR_ID(index) MODULE_RXLOS_##index
|
||||
@@ -596,8 +595,9 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
|
||||
int i, status, num_regs = 0;
|
||||
u8 values[4] = {0};
|
||||
u8 regs[] = {0x6, 0x7, 0x8, 0x14};
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5812_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
@@ -639,8 +639,9 @@ static ssize_t show_rxlos_all(struct device *dev, struct device_attribute *da,
|
||||
int i, status;
|
||||
u8 values[3] = {0};
|
||||
u8 regs[] = {0xF, 0x10, 0x11};
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5812_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
@@ -669,7 +670,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5812_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
int status = 0;
|
||||
u8 reg = 0, mask = 0, revert = 0;
|
||||
|
||||
@@ -820,8 +822,9 @@ static ssize_t set_tx_disable(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5812_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
long disable;
|
||||
int status;
|
||||
u8 reg = 0, mask = 0;
|
||||
@@ -891,10 +894,11 @@ exit:
|
||||
static ssize_t access(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
int status;
|
||||
u32 addr, val;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as5812_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
|
||||
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
|
||||
return -EINVAL;
|
||||
@@ -916,7 +920,6 @@ exit:
|
||||
mutex_unlock(&data->update_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer()
|
||||
for this as they will try to lock adapter a second time */
|
||||
static int as5812_54x_cpld_mux_reg_write(struct i2c_adapter *adap,
|
||||
@@ -950,32 +953,35 @@ static int as5812_54x_cpld_mux_reg_write(struct i2c_adapter *adap,
|
||||
return res;
|
||||
}
|
||||
|
||||
static int as5812_54x_cpld_mux_select_chan(struct i2c_adapter *adap,
|
||||
void *client, u32 chan)
|
||||
static int as5812_54x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
|
||||
u32 chan)
|
||||
{
|
||||
struct as5812_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
u8 regval;
|
||||
int ret = 0;
|
||||
|
||||
regval = chan;
|
||||
|
||||
/* Only select the channel if its different from the last channel */
|
||||
if (data->last_chan != regval) {
|
||||
ret = as5812_54x_cpld_mux_reg_write(adap, client, regval);
|
||||
ret = as5812_54x_cpld_mux_reg_write(muxc->parent, client, regval);
|
||||
data->last_chan = regval;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as5812_54x_cpld_mux_deselect_mux(struct i2c_adapter *adap,
|
||||
void *client, u32 chan)
|
||||
static int as5812_54x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc,
|
||||
u32 chan)
|
||||
{
|
||||
struct as5812_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
|
||||
/* Deselect active channel */
|
||||
data->last_chan = chips[data->type].deselectChan;
|
||||
|
||||
return as5812_54x_cpld_mux_reg_write(adap, client, data->last_chan);
|
||||
return as5812_54x_cpld_mux_reg_write(muxc->parent, client, data->last_chan);
|
||||
}
|
||||
|
||||
static void as5812_54x_cpld_add_client(struct i2c_client *client)
|
||||
@@ -1002,8 +1008,7 @@ static void as5812_54x_cpld_remove_client(struct i2c_client *client)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client == client) {
|
||||
@@ -1040,44 +1045,43 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c
|
||||
static int as5812_54x_cpld_mux_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
int chan=0;
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
int num, force, class;
|
||||
struct i2c_mux_core *muxc;
|
||||
struct as5812_54x_cpld_data *data;
|
||||
int ret = -ENODEV;
|
||||
const struct attribute_group *group = NULL;
|
||||
int ret = 0;
|
||||
const struct attribute_group *group = NULL;
|
||||
|
||||
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
|
||||
goto exit;
|
||||
return -ENODEV;
|
||||
|
||||
data = kzalloc(sizeof(struct as5812_54x_cpld_data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
muxc = i2c_mux_alloc(adap, &client->dev,
|
||||
chips[id->driver_data].nchans, sizeof(*data), 0,
|
||||
as5812_54x_cpld_mux_select_chan, as5812_54x_cpld_mux_deselect_mux);
|
||||
if (!muxc)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
i2c_set_clientdata(client, muxc);
|
||||
data = i2c_mux_priv(muxc);
|
||||
data->client = client;
|
||||
data->type = id->driver_data;
|
||||
data->last_chan = CPLD_DESELECT_CHANNEL; /* force the first selection */
|
||||
mutex_init(&data->update_lock);
|
||||
data->type = id->driver_data;
|
||||
|
||||
if (data->type == as5812_54x_cpld2 || data->type == as5812_54x_cpld3) {
|
||||
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
||||
/* Now create an adapter for each channel */
|
||||
for (num = 0; num < chips[data->type].nchans; num++) {
|
||||
force = 0; /* dynamic adap number */
|
||||
class = 0; /* no class by default */
|
||||
|
||||
/* Now create an adapter for each channel */
|
||||
for (chan = 0; chan < chips[data->type].nchans; chan++) {
|
||||
data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, 0,
|
||||
as5812_54x_cpld_mux_select_chan,
|
||||
as5812_54x_cpld_mux_deselect_mux);
|
||||
ret = i2c_mux_add_adapter(muxc, force, num, class);
|
||||
|
||||
if (data->virt_adaps[chan] == NULL) {
|
||||
ret = -ENODEV;
|
||||
dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan);
|
||||
goto exit_mux_register;
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n",
|
||||
chan, client->name);
|
||||
}
|
||||
if (ret) {
|
||||
dev_err(&client->dev,
|
||||
"failed to register multiplexed adapter"
|
||||
" %d as bus %d\n", num, force);
|
||||
goto add_mux_failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register sysfs hooks */
|
||||
switch (data->type) {
|
||||
@@ -1096,33 +1100,37 @@ static int as5812_54x_cpld_mux_probe(struct i2c_client *client,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (group) {
|
||||
ret = sysfs_create_group(&client->dev.kobj, group);
|
||||
if (ret) {
|
||||
goto exit_mux_register;
|
||||
goto add_mux_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (chips[data->type].nchans) {
|
||||
dev_info(&client->dev,
|
||||
"registered %d multiplexed busses for I2C %s\n",
|
||||
num, client->name);
|
||||
}
|
||||
else {
|
||||
dev_info(&client->dev,
|
||||
"device %s registered\n", client->name);
|
||||
}
|
||||
|
||||
as5812_54x_cpld_add_client(client);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_mux_register:
|
||||
for (chan--; chan >= 0; chan--) {
|
||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
||||
}
|
||||
kfree(data);
|
||||
exit:
|
||||
add_mux_failed:
|
||||
i2c_mux_del_adapters(muxc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as5812_54x_cpld_mux_remove(struct i2c_client *client)
|
||||
{
|
||||
struct as5812_54x_cpld_data *data = i2c_get_clientdata(client);
|
||||
const struct chip_desc *chip = &chips[data->type];
|
||||
int chan;
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as5812_54x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
const struct attribute_group *group = NULL;
|
||||
|
||||
as5812_54x_cpld_remove_client(client);
|
||||
@@ -1146,14 +1154,7 @@ static int as5812_54x_cpld_mux_remove(struct i2c_client *client)
|
||||
sysfs_remove_group(&client->dev.kobj, group);
|
||||
}
|
||||
|
||||
for (chan = 0; chan < chip->nchans; ++chan) {
|
||||
if (data->virt_adaps[chan]) {
|
||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
||||
data->virt_adaps[chan] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(data);
|
||||
i2c_mux_del_adapters(muxc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1202,8 +1203,7 @@ int as5812_54x_cpld_read(unsigned short cpld_addr, u8 reg)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client->addr == cpld_addr) {
|
||||
@@ -1226,8 +1226,7 @@ int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client->addr == cpld_addr) {
|
||||
@@ -1264,7 +1263,7 @@ static void __exit as5812_54x_cpld_mux_exit(void)
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Brandon Chuang <brandon_chuang@accton.com.tw>");
|
||||
MODULE_DESCRIPTION("Accton I2C CPLD mux driver");
|
||||
MODULE_DESCRIPTION("Accton as5812-54x CPLD driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
module_init(as5812_54x_cpld_mux_init);
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
extern int as5812_54x_cpld_read (unsigned short cpld_addr, u8 reg);
|
||||
extern int as5812_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "as5812_54x_led"
|
||||
|
||||
struct accton_as5812_54x_led_data {
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5812-54x-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5822-54x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5822-54x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5822-54x
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5822-54x-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5912-54x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5912-54x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5912-54x
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5912-54x-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5912-54xk ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5912-54xk ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5912-54xk
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5912-54xk-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5916-54x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5916-54x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5916-54x
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5916-54x-r1:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5916-54xk ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5916-54xk ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5916-54xk
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5916-54xk-r1:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5916-54xm ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as5916-54xm ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as5916-54xm
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <onlplib/i2c.h>
|
||||
#include <onlplib/file.h>
|
||||
#include <onlp/platformi/sysi.h>
|
||||
#include <onlp/platformi/ledi.h>
|
||||
@@ -55,17 +56,26 @@ onlp_sysi_platform_get(void)
|
||||
int
|
||||
onlp_sysi_onie_data_get(uint8_t** data, int* size)
|
||||
{
|
||||
int ret = ONLP_STATUS_OK;
|
||||
int i = 0;
|
||||
uint8_t* rdata = aim_zmalloc(256);
|
||||
if(onlp_file_read(rdata, 256, size, IDPROM_PATH) == ONLP_STATUS_OK) {
|
||||
if(*size == 256) {
|
||||
*data = rdata;
|
||||
return ONLP_STATUS_OK;
|
||||
|
||||
for (i = 0; i < 128; i++) {
|
||||
ret = onlp_i2c_readw(0, 0x56, i*2, ONLP_I2C_F_FORCE);
|
||||
if (ret < 0) {
|
||||
aim_free(rdata);
|
||||
*size = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
rdata[i*2] = ret & 0xff;
|
||||
rdata[i*2+1] = (ret >> 8) & 0xff;
|
||||
}
|
||||
|
||||
aim_free(rdata);
|
||||
*size = 0;
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
*size = 256;
|
||||
*data = rdata;
|
||||
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as5916-54xm-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -17,9 +17,6 @@ class OnlPlatform_x86_64_accton_as5916_54xm_r0(OnlPlatformAccton,
|
||||
self.new_i2c_devices([
|
||||
# initialize multiplexer (PCA9548)
|
||||
('pca9548', 0x77, 0),
|
||||
|
||||
# initiate IDPROM
|
||||
('24c02', 0x56, 0),
|
||||
])
|
||||
|
||||
self.new_i2c_devices([
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as6712-32x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as6712-32x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as6712-32x
|
||||
|
||||
@@ -44,9 +44,6 @@
|
||||
#define NUM_OF_CPLD2_CHANS 0x10
|
||||
#define NUM_OF_CPLD3_CHANS 0x10
|
||||
#define CPLD_CHANNEL_SELECT_REG 0x2
|
||||
#define CPLD_DESELECT_CHANNEL 0xFF
|
||||
|
||||
#define ACCTON_I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD3_CHANS
|
||||
|
||||
static LIST_HEAD(cpld_client_list);
|
||||
static struct mutex list_lock;
|
||||
@@ -64,7 +61,7 @@ enum cpld_mux_type {
|
||||
|
||||
struct as6712_32x_cpld_data {
|
||||
enum cpld_mux_type type;
|
||||
struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS];
|
||||
struct i2c_client *client;
|
||||
u8 last_chan; /* last register value */
|
||||
|
||||
struct device *hwmon_dev;
|
||||
@@ -273,8 +270,9 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
|
||||
int i, status;
|
||||
u8 values[2] = {0};
|
||||
u8 regs[] = {0xA, 0xB};
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
@@ -303,7 +301,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
int status = 0;
|
||||
u8 reg = 0, mask = 0;
|
||||
|
||||
@@ -345,10 +344,11 @@ exit:
|
||||
static ssize_t access(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
int status;
|
||||
u32 addr, val;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
|
||||
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
|
||||
return -EINVAL;
|
||||
@@ -404,32 +404,34 @@ static int as6712_32x_cpld_mux_reg_write(struct i2c_adapter *adap,
|
||||
return res;
|
||||
}
|
||||
|
||||
static int as6712_32x_cpld_mux_select_chan(struct i2c_adapter *adap,
|
||||
void *client, u32 chan)
|
||||
static int as6712_32x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
|
||||
u32 chan)
|
||||
{
|
||||
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
u8 regval;
|
||||
int ret = 0;
|
||||
regval = chan;
|
||||
|
||||
/* Only select the channel if its different from the last channel */
|
||||
if (data->last_chan != regval) {
|
||||
ret = as6712_32x_cpld_mux_reg_write(adap, client, regval);
|
||||
ret = as6712_32x_cpld_mux_reg_write(muxc->parent, client, regval);
|
||||
data->last_chan = regval;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as6712_32x_cpld_mux_deselect_mux(struct i2c_adapter *adap,
|
||||
void *client, u32 chan)
|
||||
static int as6712_32x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc,
|
||||
u32 chan)
|
||||
{
|
||||
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
|
||||
/* Deselect active channel */
|
||||
data->last_chan = chips[data->type].deselectChan;
|
||||
|
||||
return as6712_32x_cpld_mux_reg_write(adap, client, data->last_chan);
|
||||
return as6712_32x_cpld_mux_reg_write(muxc->parent, client, data->last_chan);
|
||||
}
|
||||
|
||||
static void as6712_32x_cpld_add_client(struct i2c_client *client)
|
||||
@@ -456,8 +458,7 @@ static void as6712_32x_cpld_remove_client(struct i2c_client *client)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client == client) {
|
||||
@@ -494,44 +495,43 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c
|
||||
static int as6712_32x_cpld_mux_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
int chan=0;
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
int num, force, class;
|
||||
struct i2c_mux_core *muxc;
|
||||
struct as6712_32x_cpld_data *data;
|
||||
int ret = -ENODEV;
|
||||
const struct attribute_group *group = NULL;
|
||||
int ret = 0;
|
||||
const struct attribute_group *group = NULL;
|
||||
|
||||
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
|
||||
goto exit;
|
||||
return -ENODEV;
|
||||
|
||||
data = kzalloc(sizeof(struct as6712_32x_cpld_data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
muxc = i2c_mux_alloc(adap, &client->dev,
|
||||
chips[id->driver_data].nchans, sizeof(*data), 0,
|
||||
as6712_32x_cpld_mux_select_chan, as6712_32x_cpld_mux_deselect_mux);
|
||||
if (!muxc)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
i2c_set_clientdata(client, muxc);
|
||||
data = i2c_mux_priv(muxc);
|
||||
data->client = client;
|
||||
data->type = id->driver_data;
|
||||
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
||||
mutex_init(&data->update_lock);
|
||||
data->type = id->driver_data;
|
||||
|
||||
if (data->type == as6712_32x_cpld2 || data->type == as6712_32x_cpld3) {
|
||||
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
||||
/* Now create an adapter for each channel */
|
||||
for (num = 0; num < chips[data->type].nchans; num++) {
|
||||
force = 0; /* dynamic adap number */
|
||||
class = 0; /* no class by default */
|
||||
|
||||
/* Now create an adapter for each channel */
|
||||
for (chan = 0; chan < chips[data->type].nchans; chan++) {
|
||||
data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, 0,
|
||||
as6712_32x_cpld_mux_select_chan,
|
||||
as6712_32x_cpld_mux_deselect_mux);
|
||||
ret = i2c_mux_add_adapter(muxc, force, num, class);
|
||||
|
||||
if (data->virt_adaps[chan] == NULL) {
|
||||
ret = -ENODEV;
|
||||
dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan);
|
||||
goto exit_mux_register;
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n",
|
||||
chan, client->name);
|
||||
}
|
||||
if (ret) {
|
||||
dev_err(&client->dev,
|
||||
"failed to register multiplexed adapter"
|
||||
" %d as bus %d\n", num, force);
|
||||
goto add_mux_failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register sysfs hooks */
|
||||
switch (data->type) {
|
||||
@@ -547,33 +547,37 @@ static int as6712_32x_cpld_mux_probe(struct i2c_client *client,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (group) {
|
||||
ret = sysfs_create_group(&client->dev.kobj, group);
|
||||
if (ret) {
|
||||
goto exit_mux_register;
|
||||
goto add_mux_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (chips[data->type].nchans) {
|
||||
dev_info(&client->dev,
|
||||
"registered %d multiplexed busses for I2C %s\n",
|
||||
num, client->name);
|
||||
}
|
||||
else {
|
||||
dev_info(&client->dev,
|
||||
"device %s registered\n", client->name);
|
||||
}
|
||||
|
||||
as6712_32x_cpld_add_client(client);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_mux_register:
|
||||
for (chan--; chan >= 0; chan--) {
|
||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
||||
}
|
||||
kfree(data);
|
||||
exit:
|
||||
add_mux_failed:
|
||||
i2c_mux_del_adapters(muxc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as6712_32x_cpld_mux_remove(struct i2c_client *client)
|
||||
{
|
||||
struct as6712_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
const struct chip_desc *chip = &chips[data->type];
|
||||
int chan;
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as6712_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
const struct attribute_group *group = NULL;
|
||||
|
||||
as6712_32x_cpld_remove_client(client);
|
||||
@@ -597,14 +601,7 @@ static int as6712_32x_cpld_mux_remove(struct i2c_client *client)
|
||||
sysfs_remove_group(&client->dev.kobj, group);
|
||||
}
|
||||
|
||||
for (chan = 0; chan < chip->nchans; ++chan) {
|
||||
if (data->virt_adaps[chan]) {
|
||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
||||
data->virt_adaps[chan] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(data);
|
||||
i2c_mux_del_adapters(muxc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -653,8 +650,7 @@ int as6712_32x_cpld_read(unsigned short cpld_addr, u8 reg)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client->addr == cpld_addr) {
|
||||
@@ -677,8 +673,7 @@ int as6712_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client->addr == cpld_addr) {
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
extern int as6712_32x_cpld_read (unsigned short cpld_addr, u8 reg);
|
||||
extern int as6712_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "as6712_32x_led"
|
||||
|
||||
struct accton_as6712_32x_led_data {
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as6712-32x-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as6812-32x
|
||||
|
||||
@@ -45,9 +45,6 @@
|
||||
#define NUM_OF_CPLD2_CHANS 0x10
|
||||
#define NUM_OF_CPLD3_CHANS 0x10
|
||||
#define CPLD_CHANNEL_SELECT_REG 0x2
|
||||
#define CPLD_DESELECT_CHANNEL 0xFF
|
||||
|
||||
#define ACCTON_I2C_CPLD_MUX_MAX_NCHANS NUM_OF_CPLD3_CHANS
|
||||
|
||||
static LIST_HEAD(cpld_client_list);
|
||||
static struct mutex list_lock;
|
||||
@@ -65,7 +62,7 @@ enum cpld_mux_type {
|
||||
|
||||
struct as6812_32x_cpld_data {
|
||||
enum cpld_mux_type type;
|
||||
struct i2c_adapter *virt_adaps[ACCTON_I2C_CPLD_MUX_MAX_NCHANS];
|
||||
struct i2c_client *client;
|
||||
u8 last_chan; /* last register value */
|
||||
|
||||
struct device *hwmon_dev;
|
||||
@@ -274,8 +271,9 @@ static ssize_t show_present_all(struct device *dev, struct device_attribute *da,
|
||||
int i, status;
|
||||
u8 values[2] = {0};
|
||||
u8 regs[] = {0xA, 0xB};
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as6812_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as6812_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
|
||||
mutex_lock(&data->update_lock);
|
||||
|
||||
@@ -304,7 +302,8 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
|
||||
{
|
||||
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as6812_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as6812_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
int status = 0;
|
||||
u8 reg = 0, mask = 0;
|
||||
|
||||
@@ -346,10 +345,11 @@ exit:
|
||||
static ssize_t access(struct device *dev, struct device_attribute *da,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as6812_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
int status;
|
||||
u32 addr, val;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct as6812_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
|
||||
if (sscanf(buf, "0x%x 0x%x", &addr, &val) != 2) {
|
||||
return -EINVAL;
|
||||
@@ -405,32 +405,34 @@ static int as6812_32x_cpld_mux_reg_write(struct i2c_adapter *adap,
|
||||
return res;
|
||||
}
|
||||
|
||||
static int as6812_32x_cpld_mux_select_chan(struct i2c_adapter *adap,
|
||||
void *client, u32 chan)
|
||||
static int as6812_32x_cpld_mux_select_chan(struct i2c_mux_core *muxc,
|
||||
u32 chan)
|
||||
{
|
||||
struct as6812_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct as6812_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
u8 regval;
|
||||
int ret = 0;
|
||||
regval = chan;
|
||||
|
||||
/* Only select the channel if its different from the last channel */
|
||||
if (data->last_chan != regval) {
|
||||
ret = as6812_32x_cpld_mux_reg_write(adap, client, regval);
|
||||
ret = as6812_32x_cpld_mux_reg_write(muxc->parent, client, regval);
|
||||
data->last_chan = regval;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as6812_32x_cpld_mux_deselect_mux(struct i2c_adapter *adap,
|
||||
void *client, u32 chan)
|
||||
static int as6812_32x_cpld_mux_deselect_mux(struct i2c_mux_core *muxc,
|
||||
u32 chan)
|
||||
{
|
||||
struct as6812_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
struct as6812_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
struct i2c_client *client = data->client;
|
||||
|
||||
/* Deselect active channel */
|
||||
data->last_chan = chips[data->type].deselectChan;
|
||||
|
||||
return as6812_32x_cpld_mux_reg_write(adap, client, data->last_chan);
|
||||
return as6812_32x_cpld_mux_reg_write(muxc->parent, client, data->last_chan);
|
||||
}
|
||||
|
||||
static void as6812_32x_cpld_add_client(struct i2c_client *client)
|
||||
@@ -457,9 +459,8 @@ static void as6812_32x_cpld_remove_client(struct i2c_client *client)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client == client) {
|
||||
found = 1;
|
||||
@@ -495,44 +496,43 @@ static ssize_t show_version(struct device *dev, struct device_attribute *attr, c
|
||||
static int as6812_32x_cpld_mux_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
int chan=0;
|
||||
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
|
||||
int num, force, class;
|
||||
struct i2c_mux_core *muxc;
|
||||
struct as6812_32x_cpld_data *data;
|
||||
int ret = -ENODEV;
|
||||
const struct attribute_group *group = NULL;
|
||||
int ret = 0;
|
||||
const struct attribute_group *group = NULL;
|
||||
|
||||
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
|
||||
goto exit;
|
||||
return -ENODEV;
|
||||
|
||||
data = kzalloc(sizeof(struct as6812_32x_cpld_data), GFP_KERNEL);
|
||||
if (!data) {
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
muxc = i2c_mux_alloc(adap, &client->dev,
|
||||
chips[id->driver_data].nchans, sizeof(*data), 0,
|
||||
as6812_32x_cpld_mux_select_chan, as6812_32x_cpld_mux_deselect_mux);
|
||||
if (!muxc)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, data);
|
||||
i2c_set_clientdata(client, muxc);
|
||||
data = i2c_mux_priv(muxc);
|
||||
data->client = client;
|
||||
data->type = id->driver_data;
|
||||
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
||||
mutex_init(&data->update_lock);
|
||||
data->type = id->driver_data;
|
||||
|
||||
if (data->type == as6812_32x_cpld2 || data->type == as6812_32x_cpld3) {
|
||||
data->last_chan = chips[data->type].deselectChan; /* force the first selection */
|
||||
/* Now create an adapter for each channel */
|
||||
for (num = 0; num < chips[data->type].nchans; num++) {
|
||||
force = 0; /* dynamic adap number */
|
||||
class = 0; /* no class by default */
|
||||
|
||||
/* Now create an adapter for each channel */
|
||||
for (chan = 0; chan < chips[data->type].nchans; chan++) {
|
||||
data->virt_adaps[chan] = i2c_add_mux_adapter(adap, &client->dev, client, 0, chan, 0,
|
||||
as6812_32x_cpld_mux_select_chan,
|
||||
as6812_32x_cpld_mux_deselect_mux);
|
||||
ret = i2c_mux_add_adapter(muxc, force, num, class);
|
||||
|
||||
if (data->virt_adaps[chan] == NULL) {
|
||||
ret = -ENODEV;
|
||||
dev_err(&client->dev, "failed to register multiplexed adapter %d\n", chan);
|
||||
goto exit_mux_register;
|
||||
}
|
||||
}
|
||||
|
||||
dev_info(&client->dev, "registered %d multiplexed busses for I2C mux %s\n",
|
||||
chan, client->name);
|
||||
}
|
||||
if (ret) {
|
||||
dev_err(&client->dev,
|
||||
"failed to register multiplexed adapter"
|
||||
" %d as bus %d\n", num, force);
|
||||
goto add_mux_failed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Register sysfs hooks */
|
||||
switch (data->type) {
|
||||
@@ -553,28 +553,33 @@ static int as6812_32x_cpld_mux_probe(struct i2c_client *client,
|
||||
if (group) {
|
||||
ret = sysfs_create_group(&client->dev.kobj, group);
|
||||
if (ret) {
|
||||
goto exit_mux_register;
|
||||
goto add_mux_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (chips[data->type].nchans) {
|
||||
dev_info(&client->dev,
|
||||
"registered %d multiplexed busses for I2C %s\n",
|
||||
num, client->name);
|
||||
}
|
||||
else {
|
||||
dev_info(&client->dev,
|
||||
"device %s registered\n", client->name);
|
||||
}
|
||||
|
||||
as6812_32x_cpld_add_client(client);
|
||||
|
||||
return 0;
|
||||
|
||||
exit_mux_register:
|
||||
for (chan--; chan >= 0; chan--) {
|
||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
||||
}
|
||||
kfree(data);
|
||||
exit:
|
||||
add_mux_failed:
|
||||
i2c_mux_del_adapters(muxc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int as6812_32x_cpld_mux_remove(struct i2c_client *client)
|
||||
{
|
||||
struct as6812_32x_cpld_data *data = i2c_get_clientdata(client);
|
||||
const struct chip_desc *chip = &chips[data->type];
|
||||
int chan;
|
||||
struct i2c_mux_core *muxc = i2c_get_clientdata(client);
|
||||
struct as6812_32x_cpld_data *data = i2c_mux_priv(muxc);
|
||||
const struct attribute_group *group = NULL;
|
||||
|
||||
as6812_32x_cpld_remove_client(client);
|
||||
@@ -598,14 +603,7 @@ static int as6812_32x_cpld_mux_remove(struct i2c_client *client)
|
||||
sysfs_remove_group(&client->dev.kobj, group);
|
||||
}
|
||||
|
||||
for (chan = 0; chan < chip->nchans; ++chan) {
|
||||
if (data->virt_adaps[chan]) {
|
||||
i2c_del_mux_adapter(data->virt_adaps[chan]);
|
||||
data->virt_adaps[chan] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
kfree(data);
|
||||
i2c_mux_del_adapters(muxc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -654,8 +652,7 @@ int as6812_32x_cpld_read(unsigned short cpld_addr, u8 reg)
|
||||
|
||||
mutex_lock(&list_lock);
|
||||
|
||||
list_for_each(list_node, &cpld_client_list)
|
||||
{
|
||||
list_for_each(list_node, &cpld_client_list) {
|
||||
cpld_node = list_entry(list_node, struct cpld_client_node, list);
|
||||
|
||||
if (cpld_node->client->addr == cpld_addr) {
|
||||
|
||||
@@ -396,7 +396,7 @@ static struct platform_driver accton_as6812_32x_fan_driver = {
|
||||
static int __init accton_as6812_32x_fan_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
ret = platform_driver_register(&accton_as6812_32x_fan_driver);
|
||||
if (ret < 0) {
|
||||
goto exit;
|
||||
|
||||
@@ -32,11 +32,6 @@
|
||||
extern int as6812_32x_cpld_read (unsigned short cpld_addr, u8 reg);
|
||||
extern int as6812_32x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "as6812_32x_led"
|
||||
|
||||
struct accton_as6812_32x_led_data {
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as6812-32x-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as7312-54x ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as7312-54x ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
KERNELS := onl-kernel-3.16-lts-x86-64-all:amd64
|
||||
KERNELS := onl-kernel-4.14-lts-x86-64-all:amd64
|
||||
KMODULES := $(wildcard *.c)
|
||||
VENDOR := accton
|
||||
BASENAME := x86-64-accton-as7312-54x
|
||||
|
||||
@@ -33,11 +33,6 @@
|
||||
extern int as7312_54x_cpld_read (unsigned short cpld_addr, u8 reg);
|
||||
extern int as7312_54x_cpld_write(unsigned short cpld_addr, u8 reg, u8 value);
|
||||
|
||||
extern void led_classdev_unregister(struct led_classdev *led_cdev);
|
||||
extern int led_classdev_register(struct device *parent, struct led_classdev *led_cdev);
|
||||
extern void led_classdev_resume(struct led_classdev *led_cdev);
|
||||
extern void led_classdev_suspend(struct led_classdev *led_cdev);
|
||||
|
||||
#define DRVNAME "accton_as7312_54x_led"
|
||||
|
||||
struct accton_as7312_54x_led_data {
|
||||
|
||||
@@ -18,7 +18,7 @@ x86-64-accton-as7312-54x-r0:
|
||||
--stop=1
|
||||
|
||||
kernel:
|
||||
<<: *kernel-3-16
|
||||
<<: *kernel-4-14
|
||||
|
||||
args: >-
|
||||
nopat
|
||||
|
||||
@@ -1 +1 @@
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as7312-54xs ARCH=amd64 KERNELS="onl-kernel-3.16-lts-x86-64-all:amd64"
|
||||
!include $ONL_TEMPLATES/platform-modules.yml VENDOR=accton BASENAME=x86-64-accton-as7312-54xs ARCH=amd64 KERNELS="onl-kernel-4.14-lts-x86-64-all:amd64"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user