Skip to content

Commit

Permalink
Add kernel parameter to enable i2c-6 pinctrl mapping
Browse files Browse the repository at this point in the history
By default the pinctrl platform driver for Merrifield will register a
pinctrl mapping for i2c-6 that sets the correct pinmux once i2c-6 is
probed. If this is not desired, the following can be added to the kernel
command line: platform_mrfld_pinctrl.pinctrl_i2c6=n

Since the SCU driver is probed after the I2C bus drivers (due to the
order of PCI IDs), setting the pinmux for i2c-6 will fail since the SCU
driver must be probed to successfully set the bufcfg. As a workaround,
the I2C bus driver (i2c-designware-pci) can be compiled as a LKM and
inserted after all other PCI devices have been probed.
  • Loading branch information
svenschwermer committed Oct 14, 2017
1 parent 54f9552 commit 19dc842
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
36 changes: 33 additions & 3 deletions arch/x86/platform/intel-mid/device_libs/platform_mrfld_pinctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/pinctrl/machine.h>
#include <linux/moduleparam.h>

#include <asm/intel-mid.h>

#define FLIS_BASE_ADDR 0xff0c0000
#define FLIS_LENGTH 0x8000

static bool pinctrl_i2c6 = true;

static struct resource mrfld_pinctrl_mmio_resource = {
.start = FLIS_BASE_ADDR,
.end = FLIS_BASE_ADDR + FLIS_LENGTH - 1,
Expand All @@ -33,11 +37,37 @@ static struct platform_device mrfld_pinctrl_device = {
.num_resources = 1,
};

static const struct pinctrl_map mapping[] __initconst = {
{
.dev_name = "0000:00:09.1",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-merrifield",
.data.mux.group = "i2c6_grp",
.data.mux.function = "i2c6",
},
};

static int __init mrfld_pinctrl_init(void)
{
if (intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_TANGIER)
return platform_device_register(&mrfld_pinctrl_device);
int ret;

if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_TANGIER)
return -ENODEV;

return -ENODEV;
ret = platform_device_register(&mrfld_pinctrl_device);
if (ret)
return ret;

if (pinctrl_i2c6) {
ret = pinctrl_register_mappings(mapping, ARRAY_SIZE(mapping));
if (ret)
pr_err("Failed to register i2c6 pinctrl mapping\n");
}

return 0;
}
arch_initcall(mrfld_pinctrl_init);

module_param(pinctrl_i2c6, bool, 0444);
MODULE_PARM_DESC(pinctrl_i2c6, "Configure pinctrl to use i2c-6");
7 changes: 6 additions & 1 deletion drivers/pinctrl/intel/pinctrl-merrifield.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,14 +564,18 @@ static int mrfld_update_phys(struct mrfld_pinctrl *mp, unsigned int pin,
void __iomem *bufcfg;
phys_addr_t phys;
u32 v, value;
int ret;

bufcfg = mrfld_get_bufcfg(mp, pin);
value = readl(bufcfg);

v = (value & ~mask) | (bits & mask);

phys = mrfld_get_phys(mp, pin);
return intel_scu_ipc_raw_command(cmd, 0, (u8 *)&v, 4, NULL, 0, phys, 0);
ret = intel_scu_ipc_raw_command(cmd, 0, (u8 *)&v, 4, NULL, 0, phys, 0);
if (ret)
dev_err(mp->dev, "Failed to set bufcfg via SCU IPC for pin %u (%d)\n", pin, ret);
return ret;
}

static int mrfld_get_groups_count(struct pinctrl_dev *pctldev)
Expand Down Expand Up @@ -682,6 +686,7 @@ static int mrfld_pinmux_set_mux(struct pinctrl_dev *pctldev,

if (protected) {
for (i = 0; i < grp->npins; i++)
/* TODO: We always return success, because rolling back is a challenge */
mrfld_update_phys(mp, grp->pins[i], bits, mask);
return 0;
}
Expand Down

4 comments on commit 19dc842

@andy-shev
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for finding a root cause why it wasn't working!
Though, looking to above change makes me clear that it should be done rather in U-Boot.

@andy-shev
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, there are macros to help filling mappings structure http://elixir.free-electrons.com/linux/latest/source/include/linux/pinctrl/machine.h#L88

@svenschwermer
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't deny that this is a hack ;)
I am aware of the macros, but I had to go back and forth a lot and not using the macro gave me some extra agility. For some reason, I never went back to using the macro.

@andy-shev
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TWIMC, I2C mode has been "fixed" thru U-Boot: u-boot/u-boot@f26b260

Please sign in to comment.