wan: ixp4xx_hss: prepare compile testing
The ixp4xx_hss driver needs the platform data definition and the system clock rate to be compiled. Move both into a new platform_data header file. This is a prerequisite for compile testing, but turning on compile testing requires further patches to isolate the SoC headers. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:

committed by
Jakub Kicinski

parent
504c28c853
commit
c74f16b603
@@ -11,6 +11,7 @@
|
|||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
|
#include <linux/platform_data/wan_ixp4xx_hss.h>
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/serial_8250.h>
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
@@ -405,6 +406,9 @@ static void __init gmlr_init(void)
|
|||||||
if (hw_bits & CFG_HW_HAS_HSS1)
|
if (hw_bits & CFG_HW_HAS_HSS1)
|
||||||
device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
|
device_tab[devices++] = &device_hss_tab[1]; /* max index 5 */
|
||||||
|
|
||||||
|
hss_plat[0].timer_freq = ixp4xx_timer_freq;
|
||||||
|
hss_plat[1].timer_freq = ixp4xx_timer_freq;
|
||||||
|
|
||||||
gpio_request(GPIO_SCL, "SCL/clock");
|
gpio_request(GPIO_SCL, "SCL/clock");
|
||||||
gpio_request(GPIO_SDA, "SDA/data");
|
gpio_request(GPIO_SDA, "SDA/data");
|
||||||
gpio_request(GPIO_STR, "strobe");
|
gpio_request(GPIO_STR, "strobe");
|
||||||
|
@@ -104,15 +104,6 @@ struct eth_plat_info {
|
|||||||
u8 hwaddr[6];
|
u8 hwaddr[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information about built-in HSS (synchronous serial) interfaces */
|
|
||||||
struct hss_plat_info {
|
|
||||||
int (*set_clock)(int port, unsigned int clock_type);
|
|
||||||
int (*open)(int port, void *pdev,
|
|
||||||
void (*set_carrier_cb)(void *pdev, int carrier));
|
|
||||||
void (*close)(int port, void *pdev);
|
|
||||||
u8 txreadyq;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Frequency of clock used for primary clocksource
|
* Frequency of clock used for primary clocksource
|
||||||
*/
|
*/
|
||||||
|
@@ -315,7 +315,8 @@ config DSCC4_PCI_RST
|
|||||||
|
|
||||||
config IXP4XX_HSS
|
config IXP4XX_HSS
|
||||||
tristate "Intel IXP4xx HSS (synchronous serial port) support"
|
tristate "Intel IXP4xx HSS (synchronous serial port) support"
|
||||||
depends on HDLC && ARM && ARCH_IXP4XX && IXP4XX_NPE && IXP4XX_QMGR
|
depends on HDLC && IXP4XX_NPE && IXP4XX_QMGR
|
||||||
|
depends on ARCH_IXP4XX
|
||||||
help
|
help
|
||||||
Say Y here if you want to use built-in HSS ports
|
Say Y here if you want to use built-in HSS ports
|
||||||
on IXP4xx processor.
|
on IXP4xx processor.
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/platform_data/wan_ixp4xx_hss.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/soc/ixp4xx/npe.h>
|
#include <linux/soc/ixp4xx/npe.h>
|
||||||
@@ -1182,14 +1183,14 @@ static int hss_hdlc_attach(struct net_device *dev, unsigned short encoding,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 check_clock(u32 rate, u32 a, u32 b, u32 c,
|
static u32 check_clock(u32 timer_freq, u32 rate, u32 a, u32 b, u32 c,
|
||||||
u32 *best, u32 *best_diff, u32 *reg)
|
u32 *best, u32 *best_diff, u32 *reg)
|
||||||
{
|
{
|
||||||
/* a is 10-bit, b is 10-bit, c is 12-bit */
|
/* a is 10-bit, b is 10-bit, c is 12-bit */
|
||||||
u64 new_rate;
|
u64 new_rate;
|
||||||
u32 new_diff;
|
u32 new_diff;
|
||||||
|
|
||||||
new_rate = ixp4xx_timer_freq * (u64)(c + 1);
|
new_rate = timer_freq * (u64)(c + 1);
|
||||||
do_div(new_rate, a * (c + 1) + b + 1);
|
do_div(new_rate, a * (c + 1) + b + 1);
|
||||||
new_diff = abs((u32)new_rate - rate);
|
new_diff = abs((u32)new_rate - rate);
|
||||||
|
|
||||||
@@ -1201,40 +1202,43 @@ static u32 check_clock(u32 rate, u32 a, u32 b, u32 c,
|
|||||||
return new_diff;
|
return new_diff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void find_best_clock(u32 rate, u32 *best, u32 *reg)
|
static void find_best_clock(u32 timer_freq, u32 rate, u32 *best, u32 *reg)
|
||||||
{
|
{
|
||||||
u32 a, b, diff = 0xFFFFFFFF;
|
u32 a, b, diff = 0xFFFFFFFF;
|
||||||
|
|
||||||
a = ixp4xx_timer_freq / rate;
|
a = timer_freq / rate;
|
||||||
|
|
||||||
if (a > 0x3FF) { /* 10-bit value - we can go as slow as ca. 65 kb/s */
|
if (a > 0x3FF) { /* 10-bit value - we can go as slow as ca. 65 kb/s */
|
||||||
check_clock(rate, 0x3FF, 1, 1, best, &diff, reg);
|
check_clock(timer_freq, rate, 0x3FF, 1, 1, best, &diff, reg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (a == 0) { /* > 66.666 MHz */
|
if (a == 0) { /* > 66.666 MHz */
|
||||||
a = 1; /* minimum divider is 1 (a = 0, b = 1, c = 1) */
|
a = 1; /* minimum divider is 1 (a = 0, b = 1, c = 1) */
|
||||||
rate = ixp4xx_timer_freq;
|
rate = timer_freq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rate * a == ixp4xx_timer_freq) { /* don't divide by 0 later */
|
if (rate * a == timer_freq) { /* don't divide by 0 later */
|
||||||
check_clock(rate, a - 1, 1, 1, best, &diff, reg);
|
check_clock(timer_freq, rate, a - 1, 1, 1, best, &diff, reg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (b = 0; b < 0x400; b++) {
|
for (b = 0; b < 0x400; b++) {
|
||||||
u64 c = (b + 1) * (u64)rate;
|
u64 c = (b + 1) * (u64)rate;
|
||||||
do_div(c, ixp4xx_timer_freq - rate * a);
|
do_div(c, timer_freq - rate * a);
|
||||||
c--;
|
c--;
|
||||||
if (c >= 0xFFF) { /* 12-bit - no need to check more 'b's */
|
if (c >= 0xFFF) { /* 12-bit - no need to check more 'b's */
|
||||||
if (b == 0 && /* also try a bit higher rate */
|
if (b == 0 && /* also try a bit higher rate */
|
||||||
!check_clock(rate, a - 1, 1, 1, best, &diff, reg))
|
!check_clock(timer_freq, rate, a - 1, 1, 1, best,
|
||||||
|
&diff, reg))
|
||||||
return;
|
return;
|
||||||
check_clock(rate, a, b, 0xFFF, best, &diff, reg);
|
check_clock(timer_freq, rate, a, b, 0xFFF, best,
|
||||||
|
&diff, reg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!check_clock(rate, a, b, c, best, &diff, reg))
|
if (!check_clock(timer_freq, rate, a, b, c, best, &diff, reg))
|
||||||
return;
|
return;
|
||||||
if (!check_clock(rate, a, b, c + 1, best, &diff, reg))
|
if (!check_clock(timer_freq, rate, a, b, c + 1, best, &diff,
|
||||||
|
reg))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1285,8 +1289,9 @@ static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||||||
|
|
||||||
port->clock_type = clk; /* Update settings */
|
port->clock_type = clk; /* Update settings */
|
||||||
if (clk == CLOCK_INT)
|
if (clk == CLOCK_INT)
|
||||||
find_best_clock(new_line.clock_rate, &port->clock_rate,
|
find_best_clock(port->plat->timer_freq,
|
||||||
&port->clock_reg);
|
new_line.clock_rate,
|
||||||
|
&port->clock_rate, &port->clock_reg);
|
||||||
else {
|
else {
|
||||||
port->clock_rate = 0;
|
port->clock_rate = 0;
|
||||||
port->clock_reg = CLK42X_SPEED_2048KHZ;
|
port->clock_reg = CLK42X_SPEED_2048KHZ;
|
||||||
|
17
include/linux/platform_data/wan_ixp4xx_hss.h
Normal file
17
include/linux/platform_data/wan_ixp4xx_hss.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
#ifndef __PLATFORM_DATA_WAN_IXP4XX_HSS_H
|
||||||
|
#define __PLATFORM_DATA_WAN_IXP4XX_HSS_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
/* Information about built-in HSS (synchronous serial) interfaces */
|
||||||
|
struct hss_plat_info {
|
||||||
|
int (*set_clock)(int port, unsigned int clock_type);
|
||||||
|
int (*open)(int port, void *pdev,
|
||||||
|
void (*set_carrier_cb)(void *pdev, int carrier));
|
||||||
|
void (*close)(int port, void *pdev);
|
||||||
|
u8 txreadyq;
|
||||||
|
u32 timer_freq;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user